aboutsummaryrefslogtreecommitdiff
path: root/agent
diff options
context:
space:
mode:
authorkvn <none@none>2009-10-21 09:15:33 -0700
committerkvn <none@none>2009-10-21 09:15:33 -0700
commitd806ed2ca7794b845a23ce57c3fd327ee5832c25 (patch)
treecce957cb20d46c0087156a4f1972f3a9cb3c1c73 /agent
parent9efaa48ce3eb845c46fa785f22c3faf2ace0f1d2 (diff)
6892186: SA does not dump debug info for scalar replaced objects
Summary: Implement scalar replaced objects debug info dump in SA. Reviewed-by: twisti
Diffstat (limited to 'agent')
-rw-r--r--agent/make/saenv.sh12
-rw-r--r--agent/make/saenv64.sh12
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java22
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java3
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java12
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java6
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java9
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java158
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js2
9 files changed, 195 insertions, 41 deletions
diff --git a/agent/make/saenv.sh b/agent/make/saenv.sh
index 81faf5e3c..ae121dddc 100644
--- a/agent/make/saenv.sh
+++ b/agent/make/saenv.sh
@@ -48,8 +48,16 @@ if [ "$OS" = "Linux" ]; then
CPU=i386
fi
else
- LD_AUDIT_32=$STARTDIR/../src/os/solaris/proc/`uname -p`/libsaproc_audit.so
- export LD_AUDIT_32
+ # configure audit helper library if SA_ALTROOT is set
+ if [ -n "$SA_ALTROOT" ]; then
+ LD_AUDIT_32=$STARTDIR/../src/os/solaris/proc/`uname -p`/libsaproc_audit.so
+ export LD_AUDIT_32
+ if [ ! -f $LD_AUDIT_32 ]; then
+ echo "SA_ALTROOT is set and can't find libsaproc_audit.so."
+ echo "Make sure to build it with 'make natives'."
+ exit 1
+ fi
+ fi
SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/`uname -p`:$STARTDIR/solaris/`uname -p`
OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
CPU=sparc
diff --git a/agent/make/saenv64.sh b/agent/make/saenv64.sh
index 6990c4f5a..e86f3dd61 100644
--- a/agent/make/saenv64.sh
+++ b/agent/make/saenv64.sh
@@ -43,8 +43,16 @@ else
fi
fi
-LD_AUDIT_64=$STARTDIR/../src/os/solaris/proc/$CPU/libsaproc_audit.so
-export LD_AUDIT_64
+# configure audit helper library if SA_ALTROOT is set
+if [ -n "$SA_ALTROOT" ]; then
+ LD_AUDIT_64=$STARTDIR/../src/os/solaris/proc/$CPU/libsaproc_audit.so
+ export LD_AUDIT_64
+ if [ ! -f $LD_AUDIT_64 ]; then
+ echo "SA_ALTROOT is set and can't find libsaproc_audit.so."
+ echo "Make sure to build it with 'make natives'."
+ exit 1
+ fi
+fi
SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/$CPU:$STARTDIR/solaris/$CPU
OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
diff --git a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
index bb3dba9ea..a8d802f2f 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
@@ -926,6 +926,28 @@ public class CommandProcessor {
}
}
},
+ new Command("dumpcodecache", "dumpcodecache", false) {
+ public void doit(Tokens t) {
+ if (t.countTokens() != 0) {
+ usage();
+ } else {
+ final PrintStream fout = out;
+ final HTMLGenerator gen = new HTMLGenerator(false);
+ CodeCacheVisitor v = new CodeCacheVisitor() {
+ public void prologue(Address start, Address end) {
+ }
+ public void visit(CodeBlob blob) {
+ fout.println(gen.genHTML(blob.instructionsBegin()));
+ }
+ public void epilogue() {
+ }
+
+
+ };
+ VM.getVM().getCodeCache().iterate(v);
+ }
+ }
+ },
new Command("where", "where { -a | id }", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java b/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
index 9fc04f5df..065c41e97 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
@@ -173,7 +173,8 @@ public class CodeCache {
CodeBlob lastBlob = null;
while (ptr != null && ptr.lessThan(end)) {
try {
- CodeBlob blob = findBlobUnsafe(ptr);
+ // Use findStart to get a pointer inside blob other findBlob asserts
+ CodeBlob blob = findBlobUnsafe(heap.findStart(ptr));
if (blob != null) {
visitor.visit(blob);
if (blob == lastBlob) {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
index 7f48d5807..011ca78cc 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java
@@ -42,7 +42,7 @@ public class NMethod extends CodeBlob {
/** To support simple linked-list chaining of nmethods */
private static AddressField osrLinkField;
private static AddressField scavengeRootLinkField;
- private static CIntegerField scavengeRootStateField;
+ private static JByteField scavengeRootStateField;
/** Offsets for different nmethod parts */
private static CIntegerField exceptionOffsetField;
@@ -92,7 +92,7 @@ public class NMethod extends CodeBlob {
entryBCIField = type.getCIntegerField("_entry_bci");
osrLinkField = type.getAddressField("_osr_link");
scavengeRootLinkField = type.getAddressField("_scavenge_root_link");
- scavengeRootStateField = type.getCIntegerField("_scavenge_root_state");
+ scavengeRootStateField = type.getJByteField("_scavenge_root_state");
exceptionOffsetField = type.getCIntegerField("_exception_offset");
deoptOffsetField = type.getCIntegerField("_deoptimize_offset");
@@ -274,7 +274,7 @@ public class NMethod extends CodeBlob {
if (Assert.ASSERTS_ENABLED) {
Assert.that(pd != null, "scope must be present");
}
- return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute());
+ return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
}
/** This is only for use by the debugging system, and is only
@@ -306,11 +306,11 @@ public class NMethod extends CodeBlob {
public ScopeDesc getScopeDescNearDbg(Address pc) {
PCDesc pd = getPCDescNearDbg(pc);
if (pd == null) return null;
- return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute());
+ return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
}
- public Map/*<Address, PcDesc>*/ getSafepoints() {
- Map safepoints = new HashMap(); // Map<Address, PcDesc>
+ public Map/*<Address, PCDesc>*/ getSafepoints() {
+ Map safepoints = new HashMap(); // Map<Address, PCDesc>
sun.jvm.hotspot.debugger.Address p = null;
for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd());
p = p.addOffsetTo(pcDescSize)) {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java b/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java
index e28afc51d..b0586d71c 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java
@@ -36,6 +36,7 @@ import sun.jvm.hotspot.types.*;
public class PCDesc extends VMObject {
private static CIntegerField pcOffsetField;
private static CIntegerField scopeDecodeOffsetField;
+ private static CIntegerField objDecodeOffsetField;
private static CIntegerField pcFlagsField;
static {
@@ -51,6 +52,7 @@ public class PCDesc extends VMObject {
pcOffsetField = type.getCIntegerField("_pc_offset");
scopeDecodeOffsetField = type.getCIntegerField("_scope_decode_offset");
+ objDecodeOffsetField = type.getCIntegerField("_obj_decode_offset");
pcFlagsField = type.getCIntegerField("_flags");
}
@@ -68,6 +70,10 @@ public class PCDesc extends VMObject {
return ((int) scopeDecodeOffsetField.getValue(addr));
}
+ public int getObjDecodeOffset() {
+ return ((int) objDecodeOffsetField.getValue(addr));
+ }
+
public Address getRealPC(NMethod code) {
return code.instructionsBegin().addOffsetTo(getPCOffset());
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java b/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
index ebac4a235..941a0e18e 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java
@@ -51,11 +51,10 @@ public class ScopeDesc {
/** Scalar replaced bjects pool */
private List objects; // ArrayList<ScopeValue>
-
- public ScopeDesc(NMethod code, int decodeOffset, boolean reexecute) {
+ private ScopeDesc(NMethod code, int decodeOffset, List objects, boolean reexecute) {
this.code = code;
this.decodeOffset = decodeOffset;
- this.objects = decodeObjectValues(DebugInformationRecorder.SERIALIZED_NULL);
+ this.objects = objects;
this.reexecute = reexecute;
// Decode header
@@ -108,7 +107,7 @@ public class ScopeDesc {
return decodeMonitorValues(monitorsDecodeOffset);
}
- /** Returns a List&lt;MonitorValue&gt; */
+ /** Returns a List&lt;ObjectValue&gt; */
public List getObjects() {
return objects;
}
@@ -119,7 +118,7 @@ public class ScopeDesc {
return null;
}
- return new ScopeDesc(code, senderDecodeOffset, false);
+ return new ScopeDesc(code, senderDecodeOffset, objects, false);
}
/** Returns where the scope was decoded */
diff --git a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
index 0be7fad5a..c7d29d7d2 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
@@ -807,6 +807,9 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
Interpreter interp = VM.getVM().getInterpreter();
if (interp.contains(pc)) {
InterpreterCodelet codelet = interp.getCodeletContaining(pc);
+ if (codelet == null) {
+ return "Unknown location in the Interpreter: " + pc;
+ }
return genHTML(codelet);
}
return genHTML(blob);
@@ -969,16 +972,24 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
}
protected String genSafepointInfo(NMethod nm, PCDesc pcDesc) {
- ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm));
- Formatter buf = new Formatter(genHTML);
- Formatter tabs = new Formatter(genHTML);
+ ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm));
+ Formatter buf = new Formatter(genHTML);
+ Formatter tabs = new Formatter(genHTML);
+ tabs.append(tab + tab + tab); // Initial indent for debug info
- buf.beginTag("pre");
- genScope(buf, tabs, sd);
- buf.endTag("pre");
- buf.append(genOopMapInfo(nm, pcDesc));
+ buf.beginTag("pre");
+ genScope(buf, tabs, sd);
- return buf.toString();
+ // Reset indent for scalar replaced objects
+ tabs = new Formatter(genHTML);
+ tabs.append(tab + tab + tab); // Initial indent for debug info
+
+ genScObjInfo(buf, tabs, sd);
+ buf.endTag("pre");
+
+ buf.append(genOopMapInfo(nm, pcDesc));
+
+ return buf.toString();
}
protected void genScope(Formatter buf, Formatter tabs, ScopeDesc sd) {
@@ -1022,8 +1033,95 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
buf.append(genHTMLForMonitors(sd, monitors));
}
- tabs.append(tab);
buf.br();
+ tabs.append(tab);
+ }
+
+ protected void genScObjInfo(Formatter buf, Formatter tabs, ScopeDesc sd) {
+ if (sd == null) {
+ return;
+ }
+
+ List objects = sd.getObjects();
+ if (objects == null) {
+ return;
+ }
+ int length = objects.size();
+ for (int i = 0; i < length; i++) {
+ buf.append(tabs);
+ ObjectValue ov = (ObjectValue)objects.get(i);
+ buf.append("ScObj" + i);
+ ScopeValue sv = ov.getKlass();
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(sv.isConstantOop(), "scalar replaced object klass must be constant oop");
+ }
+ ConstantOopReadValue klv = (ConstantOopReadValue)sv;
+ OopHandle klHandle = klv.getValue();
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(klHandle != null, "scalar replaced object klass must be not NULL");
+ }
+ Oop obj = VM.getVM().getObjectHeap().newOop(klHandle);
+ if (obj instanceof InstanceKlass) {
+ InstanceKlass kls = (InstanceKlass) obj;
+ buf.append(" " + kls.getName().asString() + "={");
+ int flen = ov.fieldsSize();
+
+ TypeArray klfields = kls.getFields();
+ int klen = (int) klfields.getLength();
+
+ ConstantPool cp = kls.getConstants();
+ int findex = 0;
+ for (int index = 0; index < klen; index += kls.NEXT_OFFSET) {
+ int accsFlags = klfields.getShortAt(index + kls.ACCESS_FLAGS_OFFSET);
+ int nameIndex = klfields.getShortAt(index + kls.NAME_INDEX_OFFSET);
+ AccessFlags access = new AccessFlags(accsFlags);
+ if (!access.isStatic()) {
+ ScopeValue svf = ov.getFieldAt(findex++);
+ String fstr = scopeValueAsString(sd, svf);
+ Symbol f_name = cp.getSymbolAt(nameIndex);
+ buf.append(" [" + f_name.asString() + " :"+ index + "]=(#" + fstr + ")");
+ }
+ }
+ buf.append(" }");
+ } else {
+ buf.append(" ");
+ int flen = ov.fieldsSize();
+ if (obj instanceof TypeArrayKlass) {
+ TypeArrayKlass kls = (TypeArrayKlass) obj;
+ buf.append(kls.getElementTypeName() + "[" + flen + "]");
+ } else if (obj instanceof ObjArrayKlass) {
+ ObjArrayKlass kls = (ObjArrayKlass) obj;
+ Klass elobj = kls.getBottomKlass();
+ if (elobj instanceof InstanceKlass) {
+ buf.append(elobj.getName().asString());
+ } else if (elobj instanceof TypeArrayKlass) {
+ TypeArrayKlass elkls = (TypeArrayKlass) elobj;
+ buf.append(elkls.getElementTypeName());
+ } else {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(false, "unknown scalar replaced object klass!");
+ }
+ }
+ buf.append("[" + flen + "]");
+ int ndim = (int) kls.getDimension();
+ while (--ndim > 0) {
+ buf.append("[]");
+ }
+ } else {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(false, "unknown scalar replaced object klass!");
+ }
+ }
+ buf.append("={");
+ for (int findex = 0; findex < flen; findex++) {
+ ScopeValue svf = ov.getFieldAt(findex);
+ String fstr = scopeValueAsString(sd, svf);
+ buf.append(" [" + findex + "]=(#" + fstr + ")");
+ }
+ buf.append(" }");
+ }
+ buf.br();
+ }
}
protected String genHTMLForOopMap(OopMap map) {
@@ -1037,8 +1135,6 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
tmpBuf.beginTag("tr");
tmpBuf.beginTag("td");
tmpBuf.append(type);
- tmpBuf.endTag("td");
- tmpBuf.endTag("tr");
for (; ! oms.isDone(); oms.next()) {
OopMapValue omv = oms.getCurrent();
if (omv == null) {
@@ -1048,7 +1144,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
VMReg vmReg = omv.getReg();
int reg = vmReg.getValue();
if (reg < stack0) {
- tmpBuf.append(VMRegImpl.getRegisterName(vmReg.getValue()));
+ tmpBuf.append(VMRegImpl.getRegisterName(reg));
} else {
tmpBuf.append('[');
tmpBuf.append(Integer.toString((reg - stack0) * 4));
@@ -1058,7 +1154,13 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
tmpBuf.append(" = ");
VMReg vmContentReg = omv.getContentReg();
int contentReg = vmContentReg.getValue();
- tmpBuf.append(VMRegImpl.getRegisterName(vmContentReg.getValue()));
+ if (contentReg < stack0) {
+ tmpBuf.append(VMRegImpl.getRegisterName(contentReg));
+ } else {
+ tmpBuf.append('[');
+ tmpBuf.append(Integer.toString((contentReg - stack0) * 4));
+ tmpBuf.append(']');
+ }
}
tmpBuf.append(spaces);
}
@@ -1072,19 +1174,19 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
OopMapValueIterator omvIterator = new OopMapValueIterator();
OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE);
- buf.append(omvIterator.iterate(oms, "Oop:", false));
-
- oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
- buf.append(omvIterator.iterate(oms, "Value:", false));
+ buf.append(omvIterator.iterate(oms, "Oops:", false));
oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
- buf.append(omvIterator.iterate(oms, "Oop:", false));
+ buf.append(omvIterator.iterate(oms, "narrowOops:", false));
+
+ oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
+ buf.append(omvIterator.iterate(oms, "Values:", false));
oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
buf.append(omvIterator.iterate(oms, "Callee saved:", true));
oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE);
- buf.append(omvIterator.iterate(oms, "Derived oop:", true));
+ buf.append(omvIterator.iterate(oms, "Derived oops:", true));
buf.endTag("table");
return buf.toString();
@@ -1093,6 +1195,8 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) {
OopMapSet mapSet = nmethod.getOopMaps();
+ if (mapSet == null || (mapSet.getSize() <= 0))
+ return "";
int pcOffset = pcDesc.getPCOffset();
OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
if (map == null) {
@@ -1106,6 +1210,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
Formatter buf = new Formatter(genHTML);
buf.beginTag("pre");
buf.append("OopMap: ");
+ buf.br();
buf.append(genHTMLForOopMap(map));
buf.endTag("pre");
@@ -1154,7 +1259,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
return buf.toString();
}
- private String scopeValueAsString(ScopeValue sv) {
+ private String scopeValueAsString(ScopeDesc sd, ScopeValue sv) {
Formatter buf = new Formatter(genHTML);
if (sv.isConstantInt()) {
buf.append("int ");
@@ -1187,6 +1292,11 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
} else {
buf.append("null");
}
+ } else if (sv.isObject()) {
+ ObjectValue ov = (ObjectValue)sv;
+ buf.append("#ScObj" + sd.getObjects().indexOf(ov));
+ } else {
+ buf.append("unknown scope value " + sv);
}
return buf.toString();
}
@@ -1219,7 +1329,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
}
buf.append(", ");
- buf.append(scopeValueAsString(sv));
+ buf.append(scopeValueAsString(sd, sv));
buf.append(") ");
}
@@ -1246,7 +1356,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
buf.append("(owner = ");
ScopeValue owner = mv.owner();
if (owner != null) {
- buf.append(scopeValueAsString(owner));
+ buf.append(scopeValueAsString(sd, owner));
} else {
buf.append("null");
}
@@ -1324,11 +1434,11 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
buf.append(instr.asString(currentPc, symFinder));
}
+ buf.br();
if (isSafepoint && !prevWasCall) {
- buf.append(genSafepointInfo(nmethod, pcDesc));
+ buf.append(genSafepointInfo(nmethod, pcDesc));
}
- buf.br();
prevWasCall = instr.isCall();
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
index 226e793e7..78754094e 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
@@ -1047,7 +1047,7 @@ while (tmp.itr.hasNext()) {
} else {
// some type names have ':'. replace to make it as a
// JavaScript identifier
- tmp.name = tmp.name.replace(':', '_');
+ tmp.name = tmp.name.replace(':', '_').replace('<', '_').replace('>', '_').replace('*', '_').replace(' ', '_');
eval("function read" + tmp.name + "(addr) {" +
" return readVMType('" + tmp.name + "', addr);}");
eval("function print" + tmp.name + "(addr) {" +