Mercurial > hg > graal-compiler
diff src/share/vm/code/nmethod.cpp @ 6948:e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Nov 2012 23:14:12 +0100 |
parents | 957c266d8bc5 18fb7da42534 |
children | 2cb439954abf |
line wrap: on
line diff
--- a/src/share/vm/code/nmethod.cpp Mon Nov 12 18:11:17 2012 +0100 +++ b/src/share/vm/code/nmethod.cpp Mon Nov 12 23:14:12 2012 +0100 @@ -34,7 +34,7 @@ #include "compiler/compilerOracle.hpp" #include "compiler/disassembler.hpp" #include "interpreter/bytecode.hpp" -#include "oops/methodDataOop.hpp" +#include "oops/methodData.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" #include "prims/jvmtiImpl.hpp" #include "runtime/sharedRuntime.hpp" @@ -62,7 +62,7 @@ #define DTRACE_METHOD_UNLOAD_PROBE(method) \ { \ - methodOop m = (method); \ + Method* m = (method); \ if (m != NULL) { \ Symbol* klass_name = m->klass_name(); \ Symbol* name = m->name(); \ @@ -76,7 +76,7 @@ #else /* USDT2 */ #define DTRACE_METHOD_UNLOAD_PROBE(method) \ { \ - methodOop m = (method); \ + Method* m = (method); \ if (m != NULL) { \ Symbol* klass_name = m->klass_name(); \ Symbol* name = m->name(); \ @@ -464,6 +464,7 @@ _has_unsafe_access = 0; _has_method_handle_invokes = 0; _lazy_critical_native = 0; + _has_wide_vectors = 0; _marked_for_deoptimization = 0; _lock_count = 0; _stack_traversal_mark = 0; @@ -480,9 +481,9 @@ _scavenge_root_state = 0; _saved_nmethod_link = NULL; _compiler = NULL; - - _graal_compiled_method = NULL; - +#ifdef GRAAL + _graal_installed_code = (oop) Universe::non_oop_word(); +#endif #ifdef HAVE_DTRACE_H _trap_offset = 0; #endif // def HAVE_DTRACE_H @@ -498,6 +499,7 @@ ByteSize basic_lock_owner_sp_offset, ByteSize basic_lock_sp_offset, OopMapSet* oop_maps) { + code_buffer->finalize_oop_references(method); // create nmethod nmethod* nm = NULL; { @@ -532,6 +534,7 @@ int trap_offset, int frame_complete, int frame_size) { + code_buffer->finalize_oop_references(method); // create nmethod nmethod* nm = NULL; { @@ -576,6 +579,7 @@ ) { assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR"); + code_buffer->finalize_oop_references(method); // create nmethod nmethod* nm = NULL; { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); @@ -604,11 +608,11 @@ // the number of methods compiled. For applications with a lot // classes the slow way is too slow. for (Dependencies::DepStream deps(nm); deps.next(); ) { - klassOop klass = deps.context_type(); + Klass* klass = deps.context_type(); if (klass == NULL) continue; // ignore things like evol_method // record this nmethod as dependent on this klass - instanceKlass::cast(klass)->add_dependent_nmethod(nm); + InstanceKlass::cast(klass)->add_dependent_nmethod(nm); } } if (nm != NULL) nmethod_stats.note_nmethod(nm); @@ -630,7 +634,7 @@ // For native wrappers nmethod::nmethod( - methodOop method, + Method* method, int nmethod_size, int compile_id, CodeOffsets* offsets, @@ -661,7 +665,8 @@ _consts_offset = data_offset(); _stub_offset = data_offset(); _oops_offset = data_offset(); - _scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); + _metadata_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); + _scopes_data_offset = _metadata_offset + round_to(code_buffer->total_metadata_size(), wordSize); _scopes_pcs_offset = _scopes_data_offset; _dependencies_offset = _scopes_pcs_offset; _handler_table_offset = _dependencies_offset; @@ -675,7 +680,7 @@ _exception_cache = NULL; _pc_desc_cache.reset_to(NULL); - code_buffer->copy_oops_to(this); + code_buffer->copy_values_to(this); if (ScavengeRootsInCode && detect_scavenge_root_oops()) { CodeCache::add_scavenge_root_nmethod(this); } @@ -699,7 +704,9 @@ // then print the requested information if (PrintNativeNMethods) { print_code(); - oop_maps->print(); + if (oop_maps != NULL) { + oop_maps->print(); + } } if (PrintRelocations) { print_relocations(); @@ -713,7 +720,7 @@ // For dtrace wrappers #ifdef HAVE_DTRACE_H nmethod::nmethod( - methodOop method, + Method* method, int nmethod_size, CodeOffsets* offsets, CodeBuffer* code_buffer, @@ -741,7 +748,8 @@ _consts_offset = data_offset(); _stub_offset = data_offset(); _oops_offset = data_offset(); - _scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); + _metadata_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); + _scopes_data_offset = _metadata_offset + round_to(code_buffer->total_metadata_size(), wordSize); _scopes_pcs_offset = _scopes_data_offset; _dependencies_offset = _scopes_pcs_offset; _handler_table_offset = _dependencies_offset; @@ -755,7 +763,7 @@ _exception_cache = NULL; _pc_desc_cache.reset_to(NULL); - code_buffer->copy_oops_to(this); + code_buffer->copy_values_to(this); debug_only(verify_scavenge_root_oops()); CodeCache::commit(this); } @@ -795,7 +803,7 @@ nmethod::nmethod( - methodOop method, + Method* method, int nmethod_size, int compile_id, int entry_bci, @@ -870,7 +878,9 @@ } _oops_offset = data_offset(); - _scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size (), oopSize); + _metadata_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize); + _scopes_data_offset = _metadata_offset + round_to(code_buffer->total_metadata_size(), wordSize); + _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize); _dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size()); _handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize); @@ -884,7 +894,7 @@ _pc_desc_cache.reset_to(scopes_pcs_begin()); // Copy contents of ScopeDescRecorder to nmethod - code_buffer->copy_oops_to(this); + code_buffer->copy_values_to(this); debug_info->copy_to(this); dependencies->copy_to(this); if (ScavengeRootsInCode && detect_scavenge_root_oops()) { @@ -1026,10 +1036,10 @@ } -void nmethod::copy_oops(GrowableArray<jobject>* array) { - //assert(oops_size() == 0, "do this handshake just once, please"); +// Have to have the same name because it's called by a template +void nmethod::copy_values(GrowableArray<jobject>* array) { int length = array->length(); - assert((address)(oops_begin() + length) <= data_end(), "oops big enough"); + assert((address)(oops_begin() + length) <= (address)oops_end(), "oops big enough"); oop* dest = oops_begin(); for (int index = 0 ; index < length; index++) { initialize_immediate_oop(&dest[index], array->at(index)); @@ -1043,6 +1053,14 @@ fix_oop_relocations(NULL, NULL, /*initialize_immediates=*/ true); } +void nmethod::copy_values(GrowableArray<Metadata*>* array) { + int length = array->length(); + assert((address)(metadata_begin() + length) <= (address)metadata_end(), "big enough"); + Metadata** dest = metadata_begin(); + for (int index = 0 ; index < length; index++) { + dest[index] = array->at(index); + } +} bool nmethod::is_at_poll_return(address pc) { RelocIterator iter(this, pc, pc+1); @@ -1077,6 +1095,9 @@ } // Refresh the oop-related bits of this instruction. reloc->fix_oop_relocation(); + } else if (iter.type() == relocInfo::metadata_type) { + metadata_Relocation* reloc = iter.metadata_reloc(); + reloc->fix_metadata_relocation(); } // There must not be any interfering patches or breakpoints. @@ -1197,11 +1218,11 @@ if (!is_compiled_by_c2()) return; #endif // Could be gated by ProfileTraps, but do not bother... - methodOop m = method(); + Method* m = method(); if (m == NULL) return; - methodDataOop mdo = m->method_data(); + MethodData* mdo = m->method_data(); if (mdo == NULL) return; - // There is a benign race here. See comments in methodDataOop.hpp. + // There is a benign race here. See comments in methodData.hpp. mdo->inc_decompile_count(); } @@ -1220,7 +1241,7 @@ // Break cycle between nmethod & method if (TraceClassUnloading && WizardMode) { tty->print_cr("[Class unloading: Making nmethod " INTPTR_FORMAT - " unloadable], methodOop(" INTPTR_FORMAT + " unloadable], Method*(" INTPTR_FORMAT "), cause(" INTPTR_FORMAT ")", this, (address)_method, (address)cause); if (!Universe::heap()->is_gc_active()) @@ -1230,12 +1251,12 @@ if (is_osr_method()) { invalidate_osr_method(); } - // If _method is already NULL the methodOop is about to be unloaded, + // If _method is already NULL the Method* is about to be unloaded, // so we don't have to break the cycle. Note that it is possible to - // have the methodOop live here, in case we unload the nmethod because - // it is pointing to some oop (other than the methodOop) being unloaded. + // have the Method* live here, in case we unload the nmethod because + // it is pointing to some oop (other than the Method*) being unloaded. if (_method != NULL) { - // OSR methods point to the methodOop, but the methodOop does not + // OSR methods point to the Method*, but the Method* does not // point back! if (_method->code() == this) { _method->clear_code(); // Break a cycle @@ -1244,9 +1265,9 @@ } #ifdef GRAAL - if (_graal_compiled_method != NULL) { - HotSpotCompiledMethod::set_nmethod(_graal_compiled_method, 0); - _graal_compiled_method = NULL; + if (graal_installed_code() != NULL) { + HotSpotInstalledCode::set_nmethod(_graal_installed_code, 0); + _graal_installed_code = NULL; } #endif @@ -1263,7 +1284,7 @@ // Log the unloading. log_state_change(); - // The methodOop is gone at this point + // The Method* is gone at this point assert(_method == NULL, "Tautology"); set_osr_link(NULL); @@ -1275,7 +1296,7 @@ assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); // Remove from list of active nmethods if (method() != NULL) - instanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this); + method()->method_holder()->remove_osr_nmethod(this); // Set entry as invalid _entry_bci = InvalidOSREntryBci; } @@ -1332,9 +1353,9 @@ } #ifdef GRAAL - if (_graal_compiled_method != NULL) { - HotSpotCompiledMethod::set_nmethod(_graal_compiled_method, 0); - _graal_compiled_method = NULL; + if (graal_installed_code() != NULL) { + HotSpotInstalledCode::set_nmethod(_graal_installed_code, 0); + _graal_installed_code = NULL; } #endif @@ -1360,7 +1381,7 @@ // Remove nmethod from method. // We need to check if both the _code and _from_compiled_code_entry_point // refer to this nmethod because there is a race in setting these two fields - // in methodOop as seen in bugid 4947125. + // 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. @@ -1480,13 +1501,13 @@ if (!has_flushed_dependencies()) { set_has_flushed_dependencies(); for (Dependencies::DepStream deps(this); deps.next(); ) { - klassOop klass = deps.context_type(); + Klass* klass = deps.context_type(); if (klass == NULL) continue; // ignore things like evol_method // During GC the is_alive closure is non-NULL, and is used to // determine liveness of dependees that need to be updated. - if (is_alive == NULL || is_alive->do_object_b(klass)) { - instanceKlass::cast(klass)->remove_dependent_nmethod(this); + if (is_alive == NULL || klass->is_loader_alive(is_alive)) { + InstanceKlass::cast(klass)->remove_dependent_nmethod(this); } } } @@ -1494,24 +1515,13 @@ // If this oop is not live, the nmethod can be unloaded. -bool nmethod::can_unload(BoolObjectClosure* is_alive, - OopClosure* keep_alive, - oop* root, bool unloading_occurred) { +bool nmethod::can_unload(BoolObjectClosure* is_alive, oop* root, bool unloading_occurred) { assert(root != NULL, "just checking"); oop obj = *root; if (obj == NULL || is_alive->do_object_b(obj)) { return false; } - if (obj->is_compiledICHolder()) { - compiledICHolderOop cichk_oop = compiledICHolderOop(obj); - if (is_alive->do_object_b( - cichk_oop->holder_method()->method_holder()) && - is_alive->do_object_b(cichk_oop->holder_klass())) { - // The oop should be kept alive - keep_alive->do_oop(root); - return false; - } - } + // If ScavengeRootsInCode is true, an nmethod might be unloaded // simply because one of its constant oops has gone dead. // No actual classes need to be unloaded in order for this to occur. @@ -1526,7 +1536,7 @@ // Transfer information from compilation to jvmti void nmethod::post_compiled_method_load_event() { - methodOop moop = method(); + Method* moop = method(); #ifndef USDT2 HS_DTRACE_PROBE8(hotspot, compiled__method__load, moop->klass_name()->bytes(), @@ -1581,10 +1591,10 @@ // If a JVMTI agent has enabled the CompiledMethodUnload event then // post the event. Sometime later this nmethod will be made a zombie - // by the sweeper but the methodOop will not be valid at that point. + // by the sweeper but the Method* will not be valid at that point. // If the _jmethod_id is null then no load event was ever requested // so don't bother posting the unload. The main reason for this is - // that the jmethodID is a weak reference to the methodOop so if + // that the jmethodID is a weak reference to the Method* so if // it's being unloaded there's no way to look it up since the weak // ref will have been cleared. if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) { @@ -1614,8 +1624,7 @@ // GC to unload an nmethod if it contains otherwise unreachable // oops. -void nmethod::do_unloading(BoolObjectClosure* is_alive, - OopClosure* keep_alive, bool unloading_occurred) { +void nmethod::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) { // Make sure the oop's ready to receive visitors assert(!is_zombie() && !is_unloaded(), "should not call follow on zombie or unloaded nmethod"); @@ -1642,23 +1651,23 @@ unloading_occurred = true; } - // Follow methodOop - if (can_unload(is_alive, keep_alive, (oop*)&_method, unloading_occurred)) { +#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_compiled_method != NULL && can_unload(is_alive, keep_alive, (oop*)&_graal_compiled_method, unloading_occurred)) { + if (_graal_installed_code != NULL && can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) { return; } +#endif // Exception cache ExceptionCache* ec = exception_cache(); while (ec != NULL) { - oop* ex_addr = (oop*)ec->exception_type_addr(); - oop ex = *ex_addr; + Klass* ex_klass = ec->exception_type(); ExceptionCache* next_ec = ec->next(); - if (ex != NULL && !is_alive->do_object_b(ex)) { - assert(!ex->is_compiledICHolder(), "Possible error here"); + if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) { remove_from_exception_cache(ec); } ec = next_ec; @@ -1673,27 +1682,37 @@ while(iter.next()) { if (iter.type() == relocInfo::virtual_call_type) { CompiledIC *ic = CompiledIC_at(iter.reloc()); - oop ic_oop = ic->cached_oop(); - if (ic_oop != NULL && !is_alive->do_object_b(ic_oop)) { + if (ic->is_icholder_call()) { // The only exception is compiledICHolder oops which may // yet be marked below. (We check this further below). - if (ic_oop->is_compiledICHolder()) { - compiledICHolderOop cichk_oop = compiledICHolderOop(ic_oop); - if (is_alive->do_object_b( - cichk_oop->holder_method()->method_holder()) && - is_alive->do_object_b(cichk_oop->holder_klass())) { + CompiledICHolder* cichk_oop = ic->cached_icholder(); + if (cichk_oop->holder_method()->method_holder()->is_loader_alive(is_alive) && + cichk_oop->holder_klass()->is_loader_alive(is_alive)) { continue; } + } else { + Metadata* ic_oop = ic->cached_metadata(); + if (ic_oop != NULL) { + if (ic_oop->is_klass()) { + if (((Klass*)ic_oop)->is_loader_alive(is_alive)) { + continue; + } + } else if (ic_oop->is_method()) { + if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) { + continue; + } + } else { + ShouldNotReachHere(); + } + } } ic->set_to_clean(); - assert(ic->cached_oop() == NULL, - "cached oop in IC should be cleared"); - } } } } // Compiled code + { RelocIterator iter(this, low_boundary); while (iter.next()) { if (iter.type() == relocInfo::oop_type) { @@ -1704,39 +1723,138 @@ (r->oop_addr() >= oops_begin() && r->oop_addr() < oops_end()), "oop must be found in exactly one place"); if (r->oop_is_immediate() && r->oop_value() != NULL) { - if (can_unload(is_alive, keep_alive, r->oop_addr(), unloading_occurred)) { + if (can_unload(is_alive, r->oop_addr(), unloading_occurred)) { return; } } } } + } // Scopes for (oop* p = oops_begin(); p < oops_end(); p++) { if (*p == Universe::non_oop_word()) continue; // skip non-oops - if (can_unload(is_alive, keep_alive, p, unloading_occurred)) { + if (can_unload(is_alive, p, unloading_occurred)) { return; } } -#ifndef PRODUCT - // This nmethod was not unloaded; check below that all CompiledICs - // refer to marked oops. - { + // Ensure that all metadata is still alive + verify_metadata_loaders(low_boundary, is_alive); +} + +#ifdef ASSERT + +class CheckClass : AllStatic { + static BoolObjectClosure* _is_alive; + + // Check class_loader is alive for this bit of metadata. + static void check_class(Metadata* md) { + Klass* klass = NULL; + if (md->is_klass()) { + klass = ((Klass*)md); + } else if (md->is_method()) { + klass = ((Method*)md)->method_holder(); + } else if (md->is_methodData()) { + klass = ((MethodData*)md)->method()->method_holder(); + } else { + md->print(); + ShouldNotReachHere(); + } + assert(klass->is_loader_alive(_is_alive), "must be alive"); + } + public: + static void do_check_class(BoolObjectClosure* is_alive, nmethod* nm) { + assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint"); + _is_alive = is_alive; + nm->metadata_do(check_class); + } +}; + +// This is called during a safepoint so can use static data +BoolObjectClosure* CheckClass::_is_alive = NULL; +#endif // ASSERT + + +// Processing of oop references should have been sufficient to keep +// all strong references alive. Any weak references should have been +// cleared as well. Visit all the metadata and ensure that it's +// really alive. +void nmethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) { +#ifdef ASSERT RelocIterator iter(this, low_boundary); while (iter.next()) { - if (iter.type() == relocInfo::virtual_call_type) { - CompiledIC *ic = CompiledIC_at(iter.reloc()); - oop ic_oop = ic->cached_oop(); - assert(ic_oop == NULL || is_alive->do_object_b(ic_oop), - "Found unmarked ic_oop in reachable nmethod"); - } + // static_stub_Relocations may have dangling references to + // Method*s so trim them out here. Otherwise it looks like + // compiled code is maintaining a link to dead metadata. + address static_call_addr = NULL; + if (iter.type() == relocInfo::opt_virtual_call_type) { + CompiledIC* cic = CompiledIC_at(iter.reloc()); + if (!cic->is_call_to_interpreted()) { + static_call_addr = iter.addr(); + } + } else if (iter.type() == relocInfo::static_call_type) { + CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc()); + if (!csc->is_call_to_interpreted()) { + static_call_addr = iter.addr(); + } + } + if (static_call_addr != NULL) { + RelocIterator sciter(this, low_boundary); + while (sciter.next()) { + if (sciter.type() == relocInfo::static_stub_type && + sciter.static_stub_reloc()->static_call() == static_call_addr) { + sciter.static_stub_reloc()->clear_inline_cache(); + } + } } } -#endif // !PRODUCT + // Check that the metadata embedded in the nmethod is alive + CheckClass::do_check_class(is_alive, this); +#endif } + +// Iterate over metadata calling this function. Used by RedefineClasses +void nmethod::metadata_do(void f(Metadata*)) { + address low_boundary = verified_entry_point(); + if (is_not_entrant()) { + low_boundary += NativeJump::instruction_size; + // %%% Note: On SPARC we patch only a 4-byte trap, not a full NativeJump. + // (See comment above.) + } + { + // Visit all immediate references that are embedded in the instruction stream. + RelocIterator iter(this, low_boundary); + while (iter.next()) { + if (iter.type() == relocInfo::metadata_type ) { + metadata_Relocation* r = iter.metadata_reloc(); + // In this lmetadata, we must only follow those metadatas directly embedded in + // the code. Other metadatas (oop_index>0) are seen as part of + // the metadata section below. + assert(1 == (r->metadata_is_immediate()) + + (r->metadata_addr() >= metadata_begin() && r->metadata_addr() < metadata_end()), + "metadata must be found in exactly one place"); + if (r->metadata_is_immediate() && r->metadata_value() != NULL) { + Metadata* md = r->metadata_value(); + f(md); + } + } + } + } + + // Visit the metadata section + for (Metadata** p = metadata_begin(); p < metadata_end(); p++) { + if (*p == Universe::non_oop_word() || *p == NULL) continue; // skip non-oops + Metadata* md = *p; + f(md); + } + // Call function Method*, not embedded in these other places. + if (_method != NULL) f(_method); +} + + // This method is called twice during GC -- once while // tracing the "active" nmethods on thread stacks during // the (strong) marking phase, and then again when walking @@ -1763,17 +1881,11 @@ // (See comment above.) } - // Compiled code - f->do_oop((oop*) &_method); - f->do_oop((oop*) &_graal_compiled_method); - if (!do_strong_roots_only) { - // weak roots processing phase -- update ExceptionCache oops - ExceptionCache* ec = exception_cache(); - while(ec != NULL) { - f->do_oop((oop*)ec->exception_type_addr()); - ec = ec->next(); - } - } // Else strong roots phase -- skip oops in ExceptionCache +#ifdef GRAAL + if (graal_installed_code() != NULL) { + f->do_oop((oop*) &_graal_installed_code); + } +#endif RelocIterator iter(this, low_boundary); @@ -2108,21 +2220,21 @@ return found_check; } -bool nmethod::is_evol_dependent_on(klassOop dependee) { - instanceKlass *dependee_ik = instanceKlass::cast(dependee); - objArrayOop dependee_methods = dependee_ik->methods(); +bool nmethod::is_evol_dependent_on(Klass* dependee) { + InstanceKlass *dependee_ik = InstanceKlass::cast(dependee); + Array<Method*>* dependee_methods = dependee_ik->methods(); for (Dependencies::DepStream deps(this); deps.next(); ) { if (deps.type() == Dependencies::evol_method) { - methodOop method = deps.method_argument(0); + Method* method = deps.method_argument(0); for (int j = 0; j < dependee_methods->length(); j++) { - if ((methodOop) dependee_methods->obj_at(j) == method) { + if (dependee_methods->at(j) == method) { // RC_TRACE macro has an embedded ResourceMark RC_TRACE(0x01000000, ("Found evol dependency of nmethod %s.%s(%s) compile_id=%d on method %s.%s(%s)", - _method->method_holder()->klass_part()->external_name(), + _method->method_holder()->external_name(), _method->name()->as_C_string(), _method->signature()->as_C_string(), compile_id(), - method->method_holder()->klass_part()->external_name(), + method->method_holder()->external_name(), method->name()->as_C_string(), method->signature()->as_C_string())); if (TraceDependencies || LogCompilation) @@ -2136,11 +2248,11 @@ } // Called from mark_for_deoptimization, when dependee is invalidated. -bool nmethod::is_dependent_on_method(methodOop dependee) { +bool nmethod::is_dependent_on_method(Method* dependee) { for (Dependencies::DepStream deps(this); deps.next(); ) { if (deps.type() != Dependencies::evol_method) continue; - methodOop method = deps.method_argument(0); + Method* method = deps.method_argument(0); if (method == dependee) return true; } return false; @@ -2279,7 +2391,7 @@ // Make sure all the entry points are correctly aligned for patching. NativeJump::check_verified_entry_alignment(entry_point(), verified_entry_point()); - assert(method()->is_oop(), "must be valid"); + // assert(method()->is_oop(), "must be valid"); ResourceMark rm; @@ -2319,11 +2431,11 @@ if (CompiledIC_lock->owner() == cur || ((cur->is_VM_thread() || cur->is_ConcurrentGC_thread()) && SafepointSynchronize::is_at_safepoint())) { - ic = CompiledIC_at(call_site); + ic = CompiledIC_at(this, call_site); CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); } else { MutexLocker ml_verify (CompiledIC_lock); - ic = CompiledIC_at(call_site); + ic = CompiledIC_at(this, call_site); } PcDesc* pd = pc_desc_at(ic->end_of_call()); assert(pd != NULL, "PcDesc must exist"); @@ -2460,6 +2572,10 @@ oops_begin(), oops_end(), oops_size()); + if (metadata_size () > 0) tty->print_cr(" metadata [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", + metadata_begin(), + metadata_end(), + metadata_size()); if (scopes_data_size () > 0) tty->print_cr(" scopes data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d", scopes_data_begin(), scopes_data_end(), @@ -2509,10 +2625,10 @@ tty->print_cr("Dependencies:"); for (Dependencies::DepStream deps(this); deps.next(); ) { deps.print_dependency(); - klassOop ctxk = deps.context_type(); + Klass* ctxk = deps.context_type(); if (ctxk != NULL) { Klass* k = Klass::cast(ctxk); - if (k->oop_is_instance() && ((instanceKlass*)k)->is_dependent_nmethod(this)) { + if (k->oop_is_instance() && ((InstanceKlass*)k)->is_dependent_nmethod(this)) { tty->print_cr(" [nmethod<=klass]%s", k->external_name()); } } @@ -2575,6 +2691,16 @@ st.print(")"); return st.as_string(); } + case relocInfo::metadata_type: { + stringStream st; + metadata_Relocation* r = iter.metadata_reloc(); + Metadata* obj = r->metadata_value(); + st.print("metadata("); + if (obj == NULL) st.print("NULL"); + else obj->print_value_on(&st); + st.print(")"); + return st.as_string(); + } case relocInfo::virtual_call_type: return "virtual_call"; case relocInfo::opt_virtual_call_type: return "optimized virtual_call"; case relocInfo::static_call_type: return "static_call"; @@ -2602,7 +2728,7 @@ return NULL; } -void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) { +void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const { if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); if (GRAAL_ONLY(_exception_offset >= 0 &&) block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); @@ -2737,7 +2863,7 @@ if (sd->bci() == SynchronizationEntryBCI) { st->print(";*synchronization entry"); } else { - if (sd->method().is_null()) { + if (sd->method() == NULL) { st->print("method is NULL"); } else if (sd->method()->is_native()) { st->print("method is native"); @@ -2778,7 +2904,7 @@ for (;sd != NULL; sd = sd->sender()) { st->move_to(column); st->print("; -"); - if (sd->method().is_null()) { + if (sd->method() == NULL) { st->print("method is NULL"); } else { sd->method()->print_short_name(st);