diff --git a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java index 0aae96fcf42a7360f3f578132c6f892a95eb3235..bbb7fe77de792e463aba550abe9b5cb697f6ca53 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java @@ -316,6 +316,14 @@ public class ObjectHeap { iterateLiveRegions(liveRegions, visitor, null); } + public boolean isValidMethod(OopHandle handle) { + OopHandle klass = Oop.getKlassForOopHandle(handle); + if (klass != null && klass.equals(methodKlassHandle)) { + return true; + } + return false; + } + // Creates an instance from the Oop hierarchy based based on the handle public Oop newOop(OopHandle handle) { // The only known way to detect the right type of an oop is @@ -375,8 +383,10 @@ public class ObjectHeap { } } - System.err.println("Unknown oop at " + handle); - System.err.println("Oop's klass is " + klass); + if (DEBUG) { + System.err.println("Unknown oop at " + handle); + System.err.println("Oop's klass is " + klass); + } throw new UnknownOopException(); } diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java index 43ad81d44e5f3b9d80a816fddbd1e4d529435bca..204156c3ff87d35973c40b4c1428367104bf1edc 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java @@ -215,11 +215,11 @@ public class JavaThread extends Thread { if (f == null) return null; boolean imprecise = true; if (f.isInterpretedFrame() && !f.isInterpretedFrameValid()) { - if (DEBUG) { - System.out.println("Correcting for invalid interpreter frame"); - } - f = f.sender(regMap); - imprecise = false; + if (DEBUG) { + System.out.println("Correcting for invalid interpreter frame"); + } + f = f.sender(regMap); + imprecise = false; } VFrame vf = VFrame.newVFrame(f, regMap, this, true, imprecise); if (vf == null) { @@ -228,10 +228,7 @@ public class JavaThread extends Thread { } return null; } - if (vf.isJavaFrame()) { - return (JavaVFrame) vf; - } - return (JavaVFrame) vf.javaSender(); + return vf.isJavaFrame() ? (JavaVFrame)vf : vf.javaSender(); } /** In this system, a JavaThread is the top-level factory for a diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java index 7d42c211d152e9fc2308c6b137652effb3c24d25..93b5acf067d10e5c6b87f68cd6298bf371e04501 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java @@ -121,6 +121,13 @@ public class SolarisSPARCJavaThreadPDAccess implements JavaThreadPDAccess { } public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { + + // If java stack is walkable then both last_Java_sp and last_Java_pc are + // non null and we can start stack walk from this frame. + if (thread.getLastJavaSP() != null && thread.getLastJavaPC() != null) { + return new SPARCFrame(SPARCFrame.biasSP(thread.getLastJavaSP()), thread.getLastJavaPC()); + } + ThreadProxy t = getThreadProxy(addr); SPARCThreadContext context = (SPARCThreadContext) t.getContext(); // For now, let's see what happens if we do a similar thing to diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java index 015329117dc0f55330dc309b449bb12aca6f904f..b9c07b6bc4e64463999968a23ddf1e8b9a6ba8ee 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java @@ -422,6 +422,13 @@ public class SPARCFrame extends Frame { if (getFP().addOffsetTo(INTERPRETER_FRAME_VM_LOCAL_WORDS * VM.getVM().getAddressSize()).lessThan(getSP())) { return false; } + + OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0); + + if (VM.getVM().getObjectHeap().isValidMethod(methodHandle) == false) { + return false; + } + // These are hacks to keep us out of trouble. // The problem with these is that they mask other problems if (getFP().lessThanOrEqual(getSP())) { // this attempts to deal with unsigned comparison above @@ -433,9 +440,18 @@ public class SPARCFrame extends Frame { // FIXME: this is not atomic with respect to GC and is unsuitable // for use in a non-debugging, or reflective, system. Need to // figure out how to express this. - if (addressOfInterpreterFrameBCX().getAddressAt(0) == null) { - return false; // BCP not yet set up + Address bcx = addressOfInterpreterFrameBCX().getAddressAt(0); + + Method method; + try { + method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle); + } catch (UnknownOopException ex) { + return false; } + int bci = bcpToBci(bcx, method); + //validate bci + if (bci < 0) return false; + return true; } @@ -471,7 +487,7 @@ public class SPARCFrame extends Frame { // will update it accordingly map.setIncludeArgumentOops(false); - if (cb == null && isEntryFrame()) { + if (isEntryFrame()) { return senderForEntryFrame(map); } @@ -539,7 +555,6 @@ public class SPARCFrame extends Frame { int SP_OFFSET_IN_GREGSET = 17; raw_sp = fp.getAddressAt(VM.getVM().getAddressSize() * SP_OFFSET_IN_GREGSET); Address pc = fp.getAddressAt(VM.getVM().getAddressSize() * PC_OFFSET_IN_GREGSET); - // System.out.println(" next frame's SP: " + sp + " PC: " + pc); return new SPARCFrame(raw_sp, pc); } } @@ -562,10 +577,8 @@ public class SPARCFrame extends Frame { // sender's _interpreter_sp_adjustment field. if (VM.getVM().getInterpreter().contains(pc)) { isInterpreted = true; - if (VM.getVM().isClientCompiler()) { - map.makeIntegerRegsUnsaved(); - map.shiftWindow(sp, youngerSP); - } + map.makeIntegerRegsUnsaved(); + map.shiftWindow(sp, youngerSP); } else { // Find a CodeBlob containing this frame's pc or elide the lookup and use the // supplied blob which is already known to be associated with this frame. diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java index 9bab664f2740dafe35effa19ef78a5d359a9fc5d..a928d56905abbb8d59232bc58d6871241fc7d8f8 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @@ -87,12 +87,13 @@ public class PStack extends Tool { while (f != null) { ClosestSymbol sym = f.closestSymbolToPC(); Address pc = f.pc(); + out.print(pc + "\t"); if (sym != null) { String name = sym.getName(); if (cdbgCanDemangle) { name = cdbg.demangle(name); } - out.print(pc + "\t" + name); + out.print(name); long diff = sym.getOffset(); if (diff != 0L) { out.print(" + 0x" + Long.toHexString(diff)); @@ -120,7 +121,6 @@ public class PStack extends Tool { // look for known code blobs CodeCache c = VM.getVM().getCodeCache(); if (c.contains(pc)) { - out.print(pc + "\t"); CodeBlob cb = c.findBlobUnsafe(pc); if (cb.isNMethod()) { names = getJavaNames(th, f.localVariableBase()); @@ -144,18 +144,18 @@ public class PStack extends Tool { out.println(""); } } else { - printUnknown(out,pc); + printUnknown(out); } } // print java frames, if any if (names != null && names.length != 0) { // print java frame(s) for (int i = 0; i < names.length; i++) { - out.println(pc + "\t" + names[i]); + out.println(names[i]); } } } else { - printUnknown(out,pc); + printUnknown(out); } } f = f.sender(); @@ -220,8 +220,8 @@ public class PStack extends Tool { } } - private void printUnknown(PrintStream out, Address pc) { - out.println(pc + "\t????????"); + private void printUnknown(PrintStream out) { + out.println("\t????????"); } private String[] getJavaNames(ThreadProxy th, Address fp) {