hotspot/src/share/vm/code/nmethod.cpp

Print this page
rev 611 : Merge

*** 1,10 **** #ifdef USE_PRAGMA_IDENT_SRC #pragma ident "@(#)nmethod.cpp 1.371 08/02/29 12:46:11 JVM" #endif /* ! * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,10 ---- #ifdef USE_PRAGMA_IDENT_SRC #pragma ident "@(#)nmethod.cpp 1.371 08/02/29 12:46:11 JVM" #endif /* ! * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 28,38 **** # include "incls/_precompiled.incl" # include "incls/_nmethod.cpp.incl" #ifdef DTRACE_ENABLED - // Only bother with this argument setup if dtrace is available HS_DTRACE_PROBE_DECL8(hotspot, compiled__method__load, const char*, int, const char*, int, const char*, int, void*, size_t); --- 28,37 ----
*** 439,449 **** // create nmethod nmethod* nm = NULL; { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); int native_nmethod_size = allocation_size(code_buffer, sizeof(nmethod)); - const int dummy = -1; // Flag to force proper "operator new" CodeOffsets offsets; offsets.set_value(CodeOffsets::Verified_Entry, vep_offset); offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); nm = new (native_nmethod_size) nmethod(method(), native_nmethod_size, &offsets, --- 438,447 ----
*** 462,471 **** --- 460,504 ---- } return nm; } + #ifdef HAVE_DTRACE_H + nmethod* nmethod::new_dtrace_nmethod(methodHandle method, + CodeBuffer *code_buffer, + int vep_offset, + int trap_offset, + int frame_complete, + int frame_size) { + // create nmethod + nmethod* nm = NULL; + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + int nmethod_size = allocation_size(code_buffer, sizeof(nmethod)); + CodeOffsets offsets; + offsets.set_value(CodeOffsets::Verified_Entry, vep_offset); + offsets.set_value(CodeOffsets::Dtrace_trap, trap_offset); + offsets.set_value(CodeOffsets::Frame_Complete, frame_complete); + + nm = new (nmethod_size) nmethod(method(), nmethod_size, &offsets, code_buffer, frame_size); + + NOT_PRODUCT(if (nm != NULL) nmethod_stats.note_nmethod(nm)); + if (PrintAssembly && nm != NULL) + Disassembler::decode(nm); + } + // verify nmethod + debug_only(if (nm) nm->verify();) // might block + + if (nm != NULL) { + nm->log_new_nmethod(); + } + + return nm; + } + + #endif // def HAVE_DTRACE_H + nmethod* nmethod::new_nmethod(methodHandle method, int compile_id, int entry_bci, CodeOffsets* offsets, int orig_pc_offset,
*** 559,568 **** --- 592,604 ---- // We have no exception handler or deopt handler make the // values something that will never match a pc like the nmethod vtable entry _exception_offset = 0; _deoptimize_offset = 0; _orig_pc_offset = 0; + #ifdef HAVE_DTRACE_H + _trap_offset = 0; + #endif // def HAVE_DTRACE_H _stub_offset = data_offset(); _consts_offset = data_offset(); _scopes_data_offset = data_offset(); _scopes_pcs_offset = _scopes_data_offset; _dependencies_offset = _scopes_pcs_offset;
*** 616,625 **** --- 652,745 ---- } } Events::log("Create nmethod " INTPTR_FORMAT, this); } + // For dtrace wrappers + #ifdef HAVE_DTRACE_H + nmethod::nmethod( + methodOop method, + int nmethod_size, + CodeOffsets* offsets, + CodeBuffer* code_buffer, + int frame_size) + : CodeBlob("dtrace nmethod", code_buffer, sizeof(nmethod), + nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, NULL), + _compiled_synchronized_native_basic_lock_owner_sp_offset(in_ByteSize(-1)), + _compiled_synchronized_native_basic_lock_sp_offset(in_ByteSize(-1)) + { + { + debug_only(No_Safepoint_Verifier nsv;) + assert_locked_or_safepoint(CodeCache_lock); + + NOT_PRODUCT(_has_debug_info = false; ) + _method = method; + _entry_bci = InvocationEntryBci; + _link = NULL; + _compiler = NULL; + // We have no exception handler or deopt handler make the + // values something that will never match a pc like the nmethod vtable entry + _exception_offset = 0; + _deoptimize_offset = 0; + _trap_offset = offsets->value(CodeOffsets::Dtrace_trap); + _orig_pc_offset = 0; + _stub_offset = data_offset(); + _consts_offset = data_offset(); + _scopes_data_offset = data_offset(); + _scopes_pcs_offset = _scopes_data_offset; + _dependencies_offset = _scopes_pcs_offset; + _handler_table_offset = _dependencies_offset; + _nul_chk_table_offset = _handler_table_offset; + _nmethod_end_offset = _nul_chk_table_offset; + _compile_id = 0; // default + _comp_level = CompLevel_none; + _entry_point = instructions_begin(); + _verified_entry_point = instructions_begin() + offsets->value(CodeOffsets::Verified_Entry); + _osr_entry_point = NULL; + _exception_cache = NULL; + _pc_desc_cache.reset_to(NULL); + + flags.clear(); + flags.state = alive; + _markedForDeoptimization = 0; + + _lock_count = 0; + _stack_traversal_mark = 0; + + code_buffer->copy_oops_to(this); + debug_only(check_store();) + CodeCache::commit(this); + VTune::create_nmethod(this); + } + + if (PrintNMethods || PrintDebugInfo || PrintRelocations || PrintDependencies) { + ttyLocker ttyl; // keep the following output all in one block + // This output goes directly to the tty, not the compiler log. + // To enable tools to match it up with the compilation activity, + // be sure to tag this tty output with the compile ID. + if (xtty != NULL) { + xtty->begin_head("print_dtrace_nmethod"); + xtty->method(_method); + xtty->stamp(); + xtty->end_head(" address='" INTPTR_FORMAT "'", (intptr_t) this); + } + // print the header part first + print(); + // then print the requested information + if (PrintNMethods) { + print_code(); + } + if (PrintRelocations) { + print_relocations(); + } + if (xtty != NULL) { + xtty->tail("print_dtrace_nmethod"); + } + } + Events::log("Create nmethod " INTPTR_FORMAT, this); + } + #endif // def HAVE_DTRACE_H void* nmethod::operator new(size_t size, int nmethod_size) { // Always leave some room in the CodeCache for I2C/C2I adapters if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) return NULL; return CodeCache::allocate(nmethod_size);
*** 659,668 **** --- 779,791 ---- _comp_level = comp_level; _entry_bci = entry_bci; _link = NULL; _compiler = compiler; _orig_pc_offset = orig_pc_offset; + #ifdef HAVE_DTRACE_H + _trap_offset = 0; + #endif // def HAVE_DTRACE_H _stub_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start()); // Exception handler and deopt handler are in the stub section _exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions); _deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt);
*** 708,718 **** assert(compiler->is_c2() || _method->is_static() == (entry_point() == _verified_entry_point), " entry points must be same for static methods and vice versa"); } ! bool printnmethods = PrintNMethods || CompilerOracle::has_option_string(_method, "PrintNMethods"); if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { print_nmethod(printnmethods); } // Note: Do not verify in here as the CodeCache_lock is --- 831,843 ---- assert(compiler->is_c2() || _method->is_static() == (entry_point() == _verified_entry_point), " entry points must be same for static methods and vice versa"); } ! bool printnmethods = PrintNMethods ! || CompilerOracle::should_print(_method) ! || CompilerOracle::has_option_string(_method, "PrintNMethods"); if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { print_nmethod(printnmethods); } // Note: Do not verify in here as the CodeCache_lock is
*** 799,809 **** } } } - #ifndef PRODUCT void nmethod::print_nmethod(bool printmethod) { ttyLocker ttyl; // keep the following output all in one block if (xtty != NULL) { xtty->begin_head("print_nmethod"); xtty->stamp(); --- 924,933 ----
*** 832,842 **** } if (xtty != NULL) { xtty->tail("print_nmethod"); } } - #endif void nmethod::set_version(int v) { flags.version = v; } --- 956,965 ----
*** 1228,1242 **** // The oop should be kept alive keep_alive->do_oop(root); return false; } } - if (!UseParallelOldGC || !VerifyParallelOldWithMarkSweep) { - // Cannot do this test if verification of the UseParallelOldGC - // code using the PSMarkSweep code is being done. assert(unloading_occurred, "Inconsistency in unloading"); - } make_unloaded(is_alive, obj); return true; } // ------------------------------------------------------------------ --- 1351,1361 ----
*** 1871,1880 **** --- 1990,2000 ---- } } } } + #endif // PRODUCT // Printing operations void nmethod::print() const { ResourceMark rm;
*** 1885,1895 **** if (is_compiled_by_c1()) { tty->print("(c1) "); } else if (is_compiled_by_c2()) { tty->print("(c2) "); } else { - assert(is_native_method(), "Who else?"); tty->print("(nm) "); } print_on(tty, "nmethod"); tty->cr(); --- 2005,2014 ----
*** 1949,1958 **** --- 2068,2085 ---- oops_begin(), oops_end(), oops_size()); } + void nmethod::print_code() { + HandleMark hm; + ResourceMark m; + Disassembler::decode(this); + } + + + #ifndef PRODUCT void nmethod::print_scopes() { // Find the first pc desc for all scopes in the code and print it. ResourceMark rm; for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) {
*** 1980,1996 **** deps.log_dependency(); // put it into the xml log also } } - void nmethod::print_code() { - HandleMark hm; - ResourceMark m; - Disassembler().decode(this); - } - - void nmethod::print_relocations() { ResourceMark m; // in case methods get printed via the debugger tty->print_cr("relocations:"); RelocIterator iter(this); iter.print(); --- 2107,2116 ----
*** 2022,2031 **** --- 2142,2152 ---- for (PcDesc* p = scopes_pcs_begin(); p < scopes_pcs_end(); p++) { p->print(this); } } + #endif // PRODUCT const char* nmethod::reloc_string_for(u_char* begin, u_char* end) { RelocIterator iter(this, begin, end); bool have_one = false; while (iter.next()) {
*** 2056,2066 **** } } return have_one ? "other" : NULL; } - // Return a the last scope in (begin..end] ScopeDesc* nmethod::scope_desc_in(address begin, address end) { PcDesc* p = pc_desc_near(begin+1); if (p != NULL && p->real_pc(this) <= end) { return new ScopeDesc(this, p->scope_decode_offset(), --- 2177,2186 ----
*** 2079,2111 **** for (int i = 0, imax = oms->size(); i < imax; i++) { OopMap* om = oms->at(i); address pc = base + om->offset(); if (pc > begin) { if (pc <= end) { ! st->fill_to(column); ! if (st == tty) { ! st->print("; OopMap "); ! om->print(); ! tty->cr(); ! } else { ! st->print_cr("; OopMap #%d offset:%d", i, om->offset()); ! } } break; } } } ScopeDesc* sd = scope_desc_in(begin, end); if (sd != NULL) { ! st->fill_to(column); if (sd->bci() == SynchronizationEntryBCI) { st->print(";*synchronization entry"); } else { if (sd->method().is_null()) { ! tty->print("method is NULL"); } else if (sd->method()->is_native()) { ! tty->print("method is native"); } else { address bcp = sd->method()->bcp_from(sd->bci()); Bytecodes::Code bc = Bytecodes::java_code_at(bcp); st->print(";*%s", Bytecodes::name(bc)); switch (bc) { --- 2199,2228 ---- for (int i = 0, imax = oms->size(); i < imax; i++) { OopMap* om = oms->at(i); address pc = base + om->offset(); if (pc > begin) { if (pc <= end) { ! st->move_to(column); ! st->print("; "); ! om->print_on(st); } break; } } } + + // Print any debug info present at this pc. ScopeDesc* sd = scope_desc_in(begin, end); if (sd != NULL) { ! st->move_to(column); if (sd->bci() == SynchronizationEntryBCI) { st->print(";*synchronization entry"); } else { if (sd->method().is_null()) { ! st->print("method is NULL"); } else if (sd->method()->is_native()) { ! st->print("method is native"); } else { address bcp = sd->method()->bcp_from(sd->bci()); Bytecodes::Code bc = Bytecodes::java_code_at(bcp); st->print(";*%s", Bytecodes::name(bc)); switch (bc) {
*** 2138,2154 **** st->print("<UNKNOWN>"); } } } } ! st->cr(); // Print all scopes for (;sd != NULL; sd = sd->sender()) { ! st->fill_to(column); st->print("; -"); if (sd->method().is_null()) { ! tty->print("method is NULL"); } else { sd->method()->print_short_name(st); } int lineno = sd->method()->line_number_from_bci(sd->bci()); if (lineno != -1) { --- 2255,2271 ---- st->print("<UNKNOWN>"); } } } } ! // Print all scopes for (;sd != NULL; sd = sd->sender()) { ! st->move_to(column); st->print("; -"); if (sd->method().is_null()) { ! st->print("method is NULL"); } else { sd->method()->print_short_name(st); } int lineno = sd->method()->line_number_from_bci(sd->bci()); if (lineno != -1) {
*** 2162,2182 **** // Print relocation information const char* str = reloc_string_for(begin, end); if (str != NULL) { if (sd != NULL) st->cr(); ! st->fill_to(column); st->print("; {%s}", str); } int cont_offset = ImplicitExceptionTable(this).at(begin - instructions_begin()); if (cont_offset != 0) { ! st->fill_to(column); st->print("; implicit exception: dispatches to " INTPTR_FORMAT, instructions_begin() + cont_offset); } } void nmethod::print_value_on(outputStream* st) const { print_on(st, "nmethod"); } void nmethod::print_calls(outputStream* st) { --- 2279,2301 ---- // Print relocation information const char* str = reloc_string_for(begin, end); if (str != NULL) { if (sd != NULL) st->cr(); ! st->move_to(column); st->print("; {%s}", str); } int cont_offset = ImplicitExceptionTable(this).at(begin - instructions_begin()); if (cont_offset != 0) { ! st->move_to(column); st->print("; implicit exception: dispatches to " INTPTR_FORMAT, instructions_begin() + cont_offset); } } + #ifndef PRODUCT + void nmethod::print_value_on(outputStream* st) const { print_on(st, "nmethod"); } void nmethod::print_calls(outputStream* st) {