@@ -3385,6 +3385,46 @@ void nmethod::print_value_on(outputStream* st) const {
33853385}
33863386#endif
33873387
3388+ void nmethod::print_code_snippet (outputStream* st, address addr) const {
3389+ if (entry_point () <= addr && addr < code_end ()) {
3390+ // Pointing into the nmethod's code. Try to disassemble some instructions around addr.
3391+ // Determine conservative start and end points.
3392+ address start;
3393+ if (frame_complete_offset () != CodeOffsets::frame_never_safe &&
3394+ addr >= code_begin () + frame_complete_offset ()) {
3395+ start = code_begin () + frame_complete_offset ();
3396+ } else {
3397+ start = (addr < verified_entry_point ()) ? entry_point () : verified_entry_point ();
3398+ }
3399+ address start_for_hex_dump = start; // We can choose a different starting point for hex dump, below.
3400+ address end = code_end ();
3401+
3402+ // Try using relocations to find closer instruction start and end points.
3403+ // (Some platforms have variable length instructions and can only
3404+ // disassemble correctly at instruction start addresses.)
3405+ RelocIterator iter ((nmethod*)this , start);
3406+ while (iter.next () && iter.addr () < addr) { // find relocation before addr
3407+ // Note: There's a relocation which doesn't point to an instruction start:
3408+ // ZBarrierRelocationFormatStoreGoodAfterMov with ZGC on x86_64
3409+ // We could detect and skip it, but hex dump is still usable when
3410+ // disassembler produces garbage in such a very rare case.
3411+ start = iter.addr ();
3412+ // We want at least 64 Bytes ahead in hex dump.
3413+ if (iter.addr () <= (addr - 64 )) start_for_hex_dump = iter.addr ();
3414+ }
3415+ if (iter.has_current ()) {
3416+ if (iter.addr () == addr) iter.next (); // find relocation after addr
3417+ if (iter.has_current ()) end = iter.addr ();
3418+ }
3419+
3420+ // Always print hex. Disassembler may still have problems when hitting an incorrect instruction start.
3421+ os::print_hex_dump (st, start_for_hex_dump, end, 1 , /* print_ascii=*/ false );
3422+ if (!Disassembler::is_abstract ()) {
3423+ Disassembler::decode (start, end, st);
3424+ }
3425+ }
3426+ }
3427+
33883428#ifndef PRODUCT
33893429
33903430void nmethod::print_calls (outputStream* st) {
0 commit comments