virtual void do_object(oop obj) { if (obj->is_klass()) { Klass* k = klassOop(obj)->klass_part(); if (k->name() != NULL) { ResourceMark rm; const char* ext = k->external_name(); if ( strcmp(_target, ext) == 0 ) { tty->print_cr("Found " INTPTR_FORMAT, obj); obj->print(); } } } }
void trace_method_handle_stub(const char* adaptername, oop mh, intptr_t* saved_regs, intptr_t* entry_sp) { // called as a leaf from native code: do not block the JVM! bool has_mh = (strstr(adaptername, "/static") == NULL && strstr(adaptername, "linkTo") == NULL); // static linkers don't have MH const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx"; tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT, adaptername, mh_reg_name, mh, entry_sp); if (Verbose) { tty->print_cr("Registers:"); const int saved_regs_count = RegisterImpl::number_of_registers; for (int i = 0; i < saved_regs_count; i++) { Register r = as_Register(i); // The registers are stored in reverse order on the stack (by pusha). tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[((saved_regs_count - 1) - i)]); if ((i + 1) % 4 == 0) { tty->cr(); } else { tty->print(", "); } } tty->cr(); { // dumping last frame with frame::describe JavaThread* p = JavaThread::active(); ResourceMark rm; PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here FrameValues values; // Note: We want to allow trace_method_handle from any call site. // While trace_method_handle creates a frame, it may be entered // without a PC on the stack top (e.g. not just after a call). // Walking that frame could lead to failures due to that invalid PC. // => carefully detect that frame when doing the stack walking // Current C frame frame cur_frame = os::current_frame(); // Robust search of trace_calling_frame (independant of inlining). // Assumes saved_regs comes from a pusha in the trace_calling_frame. assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?"); frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame); while (trace_calling_frame.fp() < saved_regs) { trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame); } // safely create a frame and call frame::describe intptr_t *dump_sp = trace_calling_frame.sender_sp(); intptr_t *dump_fp = trace_calling_frame.link(); bool walkable = has_mh; // whether the traced frame shoud be walkable if (walkable) { // The previous definition of walkable may have to be refined // if new call sites cause the next frame constructor to start // failing. Alternatively, frame constructors could be // modified to support the current or future non walkable // frames (but this is more intrusive and is not considered as // part of this RFE, which will instead use a simpler output). frame dump_frame = frame(dump_sp, dump_fp); dump_frame.describe(values, 1); } else { // Stack may not be walkable (invalid PC above FP): // Add descriptions without building a Java frame to avoid issues values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>"); values.describe(-1, dump_sp, "sp for #1"); } values.describe(-1, entry_sp, "raw top of stack"); tty->print_cr("Stack layout:"); values.print(p); } if (has_mh && mh->is_oop()) { mh->print(); if (java_lang_invoke_MethodHandle::is_instance(mh)) { if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) java_lang_invoke_MethodHandle::form(mh)->print(); } } } }