# HG changeset patch # User Gilles Duboscq # Date 1353537223 -3600 # Node ID bf2ea3ed3bce5e274ce14f87ad78bb14d56b1818 # Parent 679e6584c1776eb5c29fc032086150dabb21321c Fixed nmethod not being unloaded after their classloader has been unloaded by initializing _graal_installed_code in an nmethod's constructor diff -r 679e6584c177 -r bf2ea3ed3bce src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Wed Nov 21 19:23:43 2012 +0100 +++ b/src/share/vm/code/nmethod.cpp Wed Nov 21 23:33:43 2012 +0100 @@ -483,7 +483,7 @@ _saved_nmethod_link = NULL; _compiler = NULL; #ifdef GRAAL - _graal_installed_code = (oop) Universe::non_oop_word(); + _graal_installed_code = NULL; #endif #ifdef HAVE_DTRACE_H _trap_offset = 0; @@ -577,6 +577,9 @@ ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, int comp_level +#ifdef GRAAL + , Handle installed_code +#endif ) { assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); @@ -598,7 +601,11 @@ handler_table, nul_chk_table, compiler, - comp_level); + comp_level +#ifdef GRAAL + , installed_code +#endif + ); if (nm != NULL) { // To make dependency checking during class loading fast, record // the nmethod dependencies in the classes it is dependent on. @@ -819,6 +826,9 @@ ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, int comp_level +#ifdef GRAAL + , Handle installed_code +#endif ) : CodeBlob("nmethod", code_buffer, sizeof(nmethod), nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps), @@ -843,22 +853,24 @@ _stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()); #ifdef GRAAL - // graal produces no (!) stub section - if (offsets->value(CodeOffsets::Exceptions) != -1) { - _exception_offset = code_offset() + offsets->value(CodeOffsets::Exceptions); - } else { - _exception_offset = -1; - } - if (offsets->value(CodeOffsets::Deopt) != -1) { - _deoptimize_offset = code_offset() + offsets->value(CodeOffsets::Deopt); - } else { - _deoptimize_offset = -1; - } - if (offsets->value(CodeOffsets::DeoptMH) != -1) { - _deoptimize_mh_offset = code_offset() + offsets->value(CodeOffsets::DeoptMH); - } else { - _deoptimize_mh_offset = -1; - } + _graal_installed_code = installed_code(); + + // graal produces no (!) stub section + if (offsets->value(CodeOffsets::Exceptions) != -1) { + _exception_offset = code_offset() + offsets->value(CodeOffsets::Exceptions); + } else { + _exception_offset = -1; + } + if (offsets->value(CodeOffsets::Deopt) != -1) { + _deoptimize_offset = code_offset() + offsets->value(CodeOffsets::Deopt); + } else { + _deoptimize_offset = -1; + } + if (offsets->value(CodeOffsets::DeoptMH) != -1) { + _deoptimize_mh_offset = code_offset() + offsets->value(CodeOffsets::DeoptMH); + } else { + _deoptimize_mh_offset = -1; + } #else // Exception handler and deopt handler are in the stub section assert(offsets->value(CodeOffsets::Exceptions) != -1, "must be set"); @@ -1266,7 +1278,7 @@ } #ifdef GRAAL - if (graal_installed_code() != NULL) { + if (_graal_installed_code != NULL) { HotSpotInstalledCode::set_nmethod(_graal_installed_code, 0); _graal_installed_code = NULL; } @@ -1354,7 +1366,7 @@ } #ifdef GRAAL - if (graal_installed_code() != NULL) { + if (_graal_installed_code != NULL) { HotSpotInstalledCode::set_nmethod(_graal_installed_code, 0); _graal_installed_code = NULL; } @@ -1654,10 +1666,6 @@ #ifdef GRAAL // Follow Graal method - if (_graal_installed_code == Universe::non_oop_word()) { - // May have not yet finished initializing a non-default nmethod - return; - } if (_graal_installed_code != NULL && can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) { return; } @@ -1883,7 +1891,7 @@ } #ifdef GRAAL - if (graal_installed_code() != NULL) { + if (_graal_installed_code != NULL) { f->do_oop((oop*) &_graal_installed_code); } #endif diff -r 679e6584c177 -r bf2ea3ed3bce src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Wed Nov 21 19:23:43 2012 +0100 +++ b/src/share/vm/code/nmethod.hpp Wed Nov 21 23:33:43 2012 +0100 @@ -269,7 +269,11 @@ ExceptionHandlerTable* handler_table, ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, - int comp_level); + int comp_level +#ifdef GRAAL + , Handle installed_code = NULL +#endif + ); // helper methods void* operator new(size_t size, int nmethod_size); @@ -287,7 +291,7 @@ // Inform external interfaces that a compiled method has been unloaded void post_compiled_method_unload(); - // Initailize fields to their default values + // Initialize fields to their default values void init_defaults(); public: @@ -305,7 +309,11 @@ ExceptionHandlerTable* handler_table, ImplicitExceptionTable* nul_chk_table, AbstractCompiler* compiler, - int comp_level); + int comp_level +#ifdef GRAAL + , Handle installed_code = NULL +#endif + ); static nmethod* new_native_nmethod(methodHandle method, int compile_id, @@ -570,7 +578,7 @@ void set_method(Method* method) { _method = method; } #ifdef GRAAL - oop graal_installed_code() { return _graal_installed_code == Universe::non_oop_word() ? NULL : _graal_installed_code ; } + oop graal_installed_code() { return _graal_installed_code ; } void set_graal_installed_code(oop installed_code) { _graal_installed_code = installed_code; } #endif diff -r 679e6584c177 -r bf2ea3ed3bce src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Nov 21 19:23:43 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Nov 21 23:33:43 2012 +0100 @@ -291,7 +291,7 @@ } // constructor used to create a method -CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, nmethod*& nm, bool bind_to_method) { +CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, nmethod*& nm, Handle installed_code) { _env = CURRENT_ENV; GraalCompiler::initialize_buffer_blob(); CodeBuffer buffer(JavaThread::current()->get_buffer_blob()); @@ -309,7 +309,7 @@ int stack_slots = _total_frame_size / HeapWordSize; // conversion to words nm = GraalEnv::register_method(method, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, - &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, bind_to_method); + &_implicit_exception_table, GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, true, false, installed_code); method->clear_queued_for_compilation(); } diff -r 679e6584c177 -r bf2ea3ed3bce src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Wed Nov 21 19:23:43 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Wed Nov 21 23:33:43 2012 +0100 @@ -85,7 +85,7 @@ public: // constructor used to create a method - CodeInstaller(Handle& comp_result, methodHandle method, nmethod*& nm, bool bind_to_method); + CodeInstaller(Handle& comp_result, methodHandle method, nmethod*& nm, Handle installed_code); // constructor used to create a stub CodeInstaller(Handle& target_method, BufferBlob*& blob, jlong& id); diff -r 679e6584c177 -r bf2ea3ed3bce src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Nov 21 19:23:43 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Nov 21 23:33:43 2012 +0100 @@ -774,8 +774,8 @@ methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult)); Arena arena; ciEnv env(&arena); - bool bind_to_method = installed_code == NULL; - CodeInstaller installer(compResultHandle, method, nm, bind_to_method); + Handle installed_code_handle = JNIHandles::resolve(installed_code); + CodeInstaller installer(compResultHandle, method, nm, installed_code_handle); if (info != NULL) { arrayOop codeCopy = oopFactory::new_byteArray(nm->code_size(), CHECK_0); @@ -784,22 +784,12 @@ HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin()); } - if (installed_code != NULL && nm != NULL) { - Handle obj = JNIHandles::resolve(installed_code); - assert(obj->is_a(HotSpotInstalledCode::klass()), "wrong type"); - HotSpotInstalledCode::set_nmethod(obj, (jlong) nm); - HotSpotInstalledCode::set_method(obj, HotSpotCompilationResult::method(compResult)); - nm->set_graal_installed_code(obj()); - assert(nm->graal_installed_code() == obj(), "must be"); - if (!nm->on_scavenge_root_list()) { - // Since the nmethod now contains a normal oop (i.e. installed_code) it must - // be on the list of nmethods scavenged for oops. - // Must hold the code cache lock when adding to the scavenger list - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - CodeCache::add_scavenge_root_nmethod(nm); - assert(nm->on_scavenge_root_list(), "must be"); - } - return JNIHandles::make_local(obj()); + if (!installed_code_handle.is_null()) { + assert(installed_code_handle->is_a(HotSpotInstalledCode::klass()), "wrong type"); + HotSpotInstalledCode::set_nmethod(installed_code_handle, (jlong) nm); + HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult)); + assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable"); + return installed_code; } else { return NULL; } diff -r 679e6584c177 -r bf2ea3ed3bce src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Wed Nov 21 19:23:43 2012 +0100 +++ b/src/share/vm/graal/graalEnv.cpp Wed Nov 21 23:33:43 2012 +0100 @@ -444,7 +444,7 @@ int compile_id, bool has_debug_info, bool has_unsafe_access, - bool bind_to_method) { + Handle installed_code) { EXCEPTION_CONTEXT; NMethodSweeper::possibly_sweep(); nmethod* nm = NULL; @@ -483,7 +483,7 @@ debug_info, dependencies, code_buffer, frame_words, oop_map_set, handler_table, inc_table, - compiler, comp_level); + compiler, comp_level, installed_code); // Free codeBlobs //code_buffer->free_blob(); @@ -512,7 +512,7 @@ // (Put nm into the task handle *before* publishing to the Java heap.) if (task != NULL) task->set_code(nm); - if (bind_to_method) { + if (installed_code.is_null()) { if (entry_bci == InvocationEntryBci) { if (TieredCompilation) { // If there is an old version we're done with it diff -r 679e6584c177 -r bf2ea3ed3bce src/share/vm/graal/graalEnv.hpp --- a/src/share/vm/graal/graalEnv.hpp Wed Nov 21 19:23:43 2012 +0100 +++ b/src/share/vm/graal/graalEnv.hpp Wed Nov 21 23:33:43 2012 +0100 @@ -125,7 +125,7 @@ int compile_id, bool has_debug_info, bool has_unsafe_access, - bool bind_to_method); + Handle installed_code); static ciKlass* find_system_klass(ciSymbol* klass_name); // Note: To find a class from its name string, use ciSymbol::make,