Mercurial > hg > graal-compiler
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 } |