--- old/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Wed Aug 26 18:20:02 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Wed Aug 26 18:20:02 2009 @@ -27,9 +27,6 @@ import java.io.*; import java.util.*; import sun.jvm.hotspot.asm.*; -import sun.jvm.hotspot.asm.sparc.*; -import sun.jvm.hotspot.asm.x86.*; -import sun.jvm.hotspot.asm.ia64.*; import sun.jvm.hotspot.code.*; import sun.jvm.hotspot.compiler.*; import sun.jvm.hotspot.debugger.*; @@ -181,32 +178,6 @@ } } - private static CPUHelper cpuHelper; - static { - VM.registerVMInitializedObserver(new Observer() { - public void update(Observable o, Object data) { - initialize(); - } - }); - } - - private static synchronized void initialize() { - String cpu = VM.getVM().getCPU(); - if (cpu.equals("sparc")) { - cpuHelper = new SPARCHelper(); - } else if (cpu.equals("x86")) { - cpuHelper = new X86Helper(); - } else if (cpu.equals("ia64")) { - cpuHelper = new IA64Helper(); - } else { - throw new RuntimeException("cpu '" + cpu + "' is not yet supported!"); - } - } - - protected static synchronized CPUHelper getCPUHelper() { - return cpuHelper; - } - protected String escapeHTMLSpecialChars(String value) { if (!genHTML) return value; @@ -775,10 +746,6 @@ } } - protected Disassembler createDisassembler(long startPc, byte[] code) { - return getCPUHelper().createDisassembler(startPc, code); - } - protected SymbolFinder createSymbolFinder() { return new DummySymbolFinder(); } @@ -872,25 +839,28 @@ return buf.toString(); } - protected String genPCHref(long currentPc, sun.jvm.hotspot.asm.Address addr) { - String href = null; - if (addr instanceof PCRelativeAddress) { - PCRelativeAddress pcRelAddr = (PCRelativeAddress) addr; - href = genPCHref(currentPc + pcRelAddr.getDisplacement()); - } else if(addr instanceof DirectAddress) { - href = genPCHref(((DirectAddress) addr).getValue()); - } - - return href; + protected String genPCHref(Address addr) { + return genPCHref(addressToLong(addr)); } - class RawCodeVisitor implements InstructionVisitor { + class HTMLDisassembler implements InstructionVisitor { private int instrSize = 0; private Formatter buf; private SymbolFinder symFinder = createSymbolFinder(); + private long pc; + private OopMapSet oms; + private CodeBlob blob; + private NMethod nmethod; - RawCodeVisitor(Formatter buf) { + HTMLDisassembler(Formatter buf, CodeBlob blob) { this.buf = buf; + this.blob = blob; + if (blob != null) { + if (blob instanceof NMethod) { + nmethod = (NMethod)blob; + } + oms = blob.getOopMaps(); + } } public int getInstructionSize() { @@ -900,28 +870,67 @@ public void prologue() { } - public void visit(long currentPc, Instruction instr) { - String href = null; - if (instr.isCall()) { - CallInstruction call = (CallInstruction) instr; - sun.jvm.hotspot.asm.Address addr = call.getBranchDestination(); - href = genPCHref(currentPc, addr); - } + public void beginInstruction(long currentPc) { + pc = currentPc; - instrSize += instr.getSize(); - buf.append("0x"); - buf.append(Long.toHexString(currentPc)); - buf.append(':'); - buf.append(tab); + if (nmethod != null) { + if (pc == addressToLong(nmethod.getEntryPoint())) print("[Entry Point]\n"); + if (pc == addressToLong(nmethod.getVerifiedEntryPoint())) print("[Verified Entry Point]\n"); + if (pc == addressToLong(nmethod.exceptionBegin())) print("[Exception Handler]\n"); + if (pc == addressToLong(nmethod.stubBegin())) print("[Stub Code]\n"); + // if (p == addressToLong(nmethod.getConstsBegin())) print("[Constants]\n"); + } - if (href != null) { - buf.link(href, instr.asString(currentPc, symFinder)); - } else { - buf.append(instr.asString(currentPc, symFinder)); - } - buf.br(); + buf.append("0x"); + buf.append(Long.toHexString(currentPc)); + buf.append(':'); + buf.append(tab); } + public void printAddress(long address) { + Address addr = longToAddress(address); + if (VM.getVM().getCodeCache().contains(addr)) { + buf.link(genPCHref(address), addr.toString()); + } else { + buf.append(addr.toString()); + } + } + + public void print(String s) { + buf.append(s); + } + + public void endInstruction(long endPc) { + instrSize += endPc - pc; + if (genHTML) buf.br(); + + if (nmethod != null) { + ScopeDesc sd = nmethod.scope_desc_in(pc, endPc); + if (sd != null) { + buf.br(); + buf.append(genSafepointInfo(nmethod, sd)); + } + } + + if (oms != null) { + long base = addressToLong(nmethod.instructionsBegin()); + for (int i = 0, imax = (int)oms.getSize(); i < imax; i++) { + OopMap om = oms.getMapAt(i); + long omspc = base + om.getOffset(); + if (omspc > pc) { + if (omspc <= endPc) { + buf.br(); + buf.append(genOopMapInfo(om)); + // st.move_to(column); + // visitor.print("; "); + // om.print_on(st); + } + break; + } + } + } + } + public void epilogue() { } }; @@ -930,10 +939,8 @@ String prevPCs, byte[] code) { try { - long startPc = addressToLong(addr); - Disassembler disasm = createDisassembler(startPc, code); final Formatter buf = new Formatter(genHTML); - buf.genHTMLPrologue("Disassembly @0x" + Long.toHexString(startPc)); + buf.genHTMLPrologue("Disassembly @ " + addr); if (prevPCs != null && genHTML) { buf.beginTag("p"); @@ -943,11 +950,12 @@ buf.h3("Code"); - RawCodeVisitor visitor = new RawCodeVisitor(buf); - disasm.decode(visitor); + HTMLDisassembler visitor = new HTMLDisassembler(buf, null); + Disassembler.decode(visitor, null, addr, addr.addOffsetTo(code.length)); if (genHTML) buf.beginTag("p"); Formatter tmpBuf = new Formatter(genHTML); + long startPc = addressToLong(addr); tmpBuf.append("0x"); tmpBuf.append(Long.toHexString(startPc + visitor.getInstructionSize()).toString()); tmpBuf.append(",0x"); @@ -968,8 +976,7 @@ } } - protected String genSafepointInfo(NMethod nm, PCDesc pcDesc) { - ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm)); + protected String genSafepointInfo(NMethod nm, ScopeDesc sd) { Formatter buf = new Formatter(genHTML); Formatter tabs = new Formatter(genHTML); @@ -976,7 +983,6 @@ buf.beginTag("pre"); genScope(buf, tabs, sd); buf.endTag("pre"); - buf.append(genOopMapInfo(nm, pcDesc)); return buf.toString(); } @@ -1078,7 +1084,7 @@ buf.append(omvIterator.iterate(oms, "Value:", false)); oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE); - buf.append(omvIterator.iterate(oms, "Oop:", false)); + buf.append(omvIterator.iterate(oms, "NarrowOop:", false)); oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); buf.append(omvIterator.iterate(oms, "Callee saved:", true)); @@ -1271,84 +1277,7 @@ buf.append(genMethodAndKlassLink(nmethod.getMethod())); buf.h3("Compiled Code"); - sun.jvm.hotspot.debugger.Address codeBegin = nmethod.codeBegin(); - sun.jvm.hotspot.debugger.Address codeEnd = nmethod.codeEnd(); - final int codeSize = (int)codeEnd.minus(codeBegin); - final long startPc = addressToLong(codeBegin); - final byte[] code = new byte[codeSize]; - for (int i=0; i < code.length; i++) - code[i] = codeBegin.getJByteAt(i); - - final long verifiedEntryPoint = addressToLong(nmethod.getVerifiedEntryPoint()); - final long entryPoint = addressToLong(nmethod.getEntryPoint()); - final Map safepoints = nmethod.getSafepoints(); - - final SymbolFinder symFinder = createSymbolFinder(); - final Disassembler disasm = createDisassembler(startPc, code); - class NMethodVisitor implements InstructionVisitor { - boolean prevWasCall; - public void prologue() { - prevWasCall = false; - } - - public void visit(long currentPc, Instruction instr) { - String href = null; - if (instr.isCall()) { - CallInstruction call = (CallInstruction) instr; - sun.jvm.hotspot.asm.Address addr = call.getBranchDestination(); - href = genPCHref(currentPc, addr); - } - - if (currentPc == verifiedEntryPoint) { - buf.bold("Verified Entry Point"); buf.br(); - } - if (currentPc == entryPoint) { - buf.bold(">Entry Point"); buf.br(); - } - - PCDesc pcDesc = (PCDesc) safepoints.get(longToAddress(currentPc)); - - boolean isSafepoint = (pcDesc != null); - if (isSafepoint && prevWasCall) { - buf.append(genSafepointInfo(nmethod, pcDesc)); - } - - buf.append("0x"); - buf.append(Long.toHexString(currentPc)); - buf.append(':'); - buf.append(tab); - - if (href != null) { - buf.link(href, instr.asString(currentPc, symFinder)); - } else { - buf.append(instr.asString(currentPc, symFinder)); - } - - if (isSafepoint && !prevWasCall) { - buf.append(genSafepointInfo(nmethod, pcDesc)); - } - - buf.br(); - prevWasCall = instr.isCall(); - } - - public void epilogue() { - } - }; - - disasm.decode(new NMethodVisitor()); - - sun.jvm.hotspot.debugger.Address stubBegin = nmethod.stubBegin(); - if (stubBegin != null) { - sun.jvm.hotspot.debugger.Address stubEnd = nmethod.stubEnd(); - buf.h3("Stub"); - long stubStartPc = addressToLong(stubBegin); - long stubEndPc = addressToLong(stubEnd); - int range = (int) (stubEndPc - stubStartPc); - byte[] stubCode = readBuffer(stubBegin, range); - Disassembler disasm2 = createDisassembler(stubStartPc, stubCode); - disasm2.decode(new NMethodVisitor()); - } + Disassembler.decode(new HTMLDisassembler(buf, nmethod), nmethod); buf.genHTMLEpilogue(); return buf.toString(); } catch (Exception exp) { @@ -1363,73 +1292,8 @@ buf.h3("CodeBlob"); buf.h3("Compiled Code"); - final sun.jvm.hotspot.debugger.Address codeBegin = blob.instructionsBegin(); - final int codeSize = blob.getInstructionsSize(); - final long startPc = addressToLong(codeBegin); - final byte[] code = new byte[codeSize]; - for (int i=0; i < code.length; i++) - code[i] = codeBegin.getJByteAt(i); + Disassembler.decode(new HTMLDisassembler(buf, blob), blob); - final SymbolFinder symFinder = createSymbolFinder(); - final Disassembler disasm = createDisassembler(startPc, code); - class CodeBlobVisitor implements InstructionVisitor { - OopMapSet maps; - OopMap curMap; - int curMapIndex; - long curMapOffset; - public void prologue() { - maps = blob.getOopMaps(); - if (maps != null && (maps.getSize() > 0)) { - curMap = maps.getMapAt(0); - if (curMap != null) { - curMapOffset = curMap.getOffset(); - } - } - } - - public void visit(long currentPc, Instruction instr) { - String href = null; - if (instr.isCall()) { - CallInstruction call = (CallInstruction) instr; - sun.jvm.hotspot.asm.Address addr = call.getBranchDestination(); - href = genPCHref(currentPc, addr); - } - - buf.append("0x"); - buf.append(Long.toHexString(currentPc)); - buf.append(':'); - buf.append(tab); - - if (href != null) { - buf.link(href, instr.asString(currentPc, symFinder)); - } else { - buf.append(instr.asString(currentPc, symFinder)); - } - buf.br(); - - // See whether we have an oop map at this PC - if (curMap != null) { - long curOffset = currentPc - startPc; - if (curOffset == curMapOffset) { - buf.append(genOopMapInfo(curMap)); - if (++curMapIndex >= maps.getSize()) { - curMap = null; - } else { - curMap = maps.getMapAt(curMapIndex); - if (curMap != null) { - curMapOffset = curMap.getOffset(); - } - } - } - } - } - - public void epilogue() { - } - }; - - disasm.decode(new CodeBlobVisitor()); - buf.genHTMLEpilogue(); return buf.toString(); } catch (Exception exp) { @@ -1499,14 +1363,9 @@ } buf.h3("Code"); - long stubStartPc = addressToLong(codelet.codeBegin()); - long stubEndPc = addressToLong(codelet.codeEnd()); - int range = (int) (stubEndPc - stubStartPc); - byte[] stubCode = readBuffer(codelet.codeBegin(), range); - Disassembler disasm = createDisassembler(stubStartPc, stubCode); - disasm.decode(new RawCodeVisitor(buf)); + Disassembler.decode(new HTMLDisassembler(buf, null), null, + codelet.codeBegin(), codelet.codeEnd()); - Stub next = stubq.getNext(codelet); if (next != null) { if (genHTML) {