diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 748c3e8fb11..4b3b8e58b9a 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -683,12 +683,12 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, int comp_args_on_stack, const BasicType *sig_bt, const VMRegPair *regs, - AdapterHandlerEntry* handler) { - address i2c_entry = __ pc(); + address entry_address[AdapterBlob::ENTRY_COUNT]) { + entry_address[AdapterBlob::I2C] = __ pc(); gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); - address c2i_unverified_entry = __ pc(); + entry_address[AdapterBlob::C2I_Unverified] = __ pc(); Label skip_fixup; Register data = rscratch2; @@ -718,10 +718,10 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ block_comment("} c2i_unverified_entry"); } - address c2i_entry = __ pc(); + entry_address[AdapterBlob::C2I] = __ pc(); // Class initialization barrier for static methods - address c2i_no_clinit_check_entry = nullptr; + entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr; if (VM_Version::supports_fast_class_init_checks()) { Label L_skip_barrier; @@ -736,15 +736,13 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); __ bind(L_skip_barrier); - c2i_no_clinit_check_entry = __ pc(); + entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc(); } BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); bs->c2i_entry_barrier(masm); gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); - - handler->set_entry_points(i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry); return; } diff --git a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp index dcf631525ab..9e90b56f9f0 100644 --- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp +++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp @@ -617,11 +617,11 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, int comp_args_on_stack, const BasicType *sig_bt, const VMRegPair *regs, - AdapterHandlerEntry* handler) { - address i2c_entry = __ pc(); + address entry_address[AdapterBlob::ENTRY_COUNT]) { + entry_address[AdapterBlob::I2C] = __ pc(); gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); - address c2i_unverified_entry = __ pc(); + entry_address[AdapterBlob::C2I_Unverified] = __ pc(); Label skip_fixup; const Register receiver = R0; const Register holder_klass = Rtemp; // XXX should be OK for C2 but not 100% sure @@ -634,10 +634,9 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ b(skip_fixup, eq); __ jump(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type, noreg, ne); - address c2i_entry = __ pc(); + entry_address[AdapterBlob::C2I] = __ pc(); + entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr; gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); - - handler->set_entry_points(i2c_entry, c2i_entry, c2i_unverified_entry, nullptr); return; } diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index 2a9bad059ba..aec36b3f3f9 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1199,16 +1199,11 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, int comp_args_on_stack, const BasicType *sig_bt, const VMRegPair *regs, - AdapterHandlerEntry* handler) { - address i2c_entry; - address c2i_unverified_entry; - address c2i_entry; - - + address entry_address[AdapterBlob::ENTRY_COUNT]) { // entry: i2c __ align(CodeEntryAlignment); - i2c_entry = __ pc(); + entry_address[AdapterBlob::I2C] = __ pc(); gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); @@ -1216,7 +1211,7 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ align(CodeEntryAlignment); BLOCK_COMMENT("c2i unverified entry"); - c2i_unverified_entry = __ pc(); + entry_address[AdapterBlob::C2I_Unverified] = __ pc(); // inline_cache contains a CompiledICData const Register ic = R19_inline_cache_reg; @@ -1244,10 +1239,10 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, // entry: c2i - c2i_entry = __ pc(); + entry_address[AdapterBlob::C2I] = __ pc(); // Class initialization barrier for static methods - address c2i_no_clinit_check_entry = nullptr; + entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr; if (VM_Version::supports_fast_class_init_checks()) { Label L_skip_barrier; @@ -1266,15 +1261,13 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ bctr(); __ bind(L_skip_barrier); - c2i_no_clinit_check_entry = __ pc(); + entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc(); } BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); bs->c2i_entry_barrier(masm, /* tmp register*/ ic_klass, /* tmp register*/ receiver_klass, /* tmp register*/ code); gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, call_interpreter, ientry); - - handler->set_entry_points(i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry); return; } diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 2cc1fb8eeff..01970c68090 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -602,11 +602,11 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, int comp_args_on_stack, const BasicType *sig_bt, const VMRegPair *regs, - AdapterHandlerEntry* handler) { - address i2c_entry = __ pc(); + address entry_address[AdapterBlob::ENTRY_COUNT]) { + entry_address[AdapterBlob::I2C] = __ pc(); gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); - address c2i_unverified_entry = __ pc(); + entry_address[AdapterBlob::C2I_Unverified] = __ pc(); Label skip_fixup; const Register receiver = j_rarg0; @@ -633,10 +633,10 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ block_comment("} c2i_unverified_entry"); } - address c2i_entry = __ pc(); + entry_address[AdapterBlob::C2I] = __ pc(); // Class initialization barrier for static methods - address c2i_no_clinit_check_entry = nullptr; + entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr; if (VM_Version::supports_fast_class_init_checks()) { Label L_skip_barrier; @@ -651,15 +651,13 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); __ bind(L_skip_barrier); - c2i_no_clinit_check_entry = __ pc(); + entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc(); } BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); bs->c2i_entry_barrier(masm); gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); - - handler->set_entry_points(i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry); return; } diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 3b1d06cf560..db1ee8351ac 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -2347,13 +2347,11 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, int comp_args_on_stack, const BasicType *sig_bt, const VMRegPair *regs, - AdapterHandlerEntry* handler) { + address entry_address[AdapterBlob::ENTRY_COUNT]) { __ align(CodeEntryAlignment); - address i2c_entry = __ pc(); + entry_address[AdapterBlob::I2C] = __ pc(); gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); - address c2i_unverified_entry; - Label skip_fixup; { Label ic_miss; @@ -2363,7 +2361,7 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, // Unverified Entry Point UEP __ align(CodeEntryAlignment); - c2i_unverified_entry = __ pc(); + entry_address[AdapterBlob::C2I_Unverified] = __ pc(); __ ic_check(2); __ z_lg(Z_method, Address(Z_inline_cache, CompiledICData::speculated_method_offset())); @@ -2376,10 +2374,10 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, // Fallthru to VEP. Duplicate LTG, but saved taken branch. } - address c2i_entry = __ pc(); + entry_address[AdapterBlob::C2I] = __ pc(); // Class initialization barrier for static methods - address c2i_no_clinit_check_entry = nullptr; + entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr; if (VM_Version::supports_fast_class_init_checks()) { Label L_skip_barrier; @@ -2396,12 +2394,10 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ z_br(klass); __ bind(L_skip_barrier); - c2i_no_clinit_check_entry = __ pc(); + entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc(); } gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); - - handler->set_entry_points(i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry); return; } diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index d60f535fefc..e2a8f36b050 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -1007,8 +1007,8 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, int comp_args_on_stack, const BasicType *sig_bt, const VMRegPair *regs, - AdapterHandlerEntry* handler) { - address i2c_entry = __ pc(); + address entry_address[AdapterBlob::ENTRY_COUNT]) { + entry_address[AdapterBlob::I2C] = __ pc(); gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); @@ -1021,7 +1021,7 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, // On exit from the interpreter, the interpreter will restore our SP (lest the // compiled code, which relies solely on SP and not RBP, get sick). - address c2i_unverified_entry = __ pc(); + entry_address[AdapterBlob::C2I_Unverified] = __ pc(); Label skip_fixup; Register data = rax; @@ -1039,10 +1039,10 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); } - address c2i_entry = __ pc(); + entry_address[AdapterBlob::C2I] = __ pc(); // Class initialization barrier for static methods - address c2i_no_clinit_check_entry = nullptr; + entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr; if (VM_Version::supports_fast_class_init_checks()) { Label L_skip_barrier; Register method = rbx; @@ -1061,15 +1061,13 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path __ bind(L_skip_barrier); - c2i_no_clinit_check_entry = __ pc(); + entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc(); } BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); bs->c2i_entry_barrier(masm); gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); - - handler->set_entry_points(i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry); return; } diff --git a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp index b2e406c205b..6e18097c992 100644 --- a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp +++ b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp @@ -38,12 +38,6 @@ #include "opto/runtime.hpp" #endif - -static address zero_null_code_stub() { - address start = ShouldNotCallThisStub(); - return start; -} - int SharedRuntime::java_calling_convention(const BasicType *sig_bt, VMRegPair *regs, int total_args_passed) { @@ -55,12 +49,9 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, int comp_args_on_stack, const BasicType *sig_bt, const VMRegPair *regs, - AdapterHandlerEntry* handler) { - // foil any attempt to call the i2c, c2i or unverified c2i entries - handler->set_entry_points(CAST_FROM_FN_PTR(address,zero_null_code_stub), - CAST_FROM_FN_PTR(address,zero_null_code_stub), - CAST_FROM_FN_PTR(address,zero_null_code_stub), - nullptr); + address entry_address[AdapterBlob::ENTRY_COUNT]) { + ShouldNotCallThis(); + return; } nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 9ec5478a071..18e77520139 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -448,16 +448,19 @@ void BufferBlob::free(BufferBlob *blob) { AdapterBlob::AdapterBlob(int size, CodeBuffer* cb, int entry_offset[AdapterBlob::ENTRY_COUNT]) : BufferBlob("I2C/C2I adapters", CodeBlobKind::Adapter, cb, size, sizeof(AdapterBlob)) { - assert(entry_offset[0] == 0, "sanity check"); + assert(entry_offset[I2C] == 0, "sanity check"); +#ifdef ASSERT for (int i = 1; i < AdapterBlob::ENTRY_COUNT; i++) { // The entry is within the adapter blob or unset. - assert((entry_offset[i] > 0 && entry_offset[i] < cb->insts()->size()) || - (entry_offset[i] == -1), - "invalid entry offset[%d] = 0x%x", i, entry_offset[i]); + int offset = entry_offset[i]; + assert((offset > 0 && offset < cb->insts()->size()) || + (i >= C2I_No_Clinit_Check && offset == -1), + "invalid entry offset[%d] = 0x%x", i, offset); } - _c2i_offset = entry_offset[1]; - _c2i_unverified_offset = entry_offset[2]; - _c2i_no_clinit_check_offset = entry_offset[3]; +#endif // ASSERT + _c2i_offset = entry_offset[C2I]; + _c2i_unverified_offset = entry_offset[C2I_Unverified]; + _c2i_no_clinit_check_offset = entry_offset[C2I_No_Clinit_Check]; CodeCache::commit(this); } @@ -478,13 +481,6 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb, int entry_offset[AdapterBlob::E return blob; } -void AdapterBlob::get_offsets(int entry_offset[ENTRY_COUNT]) { - entry_offset[0] = 0; - entry_offset[1] = _c2i_offset; - entry_offset[2] = _c2i_unverified_offset; - entry_offset[3] = _c2i_no_clinit_check_offset; -} - //---------------------------------------------------------------------------------------------------- // Implementation of VtableBlob diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index 407974f0428..0b4760e7e1e 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -405,7 +405,13 @@ class BufferBlob: public RuntimeBlob { class AdapterBlob: public BufferBlob { public: - static const int ENTRY_COUNT = 4; + enum Entry { + I2C, + C2I, + C2I_Unverified, + C2I_No_Clinit_Check, + ENTRY_COUNT + }; private: AdapterBlob(int size, CodeBuffer* cb, int entry_offset[ENTRY_COUNT]); // _i2c_offset is always 0 so no need to store it @@ -415,7 +421,10 @@ private: public: // Creation static AdapterBlob* create(CodeBuffer* cb, int entry_offset[ENTRY_COUNT]); - void get_offsets(int entry_offset[ENTRY_COUNT]); + address i2c_entry() { return code_begin(); } + address c2i_entry() { return i2c_entry() + _c2i_offset; } + address c2i_unverified_entry() { return i2c_entry() + _c2i_unverified_offset; } + address c2i_no_clinit_check_entry() { return _c2i_no_clinit_check_offset == -1 ? nullptr : i2c_entry() + _c2i_no_clinit_check_offset; } }; //--------------------------------------------------------------------------------------------------- diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index c09a6c14485..cb1c8ea37e8 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1287,7 +1287,9 @@ void Method::link_method(const methodHandle& h_method, TRAPS) { h_method->_from_compiled_entry = SharedRuntime::get_handle_wrong_method_abstract_stub(); } else if (_adapter == nullptr) { (void) make_adapters(h_method, CHECK); +#ifndef ZERO assert(adapter()->is_linked(), "Adapter must have been linked"); +#endif h_method->_from_compiled_entry = adapter()->get_c2i_entry(); } diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 2f7161ff744..c3a6e0a4dc3 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -2526,21 +2526,21 @@ BufferBlob* AdapterHandlerLibrary::buffer_blob() { return _buffer; } -static void post_adapter_creation(const AdapterBlob* new_adapter, - const AdapterHandlerEntry* entry) { +static void post_adapter_creation(const AdapterHandlerEntry* entry) { if (Forte::is_enabled() || JvmtiExport::should_post_dynamic_code_generated()) { + AdapterBlob* adapter_blob = entry->adapter_blob(); char blob_id[256]; jio_snprintf(blob_id, sizeof(blob_id), "%s(%s)", - new_adapter->name(), + adapter_blob->name(), entry->fingerprint()->as_string()); if (Forte::is_enabled()) { - Forte::register_stub(blob_id, new_adapter->content_begin(), new_adapter->content_end()); + Forte::register_stub(blob_id, adapter_blob->content_begin(), adapter_blob->content_end()); } if (JvmtiExport::should_post_dynamic_code_generated()) { - JvmtiExport::post_dynamic_code_generated(blob_id, new_adapter->content_begin(), new_adapter->content_end()); + JvmtiExport::post_dynamic_code_generated(blob_id, adapter_blob->content_begin(), adapter_blob->content_end()); } } } @@ -2562,27 +2562,22 @@ void AdapterHandlerLibrary::initialize() { #endif // INCLUDE_CDS ResourceMark rm; - AdapterBlob* no_arg_blob = nullptr; - AdapterBlob* int_arg_blob = nullptr; - AdapterBlob* obj_arg_blob = nullptr; - AdapterBlob* obj_int_arg_blob = nullptr; - AdapterBlob* obj_obj_arg_blob = nullptr; { MutexLocker mu(AdapterHandlerLibrary_lock); - _no_arg_handler = create_adapter(no_arg_blob, 0, nullptr); + _no_arg_handler = create_adapter(0, nullptr); BasicType obj_args[] = { T_OBJECT }; - _obj_arg_handler = create_adapter(obj_arg_blob, 1, obj_args); + _obj_arg_handler = create_adapter(1, obj_args); BasicType int_args[] = { T_INT }; - _int_arg_handler = create_adapter(int_arg_blob, 1, int_args); + _int_arg_handler = create_adapter(1, int_args); BasicType obj_int_args[] = { T_OBJECT, T_INT }; - _obj_int_arg_handler = create_adapter(obj_int_arg_blob, 2, obj_int_args); + _obj_int_arg_handler = create_adapter(2, obj_int_args); BasicType obj_obj_args[] = { T_OBJECT, T_OBJECT }; - _obj_obj_arg_handler = create_adapter(obj_obj_arg_blob, 2, obj_obj_args); + _obj_obj_arg_handler = create_adapter(2, obj_obj_args); // we should always get an entry back but we don't have any // associated blob on Zero @@ -2596,11 +2591,11 @@ void AdapterHandlerLibrary::initialize() { // Outside of the lock #ifndef ZERO // no blobs to register when we are on Zero - post_adapter_creation(no_arg_blob, _no_arg_handler); - post_adapter_creation(obj_arg_blob, _obj_arg_handler); - post_adapter_creation(int_arg_blob, _int_arg_handler); - post_adapter_creation(obj_int_arg_blob, _obj_int_arg_handler); - post_adapter_creation(obj_obj_arg_blob, _obj_obj_arg_handler); + post_adapter_creation(_no_arg_handler); + post_adapter_creation(_obj_arg_handler); + post_adapter_creation(_int_arg_handler); + post_adapter_creation(_obj_int_arg_handler); + post_adapter_creation(_obj_obj_arg_handler); #endif // ZERO } @@ -2695,9 +2690,8 @@ const char* AdapterHandlerEntry::_entry_names[] = { void AdapterHandlerLibrary::verify_adapter_sharing(int total_args_passed, BasicType* sig_bt, AdapterHandlerEntry* cached_entry) { // we can only check for the same code if there is any #ifndef ZERO - AdapterBlob* comparison_blob = nullptr; - AdapterHandlerEntry* comparison_entry = create_adapter(comparison_blob, total_args_passed, sig_bt, true); - assert(comparison_blob == nullptr, "no blob should be created when creating an adapter for comparison"); + AdapterHandlerEntry* comparison_entry = create_adapter(total_args_passed, sig_bt, true); + assert(comparison_entry->adapter_blob() == nullptr, "no blob should be created when creating an adapter for comparison"); assert(comparison_entry->compare_code(cached_entry), "code must match"); // Release the one just created AdapterHandlerEntry::deallocate(comparison_entry); @@ -2719,7 +2713,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& meth } ResourceMark rm; - AdapterBlob* adapter_blob = nullptr; + bool new_entry = false; // Fill in the signature array, for the calling-convention call. int total_args_passed = method->size_of_parameters(); // All args on stack @@ -2735,54 +2729,48 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& meth entry = lookup(total_args_passed, sig_bt); if (entry != nullptr) { +#ifndef ZERO assert(entry->is_linked(), "AdapterHandlerEntry must have been linked"); +#endif #ifdef ASSERT if (!entry->in_aot_cache() && VerifyAdapterSharing) { verify_adapter_sharing(total_args_passed, sig_bt, entry); } #endif } else { - entry = create_adapter(adapter_blob, total_args_passed, sig_bt); + entry = create_adapter(total_args_passed, sig_bt); + if (entry != nullptr) { + new_entry = true; + } } } // Outside of the lock - if (adapter_blob != nullptr) { - post_adapter_creation(adapter_blob, entry); + if (new_entry) { + post_adapter_creation(entry); } return entry; } -AdapterBlob* AdapterHandlerLibrary::lookup_aot_cache(AdapterHandlerEntry* handler) { +void AdapterHandlerLibrary::lookup_aot_cache(AdapterHandlerEntry* handler) { ResourceMark rm; const char* name = AdapterHandlerLibrary::name(handler->fingerprint()); const uint32_t id = AdapterHandlerLibrary::id(handler->fingerprint()); - int offsets[AdapterBlob::ENTRY_COUNT]; - AdapterBlob* adapter_blob = nullptr; CodeBlob* blob = AOTCodeCache::load_code_blob(AOTCodeEntry::Adapter, id, name); if (blob != nullptr) { - adapter_blob = blob->as_adapter_blob(); - adapter_blob->get_offsets(offsets); - address i2c_entry = adapter_blob->content_begin(); - assert(offsets[0] == 0, "sanity check"); - handler->set_entry_points( - i2c_entry, - (offsets[1] != -1) ? (i2c_entry + offsets[1]) : nullptr, - (offsets[2] != -1) ? (i2c_entry + offsets[2]) : nullptr, - (offsets[3] != -1) ? (i2c_entry + offsets[3]) : nullptr - ); + handler->set_adapter_blob(blob->as_adapter_blob()); } - return adapter_blob; } #ifndef PRODUCT -void AdapterHandlerLibrary::print_adapter_handler_info(outputStream* st, AdapterHandlerEntry* handler, AdapterBlob* adapter_blob) { +void AdapterHandlerLibrary::print_adapter_handler_info(outputStream* st, AdapterHandlerEntry* handler) { ttyLocker ttyl; ResourceMark rm; int insts_size; // on Zero the blob may be null handler->print_adapter_on(tty); + AdapterBlob* adapter_blob = handler->adapter_blob(); if (adapter_blob == nullptr) { return; } @@ -2792,7 +2780,7 @@ void AdapterHandlerLibrary::print_adapter_handler_info(outputStream* st, Adapter handler->fingerprint()->as_string(), insts_size); st->print_cr("c2i argument handler starts at " INTPTR_FORMAT, p2i(handler->get_c2i_entry())); if (Verbose || PrintStubCode) { - address first_pc = handler->base_address(); + address first_pc = adapter_blob->content_begin(); if (first_pc != nullptr) { Disassembler::decode(first_pc, first_pc + insts_size, st, &adapter_blob->asm_remarks()); st->cr(); @@ -2801,8 +2789,19 @@ void AdapterHandlerLibrary::print_adapter_handler_info(outputStream* st, Adapter } #endif // PRODUCT -bool AdapterHandlerLibrary::generate_adapter_code(AdapterBlob*& adapter_blob, - AdapterHandlerEntry* handler, +void AdapterHandlerLibrary::address_to_offset(address entry_address[AdapterBlob::ENTRY_COUNT], + int entry_offset[AdapterBlob::ENTRY_COUNT]) { + entry_offset[AdapterBlob::I2C] = 0; + entry_offset[AdapterBlob::C2I] = entry_address[AdapterBlob::C2I] - entry_address[AdapterBlob::I2C]; + entry_offset[AdapterBlob::C2I_Unverified] = entry_address[AdapterBlob::C2I_Unverified] - entry_address[AdapterBlob::I2C]; + if (entry_address[AdapterBlob::C2I_No_Clinit_Check] == nullptr) { + entry_offset[AdapterBlob::C2I_No_Clinit_Check] = -1; + } else { + entry_offset[AdapterBlob::C2I_No_Clinit_Check] = entry_address[AdapterBlob::C2I_No_Clinit_Check] - entry_address[AdapterBlob::I2C]; + } +} + +bool AdapterHandlerLibrary::generate_adapter_code(AdapterHandlerEntry* handler, int total_args_passed, BasicType* sig_bt, bool is_transient) { @@ -2810,6 +2809,7 @@ bool AdapterHandlerLibrary::generate_adapter_code(AdapterBlob*& adapter_blob, ClassLoader::perf_method_adapters_count()->inc(); } +#ifndef ZERO BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache CodeBuffer buffer(buf); short buffer_locs[20]; @@ -2821,17 +2821,17 @@ bool AdapterHandlerLibrary::generate_adapter_code(AdapterBlob*& adapter_blob, // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed); + address entry_address[AdapterBlob::ENTRY_COUNT]; SharedRuntime::generate_i2c2i_adapters(&masm, total_args_passed, comp_args_on_stack, sig_bt, regs, - handler); -#ifdef ZERO + entry_address); // On zero there is no code to save and no need to create a blob and // or relocate the handler. - adapter_blob = nullptr; -#else + int entry_offset[AdapterBlob::ENTRY_COUNT]; + address_to_offset(entry_address, entry_offset); #ifdef ASSERT if (VerifyAdapterSharing) { handler->save_code(buf->code_begin(), buffer.insts_size()); @@ -2840,25 +2840,14 @@ bool AdapterHandlerLibrary::generate_adapter_code(AdapterBlob*& adapter_blob, } } #endif - - int entry_offset[AdapterBlob::ENTRY_COUNT]; - assert(AdapterBlob::ENTRY_COUNT == 4, "sanity"); - address i2c_entry = handler->get_i2c_entry(); - entry_offset[0] = 0; // i2c_entry offset - entry_offset[1] = (handler->get_c2i_entry() != nullptr) ? - (handler->get_c2i_entry() - i2c_entry) : -1; - entry_offset[2] = (handler->get_c2i_unverified_entry() != nullptr) ? - (handler->get_c2i_unverified_entry() - i2c_entry) : -1; - entry_offset[3] = (handler->get_c2i_no_clinit_check_entry() != nullptr) ? - (handler->get_c2i_no_clinit_check_entry() - i2c_entry) : -1; - - adapter_blob = AdapterBlob::create(&buffer, entry_offset); + AdapterBlob* adapter_blob = AdapterBlob::create(&buffer, entry_offset); if (adapter_blob == nullptr) { // CodeCache is full, disable compilation // Ought to log this but compile log is only per compile thread // and we're some non descript Java thread. return false; } + handler->set_adapter_blob(adapter_blob); if (!is_transient && AOTCodeCache::is_dumping_adapter()) { // try to save generated code const char* name = AdapterHandlerLibrary::name(handler->fingerprint()); @@ -2866,26 +2855,24 @@ bool AdapterHandlerLibrary::generate_adapter_code(AdapterBlob*& adapter_blob, bool success = AOTCodeCache::store_code_blob(*adapter_blob, AOTCodeEntry::Adapter, id, name); assert(success || !AOTCodeCache::is_dumping_adapter(), "caching of adapter must be disabled"); } - handler->relocate(adapter_blob->content_begin()); #endif // ZERO #ifndef PRODUCT // debugging support if (PrintAdapterHandlers || PrintStubCode) { - print_adapter_handler_info(tty, handler, adapter_blob); + print_adapter_handler_info(tty, handler); } #endif return true; } -AdapterHandlerEntry* AdapterHandlerLibrary::create_adapter(AdapterBlob*& adapter_blob, - int total_args_passed, +AdapterHandlerEntry* AdapterHandlerLibrary::create_adapter(int total_args_passed, BasicType* sig_bt, bool is_transient) { AdapterFingerPrint* fp = AdapterFingerPrint::allocate(total_args_passed, sig_bt); AdapterHandlerEntry* handler = AdapterHandlerLibrary::new_entry(fp); - if (!generate_adapter_code(adapter_blob, handler, total_args_passed, sig_bt, is_transient)) { + if (!generate_adapter_code(handler, total_args_passed, sig_bt, is_transient)) { AdapterHandlerEntry::deallocate(handler); return nullptr; } @@ -2902,7 +2889,8 @@ void AdapterHandlerEntry::remove_unshareable_info() { _saved_code = nullptr; _saved_code_length = 0; #endif // ASSERT - set_entry_points(nullptr, nullptr, nullptr, nullptr, false); + _adapter_blob = nullptr; + _linked = false; } class CopyAdapterTableToArchive : StackObj { @@ -2952,26 +2940,24 @@ void AdapterHandlerLibrary::serialize_shared_table_header(SerializeClosure* soc) _aot_adapter_handler_table.serialize_header(soc); } -AdapterBlob* AdapterHandlerLibrary::link_aot_adapter_handler(AdapterHandlerEntry* handler) { +void AdapterHandlerLibrary::link_aot_adapter_handler(AdapterHandlerEntry* handler) { #ifdef ASSERT if (TestAOTAdapterLinkFailure) { - return nullptr; + return; } #endif - AdapterBlob* blob = lookup_aot_cache(handler); + lookup_aot_cache(handler); #ifndef PRODUCT // debugging support - if ((blob != nullptr) && (PrintAdapterHandlers || PrintStubCode)) { - print_adapter_handler_info(tty, handler, blob); + if (PrintAdapterHandlers || PrintStubCode) { + print_adapter_handler_info(tty, handler); } #endif - return blob; } // This method is used during production run to link archived adapters (stored in AOT Cache) // to their code in AOT Code Cache void AdapterHandlerEntry::link() { - AdapterBlob* adapter_blob = nullptr; ResourceMark rm; assert(_fingerprint != nullptr, "_fingerprint must not be null"); bool generate_code = false; @@ -2979,8 +2965,9 @@ void AdapterHandlerEntry::link() { // caching adapters is disabled, or we fail to link // the AdapterHandlerEntry to its code in the AOTCodeCache if (AOTCodeCache::is_using_adapter()) { - adapter_blob = AdapterHandlerLibrary::link_aot_adapter_handler(this); - if (adapter_blob == nullptr) { + AdapterHandlerLibrary::link_aot_adapter_handler(this); + // If link_aot_adapter_handler() succeeds, _adapter_blob will be non-null + if (_adapter_blob == nullptr) { log_warning(aot)("Failed to link AdapterHandlerEntry (fp=%s) to its code in the AOT code cache", _fingerprint->as_basic_args_string()); generate_code = true; } @@ -2990,16 +2977,15 @@ void AdapterHandlerEntry::link() { if (generate_code) { int nargs; BasicType* bt = _fingerprint->as_basic_type(nargs); - if (!AdapterHandlerLibrary::generate_adapter_code(adapter_blob, this, nargs, bt, /* is_transient */ false)) { + if (!AdapterHandlerLibrary::generate_adapter_code(this, nargs, bt, /* is_transient */ false)) { // Don't throw exceptions during VM initialization because java.lang.* classes // might not have been initialized, causing problems when constructing the // Java exception object. vm_exit_during_initialization("Out of space in CodeCache for adapters"); } } - // Outside of the lock - if (adapter_blob != nullptr) { - post_adapter_creation(adapter_blob, this); + if (_adapter_blob != nullptr) { + post_adapter_creation(this); } assert(_linked, "AdapterHandlerEntry must now be linked"); } @@ -3045,30 +3031,6 @@ void AdapterHandlerLibrary::lookup_simple_adapters() { } #endif // INCLUDE_CDS -address AdapterHandlerEntry::base_address() { - address base = _i2c_entry; - if (base == nullptr) base = _c2i_entry; - assert(base <= _c2i_entry || _c2i_entry == nullptr, ""); - assert(base <= _c2i_unverified_entry || _c2i_unverified_entry == nullptr, ""); - assert(base <= _c2i_no_clinit_check_entry || _c2i_no_clinit_check_entry == nullptr, ""); - return base; -} - -void AdapterHandlerEntry::relocate(address new_base) { - address old_base = base_address(); - assert(old_base != nullptr, ""); - ptrdiff_t delta = new_base - old_base; - if (_i2c_entry != nullptr) - _i2c_entry += delta; - if (_c2i_entry != nullptr) - _c2i_entry += delta; - if (_c2i_unverified_entry != nullptr) - _c2i_unverified_entry += delta; - if (_c2i_no_clinit_check_entry != nullptr) - _c2i_no_clinit_check_entry += delta; - assert(base_address() == new_base, ""); -} - void AdapterHandlerEntry::metaspace_pointers_do(MetaspaceClosure* it) { LogStreamHandle(Trace, aot) lsh; if (lsh.is_enabled()) { @@ -3443,17 +3405,13 @@ void AdapterHandlerLibrary::print_handler_on(outputStream* st, const CodeBlob* b void AdapterHandlerEntry::print_adapter_on(outputStream* st) const { st->print("AHE@" INTPTR_FORMAT ": %s", p2i(this), fingerprint()->as_string()); - if (get_i2c_entry() != nullptr) { + if (adapter_blob() != nullptr) { st->print(" i2c: " INTPTR_FORMAT, p2i(get_i2c_entry())); - } - if (get_c2i_entry() != nullptr) { st->print(" c2i: " INTPTR_FORMAT, p2i(get_c2i_entry())); - } - if (get_c2i_unverified_entry() != nullptr) { st->print(" c2iUV: " INTPTR_FORMAT, p2i(get_c2i_unverified_entry())); - } - if (get_c2i_no_clinit_check_entry() != nullptr) { - st->print(" c2iNCI: " INTPTR_FORMAT, p2i(get_c2i_no_clinit_check_entry())); + if (get_c2i_no_clinit_check_entry() != nullptr) { + st->print(" c2iNCI: " INTPTR_FORMAT, p2i(get_c2i_no_clinit_check_entry())); + } } st->cr(); } diff --git a/src/hotspot/share/runtime/sharedRuntime.hpp b/src/hotspot/share/runtime/sharedRuntime.hpp index 288bc0adc52..374985ad921 100644 --- a/src/hotspot/share/runtime/sharedRuntime.hpp +++ b/src/hotspot/share/runtime/sharedRuntime.hpp @@ -476,11 +476,11 @@ class SharedRuntime: AllStatic { // handshaking path with compiled code to keep the stack walking correct. static void generate_i2c2i_adapters(MacroAssembler *_masm, - int total_args_passed, - int max_arg, - const BasicType *sig_bt, - const VMRegPair *regs, - AdapterHandlerEntry* handler); + int total_args_passed, + int max_arg, + const BasicType *sig_bt, + const VMRegPair *regs, + address entry_address[AdapterBlob::ENTRY_COUNT]); static void gen_i2c_adapter(MacroAssembler *_masm, int total_args_passed, @@ -685,11 +685,8 @@ class AdapterHandlerEntry : public MetaspaceObj { private: AdapterFingerPrint* _fingerprint; - address _i2c_entry; - address _c2i_entry; - address _c2i_unverified_entry; - address _c2i_no_clinit_check_entry; - bool _linked; + AdapterBlob* _adapter_blob; + bool _linked; static const char *_entry_names[]; @@ -702,10 +699,7 @@ class AdapterHandlerEntry : public MetaspaceObj { AdapterHandlerEntry(AdapterFingerPrint* fingerprint) : _fingerprint(fingerprint), - _i2c_entry(nullptr), - _c2i_entry(nullptr), - _c2i_unverified_entry(nullptr), - _c2i_no_clinit_check_entry(nullptr), + _adapter_blob(nullptr), _linked(false) #ifdef ASSERT , _saved_code(nullptr), @@ -734,27 +728,49 @@ class AdapterHandlerEntry : public MetaspaceObj { handler->~AdapterHandlerEntry(); } - void set_entry_points(address i2c_entry, address c2i_entry, address c2i_unverified_entry, address c2i_no_clinit_check_entry, bool linked = true) { - _i2c_entry = i2c_entry; - _c2i_entry = c2i_entry; - _c2i_unverified_entry = c2i_unverified_entry; - _c2i_no_clinit_check_entry = c2i_no_clinit_check_entry; - _linked = linked; + void set_adapter_blob(AdapterBlob* blob) { + _adapter_blob = blob; + _linked = true; } - address get_i2c_entry() const { return _i2c_entry; } - address get_c2i_entry() const { return _c2i_entry; } - address get_c2i_unverified_entry() const { return _c2i_unverified_entry; } - address get_c2i_no_clinit_check_entry() const { return _c2i_no_clinit_check_entry; } - - static const char* entry_name(int i) { - assert(i >=0 && i < ENTRIES_COUNT, "entry id out of range"); - return _entry_names[i]; + address get_i2c_entry() const { +#ifndef ZERO + assert(_adapter_blob != nullptr, "must be"); + return _adapter_blob->i2c_entry(); +#else + return nullptr; +#endif // ZERO } + address get_c2i_entry() const { +#ifndef ZERO + assert(_adapter_blob != nullptr, "must be"); + return _adapter_blob->c2i_entry(); +#else + return nullptr; +#endif // ZERO + } + + address get_c2i_unverified_entry() const { +#ifndef ZERO + assert(_adapter_blob != nullptr, "must be"); + return _adapter_blob->c2i_unverified_entry(); +#else + return nullptr; +#endif // ZERO + } + + address get_c2i_no_clinit_check_entry() const { +#ifndef ZERO + assert(_adapter_blob != nullptr, "must be"); + return _adapter_blob->c2i_no_clinit_check_entry(); +#else + return nullptr; +#endif // ZERO + } + + AdapterBlob* adapter_blob() const { return _adapter_blob; } bool is_linked() const { return _linked; } - address base_address(); - void relocate(address new_base); AdapterFingerPrint* fingerprint() const { return _fingerprint; } @@ -795,14 +811,13 @@ class AdapterHandlerLibrary: public AllStatic { static BufferBlob* buffer_blob(); static void initialize(); static AdapterHandlerEntry* get_simple_adapter(const methodHandle& method); - static AdapterBlob* lookup_aot_cache(AdapterHandlerEntry* handler); - static AdapterHandlerEntry* create_adapter(AdapterBlob*& new_adapter, - int total_args_passed, + static void lookup_aot_cache(AdapterHandlerEntry* handler); + static AdapterHandlerEntry* create_adapter(int total_args_passed, BasicType* sig_bt, bool is_transient = false); static void lookup_simple_adapters() NOT_CDS_RETURN; #ifndef PRODUCT - static void print_adapter_handler_info(outputStream* st, AdapterHandlerEntry* handler, AdapterBlob* adapter_blob); + static void print_adapter_handler_info(outputStream* st, AdapterHandlerEntry* handler); #endif // PRODUCT public: @@ -810,8 +825,7 @@ class AdapterHandlerLibrary: public AllStatic { static void create_native_wrapper(const methodHandle& method); static AdapterHandlerEntry* get_adapter(const methodHandle& method); static AdapterHandlerEntry* lookup(int total_args_passed, BasicType* sig_bt); - static bool generate_adapter_code(AdapterBlob*& adapter_blob, - AdapterHandlerEntry* handler, + static bool generate_adapter_code(AdapterHandlerEntry* handler, int total_args_passed, BasicType* sig_bt, bool is_transient); @@ -829,10 +843,11 @@ class AdapterHandlerLibrary: public AllStatic { static void print_statistics(); #endif // PRODUCT - static AdapterBlob* link_aot_adapter_handler(AdapterHandlerEntry* handler) NOT_CDS_RETURN_(nullptr); + static void link_aot_adapter_handler(AdapterHandlerEntry* handler) NOT_CDS_RETURN; static void dump_aot_adapter_table() NOT_CDS_RETURN; static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_RETURN; static void link_aot_adapters() NOT_CDS_RETURN; + static void address_to_offset(address entry_address[AdapterBlob::ENTRY_COUNT], int entry_offset[AdapterBlob::ENTRY_COUNT]); }; #endif // SHARE_RUNTIME_SHAREDRUNTIME_HPP