6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes

Initial checkin of JSDT code

Reviewed-by: acorn, sbohne
This commit is contained in:
Keith McGuigan 2008-04-17 22:18:15 -04:00
parent 849e0dfc44
commit f072bc9d3f
26 changed files with 2935 additions and 26 deletions

View file

@ -27,7 +27,6 @@
#ifdef DTRACE_ENABLED
// Only bother with this argument setup if dtrace is available
HS_DTRACE_PROBE_DECL8(hotspot, compiled__method__load,
@ -438,7 +437,6 @@ nmethod* nmethod::new_native_nmethod(methodHandle method,
{
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);
@ -461,6 +459,41 @@ nmethod* nmethod::new_native_nmethod(methodHandle method,
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,
@ -558,6 +591,9 @@ nmethod::nmethod(
_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();
@ -615,6 +651,90 @@ nmethod::nmethod(
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
@ -658,6 +778,9 @@ nmethod::nmethod(
_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
@ -1885,7 +2008,6 @@ void nmethod::print() const {
} else if (is_compiled_by_c2()) {
tty->print("(c2) ");
} else {
assert(is_native_method(), "Who else?");
tty->print("(nm) ");
}