src/share/vm/oops/method.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/oops/method.cpp	Thu Feb 18 15:25:08 2016
--- new/src/share/vm/oops/method.cpp	Thu Feb 18 15:25:07 2016

*** 35,44 **** --- 35,45 ---- #include "interpreter/bytecodes.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/oopMapCache.hpp" #include "memory/heapInspection.hpp" #include "memory/metadataFactory.hpp" + #include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "oops/constMethod.hpp" #include "oops/method.hpp" #include "oops/methodData.hpp" #include "oops/objArrayOop.inline.hpp"
*** 119,140 **** --- 120,141 ---- // The nmethod will be gone when we get here. if (code() != NULL) _code = NULL; } address Method::get_i2c_entry() { ! assert(_adapter != NULL, "must have"); ! return _adapter->get_i2c_entry(); ! assert(adapter() != NULL, "must have"); ! return adapter()->get_i2c_entry(); } address Method::get_c2i_entry() { ! assert(_adapter != NULL, "must have"); ! return _adapter->get_c2i_entry(); ! assert(adapter() != NULL, "must have"); ! return adapter()->get_c2i_entry(); } address Method::get_c2i_unverified_entry() { ! assert(_adapter != NULL, "must have"); ! return _adapter->get_c2i_unverified_entry(); ! assert(adapter() != NULL, "must have"); ! return adapter()->get_c2i_unverified_entry(); } char* Method::name_and_sig_as_C_string() const { return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature()); }
*** 888,920 **** --- 889,934 ---- // Revert to using the interpreter and clear out the nmethod void Method::clear_code() { // this may be NULL if c2i adapters have not been made yet // Only should happen at allocate time. ! if (_adapter == NULL) { ! if (adapter() == NULL) { _from_compiled_entry = NULL; } else { ! _from_compiled_entry = _adapter->get_c2i_entry(); ! _from_compiled_entry = adapter()->get_c2i_entry(); } OrderAccess::storestore(); _from_interpreted_entry = _i2i_entry; OrderAccess::storestore(); _code = NULL; } // Called by class data sharing to remove any entry points (which are not shared) void Method::unlink_method() { _code = NULL; + if (!DumpSharedSpaces) { _i2i_entry = NULL; _from_interpreted_entry = NULL; + } else { + _i2i_entry = Interpreter::entry_for_cds_method(this); + _from_interpreted_entry = _i2i_entry; + } + if (is_native()) { *native_function_addr() = NULL; set_signature_handler(NULL); } NOT_PRODUCT(set_compiled_invocation_count(0);) _adapter = NULL; + if (!DumpSharedSpaces) { + set_adapter_entry(NULL); _from_compiled_entry = NULL; + } else { + CDSAdapterHandlerEntry* cds_adapter = (CDSAdapterHandlerEntry*)adapter(); + 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"); + } // In case of DumpSharedSpaces, _method_data should always be NULL. // // During runtime (!DumpSharedSpaces), when we are cleaning a // shared class that failed to load, this->link_method() may
*** 929,946 **** --- 943,970 ---- // Called when the method_holder is getting linked. Setup entrypoints so the method // is ready to be called from interpreter, compiler, and vtables. void Method::link_method(const methodHandle& h_method, TRAPS) { // If the code cache is full, we may reenter this function for the // leftover methods that weren't linked. + if (is_shared()) { + if (adapter() != NULL) return; + } else { if (_i2i_entry != NULL) return; ! assert(_adapter == NULL, "init'd to NULL" ); ! assert(adapter() == NULL, "init'd to NULL" ); + } assert( _code == NULL, "nothing compiled yet" ); // Setup interpreter entrypoint assert(this == h_method(), "wrong h_method()" ); - address entry = Interpreter::entry_for_method(h_method); + + if (this->is_shared()) { + entry = Interpreter::entry_for_cds_method(h_method); + } else { + entry = Interpreter::entry_for_method(h_method); + } assert(entry != NULL, "interpreter entry must be non-null"); // Sets both _i2i_entry and _from_interpreted_entry set_interpreter_entry(entry); // Don't overwrite already registered native entries.
*** 971,982 **** --- 995,1011 ---- AdapterHandlerEntry* adapter = AdapterHandlerLibrary::get_adapter(mh); if (adapter == NULL ) { THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters"); } + if (mh->is_shared()) { + assert(mh->adapter() == adapter, "must be"); + assert(mh->_from_compiled_entry != NULL, "must be"); // FIXME, the instructions also not NULL + } else { mh->set_adapter_entry(adapter); mh->_from_compiled_entry = adapter->get_c2i_entry(); + } return adapter->get_c2i_entry(); } void Method::restore_unshareable_info(TRAPS) { // Since restore_unshareable_info can be called more than once for a method, don't
*** 988,997 **** --- 1017,1034 ---- methodHandle mh(THREAD, this); link_method(mh, CHECK); } } + volatile address Method::from_compiled_entry_no_trampoline() const { + nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code); + if (code) { + return code->verified_entry_point(); + } else { + return adapter()->get_c2i_entry(); + } + } // The verified_code_entry() must be called when a invoke is resolved // on this method. // It returns the compiled code entry point, after asserting not null.

src/share/vm/oops/method.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File