Skip to content

Commit 46d4a60

Browse files
Vladimir Kozlovstefankplummercj
committed
8349088: De-virtualize Codeblob and nmethod
Co-authored-by: Stefan Karlsson <stefank@openjdk.org> Co-authored-by: Chris Plummer <cjplummer@openjdk.org> Reviewed-by: cjplummer, aboldtch, dlong
1 parent 62d93f2 commit 46d4a60

23 files changed

+377
-267
lines changed

src/hotspot/share/code/codeBlob.cpp

Lines changed: 96 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,53 @@
5353
#include "c1/c1_Runtime1.hpp"
5454
#endif
5555

56+
#include <type_traits>
57+
58+
// Virtual methods are not allowed in code blobs to simplify caching compiled code.
59+
// Check all "leaf" subclasses of CodeBlob class.
60+
61+
static_assert(!std::is_polymorphic<nmethod>::value, "no virtual methods are allowed in nmethod");
62+
static_assert(!std::is_polymorphic<AdapterBlob>::value, "no virtual methods are allowed in code blobs");
63+
static_assert(!std::is_polymorphic<VtableBlob>::value, "no virtual methods are allowed in code blobs");
64+
static_assert(!std::is_polymorphic<MethodHandlesAdapterBlob>::value, "no virtual methods are allowed in code blobs");
65+
static_assert(!std::is_polymorphic<RuntimeStub>::value, "no virtual methods are allowed in code blobs");
66+
static_assert(!std::is_polymorphic<DeoptimizationBlob>::value, "no virtual methods are allowed in code blobs");
67+
static_assert(!std::is_polymorphic<SafepointBlob>::value, "no virtual methods are allowed in code blobs");
68+
static_assert(!std::is_polymorphic<UpcallStub>::value, "no virtual methods are allowed in code blobs");
69+
#ifdef COMPILER2
70+
static_assert(!std::is_polymorphic<ExceptionBlob>::value, "no virtual methods are allowed in code blobs");
71+
static_assert(!std::is_polymorphic<UncommonTrapBlob>::value, "no virtual methods are allowed in code blobs");
72+
#endif
73+
74+
// Add proxy vtables.
75+
// We need only few for now - they are used only from prints.
76+
const nmethod::Vptr nmethod::_vptr;
77+
const BufferBlob::Vptr BufferBlob::_vptr;
78+
const RuntimeStub::Vptr RuntimeStub::_vptr;
79+
const SingletonBlob::Vptr SingletonBlob::_vptr;
80+
const DeoptimizationBlob::Vptr DeoptimizationBlob::_vptr;
81+
const UpcallStub::Vptr UpcallStub::_vptr;
82+
83+
const CodeBlob::Vptr* CodeBlob::vptr() const {
84+
constexpr const CodeBlob::Vptr* array[(size_t)CodeBlobKind::Number_Of_Kinds] = {
85+
nullptr/* None */,
86+
&nmethod::_vptr,
87+
&BufferBlob::_vptr,
88+
&AdapterBlob::_vptr,
89+
&VtableBlob::_vptr,
90+
&MethodHandlesAdapterBlob::_vptr,
91+
&RuntimeStub::_vptr,
92+
&DeoptimizationBlob::_vptr,
93+
&SafepointBlob::_vptr,
94+
#ifdef COMPILER2
95+
&ExceptionBlob::_vptr,
96+
&UncommonTrapBlob::_vptr,
97+
#endif
98+
&UpcallStub::_vptr
99+
};
100+
101+
return array[(size_t)_kind];
102+
}
56103

57104
unsigned int CodeBlob::align_code_offset(int offset) {
58105
// align the size to CodeEntryAlignment
@@ -386,7 +433,7 @@ RuntimeStub::RuntimeStub(
386433
OopMapSet* oop_maps,
387434
bool caller_must_gc_arguments
388435
)
389-
: RuntimeBlob(name, CodeBlobKind::Runtime_Stub, cb, size, sizeof(RuntimeStub),
436+
: RuntimeBlob(name, CodeBlobKind::RuntimeStub, cb, size, sizeof(RuntimeStub),
390437
frame_complete, frame_size, oop_maps, caller_must_gc_arguments)
391438
{
392439
}
@@ -482,18 +529,18 @@ DeoptimizationBlob* DeoptimizationBlob::create(
482529
return blob;
483530
}
484531

532+
#ifdef COMPILER2
485533

486534
//----------------------------------------------------------------------------------------------------
487535
// Implementation of UncommonTrapBlob
488536

489-
#ifdef COMPILER2
490537
UncommonTrapBlob::UncommonTrapBlob(
491538
CodeBuffer* cb,
492539
int size,
493540
OopMapSet* oop_maps,
494541
int frame_size
495542
)
496-
: SingletonBlob("UncommonTrapBlob", CodeBlobKind::Uncommon_Trap, cb,
543+
: SingletonBlob("UncommonTrapBlob", CodeBlobKind::UncommonTrap, cb,
497544
size, sizeof(UncommonTrapBlob), frame_size, oop_maps)
498545
{}
499546

@@ -516,14 +563,9 @@ UncommonTrapBlob* UncommonTrapBlob::create(
516563
return blob;
517564
}
518565

519-
520-
#endif // COMPILER2
521-
522-
523566
//----------------------------------------------------------------------------------------------------
524567
// Implementation of ExceptionBlob
525568

526-
#ifdef COMPILER2
527569
ExceptionBlob::ExceptionBlob(
528570
CodeBuffer* cb,
529571
int size,
@@ -553,10 +595,8 @@ ExceptionBlob* ExceptionBlob::create(
553595
return blob;
554596
}
555597

556-
557598
#endif // COMPILER2
558599

559-
560600
//----------------------------------------------------------------------------------------------------
561601
// Implementation of SafepointBlob
562602

@@ -644,17 +684,45 @@ void UpcallStub::free(UpcallStub* blob) {
644684
//----------------------------------------------------------------------------------------------------
645685
// Verification and printing
646686

687+
void CodeBlob::verify() {
688+
if (is_nmethod()) {
689+
as_nmethod()->verify();
690+
}
691+
}
692+
647693
void CodeBlob::print_on(outputStream* st) const {
648-
st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this));
649-
st->print_cr("Framesize: %d", _frame_size);
694+
vptr()->print_on(this, st);
650695
}
651696

652697
void CodeBlob::print() const { print_on(tty); }
653698

654699
void CodeBlob::print_value_on(outputStream* st) const {
700+
vptr()->print_value_on(this, st);
701+
}
702+
703+
void CodeBlob::print_on_impl(outputStream* st) const {
704+
st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this));
705+
st->print_cr("Framesize: %d", _frame_size);
706+
}
707+
708+
void CodeBlob::print_value_on_impl(outputStream* st) const {
655709
st->print_cr("[CodeBlob]");
656710
}
657711

712+
void CodeBlob::print_block_comment(outputStream* stream, address block_begin) const {
713+
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
714+
if (is_nmethod()) {
715+
as_nmethod()->print_nmethod_labels(stream, block_begin);
716+
}
717+
#endif
718+
719+
#ifndef PRODUCT
720+
ptrdiff_t offset = block_begin - code_begin();
721+
assert(offset >= 0, "Expecting non-negative offset!");
722+
_asm_remarks.print(uint(offset), stream);
723+
#endif
724+
}
725+
658726
void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const {
659727
if (is_buffer_blob() || is_adapter_blob() || is_vtable_blob() || is_method_handles_adapter_blob()) {
660728
// the interpreter is generated into a buffer blob
@@ -708,76 +776,60 @@ void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const
708776
// verbose is only ever true when called from findpc in debug.cpp
709777
nm->print_nmethod(true);
710778
} else {
711-
nm->print(st);
779+
nm->print_on(st);
712780
}
713781
return;
714782
}
715783
st->print_cr(INTPTR_FORMAT " is at code_begin+%d in ", p2i(addr), (int)(addr - code_begin()));
716784
print_on(st);
717785
}
718786

719-
void BufferBlob::verify() {
720-
// unimplemented
787+
void BufferBlob::print_on_impl(outputStream* st) const {
788+
RuntimeBlob::print_on_impl(st);
789+
print_value_on_impl(st);
721790
}
722791

723-
void BufferBlob::print_on(outputStream* st) const {
724-
RuntimeBlob::print_on(st);
725-
print_value_on(st);
726-
}
727-
728-
void BufferBlob::print_value_on(outputStream* st) const {
792+
void BufferBlob::print_value_on_impl(outputStream* st) const {
729793
st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name());
730794
}
731795

732-
void RuntimeStub::verify() {
733-
// unimplemented
734-
}
735-
736-
void RuntimeStub::print_on(outputStream* st) const {
796+
void RuntimeStub::print_on_impl(outputStream* st) const {
737797
ttyLocker ttyl;
738-
RuntimeBlob::print_on(st);
798+
RuntimeBlob::print_on_impl(st);
739799
st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this));
740800
st->print_cr("%s", name());
741801
Disassembler::decode((RuntimeBlob*)this, st);
742802
}
743803

744-
void RuntimeStub::print_value_on(outputStream* st) const {
804+
void RuntimeStub::print_value_on_impl(outputStream* st) const {
745805
st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name());
746806
}
747807

748-
void SingletonBlob::verify() {
749-
// unimplemented
750-
}
751-
752-
void SingletonBlob::print_on(outputStream* st) const {
808+
void SingletonBlob::print_on_impl(outputStream* st) const {
753809
ttyLocker ttyl;
754-
RuntimeBlob::print_on(st);
810+
RuntimeBlob::print_on_impl(st);
755811
st->print_cr("%s", name());
756812
Disassembler::decode((RuntimeBlob*)this, st);
757813
}
758814

759-
void SingletonBlob::print_value_on(outputStream* st) const {
815+
void SingletonBlob::print_value_on_impl(outputStream* st) const {
760816
st->print_cr("%s", name());
761817
}
762818

763-
void DeoptimizationBlob::print_value_on(outputStream* st) const {
819+
void DeoptimizationBlob::print_value_on_impl(outputStream* st) const {
764820
st->print_cr("Deoptimization (frame not available)");
765821
}
766822

767-
void UpcallStub::verify() {
768-
// unimplemented
769-
}
770-
771-
void UpcallStub::print_on(outputStream* st) const {
772-
RuntimeBlob::print_on(st);
773-
print_value_on(st);
823+
void UpcallStub::print_on_impl(outputStream* st) const {
824+
RuntimeBlob::print_on_impl(st);
825+
print_value_on_impl(st);
774826
st->print_cr("Frame data offset: %d", (int) _frame_data_offset);
775827
oop recv = JNIHandles::resolve(_receiver);
776828
st->print("Receiver MH=");
777829
recv->print_on(st);
778830
Disassembler::decode((RuntimeBlob*)this, st);
779831
}
780832

781-
void UpcallStub::print_value_on(outputStream* st) const {
833+
void UpcallStub::print_value_on_impl(outputStream* st) const {
782834
st->print_cr("UpcallStub (" INTPTR_FORMAT ") used for %s", p2i(this), name());
783835
}

0 commit comments

Comments
 (0)