8365501: Remove special AdapterHandlerEntry for abstract methods

Reviewed-by: kvn, adinn
This commit is contained in:
Ashutosh Mehra 2025-09-02 14:54:50 +00:00
parent a029245a4e
commit 444a8fa14e
5 changed files with 17 additions and 44 deletions

View File

@ -563,12 +563,7 @@ ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref
ref->msotype() == MetaspaceObj::CompileTrainingDataType) {
return (TrainingData::need_data() || TrainingData::assembling_data()) ? make_a_copy : set_to_null;
} else if (ref->msotype() == MetaspaceObj::AdapterHandlerEntryType) {
if (CDSConfig::is_dumping_adapters()) {
AdapterHandlerEntry* entry = (AdapterHandlerEntry*)ref->obj();
return AdapterHandlerLibrary::is_abstract_method_adapter(entry) ? set_to_null : make_a_copy;
} else {
return set_to_null;
}
return CDSConfig::is_dumping_adapters() ? make_a_copy : set_to_null;
} else {
if (ref->msotype() == MetaspaceObj::ClassType) {
Klass* klass = (Klass*)ref->obj();

View File

@ -152,11 +152,17 @@ void Method::release_C_heap_structures() {
}
address Method::get_i2c_entry() {
if (is_abstract()) {
return SharedRuntime::throw_AbstractMethodError_entry();
}
assert(adapter() != nullptr, "must have");
return adapter()->get_i2c_entry();
}
address Method::get_c2i_entry() {
if (is_abstract()) {
return SharedRuntime::get_handle_wrong_method_abstract_stub();
}
assert(adapter() != nullptr, "must have");
return adapter()->get_c2i_entry();
}
@ -1165,9 +1171,9 @@ void Method::clear_code() {
// this may be null if c2i adapters have not been made yet
// Only should happen at allocate time.
if (adapter() == nullptr) {
_from_compiled_entry = nullptr;
_from_compiled_entry = nullptr;
} else {
_from_compiled_entry = adapter()->get_c2i_entry();
_from_compiled_entry = adapter()->get_c2i_entry();
}
OrderAccess::storestore();
_from_interpreted_entry = _i2i_entry;
@ -1196,7 +1202,7 @@ void Method::unlink_code() {
void Method::unlink_method() {
assert(CDSConfig::is_dumping_archive(), "sanity");
_code = nullptr;
if (!CDSConfig::is_dumping_adapters() || AdapterHandlerLibrary::is_abstract_method_adapter(_adapter)) {
if (!CDSConfig::is_dumping_adapters()) {
_adapter = nullptr;
}
_i2i_entry = nullptr;
@ -1277,9 +1283,12 @@ void Method::link_method(const methodHandle& h_method, TRAPS) {
// called from the vtable. We need adapters on such methods that get loaded
// later. Ditto for mega-morphic itable calls. If this proves to be a
// problem we'll make these lazily later.
if (_adapter == nullptr) {
if (is_abstract()) {
h_method->_from_compiled_entry = SharedRuntime::get_handle_wrong_method_abstract_stub();
} else if (_adapter == nullptr) {
(void) make_adapters(h_method, CHECK);
assert(adapter()->is_linked(), "Adapter must have been linked");
h_method->_from_compiled_entry = adapter()->get_c2i_entry();
}
// ONLY USE the h_method now as make_adapter may have blocked
@ -1300,6 +1309,7 @@ void Method::link_method(const methodHandle& h_method, TRAPS) {
}
address Method::make_adapters(const methodHandle& mh, TRAPS) {
assert(!mh->is_abstract(), "abstract methods do not have adapters");
PerfTraceTime timer(ClassLoader::perf_method_adapters_time());
// Adapters for compiled code are made eagerly here. They are fairly
@ -1318,7 +1328,6 @@ address Method::make_adapters(const methodHandle& mh, TRAPS) {
}
mh->set_adapter_entry(adapter);
mh->_from_compiled_entry = adapter->get_c2i_entry();
return adapter->get_c2i_entry();
}

View File

@ -406,7 +406,7 @@ void JavaCalls::call_helper(JavaValue* result, const methodHandle& method, JavaC
address verified_entry_point = (address) HotSpotJVMCI::InstalledCode::entryPoint(nullptr, alternative_target());
if (verified_entry_point != nullptr) {
thread->set_jvmci_alternate_call_target(verified_entry_point);
entry_point = method->adapter()->get_i2c_entry();
entry_point = method->get_i2c_entry();
}
}
#endif

View File

@ -2510,7 +2510,6 @@ static void print_table_statistics() {
// ---------------------------------------------------------------------------
// Implementation of AdapterHandlerLibrary
AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = nullptr;
AdapterHandlerEntry* AdapterHandlerLibrary::_no_arg_handler = nullptr;
AdapterHandlerEntry* AdapterHandlerLibrary::_int_arg_handler = nullptr;
AdapterHandlerEntry* AdapterHandlerLibrary::_obj_arg_handler = nullptr;
@ -2546,28 +2545,11 @@ static void post_adapter_creation(const AdapterBlob* new_adapter,
}
}
void AdapterHandlerLibrary::create_abstract_method_handler() {
assert_lock_strong(AdapterHandlerLibrary_lock);
// Create a special handler for abstract methods. Abstract methods
// are never compiled so an i2c entry is somewhat meaningless, but
// throw AbstractMethodError just in case.
// Pass wrong_method_abstract for the c2i transitions to return
// AbstractMethodError for invalid invocations.
address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
_abstract_method_handler = AdapterHandlerLibrary::new_entry(AdapterFingerPrint::allocate(0, nullptr));
_abstract_method_handler->set_entry_points(SharedRuntime::throw_AbstractMethodError_entry(),
wrong_method_abstract,
wrong_method_abstract,
nullptr);
}
void AdapterHandlerLibrary::initialize() {
{
ResourceMark rm;
MutexLocker mu(AdapterHandlerLibrary_lock);
_adapter_handler_table = new (mtCode) AdapterHandlerTable();
_buffer = BufferBlob::create("adapters", AdapterHandlerLibrary_size);
create_abstract_method_handler();
}
#if INCLUDE_CDS
@ -2627,9 +2609,6 @@ AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* finger
}
AdapterHandlerEntry* AdapterHandlerLibrary::get_simple_adapter(const methodHandle& method) {
if (method->is_abstract()) {
return _abstract_method_handler;
}
int total_args_passed = method->size_of_parameters(); // All args on stack
if (total_args_passed == 0) {
return _no_arg_handler;
@ -2727,6 +2706,7 @@ void AdapterHandlerLibrary::verify_adapter_sharing(int total_args_passed, BasicT
#endif /* ASSERT*/
AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
assert(!method->is_abstract(), "abstract methods do not have adapters");
// Use customized signature handler. Need to lock around updates to
// the _adapter_handler_table (it is not safe for concurrent readers
// and a single writer: this could be fixed if it becomes a
@ -3497,13 +3477,6 @@ void AdapterHandlerLibrary::print_statistics() {
#endif /* PRODUCT */
bool AdapterHandlerLibrary::is_abstract_method_adapter(AdapterHandlerEntry* entry) {
if (entry == _abstract_method_handler) {
return true;
}
return false;
}
JRT_LEAF(void, SharedRuntime::enable_stack_reserved_zone(JavaThread* current))
assert(current == JavaThread::current(), "pre-condition");
StackOverflow* overflow_state = current->stack_overflow_state();

View File

@ -783,7 +783,6 @@ class AdapterHandlerLibrary: public AllStatic {
friend class SharedRuntime;
private:
static BufferBlob* _buffer; // the temporary code buffer in CodeCache
static AdapterHandlerEntry* _abstract_method_handler;
static AdapterHandlerEntry* _no_arg_handler;
static AdapterHandlerEntry* _int_arg_handler;
static AdapterHandlerEntry* _obj_arg_handler;
@ -801,7 +800,6 @@ class AdapterHandlerLibrary: public AllStatic {
int total_args_passed,
BasicType* sig_bt,
bool is_transient = false);
static void create_abstract_method_handler();
static void lookup_simple_adapters() NOT_CDS_RETURN;
#ifndef PRODUCT
static void print_adapter_handler_info(outputStream* st, AdapterHandlerEntry* handler, AdapterBlob* adapter_blob);
@ -831,8 +829,6 @@ class AdapterHandlerLibrary: public AllStatic {
static void print_statistics();
#endif // PRODUCT
static bool is_abstract_method_adapter(AdapterHandlerEntry* adapter);
static AdapterBlob* link_aot_adapter_handler(AdapterHandlerEntry* handler) NOT_CDS_RETURN_(nullptr);
static void dump_aot_adapter_table() NOT_CDS_RETURN;
static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_RETURN;