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