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) {