--- old/src/hotspot/share/oops/method.cpp 2019-03-11 14:26:22.250354933 +0100 +++ new/src/hotspot/share/oops/method.cpp 2019-03-11 14:26:22.038354936 +0100 @@ -48,6 +48,7 @@ #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" +#include "oops/valueKlass.hpp" #include "prims/jvmtiExport.hpp" #include "prims/methodHandles.hpp" #include "prims/nativeLookup.hpp" @@ -107,7 +108,6 @@ clear_native_function(); set_signature_handler(NULL); } - NOT_PRODUCT(set_compiled_invocation_count(0);) } @@ -467,6 +467,26 @@ return rtf.type(); } +#ifdef ASSERT +// ValueKlass the method is declared to return. This must not +// safepoint as it is called with references live on the stack at +// locations the GC is unaware of. +ValueKlass* Method::returned_value_type(Thread* thread) const { + SignatureStream ss(signature()); + while (!ss.at_return_type()) { + ss.next(); + } + Handle class_loader(thread, method_holder()->class_loader()); + Handle protection_domain(thread, method_holder()->protection_domain()); + Klass* k = NULL; + { + NoSafepointVerifier nsv; + k = ss.as_klass(class_loader, protection_domain, SignatureStream::ReturnNull, thread); + } + assert(k != NULL && !thread->has_pending_exception(), "can't resolve klass"); + return ValueKlass::cast(k); +} +#endif bool Method::is_empty_method() const { return code_size() == 1 @@ -717,7 +737,7 @@ bool Method::is_klass_loaded_by_klass_index(int klass_index) const { - if( constants()->tag_at(klass_index).is_unresolved_klass() ) { + if( constants()->tag_at(klass_index).is_unresolved_klass()) { Thread *thread = Thread::current(); Symbol* klass_name = constants()->klass_name_at(klass_index); Handle loader(thread, method_holder()->class_loader()); @@ -733,7 +753,9 @@ int klass_index = constants()->klass_ref_index_at(refinfo_index); if (must_be_resolved) { // Make sure klass is resolved in constantpool. - if (constants()->tag_at(klass_index).is_unresolved_klass()) return false; + if (constants()->tag_at(klass_index).is_unresolved_klass()) { + return false; + } } return is_klass_loaded_by_klass_index(klass_index); } @@ -912,8 +934,12 @@ // Only should happen at allocate time. if (adapter() == NULL) { _from_compiled_entry = NULL; + _from_compiled_value_entry = NULL; + _from_compiled_value_ro_entry = NULL; } else { _from_compiled_entry = adapter()->get_c2i_entry(); + _from_compiled_value_entry = adapter()->get_c2i_value_entry(); + _from_compiled_value_ro_entry = adapter()->get_c2i_value_ro_entry(); } OrderAccess::storestore(); _from_interpreted_entry = _i2i_entry; @@ -942,6 +968,10 @@ constMethod()->set_adapter_trampoline(cds_adapter->get_adapter_trampoline()); _from_compiled_entry = cds_adapter->get_c2i_entry_trampoline(); assert(*((int*)_from_compiled_entry) == 0, "must be NULL during dump time, to be initialized at run time"); + _from_compiled_value_entry = cds_adapter->get_c2i_entry_trampoline(); + assert(*((int*)_from_compiled_value_entry) == 0, "must be NULL during dump time, to be initialized at run time"); + _from_compiled_value_ro_entry = cds_adapter->get_c2i_entry_trampoline(); + assert(*((int*)_from_compiled_value_ro_entry) == 0, "must be NULL during dump time, to be initialized at run time"); set_method_data(NULL); clear_method_counters(); @@ -1089,9 +1119,13 @@ if (mh->is_shared()) { assert(mh->adapter() == adapter, "must be"); assert(mh->_from_compiled_entry != NULL, "must be"); + assert(mh->_from_compiled_value_entry != NULL, "must be"); + assert(mh->_from_compiled_value_ro_entry != NULL, "must be"); } else { mh->set_adapter_entry(adapter); mh->_from_compiled_entry = adapter->get_c2i_entry(); + mh->_from_compiled_value_entry = adapter->get_c2i_value_entry(); + mh->_from_compiled_value_ro_entry = adapter->get_c2i_value_ro_entry(); } return adapter->get_c2i_entry(); } @@ -1129,6 +1163,12 @@ return _from_compiled_entry; } +address Method::verified_value_ro_code_entry() { + debug_only(NoSafepointVerifier nsv;) + assert(_from_compiled_value_ro_entry != NULL, "must be set"); + return _from_compiled_value_ro_entry; +} + // Check that if an nmethod ref exists, it has a backlink to this or no backlink at all // (could be racing a deopt). // Not inline to avoid circular ref. @@ -1160,6 +1200,8 @@ OrderAccess::storestore(); mh->_from_compiled_entry = code->verified_entry_point(); + mh->_from_compiled_value_entry = code->verified_value_entry_point(); + mh->_from_compiled_value_ro_entry = code->verified_value_ro_entry_point(); OrderAccess::storestore(); // Instantly compiled code can execute. if (!mh->is_method_handle_intrinsic()) @@ -2217,6 +2259,8 @@ if (highest_comp_level() != CompLevel_none) st->print_cr(" - highest level: %d", highest_comp_level()); st->print_cr(" - vtable index: %d", _vtable_index); + if (valid_itable_index()) + st->print_cr(" - itable index: %d", itable_index()); st->print_cr(" - i2i entry: " INTPTR_FORMAT, p2i(interpreter_entry())); st->print( " - adapters: "); AdapterHandlerEntry* a = ((Method*)this)->adapter(); @@ -2294,6 +2338,7 @@ st->print("%s", internal_name()); print_address_on(st); st->print(" "); + if (WizardMode) access_flags().print_on(st); name()->print_value_on(st); st->print(" "); signature()->print_value_on(st);