--- old/agent/make/saenv.sh Mon Oct 19 12:10:28 2009 +++ new/agent/make/saenv.sh Mon Oct 19 12:10:28 2009 @@ -48,8 +48,16 @@ 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 --- old/agent/make/saenv64.sh Mon Oct 19 12:10:29 2009 +++ new/agent/make/saenv64.sh Mon Oct 19 12:10:29 2009 @@ -43,8 +43,16 @@ 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" --- old/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Mon Oct 19 12:10:29 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Mon Oct 19 12:10:29 2009 @@ -926,6 +926,28 @@ } } }, + 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) { --- old/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Mon Oct 19 12:10:30 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java Mon Oct 19 12:10:30 2009 @@ -173,7 +173,8 @@ 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) { --- old/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Mon Oct 19 12:10:31 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Mon Oct 19 12:10:31 2009 @@ -42,7 +42,7 @@ /** 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 @@ 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 @@ 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 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/**/ getSafepoints() { - Map safepoints = new HashMap(); // Map + public Map/**/ getSafepoints() { + Map safepoints = new HashMap(); // Map sun.jvm.hotspot.debugger.Address p = null; for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) { --- old/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java Mon Oct 19 12:10:31 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java Mon Oct 19 12:10:31 2009 @@ -36,6 +36,7 @@ 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 @@ 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 @@ return ((int) scopeDecodeOffsetField.getValue(addr)); } + public int getObjDecodeOffset() { + return ((int) objDecodeOffsetField.getValue(addr)); + } + public Address getRealPC(NMethod code) { return code.instructionsBegin().addOffsetTo(getPCOffset()); } --- old/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java Mon Oct 19 12:10:32 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/code/ScopeDesc.java Mon Oct 19 12:10:32 2009 @@ -51,11 +51,10 @@ /** Scalar replaced bjects pool */ private List objects; // ArrayList - - 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 @@ return decodeMonitorValues(monitorsDecodeOffset); } - /** Returns a List<MonitorValue> */ + /** Returns a List<ObjectValue> */ public List getObjects() { return objects; } @@ -119,7 +118,7 @@ return null; } - return new ScopeDesc(code, senderDecodeOffset, false); + return new ScopeDesc(code, senderDecodeOffset, objects, false); } /** Returns where the scope was decoded */ --- old/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Mon Oct 19 12:10:32 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Mon Oct 19 12:10:32 2009 @@ -807,6 +807,9 @@ 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 @@ } 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,10 +1033,97 @@ 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) { final int stack0 = VMRegImpl.getStack0().getValue(); Formatter buf = new Formatter(genHTML); @@ -1037,8 +1135,6 @@ 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 @@ 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 @@ 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 @@ OopMapValueIterator omvIterator = new OopMapValueIterator(); OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE); - buf.append(omvIterator.iterate(oms, "Oop:", false)); + buf.append(omvIterator.iterate(oms, "Oops:", false)); - oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE); - 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, "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 @@ 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 @@ Formatter buf = new Formatter(genHTML); buf.beginTag("pre"); buf.append("OopMap: "); + buf.br(); buf.append(genHTMLForOopMap(map)); buf.endTag("pre"); @@ -1154,7 +1259,7 @@ 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 @@ } 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 @@ } buf.append(", "); - buf.append(scopeValueAsString(sv)); + buf.append(scopeValueAsString(sd, sv)); buf.append(") "); } @@ -1246,7 +1356,7 @@ 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 @@ 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(); } --- old/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Mon Oct 19 12:10:33 2009 +++ new/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Mon Oct 19 12:10:33 2009 @@ -1047,7 +1047,7 @@ } 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) {" + --- old/src/share/vm/opto/callnode.cpp Mon Oct 19 12:10:33 2009 +++ new/src/share/vm/opto/callnode.cpp Mon Oct 19 12:10:33 2009 @@ -421,21 +421,23 @@ iklass = cik->as_instance_klass(); } else if (cik->is_type_array_klass()) { cik->as_array_klass()->base_element_type()->print_name_on(st); - st->print("[%d]=", spobj->n_fields()); + st->print("[%d]", spobj->n_fields()); } else if (cik->is_obj_array_klass()) { - ciType* cie = cik->as_array_klass()->base_element_type(); - int ndim = 1; - while (cie->is_obj_array_klass()) { - ndim += 1; - cie = cie->as_array_klass()->base_element_type(); + ciKlass* cie = cik->as_obj_array_klass()->base_element_klass(); + if (cie->is_instance_klass()) { + cie->print_name_on(st); + } else if (cie->is_type_array_klass()) { + cie->as_array_klass()->base_element_type()->print_name_on(st); + } else { + ShouldNotReachHere(); } - cie->print_name_on(st); + st->print("[%d]", spobj->n_fields()); + int ndim = cik->as_array_klass()->dimension() - 1; while (ndim-- > 0) { st->print("[]"); } - st->print("[%d]=", spobj->n_fields()); } - st->print("{"); + st->print("={"); uint nf = spobj->n_fields(); if (nf > 0) { uint first_ind = spobj->first_index(); --- old/src/share/vm/runtime/vmStructs.cpp Mon Oct 19 12:10:34 2009 +++ new/src/share/vm/runtime/vmStructs.cpp Mon Oct 19 12:10:33 2009 @@ -594,6 +594,7 @@ \ nonstatic_field(PcDesc, _pc_offset, int) \ nonstatic_field(PcDesc, _scope_decode_offset, int) \ + nonstatic_field(PcDesc, _obj_decode_offset, int) \ nonstatic_field(PcDesc, _flags, PcDesc::PcDescFlags) \ \ /***************************************************/ \