src/share/vm/oops/method.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/oops/method.cpp
src/share/vm/oops/method.cpp
Print this page
*** 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 ****
// 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();
}
address Method::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();
}
char* Method::name_and_sig_as_C_string() const {
return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature());
}
--- 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();
}
address Method::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();
}
char* Method::name_and_sig_as_C_string() const {
return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature());
}
*** 888,920 ****
// 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) {
_from_compiled_entry = NULL;
} else {
! _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;
_i2i_entry = NULL;
_from_interpreted_entry = NULL;
if (is_native()) {
*native_function_addr() = NULL;
set_signature_handler(NULL);
}
NOT_PRODUCT(set_compiled_invocation_count(0);)
! _adapter = NULL;
_from_compiled_entry = NULL;
// 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
--- 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) {
_from_compiled_entry = NULL;
} else {
! _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);)
! 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 ****
// 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 (_i2i_entry != NULL) return;
! 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);
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.
--- 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( _code == NULL, "nothing compiled yet" );
// Setup interpreter entrypoint
assert(this == h_method(), "wrong h_method()" );
! address entry;
!
! 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