agent/src/share/classes/sun/jvm/hotspot/asm/Disassembler.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File sadis Cdiff agent/src/share/classes/sun/jvm/hotspot/asm/Disassembler.java

agent/src/share/classes/sun/jvm/hotspot/asm/Disassembler.java

Print this page

        

*** 22,45 **** * */ package sun.jvm.hotspot.asm; ! public abstract class Disassembler { protected long startPc; protected byte[] code; ! public Disassembler(long startPc, byte[] code) { this.startPc = startPc; this.code = code; } public long getStartPC() { return startPc; } public byte[] getCode() { return code; } ! public abstract void decode(InstructionVisitor visitor); } --- 22,345 ---- * */ package sun.jvm.hotspot.asm; ! import java.io.PrintStream; ! import java.util.Observer; ! import java.util.Observable; ! import sun.jvm.hotspot.code.CodeBlob; ! import sun.jvm.hotspot.code.NMethod; ! import sun.jvm.hotspot.debugger.Address; ! import sun.jvm.hotspot.runtime.VM; ! ! public class Disassembler { ! static final int COMMENT_COLUMN = 40; ! static final String BYTES_COMMENT = ";..."; /* funky byte display comment */ ! ! private static String libname; ! private static String options; ! private static long decode_function; ! private static int instructionAlignment; ! ! static { ! VM.registerVMInitializedObserver(new Observer() { ! public void update(Observable o, Object data) { ! options = ""; ! instructionAlignment = 1; ! libname = null; ! String cpu = VM.getVM().getCPU(); ! if (cpu.equals("sparc")) { ! libname = "hsdis-sparc"; ! instructionAlignment = 4; ! if (VM.getVM().isLP64()) { ! options = "v9only"; ! } ! } else if (cpu.equals("x86")) { ! libname = "hsdis-i386"; ! } else if (cpu.equals("amd64")) { ! libname = "hsdis-amd64"; ! } else if (cpu.equals("ia64")) { ! libname = "hsdis-ia64"; ! } ! } ! }); ! } ! protected long startPc; protected byte[] code; + private String _option_buf = ""; + private boolean _print_pc; + private long _cur_insn; + private int _bytes_per_line; // arch-specific formatting option + private CodeBlob blob; + private NMethod nmethod; + private int instruction_alignment; ! public static void decode(InstructionVisitor visitor, CodeBlob blob) { ! decode(visitor, blob, blob.instructionsBegin(), blob.instructionsEnd()); ! } ! ! public static void decode(InstructionVisitor visitor, CodeBlob blob, Address begin, Address end) { ! int codeSize = (int)end.minus(begin); ! long startPc = addressToLong(begin); ! byte[] code = new byte[codeSize]; ! for (int i = 0; i < code.length; i++) ! code[i] = begin.getJByteAt(i); ! Disassembler dis = new Disassembler(startPc, code); ! dis.decode(visitor); ! } ! ! private Disassembler(long startPc, byte[] code) { this.startPc = startPc; this.code = code; + + // Lazily load hsdis + if (decode_function == 0) { + decode_function = load_library(libname); + if (decode_function == 0) { + throw new InternalError("Can't open " + libname); } + } + } public long getStartPC() { return startPc; } public byte[] getCode() { return code; } ! private static native long load_library(String hsdis_library_name); ! ! private native void decode(InstructionVisitor visitor, long pc, byte[] code, ! String options, long decode_function); ! ! private void decode(InstructionVisitor visitor) { ! visitor.prologue(); ! decode(visitor, startPc, code, options, decode_function); ! visitor.epilogue(); ! } ! ! private boolean match(String event, String tag) { ! if (!event.startsWith(tag)) ! return false; ! int taglen = tag.length(); ! if (taglen == event.length()) return true; ! char delim = event.charAt(taglen); ! return delim == ' ' || delim == '/' || delim == '='; ! } ! ! private long handle_event(InstructionVisitor visitor, String event, long arg) { ! if (match(event, "insn")) { ! start_insn(visitor, arg); ! } else if (match(event, "/insn")) { ! end_insn(visitor, arg); ! } else if (match(event, "addr")) { ! if (arg != 0) { ! print_address(visitor, arg); ! return arg; ! } ! } else if (match(event, "mach")) { ! // output().printf("[Disassembling for mach='%s']\n", arg); ! } else if (match(event, "format bytes-per-line")) { ! _bytes_per_line = (int)arg; ! } else { ! // ignore unrecognized markup ! } ! return 0; ! } ! ! void start_insn(InstructionVisitor visitor, long pc) { ! _cur_insn = pc; ! print_insn_labels(visitor); ! visitor.beginInstruction(pc); ! } ! ! void end_insn(InstructionVisitor visitor, long pc) { ! long pc0 = _cur_insn; ! if (nmethod != null) ! print_code_comment_on(visitor, COMMENT_COLUMN, pc0, pc); ! visitor.endInstruction(pc); ! } ! ! long cur_insn() { return _cur_insn; } ! ! protected static long addressToLong(sun.jvm.hotspot.debugger.Address addr) { ! return VM.getVM().getDebugger().getAddressValue(addr); ! } ! ! void print_insn_labels(InstructionVisitor visitor) { ! long p = cur_insn(); ! if (nmethod != null) { ! if (p == addressToLong(nmethod.getEntryPoint())) visitor.print("[Entry Point]\n"); ! if (p == addressToLong(nmethod.getVerifiedEntryPoint())) visitor.print("[Verified Entry Point]\n"); ! if (p == addressToLong(nmethod.exceptionBegin())) visitor.print("[Exception Handler]\n"); ! if (p == addressToLong(nmethod.stubBegin())) visitor.print("[Stub Code]\n"); ! // if (p == addressToLong(nmethod.getConstsBegin())) visitor.print("[Constants]\n"); ! } ! CodeBlob cb = blob; ! // if (cb != null) { ! // cb.print_block_comment(st, (long)(p - addressToLong(cb.instructionsBegin()))); ! // } ! if (_print_pc) { ! visitor.print(" " + p + ": "); ! } ! } ! ! public void raw_print(InstructionVisitor visitor, String s) { ! visitor.print(s); ! } ! ! public void print_address(InstructionVisitor visitor, long adr) { ! if (adr == 0) { ! visitor.print("NULL"); ! return; ! } ! ! int small_num = (int)adr; ! if (adr == small_num && -1 <= small_num && small_num <= 9) { ! visitor.print(Integer.toString(small_num)); ! return; ! } ! ! ! // if (StubRoutines::contains(adr)) { ! // StubCodeDesc* desc = StubCodeDesc::desc_for(adr); ! // if (desc == null) ! // desc = StubCodeDesc::desc_for(adr + frame::pc_return_offset); ! // if (desc != null) { ! // visitor.print("Stub::%s", desc.name()); ! // if (desc.begin() != adr) ! // visitor.print("%+d 0x%p",adr - desc.begin(), adr); ! // else if (WizardMode) visitor.print(" " INTPTR_FORMAT, adr); ! // return; ! // } ! // visitor.print("Stub::<unknown> " INTPTR_FORMAT, adr); ! // return; ! // } ! // ! // BarrierSet* bs = Universe::heap().barrier_set(); ! // if (bs.kind() == BarrierSet::CardTableModRef && ! // adr == (address)((CardTableModRefBS*)(bs)).byte_map_base) { ! // visitor.print("word_map_base"); ! // if (WizardMode) visitor.print(" " INTPTR_FORMAT, (long)adr); ! // return; ! // } ! // ! // Oop obj; ! // if (nmethod != null && ! // (obj = nmethod.embeddedOop_at(cur_insn())) != null && ! // addresstoLong(obj) == adr) { ! // obj.printValueOn(st); ! // return; ! // } ! ! // Fall through to a simple numeral. ! visitor.printAddress(adr); ! } ! ! void print_code_comment_on(InstructionVisitor visitor, int column, long begin, long end) { ! // // First, find an oopmap in (begin, end]. ! // // We use the odd half-closed interval so that oop maps and scope descs ! // // which are tied to the byte after a call are printed with the call itself. ! // Address base = nm.instructionsBegin(); ! // OopMapSet oms = nm.oop_maps(); ! // if (oms != null) { ! // 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) { ! // case Bytecodes::_invokevirtual: ! // case Bytecodes::_invokespecial: ! // case Bytecodes::_invokestatic: ! // case Bytecodes::_invokeinterface: ! // { ! // Bytecode_invoke* invoke = Bytecode_invoke_at(sd.method(), sd.bci()); ! // st.print(" "); ! // if (invoke.name() != null) ! // invoke.name().print_symbol_on(st); ! // else ! // st.print("<UNKNOWN>"); ! // break; ! // } ! // case Bytecodes::_getfield: ! // case Bytecodes::_putfield: ! // case Bytecodes::_getstatic: ! // case Bytecodes::_putstatic: ! // { ! // methodHandle sdm = sd.method(); ! // Bytecode_field* field = Bytecode_field_at(sdm(), sdm.bcp_from(sd.bci())); ! // constantPoolOop sdmc = sdm.constants(); ! // symbolOop name = sdmc.name_ref_at(field.index()); ! // st.print(" "); ! // if (name != null) ! // name.print_symbol_on(st); ! // else ! // 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) { ! // st.print("@%d (line %d)", sd.bci(), lineno); ! // } else { ! // st.print("@%d", sd.bci()); ! // } ! // st.println(); ! // } ! // } ! ! // // Print relocation information ! // const char* str = reloc_string_for(begin, end); ! // if (str != null) { ! // if (sd != null) st.println(); ! // 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); ! // } ! ! } ! }
agent/src/share/classes/sun/jvm/hotspot/asm/Disassembler.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File