comparison agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java @ 1040:873ec3787992

6892186: SA does not dump debug info for scalar replaced objects Summary: Implement scalar replaced objects debug info dump in SA. Reviewed-by: twisti
author kvn
date Wed, 21 Oct 2009 09:15:33 -0700
parents cecd8eb4e0ca
children bc32f286fae0
comparison
equal deleted inserted replaced
1039:987e948ebbc8 1040:873ec3787992
805 } else { 805 } else {
806 // may be interpreter code. 806 // may be interpreter code.
807 Interpreter interp = VM.getVM().getInterpreter(); 807 Interpreter interp = VM.getVM().getInterpreter();
808 if (interp.contains(pc)) { 808 if (interp.contains(pc)) {
809 InterpreterCodelet codelet = interp.getCodeletContaining(pc); 809 InterpreterCodelet codelet = interp.getCodeletContaining(pc);
810 if (codelet == null) {
811 return "Unknown location in the Interpreter: " + pc;
812 }
810 return genHTML(codelet); 813 return genHTML(codelet);
811 } 814 }
812 return genHTML(blob); 815 return genHTML(blob);
813 } 816 }
814 } else if (VM.getVM().getCodeCache().contains(pc)) { 817 } else if (VM.getVM().getCodeCache().contains(pc)) {
967 return genHTMLErrorMessage(exp); 970 return genHTMLErrorMessage(exp);
968 } 971 }
969 } 972 }
970 973
971 protected String genSafepointInfo(NMethod nm, PCDesc pcDesc) { 974 protected String genSafepointInfo(NMethod nm, PCDesc pcDesc) {
972 ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm)); 975 ScopeDesc sd = nm.getScopeDescAt(pcDesc.getRealPC(nm));
973 Formatter buf = new Formatter(genHTML); 976 Formatter buf = new Formatter(genHTML);
974 Formatter tabs = new Formatter(genHTML); 977 Formatter tabs = new Formatter(genHTML);
975 978 tabs.append(tab + tab + tab); // Initial indent for debug info
976 buf.beginTag("pre"); 979
977 genScope(buf, tabs, sd); 980 buf.beginTag("pre");
978 buf.endTag("pre"); 981 genScope(buf, tabs, sd);
979 buf.append(genOopMapInfo(nm, pcDesc)); 982
980 983 // Reset indent for scalar replaced objects
981 return buf.toString(); 984 tabs = new Formatter(genHTML);
985 tabs.append(tab + tab + tab); // Initial indent for debug info
986
987 genScObjInfo(buf, tabs, sd);
988 buf.endTag("pre");
989
990 buf.append(genOopMapInfo(nm, pcDesc));
991
992 return buf.toString();
982 } 993 }
983 994
984 protected void genScope(Formatter buf, Formatter tabs, ScopeDesc sd) { 995 protected void genScope(Formatter buf, Formatter tabs, ScopeDesc sd) {
985 if (sd == null) { 996 if (sd == null) {
986 return; 997 return;
1020 buf.br(); 1031 buf.br();
1021 buf.append(tabs); 1032 buf.append(tabs);
1022 buf.append(genHTMLForMonitors(sd, monitors)); 1033 buf.append(genHTMLForMonitors(sd, monitors));
1023 } 1034 }
1024 1035
1036 buf.br();
1025 tabs.append(tab); 1037 tabs.append(tab);
1026 buf.br(); 1038 }
1039
1040 protected void genScObjInfo(Formatter buf, Formatter tabs, ScopeDesc sd) {
1041 if (sd == null) {
1042 return;
1043 }
1044
1045 List objects = sd.getObjects();
1046 if (objects == null) {
1047 return;
1048 }
1049 int length = objects.size();
1050 for (int i = 0; i < length; i++) {
1051 buf.append(tabs);
1052 ObjectValue ov = (ObjectValue)objects.get(i);
1053 buf.append("ScObj" + i);
1054 ScopeValue sv = ov.getKlass();
1055 if (Assert.ASSERTS_ENABLED) {
1056 Assert.that(sv.isConstantOop(), "scalar replaced object klass must be constant oop");
1057 }
1058 ConstantOopReadValue klv = (ConstantOopReadValue)sv;
1059 OopHandle klHandle = klv.getValue();
1060 if (Assert.ASSERTS_ENABLED) {
1061 Assert.that(klHandle != null, "scalar replaced object klass must be not NULL");
1062 }
1063 Oop obj = VM.getVM().getObjectHeap().newOop(klHandle);
1064 if (obj instanceof InstanceKlass) {
1065 InstanceKlass kls = (InstanceKlass) obj;
1066 buf.append(" " + kls.getName().asString() + "={");
1067 int flen = ov.fieldsSize();
1068
1069 TypeArray klfields = kls.getFields();
1070 int klen = (int) klfields.getLength();
1071
1072 ConstantPool cp = kls.getConstants();
1073 int findex = 0;
1074 for (int index = 0; index < klen; index += kls.NEXT_OFFSET) {
1075 int accsFlags = klfields.getShortAt(index + kls.ACCESS_FLAGS_OFFSET);
1076 int nameIndex = klfields.getShortAt(index + kls.NAME_INDEX_OFFSET);
1077 AccessFlags access = new AccessFlags(accsFlags);
1078 if (!access.isStatic()) {
1079 ScopeValue svf = ov.getFieldAt(findex++);
1080 String fstr = scopeValueAsString(sd, svf);
1081 Symbol f_name = cp.getSymbolAt(nameIndex);
1082 buf.append(" [" + f_name.asString() + " :"+ index + "]=(#" + fstr + ")");
1083 }
1084 }
1085 buf.append(" }");
1086 } else {
1087 buf.append(" ");
1088 int flen = ov.fieldsSize();
1089 if (obj instanceof TypeArrayKlass) {
1090 TypeArrayKlass kls = (TypeArrayKlass) obj;
1091 buf.append(kls.getElementTypeName() + "[" + flen + "]");
1092 } else if (obj instanceof ObjArrayKlass) {
1093 ObjArrayKlass kls = (ObjArrayKlass) obj;
1094 Klass elobj = kls.getBottomKlass();
1095 if (elobj instanceof InstanceKlass) {
1096 buf.append(elobj.getName().asString());
1097 } else if (elobj instanceof TypeArrayKlass) {
1098 TypeArrayKlass elkls = (TypeArrayKlass) elobj;
1099 buf.append(elkls.getElementTypeName());
1100 } else {
1101 if (Assert.ASSERTS_ENABLED) {
1102 Assert.that(false, "unknown scalar replaced object klass!");
1103 }
1104 }
1105 buf.append("[" + flen + "]");
1106 int ndim = (int) kls.getDimension();
1107 while (--ndim > 0) {
1108 buf.append("[]");
1109 }
1110 } else {
1111 if (Assert.ASSERTS_ENABLED) {
1112 Assert.that(false, "unknown scalar replaced object klass!");
1113 }
1114 }
1115 buf.append("={");
1116 for (int findex = 0; findex < flen; findex++) {
1117 ScopeValue svf = ov.getFieldAt(findex);
1118 String fstr = scopeValueAsString(sd, svf);
1119 buf.append(" [" + findex + "]=(#" + fstr + ")");
1120 }
1121 buf.append(" }");
1122 }
1123 buf.br();
1124 }
1027 } 1125 }
1028 1126
1029 protected String genHTMLForOopMap(OopMap map) { 1127 protected String genHTMLForOopMap(OopMap map) {
1030 final int stack0 = VMRegImpl.getStack0().getValue(); 1128 final int stack0 = VMRegImpl.getStack0().getValue();
1031 Formatter buf = new Formatter(genHTML); 1129 Formatter buf = new Formatter(genHTML);
1035 Formatter tmpBuf = new Formatter(genHTML); 1133 Formatter tmpBuf = new Formatter(genHTML);
1036 boolean found = false; 1134 boolean found = false;
1037 tmpBuf.beginTag("tr"); 1135 tmpBuf.beginTag("tr");
1038 tmpBuf.beginTag("td"); 1136 tmpBuf.beginTag("td");
1039 tmpBuf.append(type); 1137 tmpBuf.append(type);
1040 tmpBuf.endTag("td");
1041 tmpBuf.endTag("tr");
1042 for (; ! oms.isDone(); oms.next()) { 1138 for (; ! oms.isDone(); oms.next()) {
1043 OopMapValue omv = oms.getCurrent(); 1139 OopMapValue omv = oms.getCurrent();
1044 if (omv == null) { 1140 if (omv == null) {
1045 continue; 1141 continue;
1046 } 1142 }
1047 found = true; 1143 found = true;
1048 VMReg vmReg = omv.getReg(); 1144 VMReg vmReg = omv.getReg();
1049 int reg = vmReg.getValue(); 1145 int reg = vmReg.getValue();
1050 if (reg < stack0) { 1146 if (reg < stack0) {
1051 tmpBuf.append(VMRegImpl.getRegisterName(vmReg.getValue())); 1147 tmpBuf.append(VMRegImpl.getRegisterName(reg));
1052 } else { 1148 } else {
1053 tmpBuf.append('['); 1149 tmpBuf.append('[');
1054 tmpBuf.append(Integer.toString((reg - stack0) * 4)); 1150 tmpBuf.append(Integer.toString((reg - stack0) * 4));
1055 tmpBuf.append(']'); 1151 tmpBuf.append(']');
1056 } 1152 }
1057 if (printContentReg) { 1153 if (printContentReg) {
1058 tmpBuf.append(" = "); 1154 tmpBuf.append(" = ");
1059 VMReg vmContentReg = omv.getContentReg(); 1155 VMReg vmContentReg = omv.getContentReg();
1060 int contentReg = vmContentReg.getValue(); 1156 int contentReg = vmContentReg.getValue();
1061 tmpBuf.append(VMRegImpl.getRegisterName(vmContentReg.getValue())); 1157 if (contentReg < stack0) {
1158 tmpBuf.append(VMRegImpl.getRegisterName(contentReg));
1159 } else {
1160 tmpBuf.append('[');
1161 tmpBuf.append(Integer.toString((contentReg - stack0) * 4));
1162 tmpBuf.append(']');
1163 }
1062 } 1164 }
1063 tmpBuf.append(spaces); 1165 tmpBuf.append(spaces);
1064 } 1166 }
1065 tmpBuf.endTag("td"); 1167 tmpBuf.endTag("td");
1066 tmpBuf.endTag("tr"); 1168 tmpBuf.endTag("tr");
1070 1172
1071 buf.beginTable(0); 1173 buf.beginTable(0);
1072 1174
1073 OopMapValueIterator omvIterator = new OopMapValueIterator(); 1175 OopMapValueIterator omvIterator = new OopMapValueIterator();
1074 OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE); 1176 OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE);
1075 buf.append(omvIterator.iterate(oms, "Oop:", false)); 1177 buf.append(omvIterator.iterate(oms, "Oops:", false));
1178
1179 oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
1180 buf.append(omvIterator.iterate(oms, "narrowOops:", false));
1076 1181
1077 oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE); 1182 oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
1078 buf.append(omvIterator.iterate(oms, "Value:", false)); 1183 buf.append(omvIterator.iterate(oms, "Values:", false));
1079
1080 oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
1081 buf.append(omvIterator.iterate(oms, "Oop:", false));
1082 1184
1083 oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); 1185 oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
1084 buf.append(omvIterator.iterate(oms, "Callee saved:", true)); 1186 buf.append(omvIterator.iterate(oms, "Callee saved:", true));
1085 1187
1086 oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE); 1188 oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE);
1087 buf.append(omvIterator.iterate(oms, "Derived oop:", true)); 1189 buf.append(omvIterator.iterate(oms, "Derived oops:", true));
1088 1190
1089 buf.endTag("table"); 1191 buf.endTag("table");
1090 return buf.toString(); 1192 return buf.toString();
1091 } 1193 }
1092 1194
1093 1195
1094 protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) { 1196 protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) {
1095 OopMapSet mapSet = nmethod.getOopMaps(); 1197 OopMapSet mapSet = nmethod.getOopMaps();
1198 if (mapSet == null || (mapSet.getSize() <= 0))
1199 return "";
1096 int pcOffset = pcDesc.getPCOffset(); 1200 int pcOffset = pcDesc.getPCOffset();
1097 OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging()); 1201 OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
1098 if (map == null) { 1202 if (map == null) {
1099 throw new IllegalArgumentException("no oopmap at safepoint!"); 1203 throw new IllegalArgumentException("no oopmap at safepoint!");
1100 } 1204 }
1104 1208
1105 protected String genOopMapInfo(OopMap map) { 1209 protected String genOopMapInfo(OopMap map) {
1106 Formatter buf = new Formatter(genHTML); 1210 Formatter buf = new Formatter(genHTML);
1107 buf.beginTag("pre"); 1211 buf.beginTag("pre");
1108 buf.append("OopMap: "); 1212 buf.append("OopMap: ");
1213 buf.br();
1109 buf.append(genHTMLForOopMap(map)); 1214 buf.append(genHTMLForOopMap(map));
1110 buf.endTag("pre"); 1215 buf.endTag("pre");
1111 1216
1112 return buf.toString(); 1217 return buf.toString();
1113 } 1218 }
1152 } 1257 }
1153 } 1258 }
1154 return buf.toString(); 1259 return buf.toString();
1155 } 1260 }
1156 1261
1157 private String scopeValueAsString(ScopeValue sv) { 1262 private String scopeValueAsString(ScopeDesc sd, ScopeValue sv) {
1158 Formatter buf = new Formatter(genHTML); 1263 Formatter buf = new Formatter(genHTML);
1159 if (sv.isConstantInt()) { 1264 if (sv.isConstantInt()) {
1160 buf.append("int "); 1265 buf.append("int ");
1161 ConstantIntValue intValue = (ConstantIntValue) sv; 1266 ConstantIntValue intValue = (ConstantIntValue) sv;
1162 buf.append(Integer.toString(intValue.getValue())); 1267 buf.append(Integer.toString(intValue.getValue()));
1185 if (loc != null) { 1290 if (loc != null) {
1186 buf.append(locationAsString(loc)); 1291 buf.append(locationAsString(loc));
1187 } else { 1292 } else {
1188 buf.append("null"); 1293 buf.append("null");
1189 } 1294 }
1295 } else if (sv.isObject()) {
1296 ObjectValue ov = (ObjectValue)sv;
1297 buf.append("#ScObj" + sd.getObjects().indexOf(ov));
1298 } else {
1299 buf.append("unknown scope value " + sv);
1190 } 1300 }
1191 return buf.toString(); 1301 return buf.toString();
1192 } 1302 }
1193 1303
1194 protected String genHTMLForScopeValues(ScopeDesc sd, boolean locals, List values) { 1304 protected String genHTMLForScopeValues(ScopeDesc sd, boolean locals, List values) {
1217 buf.append(Integer.toString(i)); 1327 buf.append(Integer.toString(i));
1218 buf.append(']'); 1328 buf.append(']');
1219 } 1329 }
1220 1330
1221 buf.append(", "); 1331 buf.append(", ");
1222 buf.append(scopeValueAsString(sv)); 1332 buf.append(scopeValueAsString(sd, sv));
1223 buf.append(") "); 1333 buf.append(") ");
1224 } 1334 }
1225 1335
1226 return buf.toString(); 1336 return buf.toString();
1227 } 1337 }
1244 continue; 1354 continue;
1245 } 1355 }
1246 buf.append("(owner = "); 1356 buf.append("(owner = ");
1247 ScopeValue owner = mv.owner(); 1357 ScopeValue owner = mv.owner();
1248 if (owner != null) { 1358 if (owner != null) {
1249 buf.append(scopeValueAsString(owner)); 1359 buf.append(scopeValueAsString(sd, owner));
1250 } else { 1360 } else {
1251 buf.append("null"); 1361 buf.append("null");
1252 } 1362 }
1253 buf.append(", lock = "); 1363 buf.append(", lock = ");
1254 1364
1322 buf.link(href, instr.asString(currentPc, symFinder)); 1432 buf.link(href, instr.asString(currentPc, symFinder));
1323 } else { 1433 } else {
1324 buf.append(instr.asString(currentPc, symFinder)); 1434 buf.append(instr.asString(currentPc, symFinder));
1325 } 1435 }
1326 1436
1437 buf.br();
1327 if (isSafepoint && !prevWasCall) { 1438 if (isSafepoint && !prevWasCall) {
1328 buf.append(genSafepointInfo(nmethod, pcDesc)); 1439 buf.append(genSafepointInfo(nmethod, pcDesc));
1329 } 1440 }
1330 1441
1331 buf.br();
1332 prevWasCall = instr.isCall(); 1442 prevWasCall = instr.isCall();
1333 } 1443 }
1334 1444
1335 public void epilogue() { 1445 public void epilogue() {
1336 } 1446 }