< prev index next >
src/hotspot/share/oops/method.cpp
Print this page
rev 56098 : imported patch 8226705-8221734-baseline
*** 101,111 ****
set_vtable_index(Method::garbage_vtable_index);
// Fix and bury in Method*
set_interpreter_entry(NULL); // sets i2i entry and from_int
set_adapter_entry(NULL);
! clear_code(false /* don't need a lock */); // from_c/from_i get set to c2i/i2i
if (access_flags.is_native()) {
clear_native_function();
set_signature_handler(NULL);
}
--- 101,111 ----
set_vtable_index(Method::garbage_vtable_index);
// Fix and bury in Method*
set_interpreter_entry(NULL); // sets i2i entry and from_int
set_adapter_entry(NULL);
! Method::clear_code(); // from_c/from_i get set to c2i/i2i
if (access_flags.is_native()) {
clear_native_function();
set_signature_handler(NULL);
}
*** 823,833 ****
void Method::clear_native_function() {
// Note: is_method_handle_intrinsic() is allowed here.
set_native_function(
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
!native_bind_event_is_interesting);
! clear_code();
}
void Method::set_signature_handler(address handler) {
address* signature_handler = signature_handler_addr();
--- 823,833 ----
void Method::clear_native_function() {
// Note: is_method_handle_intrinsic() is allowed here.
set_native_function(
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
!native_bind_event_is_interesting);
! this->unlink_code();
}
void Method::set_signature_handler(address handler) {
address* signature_handler = signature_handler_addr();
*** 939,950 ****
CompilationPolicy::policy()->disable_compilation(this);
assert(!CompilationPolicy::can_be_osr_compiled(this, comp_level), "sanity check");
}
// Revert to using the interpreter and clear out the nmethod
! void Method::clear_code(bool acquire_lock /* = true */) {
! MutexLocker pl(acquire_lock ? Patching_lock : NULL, Mutex::_no_safepoint_check_flag);
// 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 {
--- 939,949 ----
CompilationPolicy::policy()->disable_compilation(this);
assert(!CompilationPolicy::can_be_osr_compiled(this, comp_level), "sanity check");
}
// 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 {
*** 954,963 ****
--- 953,981 ----
_from_interpreted_entry = _i2i_entry;
OrderAccess::storestore();
_code = NULL;
}
+ void Method::unlink_code(CompiledMethod *compare) {
+ MutexLocker ml(CompiledMethod_lock->owned_by_self() ? NULL : CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+ // We need to check if either the _code or _from_compiled_code_entry_point
+ // refer to this nmethod because there is a race in setting these two fields
+ // in Method* as seen in bugid 4947125.
+ // If the vep() points to the zombie nmethod, the memory for the nmethod
+ // could be flushed and the compiler and vtable stubs could still call
+ // through it.
+ if (code() == compare ||
+ from_compiled_entry() == compare->verified_entry_point()) {
+ clear_code();
+ }
+ }
+
+ void Method::unlink_code() {
+ MutexLocker ml(CompiledMethod_lock->owned_by_self() ? NULL : CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+ clear_code();
+ }
+
#if INCLUDE_CDS
// Called by class data sharing to remove any entry points (which are not shared)
void Method::unlink_method() {
_code = NULL;
*** 1180,1190 ****
return code == NULL || (code->method() == NULL) || (code->method() == (Method*)this && !code->is_osr_method());
}
// Install compiled code. Instantly it can execute.
void Method::set_code(const methodHandle& mh, CompiledMethod *code) {
! MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
assert( code, "use clear_code to remove code" );
assert( mh->check_code(), "" );
guarantee(mh->adapter() != NULL, "Adapter blob must already exist!");
--- 1198,1208 ----
return code == NULL || (code->method() == NULL) || (code->method() == (Method*)this && !code->is_osr_method());
}
// Install compiled code. Instantly it can execute.
void Method::set_code(const methodHandle& mh, CompiledMethod *code) {
! MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
assert( code, "use clear_code to remove code" );
assert( mh->check_code(), "" );
guarantee(mh->adapter() != NULL, "Adapter blob must already exist!");
< prev index next >