@@ -3556,6 +3556,46 @@ void nmethod::print_value_on(outputStream* st) const {
35563556}
35573557#endif
35583558
3559+ void nmethod::print_code_snippet (outputStream* st, address addr) const {
3560+ if (entry_point () <= addr && addr < code_end ()) {
3561+ // Pointing into the nmethod's code. Try to disassemble some instructions around addr.
3562+ // Determine conservative start and end points.
3563+ address start;
3564+ if (frame_complete_offset () != CodeOffsets::frame_never_safe &&
3565+ addr >= code_begin () + frame_complete_offset ()) {
3566+ start = code_begin () + frame_complete_offset ();
3567+ } else {
3568+ start = (addr < verified_entry_point ()) ? entry_point () : verified_entry_point ();
3569+ }
3570+ address start_for_hex_dump = start; // We can choose a different starting point for hex dump, below.
3571+ address end = code_end ();
3572+
3573+ // Try using relocations to find closer instruction start and end points.
3574+ // (Some platforms have variable length instructions and can only
3575+ // disassemble correctly at instruction start addresses.)
3576+ RelocIterator iter ((nmethod*)this , start);
3577+ while (iter.next () && iter.addr () < addr) { // find relocation before addr
3578+ // Note: There's a relocation which doesn't point to an instruction start:
3579+ // ZBarrierRelocationFormatStoreGoodAfterMov with ZGC on x86_64
3580+ // We could detect and skip it, but hex dump is still usable when
3581+ // disassembler produces garbage in such a very rare case.
3582+ start = iter.addr ();
3583+ // We want at least 64 Bytes ahead in hex dump.
3584+ if (iter.addr () <= (addr - 64 )) start_for_hex_dump = iter.addr ();
3585+ }
3586+ if (iter.has_current ()) {
3587+ if (iter.addr () == addr) iter.next (); // find relocation after addr
3588+ if (iter.has_current ()) end = iter.addr ();
3589+ }
3590+
3591+ // Always print hex. Disassembler may still have problems when hitting an incorrect instruction start.
3592+ os::print_hex_dump (st, start_for_hex_dump, end, 1 , /* print_ascii=*/ false );
3593+ if (!Disassembler::is_abstract ()) {
3594+ Disassembler::decode (start, end, st);
3595+ }
3596+ }
3597+ }
3598+
35593599#ifndef PRODUCT
35603600
35613601void nmethod::print_calls (outputStream* st) {
0 commit comments