Mercurial > hg > graal-jvmci-8
annotate agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java @ 24234:ea6f94ab283b default tip
Added tag jvmci-0.36 for changeset 8128b98d4736
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Mon, 18 Sep 2017 18:49:45 +0200 |
parents | c5f6a7397eb1 |
children |
rev | line source |
---|---|
0 | 1 /* |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1385
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1385
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1385
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.ui.classbrowser; | |
26 | |
27 import java.io.*; | |
28 import java.util.*; | |
29 import sun.jvm.hotspot.asm.*; | |
30 import sun.jvm.hotspot.code.*; | |
31 import sun.jvm.hotspot.compiler.*; | |
32 import sun.jvm.hotspot.debugger.*; | |
33 import sun.jvm.hotspot.interpreter.*; | |
34 import sun.jvm.hotspot.memory.*; | |
35 import sun.jvm.hotspot.oops.*; | |
36 import sun.jvm.hotspot.runtime.*; | |
37 import sun.jvm.hotspot.tools.jcore.*; | |
38 import sun.jvm.hotspot.types.*; | |
39 import sun.jvm.hotspot.utilities.*; | |
40 | |
41 public class HTMLGenerator implements /* imports */ ClassConstants { | |
42 static class Formatter { | |
43 boolean html; | |
44 StringBuffer buf = new StringBuffer(); | |
45 | |
46 Formatter(boolean h) { | |
47 html = h; | |
48 } | |
49 | |
50 void append(String s) { | |
51 buf.append(s); | |
52 } | |
53 | |
54 void append(int s) { | |
55 buf.append(s); | |
56 } | |
57 | |
58 void append(char s) { | |
59 buf.append(s); | |
60 } | |
61 | |
62 void append(StringBuffer s) { | |
63 buf.append(s); | |
64 } | |
65 | |
66 void append(Formatter s) { | |
67 buf.append(s); | |
68 } | |
69 | |
70 StringBuffer getBuffer() { | |
71 return buf; | |
72 } | |
73 | |
74 public String toString() { | |
75 return buf.toString(); | |
76 } | |
77 | |
78 void wrap(String tag, String text) { | |
79 wrap(tag, tag, text); | |
80 } | |
81 void wrap(String before, String after, String text) { | |
82 beginTag(before); | |
83 append(text); | |
84 endTag(after); | |
85 } | |
86 | |
87 // header tags | |
88 void h1(String s) { nl(); wrap("h1", s); nl(); } | |
89 void h2(String s) { nl(); wrap("h2", s); nl(); } | |
90 void h3(String s) { nl(); wrap("h3", s); nl(); } | |
91 void h4(String s) { nl(); wrap("h4", s); nl(); } | |
92 | |
93 // list tags | |
94 void beginList() { beginTag("ul"); nl(); } | |
1385 | 95 void endList() { endTag("ul"); nl(); } |
96 void beginListItem() { beginTag("li"); } | |
97 void endListItem() { endTag("li"); nl(); } | |
0 | 98 void li(String s) { wrap("li", s); nl(); } |
99 | |
100 // table tags | |
101 void beginTable(int border) { | |
102 beginTag("table border='" + border + "'"); | |
103 } | |
104 void cell(String s) { wrap("td", s); } | |
105 void headerCell(String s) { wrap("th", s); } | |
106 void endTable() { endTag("table"); } | |
107 | |
108 void link(String href, String text) { | |
109 wrap("a href='" + href + "'", "a", text); | |
110 } | |
111 void beginTag(String s) { | |
112 if (html) { append("<"); append(s); append(">"); } | |
113 } | |
114 void endTag(String s) { | |
115 if (html) { | |
116 append("</"); append(s); append(">"); | |
117 } else { | |
118 if (s.equals("table") || s.equals("tr")) { | |
119 nl(); | |
120 } | |
121 if (s.equals("td") || s.equals("th")) { | |
122 append(" "); | |
123 } | |
124 } | |
125 } | |
126 void bold(String s) { | |
127 wrap("b", s); | |
128 } | |
129 | |
130 void nl() { | |
131 if (!html) buf.append("\n"); | |
132 } | |
133 | |
134 void br() { | |
135 if (html) append("<br>"); | |
136 else append("\n"); | |
137 } | |
138 void genEmptyHTML() { | |
139 if (html) append("<html></html>"); | |
140 } | |
141 | |
142 void genHTMLPrologue() { | |
143 if (html) append("<html><body>"); | |
144 } | |
145 | |
146 void genHTMLPrologue(String title) { | |
147 if (html) { | |
148 append("<html><head><title>"); | |
149 append(title); | |
150 append("</title></head>"); | |
151 append("<body>"); | |
152 } | |
153 h2(title); | |
154 } | |
155 void genHTMLEpilogue() { | |
156 if (html) append("</body></html>"); | |
157 } | |
158 | |
159 } | |
160 | |
161 private static final String DUMP_KLASS_OUTPUT_DIR = "."; | |
162 private static final int NATIVE_CODE_SIZE = 200; | |
163 private final String spaces; | |
164 private final String tab; | |
165 | |
166 private boolean genHTML = true; | |
167 | |
168 public HTMLGenerator() { | |
169 this(true); | |
170 } | |
171 | |
172 public HTMLGenerator(boolean html) { | |
173 genHTML = html; | |
174 if (html) { | |
175 spaces = " "; | |
176 tab = " "; | |
177 } else { | |
178 spaces = " "; | |
179 tab = " "; | |
180 } | |
181 } | |
182 | |
183 protected String escapeHTMLSpecialChars(String value) { | |
184 if (!genHTML) return value; | |
185 | |
186 Formatter buf = new Formatter(genHTML); | |
187 int len = value.length(); | |
188 for (int i=0; i < len; i++) { | |
189 char c = value.charAt(i); | |
190 switch (c) { | |
191 case '<': | |
192 buf.append("<"); | |
193 break; | |
194 case '>': | |
195 buf.append(">"); | |
196 break; | |
197 case '&': | |
198 buf.append("&"); | |
199 break; | |
200 default: | |
201 buf.append(c); | |
202 break; | |
203 } | |
204 } | |
205 return buf.toString(); | |
206 } | |
207 | |
208 public String genHTMLForMessage(String message) { | |
209 Formatter buf = new Formatter(genHTML); | |
210 buf.genHTMLPrologue(message); | |
211 buf.genHTMLEpilogue(); | |
212 return buf.toString(); | |
213 } | |
214 | |
215 public String genHTMLErrorMessage(Exception exp) { | |
216 exp.printStackTrace(); | |
217 return genHTMLForMessage(exp.getClass().getName() + " : " + exp.getMessage()); | |
218 } | |
219 | |
220 public String genHTMLForWait(String message) { | |
221 Formatter buf = new Formatter(genHTML); | |
222 buf.genHTMLPrologue("Please wait .."); | |
223 buf.h2(message); | |
224 return buf.toString(); | |
225 } | |
226 | |
227 protected String genKlassTitle(InstanceKlass klass) { | |
228 Formatter buf = new Formatter(genHTML); | |
229 AccessFlags acc = klass.getAccessFlagsObj(); | |
230 if (acc.isPublic()) { | |
231 buf.append("public "); | |
232 } else if (acc.isProtected()) { | |
233 buf.append("protected "); | |
234 } else if (acc.isPrivate()) { | |
235 buf.append("private "); | |
236 } | |
237 | |
238 if (acc.isStatic()) { | |
239 buf.append("static "); | |
240 } | |
241 | |
242 if (acc.isAbstract() ) { | |
243 buf.append("abstract "); | |
244 } else if (acc.isFinal()) { | |
245 buf.append("final "); | |
246 } | |
247 | |
248 if (acc.isStrict()) { | |
249 buf.append("strict "); | |
250 } | |
251 | |
252 // javac generated flags | |
253 if (acc.isEnum()) { | |
254 buf.append("[enum] "); | |
255 } | |
256 if (acc.isSynthetic()) { | |
257 buf.append("[synthetic] "); | |
258 } | |
259 | |
260 if (klass.isInterface()) { | |
261 buf.append("interface"); | |
262 } else { | |
263 buf.append("class"); | |
264 } | |
265 | |
266 buf.append(' '); | |
267 buf.append(klass.getName().asString().replace('/', '.')); | |
268 // is it generic? | |
269 Symbol genSig = klass.getGenericSignature(); | |
270 if (genSig != null) { | |
271 buf.append(" [signature "); | |
272 buf.append(escapeHTMLSpecialChars(genSig.asString())); | |
273 buf.append("] "); | |
274 } else { | |
275 buf.append(' '); | |
276 } | |
277 buf.append('@'); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
278 buf.append(klass.getAddress().toString()); |
0 | 279 return buf.toString(); |
280 } | |
281 | |
282 protected String genBaseHref() { | |
283 return ""; | |
284 } | |
285 | |
286 protected String genKlassHref(InstanceKlass klass) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
287 return genBaseHref() + "klass=" + klass.getAddress(); |
0 | 288 } |
289 | |
290 protected String genKlassLink(InstanceKlass klass) { | |
291 Formatter buf = new Formatter(genHTML); | |
292 buf.link(genKlassHref(klass), genKlassTitle(klass)); | |
293 return buf.toString(); | |
294 } | |
295 | |
296 protected String genMethodModifierString(AccessFlags acc) { | |
297 Formatter buf = new Formatter(genHTML); | |
298 if (acc.isPrivate()) { | |
299 buf.append("private "); | |
300 } else if (acc.isProtected()) { | |
301 buf.append("protected "); | |
302 } else if (acc.isPublic()) { | |
303 buf.append("public "); | |
304 } | |
305 | |
306 if (acc.isStatic()) { | |
307 buf.append("static "); | |
308 } else if (acc.isAbstract() ) { | |
309 buf.append("abstract "); | |
310 } else if (acc.isFinal()) { | |
311 buf.append("final "); | |
312 } | |
313 | |
314 if (acc.isNative()) { | |
315 buf.append("native "); | |
316 } | |
317 | |
318 if (acc.isStrict()) { | |
319 buf.append("strict "); | |
320 } | |
321 | |
322 if (acc.isSynchronized()) { | |
323 buf.append("synchronized "); | |
324 } | |
325 | |
326 // javac generated flags | |
327 if (acc.isBridge()) { | |
328 buf.append("[bridge] "); | |
329 } | |
330 | |
331 if (acc.isSynthetic()) { | |
332 buf.append("[synthetic] "); | |
333 } | |
334 | |
335 if (acc.isVarArgs()) { | |
336 buf.append("[varargs] "); | |
337 } | |
338 | |
339 return buf.toString(); | |
340 } | |
341 | |
342 protected String genMethodNameAndSignature(Method method) { | |
343 Formatter buf = new Formatter(genHTML); | |
344 buf.append(genMethodModifierString(method.getAccessFlagsObj())); | |
345 Symbol sig = method.getSignature(); | |
346 new SignatureConverter(sig, buf.getBuffer()).iterateReturntype(); | |
347 buf.append(" "); | |
348 String methodName = method.getName().asString(); | |
349 buf.append(escapeHTMLSpecialChars(methodName)); | |
350 buf.append('('); | |
351 new SignatureConverter(sig, buf.getBuffer()).iterateParameters(); | |
352 buf.append(')'); | |
353 // is it generic? | |
354 Symbol genSig = method.getGenericSignature(); | |
355 if (genSig != null) { | |
356 buf.append(" [signature "); | |
357 buf.append(escapeHTMLSpecialChars(genSig.asString())); | |
358 buf.append("] "); | |
359 } | |
360 return buf.toString().replace('/', '.'); | |
361 } | |
362 | |
363 protected String genMethodTitle(Method method) { | |
364 Formatter buf = new Formatter(genHTML); | |
365 buf.append(genMethodNameAndSignature(method)); | |
366 buf.append(' '); | |
367 buf.append('@'); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
368 buf.append(method.getAddress().toString()); |
0 | 369 return buf.toString(); |
370 } | |
371 | |
372 protected String genMethodHref(Method m) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
373 return genBaseHref() + "method=" + m.getAddress(); |
0 | 374 } |
375 | |
376 protected String genMethodLink(Method m) { | |
377 Formatter buf = new Formatter(genHTML); | |
378 buf.link(genMethodHref(m), genMethodTitle(m)); | |
379 return buf.toString(); | |
380 } | |
381 | |
382 protected String genMethodAndKlassLink(Method m) { | |
383 Formatter buf = new Formatter(genHTML); | |
384 buf.append(genMethodLink(m)); | |
385 buf.append(" of "); | |
386 buf.append(genKlassLink((InstanceKlass) m.getMethodHolder())); | |
387 return buf.toString(); | |
388 } | |
389 | |
390 protected String genNMethodHref(NMethod nm) { | |
391 return genBaseHref() + "nmethod=" + nm.getAddress(); | |
392 } | |
393 | |
394 public String genNMethodTitle(NMethod nmethod) { | |
395 Formatter buf = new Formatter(genHTML); | |
396 Method m = nmethod.getMethod(); | |
397 | |
398 buf.append("Disassembly for compiled method ["); | |
399 buf.append(genMethodTitle(m)); | |
400 buf.append(" ] "); | |
401 buf.append('@'); | |
402 buf.append(nmethod.getAddress().toString()); | |
403 return buf.toString(); | |
404 } | |
405 | |
406 protected String genNMethodLink(NMethod nm) { | |
407 Formatter buf = new Formatter(genHTML); | |
408 buf.link(genNMethodHref(nm), genNMethodTitle(nm)); | |
409 return buf.toString(); | |
410 } | |
411 | |
412 public String genCodeBlobTitle(CodeBlob blob) { | |
413 Formatter buf = new Formatter(genHTML); | |
414 buf.append("Disassembly for code blob " + blob.getName() + " ["); | |
415 buf.append(blob.getClass().getName()); | |
416 buf.append(" ] @"); | |
417 buf.append(blob.getAddress().toString()); | |
418 return buf.toString(); | |
419 } | |
420 | |
421 protected BytecodeDisassembler createBytecodeDisassembler(Method m) { | |
422 return new BytecodeDisassembler(m); | |
423 } | |
424 | |
425 private String genLowHighShort(int val) { | |
426 Formatter buf = new Formatter(genHTML); | |
427 buf.append('#'); | |
428 buf.append(Integer.toString(val & 0xFFFF)); | |
429 buf.append(" #"); | |
430 buf.append(Integer.toString((val >> 16) & 0xFFFF)); | |
431 return buf.toString(); | |
432 } | |
433 | |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
434 private String genListOfShort(short[] values) { |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
435 if (values == null || values.length == 0) return ""; |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
436 Formatter buf = new Formatter(genHTML); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
437 buf.append('['); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
438 for (int i = 0; i < values.length; i++) { |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
439 if (i > 0) buf.append(' '); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
440 buf.append('#'); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
441 buf.append(Integer.toString(values[i])); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
442 } |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
443 buf.append(']'); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
444 return buf.toString(); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
445 } |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1748
diff
changeset
|
446 |
0 | 447 protected String genHTMLTableForConstantPool(ConstantPool cpool) { |
448 Formatter buf = new Formatter(genHTML); | |
449 buf.beginTable(1); | |
450 | |
451 buf.beginTag("tr"); | |
452 buf.headerCell("Index"); | |
453 buf.headerCell("Constant Type"); | |
454 buf.headerCell("Constant Value"); | |
455 buf.endTag("tr"); | |
456 | |
457 final int length = (int) cpool.getLength(); | |
458 // zero'th pool entry is always invalid. ignore it. | |
459 for (int index = 1; index < length; index++) { | |
460 buf.beginTag("tr"); | |
461 buf.cell(Integer.toString(index)); | |
462 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
463 int ctag = (int) cpool.getTags().at((int) index); |
0 | 464 switch (ctag) { |
465 case JVM_CONSTANT_Integer: | |
466 buf.cell("JVM_CONSTANT_Integer"); | |
467 buf.cell(Integer.toString(cpool.getIntAt(index))); | |
468 break; | |
469 | |
470 case JVM_CONSTANT_Float: | |
471 buf.cell("JVM_CONSTANT_Float"); | |
472 buf.cell(Float.toString(cpool.getFloatAt(index))); | |
473 break; | |
474 | |
475 case JVM_CONSTANT_Long: | |
476 buf.cell("JVM_CONSTANT_Long"); | |
477 buf.cell(Long.toString(cpool.getLongAt(index))); | |
478 // long entries occupy two slots | |
479 index++; | |
480 break; | |
481 | |
482 case JVM_CONSTANT_Double: | |
483 buf.cell("JVM_CONSTANT_Double"); | |
484 buf.cell(Double.toString(cpool.getDoubleAt(index))); | |
485 // double entries occupy two slots | |
486 index++; | |
487 break; | |
488 | |
489 case JVM_CONSTANT_UnresolvedClass: | |
490 buf.cell("JVM_CONSTANT_UnresolvedClass"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
491 buf.cell(cpool.getKlassNameAt(index).asString()); |
0 | 492 break; |
493 | |
1385 | 494 case JVM_CONSTANT_UnresolvedClassInError: |
495 buf.cell("JVM_CONSTANT_UnresolvedClassInError"); | |
496 buf.cell(cpool.getSymbolAt(index).asString()); | |
497 break; | |
498 | |
0 | 499 case JVM_CONSTANT_Class: |
500 buf.cell("JVM_CONSTANT_Class"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
501 Klass klass = (Klass) cpool.getKlassAt(index); |
0 | 502 if (klass instanceof InstanceKlass) { |
503 buf.cell(genKlassLink((InstanceKlass) klass)); | |
504 } else { | |
505 buf.cell(klass.getName().asString().replace('/', '.')); | |
506 } | |
507 break; | |
508 | |
509 case JVM_CONSTANT_Utf8: | |
510 buf.cell("JVM_CONSTANT_Utf8"); | |
511 buf.cell("\"" + | |
512 escapeHTMLSpecialChars(cpool.getSymbolAt(index).asString()) + | |
513 "\""); | |
514 break; | |
515 | |
516 case JVM_CONSTANT_String: | |
517 buf.cell("JVM_CONSTANT_String"); | |
518 buf.cell("\"" + | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
519 escapeHTMLSpecialChars(cpool.getUnresolvedStringAt(index).asString()) + "\""); |
0 | 520 break; |
521 | |
522 case JVM_CONSTANT_Fieldref: | |
523 buf.cell("JVM_CONSTANT_Fieldref"); | |
524 buf.cell(genLowHighShort(cpool.getIntAt(index))); | |
525 break; | |
526 | |
527 case JVM_CONSTANT_Methodref: | |
528 buf.cell("JVM_CONSTANT_Methodref"); | |
529 buf.cell(genLowHighShort(cpool.getIntAt(index))); | |
530 break; | |
531 | |
532 case JVM_CONSTANT_InterfaceMethodref: | |
533 buf.cell("JVM_CONSTANT_InterfaceMethodref"); | |
534 buf.cell(genLowHighShort(cpool.getIntAt(index))); | |
535 break; | |
536 | |
537 case JVM_CONSTANT_NameAndType: | |
538 buf.cell("JVM_CONSTANT_NameAndType"); | |
539 buf.cell(genLowHighShort(cpool.getIntAt(index))); | |
540 break; | |
541 | |
542 case JVM_CONSTANT_ClassIndex: | |
543 buf.cell("JVM_CONSTANT_ClassIndex"); | |
544 buf.cell(Integer.toString(cpool.getIntAt(index))); | |
545 break; | |
546 | |
547 case JVM_CONSTANT_StringIndex: | |
548 buf.cell("JVM_CONSTANT_StringIndex"); | |
549 buf.cell(Integer.toString(cpool.getIntAt(index))); | |
550 break; | |
1385 | 551 |
1602 | 552 case JVM_CONSTANT_MethodHandle: |
553 buf.cell("JVM_CONSTANT_MethodHandle"); | |
554 buf.cell(genLowHighShort(cpool.getIntAt(index))); | |
555 break; | |
556 | |
557 case JVM_CONSTANT_MethodType: | |
558 buf.cell("JVM_CONSTANT_MethodType"); | |
559 buf.cell(Integer.toString(cpool.getIntAt(index))); | |
560 break; | |
561 | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
562 case JVM_CONSTANT_InvokeDynamic: |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
563 buf.cell("JVM_CONSTANT_InvokeDynamic"); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
564 buf.cell(genLowHighShort(cpool.getIntAt(index)) + |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
565 genListOfShort(cpool.getBootstrapSpecifierAt(index))); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
566 break; |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
567 |
1385 | 568 default: |
569 throw new InternalError("unknown tag: " + ctag); | |
0 | 570 } |
571 | |
572 buf.endTag("tr"); | |
573 } | |
574 | |
575 buf.endTable(); | |
576 return buf.toString(); | |
577 } | |
578 | |
579 public String genHTML(ConstantPool cpool) { | |
580 try { | |
581 Formatter buf = new Formatter(genHTML); | |
582 buf.genHTMLPrologue(genConstantPoolTitle(cpool)); | |
583 buf.h3("Holder Class"); | |
584 buf.append(genKlassLink((InstanceKlass) cpool.getPoolHolder())); | |
585 buf.h3("Constants"); | |
586 buf.append(genHTMLTableForConstantPool(cpool)); | |
587 buf.genHTMLEpilogue(); | |
588 return buf.toString(); | |
589 } catch (Exception exp) { | |
590 return genHTMLErrorMessage(exp); | |
591 } | |
592 } | |
593 | |
594 protected String genConstantPoolHref(ConstantPool cpool) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
595 return genBaseHref() + "cpool=" + cpool.getAddress(); |
0 | 596 } |
597 | |
598 protected String genConstantPoolTitle(ConstantPool cpool) { | |
599 Formatter buf = new Formatter(genHTML); | |
600 buf.append("Constant Pool of ["); | |
601 buf.append(genKlassTitle((InstanceKlass) cpool.getPoolHolder())); | |
602 buf.append("] @"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
603 buf.append(cpool.getAddress().toString()); |
0 | 604 return buf.toString(); |
605 } | |
606 | |
607 protected String genConstantPoolLink(ConstantPool cpool) { | |
608 Formatter buf = new Formatter(genHTML); | |
609 buf.link(genConstantPoolHref(cpool), genConstantPoolTitle(cpool)); | |
610 return buf.toString(); | |
611 } | |
612 | |
613 public String genHTML(Method method) { | |
614 try { | |
615 final Formatter buf = new Formatter(genHTML); | |
616 buf.genHTMLPrologue(genMethodTitle(method)); | |
617 | |
618 buf.h3("Holder Class"); | |
619 buf.append(genKlassLink((InstanceKlass) method.getMethodHolder())); | |
620 | |
621 NMethod nmethod = method.getNativeMethod(); | |
622 if (nmethod != null) { | |
623 buf.h3("Compiled Code"); | |
624 buf.append(genNMethodLink(nmethod)); | |
625 } | |
626 | |
627 boolean hasThrows = method.hasCheckedExceptions(); | |
628 ConstantPool cpool = ((InstanceKlass) method.getMethodHolder()).getConstants(); | |
629 if (hasThrows) { | |
630 buf.h3("Checked Exception(s)"); | |
631 CheckedExceptionElement[] exceptions = method.getCheckedExceptions(); | |
632 buf.beginTag("ul"); | |
633 for (int exp = 0; exp < exceptions.length; exp++) { | |
634 short cpIndex = (short) exceptions[exp].getClassCPIndex(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2070
diff
changeset
|
635 ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
636 if (obj.isUnresolved()) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2070
diff
changeset
|
637 buf.li((obj.getSymbol()).asString().replace('/', '.')); |
0 | 638 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
639 buf.li(genKlassLink((InstanceKlass)obj.getKlass())); |
0 | 640 } |
641 } | |
642 buf.endTag("ul"); | |
643 } | |
644 | |
645 if (method.isNative() || method.isAbstract()) { | |
646 buf.genHTMLEpilogue(); | |
647 return buf.toString(); | |
648 } | |
649 | |
650 buf.h3("Bytecode"); | |
651 BytecodeDisassembler disasm = createBytecodeDisassembler(method); | |
652 final boolean hasLineNumbers = method.hasLineNumberTable(); | |
653 disasm.decode(new BytecodeVisitor() { | |
654 private Method method; | |
655 public void prologue(Method m) { | |
656 method = m; | |
657 buf.beginTable(0); | |
658 buf.beginTag("tr"); | |
659 if (hasLineNumbers) { | |
660 buf.headerCell("line"); | |
661 } | |
662 buf.headerCell("bci" + spaces); | |
663 buf.headerCell("bytecode"); | |
664 buf.endTag("tr"); | |
665 } | |
666 | |
667 public void visit(Bytecode instr) { | |
668 int curBci = instr.bci(); | |
669 buf.beginTag("tr"); | |
670 if (hasLineNumbers) { | |
671 int lineNumber = method.getLineNumberFromBCI(curBci); | |
672 buf.cell(Integer.toString(lineNumber) + spaces); | |
673 } | |
674 buf.cell(Integer.toString(curBci) + spaces); | |
675 | |
676 buf.beginTag("td"); | |
1385 | 677 String instrStr = null; |
678 try { | |
679 instrStr = escapeHTMLSpecialChars(instr.toString()); | |
680 } catch (RuntimeException re) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
681 buf.append("exception while printing " + instr.getBytecodeName()); |
1385 | 682 buf.endTag("td"); |
683 buf.endTag("tr"); | |
684 re.printStackTrace(); | |
685 return; | |
686 } | |
0 | 687 |
688 if (instr instanceof BytecodeNew) { | |
689 BytecodeNew newBytecode = (BytecodeNew) instr; | |
690 InstanceKlass klass = newBytecode.getNewKlass(); | |
691 if (klass != null) { | |
692 buf.link(genKlassHref(klass), instrStr); | |
693 } else { | |
694 buf.append(instrStr); | |
695 } | |
696 } else if(instr instanceof BytecodeInvoke) { | |
697 BytecodeInvoke invokeBytecode = (BytecodeInvoke) instr; | |
698 Method m = invokeBytecode.getInvokedMethod(); | |
699 if (m != null) { | |
700 buf.link(genMethodHref(m), instrStr); | |
701 buf.append(" of "); | |
702 InstanceKlass klass = (InstanceKlass) m.getMethodHolder(); | |
703 buf.link(genKlassHref(klass), genKlassTitle(klass)); | |
704 } else { | |
705 buf.append(instrStr); | |
706 } | |
707 } else if (instr instanceof BytecodeGetPut) { | |
708 BytecodeGetPut getPut = (BytecodeGetPut) instr; | |
709 sun.jvm.hotspot.oops.Field f = getPut.getField(); | |
710 buf.append(instrStr); | |
711 if (f != null) { | |
712 InstanceKlass klass = f.getFieldHolder(); | |
713 buf.append(" of "); | |
714 buf.link(genKlassHref(klass), genKlassTitle(klass)); | |
715 } | |
716 } else if (instr instanceof BytecodeLoadConstant) { | |
717 BytecodeLoadConstant ldc = (BytecodeLoadConstant) instr; | |
718 if (ldc.isKlassConstant()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2070
diff
changeset
|
719 Object oop = ldc.getKlass(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
720 if (oop instanceof InstanceKlass) { |
0 | 721 buf.append("<a href='"); |
722 buf.append(genKlassHref((InstanceKlass) oop)); | |
723 buf.append("'>"); | |
724 buf.append(instrStr); | |
725 buf.append("</a>"); | |
726 } else { | |
727 // unresolved klass literal | |
728 buf.append(instrStr); | |
729 } | |
730 } else { | |
731 // not a klass literal | |
732 buf.append(instrStr); | |
733 } | |
734 } else { | |
735 buf.append(instrStr); | |
736 } | |
737 buf.endTag("td"); | |
738 buf.endTag("tr"); | |
739 } | |
740 | |
741 public void epilogue() { | |
742 buf.endTable(); | |
743 } | |
744 }); | |
745 | |
746 // display exception table for this method | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
747 boolean hasException = method.hasExceptionTable(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
748 if (hasException) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
749 ExceptionTableElement[] exceptionTable = method.getExceptionTable(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
750 int numEntries = exceptionTable.length; |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
751 if (numEntries != 0) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
752 buf.h4("Exception Table"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
753 buf.beginTable(1); |
0 | 754 buf.beginTag("tr"); |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
755 buf.headerCell("start bci"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
756 buf.headerCell("end bci"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
757 buf.headerCell("handler bci"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
758 buf.headerCell("catch type"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
759 buf.endTag("tr"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
760 |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
761 for (int e = 0; e < numEntries; e ++) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
762 buf.beginTag("tr"); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
763 buf.cell(Integer.toString(exceptionTable[e].getStartPC())); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
764 buf.cell(Integer.toString(exceptionTable[e].getEndPC())); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
765 buf.cell(Integer.toString(exceptionTable[e].getHandlerPC())); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
766 short cpIndex = (short) exceptionTable[e].getCatchTypeIndex(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
767 ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
768 if (obj == null) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
769 buf.cell("Any"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
770 } else if (obj.isUnresolved()) { |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
771 buf.cell(obj.getSymbol().asString().replace('/', '.')); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
772 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
773 buf.cell(genKlassLink((InstanceKlass)obj.getKlass())); |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
774 } |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
775 buf.endTag("tr"); |
0 | 776 } |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
777 |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
6073
diff
changeset
|
778 buf.endTable(); |
0 | 779 } |
780 } | |
781 | |
782 // display constant pool hyperlink | |
783 buf.h3("Constant Pool"); | |
784 buf.append(genConstantPoolLink(cpool)); | |
785 buf.genHTMLEpilogue(); | |
786 return buf.toString(); | |
787 } catch (Exception exp) { | |
788 return genHTMLErrorMessage(exp); | |
789 } | |
790 } | |
791 | |
792 protected SymbolFinder createSymbolFinder() { | |
793 return new DummySymbolFinder(); | |
794 } | |
795 | |
796 // genHTML for a given address. Address may be a PC or | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
797 // Method* or Klass*. |
0 | 798 |
799 public String genHTMLForAddress(String addrStr) { | |
800 return genHTML(parseAddress(addrStr)); | |
801 } | |
802 | |
803 public String genHTML(sun.jvm.hotspot.debugger.Address pc) { | |
804 CodeBlob blob = null; | |
805 | |
806 try { | |
807 blob = (CodeBlob)VM.getVM().getCodeCache().findBlobUnsafe(pc); | |
808 } catch (Exception exp) { | |
809 // ignore | |
810 } | |
811 | |
812 if (blob != null) { | |
813 if (blob instanceof NMethod) { | |
814 return genHTML((NMethod)blob); | |
815 } else { | |
816 // may be interpreter code. | |
817 Interpreter interp = VM.getVM().getInterpreter(); | |
818 if (interp.contains(pc)) { | |
819 InterpreterCodelet codelet = interp.getCodeletContaining(pc); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
820 if (codelet == null) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
821 return "Unknown location in the Interpreter: " + pc; |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
822 } |
0 | 823 return genHTML(codelet); |
824 } | |
825 return genHTML(blob); | |
826 } | |
827 } else if (VM.getVM().getCodeCache().contains(pc)) { | |
828 return "Unknown location in the CodeCache: " + pc; | |
829 } | |
830 | |
831 // did not find nmethod. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
832 // try Method*, Klass* and ConstantPool*. |
0 | 833 try { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
834 Metadata obj = Metadata.instantiateWrapperFor(pc); |
0 | 835 if (obj != null) { |
836 if (obj instanceof Method) { | |
837 return genHTML((Method) obj); | |
838 } else if (obj instanceof InstanceKlass) { | |
839 return genHTML((InstanceKlass) obj); | |
840 } else if (obj instanceof ConstantPool) { | |
841 return genHTML((ConstantPool) obj); | |
842 } | |
843 } | |
844 } catch (Exception exp) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
845 exp.printStackTrace(); |
0 | 846 // ignore |
847 } | |
848 | |
849 // didn't find any. do raw disassembly. | |
850 return genHTMLForRawDisassembly(pc, null); | |
851 } | |
852 | |
6782 | 853 public String genHTMLForRawDisassembly(sun.jvm.hotspot.debugger.Address startPc, int size) { |
0 | 854 try { |
6782 | 855 return genHTMLForRawDisassembly(startPc, size, null); |
0 | 856 } catch (Exception exp) { |
857 return genHTMLErrorMessage(exp); | |
858 } | |
859 } | |
860 | |
861 protected String genHTMLForRawDisassembly(sun.jvm.hotspot.debugger.Address startPc, | |
862 String prevPCs) { | |
863 try { | |
6782 | 864 return genHTMLForRawDisassembly(startPc, NATIVE_CODE_SIZE, prevPCs); |
0 | 865 } catch (Exception exp) { |
866 return genHTMLErrorMessage(exp); | |
867 } | |
868 } | |
869 | |
870 protected String genPCHref(long targetPc) { | |
871 return genBaseHref() + "pc=0x" + Long.toHexString(targetPc); | |
872 } | |
873 | |
874 protected String genMultPCHref(String pcs) { | |
875 StringBuffer buf = new StringBuffer(genBaseHref()); | |
876 buf.append("pc_multiple="); | |
877 buf.append(pcs); | |
878 return buf.toString(); | |
879 } | |
880 | |
6782 | 881 protected String genPCHref(Address addr) { |
882 return genPCHref(addressToLong(addr)); | |
0 | 883 } |
884 | |
6782 | 885 class HTMLDisassembler implements InstructionVisitor { |
0 | 886 private int instrSize = 0; |
887 private Formatter buf; | |
888 private SymbolFinder symFinder = createSymbolFinder(); | |
6782 | 889 private long pc; |
890 private OopMapSet oms; | |
891 private CodeBlob blob; | |
892 private NMethod nmethod; | |
0 | 893 |
6782 | 894 HTMLDisassembler(Formatter buf, CodeBlob blob) { |
0 | 895 this.buf = buf; |
6782 | 896 this.blob = blob; |
897 if (blob != null) { | |
898 if (blob instanceof NMethod) { | |
899 nmethod = (NMethod)blob; | |
900 } | |
901 oms = blob.getOopMaps(); | |
902 } | |
0 | 903 } |
904 | |
905 public int getInstructionSize() { | |
906 return instrSize; | |
907 } | |
908 | |
909 public void prologue() { | |
910 } | |
911 | |
6782 | 912 public void beginInstruction(long currentPc) { |
913 pc = currentPc; | |
914 | |
915 sun.jvm.hotspot.debugger.Address adr = longToAddress(pc); | |
916 if (nmethod != null) { | |
917 if (adr.equals(nmethod.getEntryPoint())) print("[Entry Point]\n"); | |
918 if (adr.equals(nmethod.getVerifiedEntryPoint())) print("[Verified Entry Point]\n"); | |
919 if (adr.equals(nmethod.exceptionBegin())) print("[Exception Handler]\n"); | |
920 if (adr.equals(nmethod.stubBegin()) && | |
921 !nmethod.stubBegin().equals(nmethod.stubEnd())) print("[Stub Code]\n"); | |
922 // if (adr.equals(nmethod.constsBegin())) print("[Constants]\n"); | |
923 } | |
924 | |
925 buf.append(adr.toString()); | |
926 buf.append(':'); | |
927 buf.append(tab); | |
928 } | |
929 | |
930 public void printAddress(long address) { | |
931 sun.jvm.hotspot.debugger.Address addr = longToAddress(address); | |
932 if (VM.getVM().getCodeCache().contains(addr)) { | |
933 buf.link(genPCHref(address), addr.toString()); | |
934 } else { | |
935 buf.append(addr.toString()); | |
936 } | |
937 } | |
938 | |
939 public void print(String s) { | |
940 buf.append(s); | |
941 } | |
0 | 942 |
6782 | 943 public void endInstruction(long endPc) { |
944 instrSize += endPc - pc; | |
945 if (genHTML) buf.br(); | |
946 | |
947 if (nmethod != null) { | |
948 ScopeDesc sd = nmethod.scope_desc_in(pc, endPc); | |
949 if (sd != null) { | |
950 buf.br(); | |
951 buf.append(genSafepointInfo(nmethod, sd)); | |
952 } | |
953 } | |
0 | 954 |
6782 | 955 if (oms != null) { |
956 long base = addressToLong(blob.codeBegin()); | |
957 for (int i = 0, imax = (int)oms.getSize(); i < imax; i++) { | |
958 OopMap om = oms.getMapAt(i); | |
959 long omspc = base + om.getOffset(); | |
960 if (omspc > pc) { | |
961 if (omspc <= endPc) { | |
962 buf.br(); | |
963 buf.append(genOopMapInfo(om)); | |
964 // st.move_to(column); | |
965 // visitor.print("; "); | |
966 // om.print_on(st); | |
967 } | |
968 break; | |
969 } | |
970 } | |
971 } | |
972 // follow each complete insn by a nice newline | |
973 buf.br(); | |
0 | 974 } |
975 | |
976 public void epilogue() { | |
977 } | |
978 }; | |
979 | |
980 protected String genHTMLForRawDisassembly(sun.jvm.hotspot.debugger.Address addr, | |
6782 | 981 int size, |
982 String prevPCs) { | |
0 | 983 try { |
984 final Formatter buf = new Formatter(genHTML); | |
6782 | 985 buf.genHTMLPrologue("Disassembly @ " + addr); |
0 | 986 |
987 if (prevPCs != null && genHTML) { | |
988 buf.beginTag("p"); | |
989 buf.link(genMultPCHref(prevPCs), "show previous code .."); | |
990 buf.endTag("p"); | |
991 } | |
992 | |
993 | |
994 buf.h3("Code"); | |
6782 | 995 HTMLDisassembler visitor = new HTMLDisassembler(buf, null); |
996 Disassembler.decode(visitor, null, addr, addr.addOffsetTo(size)); | |
0 | 997 |
998 if (genHTML) buf.beginTag("p"); | |
999 Formatter tmpBuf = new Formatter(genHTML); | |
6782 | 1000 long startPc = addressToLong(addr); |
0 | 1001 tmpBuf.append("0x"); |
1002 tmpBuf.append(Long.toHexString(startPc + visitor.getInstructionSize()).toString()); | |
1003 tmpBuf.append(",0x"); | |
1004 tmpBuf.append(Long.toHexString(startPc)); | |
1005 if (prevPCs != null) { | |
1006 tmpBuf.append(','); | |
1007 tmpBuf.append(prevPCs); | |
1008 } | |
1009 if (genHTML) { | |
1010 buf.link(genMultPCHref(tmpBuf.toString()), "show more code .."); | |
1011 buf.endTag("p"); | |
1012 } | |
1013 | |
1014 buf.genHTMLEpilogue(); | |
1015 return buf.toString(); | |
1016 } catch (Exception exp) { | |
1017 return genHTMLErrorMessage(exp); | |
1018 } | |
1019 } | |
1020 | |
6782 | 1021 protected String genSafepointInfo(NMethod nm, ScopeDesc sd) { |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1022 Formatter buf = new Formatter(genHTML); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1023 Formatter tabs = new Formatter(genHTML); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1024 tabs.append(tab + tab + tab); // Initial indent for debug info |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1025 |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1026 buf.beginTag("pre"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1027 genScope(buf, tabs, sd); |
0 | 1028 |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1029 // Reset indent for scalar replaced objects |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1030 tabs = new Formatter(genHTML); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1031 tabs.append(tab + tab + tab); // Initial indent for debug info |
0 | 1032 |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1033 genScObjInfo(buf, tabs, sd); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1034 buf.endTag("pre"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1035 |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1036 return buf.toString(); |
0 | 1037 } |
1038 | |
1039 protected void genScope(Formatter buf, Formatter tabs, ScopeDesc sd) { | |
1040 if (sd == null) { | |
1041 return; | |
1042 } | |
1043 | |
1044 genScope(buf, tabs, sd.sender()); | |
1045 | |
1046 buf.append(tabs); | |
1047 Method m = sd.getMethod(); | |
1048 buf.append(genMethodAndKlassLink(m)); | |
1049 int bci = sd.getBCI(); | |
1050 buf.append(" @ bci = "); | |
1051 buf.append(Integer.toString(bci)); | |
1052 | |
1053 int line = m.getLineNumberFromBCI(bci); | |
1054 if (line != -1) { | |
1055 buf.append(", line = "); | |
1056 buf.append(Integer.toString(line)); | |
1057 } | |
1058 | |
1059 List locals = sd.getLocals(); | |
1060 if (locals != null) { | |
1061 buf.br(); | |
1062 buf.append(tabs); | |
1063 buf.append(genHTMLForLocals(sd, locals)); | |
1064 } | |
1065 | |
1066 List expressions = sd.getExpressions(); | |
1067 if (expressions != null) { | |
1068 buf.br(); | |
1069 buf.append(tabs); | |
1070 buf.append(genHTMLForExpressions(sd, expressions)); | |
1071 } | |
1072 | |
1073 List monitors = sd.getMonitors(); | |
1074 if (monitors != null) { | |
1075 buf.br(); | |
1076 buf.append(tabs); | |
1077 buf.append(genHTMLForMonitors(sd, monitors)); | |
1078 } | |
1079 | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1080 buf.br(); |
0 | 1081 tabs.append(tab); |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1082 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1083 |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1084 protected void genScObjInfo(Formatter buf, Formatter tabs, ScopeDesc sd) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1085 if (sd == null) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1086 return; |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1087 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1088 |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1089 List objects = sd.getObjects(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1090 if (objects == null) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1091 return; |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1092 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1093 int length = objects.size(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1094 for (int i = 0; i < length; i++) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1095 buf.append(tabs); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1096 ObjectValue ov = (ObjectValue)objects.get(i); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1097 buf.append("ScObj" + i); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1098 ScopeValue sv = ov.getKlass(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1099 if (Assert.ASSERTS_ENABLED) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1100 Assert.that(sv.isConstantOop(), "scalar replaced object klass must be constant oop"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1101 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1102 ConstantOopReadValue klv = (ConstantOopReadValue)sv; |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1103 OopHandle klHandle = klv.getValue(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1104 if (Assert.ASSERTS_ENABLED) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1105 Assert.that(klHandle != null, "scalar replaced object klass must be not NULL"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1106 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1107 Oop obj = VM.getVM().getObjectHeap().newOop(klHandle); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1108 // Obj is a Java mirror |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1109 Klass klass = java_lang_Class.asKlass(obj); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1110 if (klass instanceof InstanceKlass) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1111 InstanceKlass kls = (InstanceKlass) klass; |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1112 buf.append(" " + kls.getName().asString() + "={"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1113 int flen = ov.fieldsSize(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1114 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1115 U2Array klfields = kls.getFields(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1116 int klen = (int) klfields.length(); |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1117 int findex = 0; |
3938 | 1118 for (int index = 0; index < klen; index++) { |
1119 int accsFlags = kls.getFieldAccessFlags(index); | |
1120 Symbol f_name = kls.getFieldName(index); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1121 AccessFlags access = new AccessFlags(accsFlags); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1122 if (!access.isStatic()) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1123 ScopeValue svf = ov.getFieldAt(findex++); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1124 String fstr = scopeValueAsString(sd, svf); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1125 buf.append(" [" + f_name.asString() + " :"+ index + "]=(#" + fstr + ")"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1126 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1127 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1128 buf.append(" }"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1129 } else { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1130 buf.append(" "); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1131 int flen = ov.fieldsSize(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1132 if (klass instanceof TypeArrayKlass) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1133 TypeArrayKlass kls = (TypeArrayKlass) klass; |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1134 buf.append(kls.getElementTypeName() + "[" + flen + "]"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1135 } else if (klass instanceof ObjArrayKlass) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1136 ObjArrayKlass kls = (ObjArrayKlass) klass; |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1137 Klass elobj = kls.getBottomKlass(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1138 if (elobj instanceof InstanceKlass) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1139 buf.append(elobj.getName().asString()); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1140 } else if (elobj instanceof TypeArrayKlass) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1141 TypeArrayKlass elkls = (TypeArrayKlass) elobj; |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1142 buf.append(elkls.getElementTypeName()); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1143 } else { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1144 if (Assert.ASSERTS_ENABLED) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1145 Assert.that(false, "unknown scalar replaced object klass!"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1146 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1147 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1148 buf.append("[" + flen + "]"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1149 int ndim = (int) kls.getDimension(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1150 while (--ndim > 0) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1151 buf.append("[]"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1152 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1153 } else { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1154 if (Assert.ASSERTS_ENABLED) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1155 Assert.that(false, "unknown scalar replaced object klass!"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1156 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1157 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1158 buf.append("={"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1159 for (int findex = 0; findex < flen; findex++) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1160 ScopeValue svf = ov.getFieldAt(findex); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1161 String fstr = scopeValueAsString(sd, svf); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1162 buf.append(" [" + findex + "]=(#" + fstr + ")"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1163 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1164 buf.append(" }"); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1165 } |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1166 buf.br(); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1167 } |
0 | 1168 } |
1169 | |
1170 protected String genHTMLForOopMap(OopMap map) { | |
1171 final int stack0 = VMRegImpl.getStack0().getValue(); | |
1172 Formatter buf = new Formatter(genHTML); | |
1173 | |
1174 final class OopMapValueIterator { | |
1175 final Formatter iterate(OopMapStream oms, String type, boolean printContentReg) { | |
1176 Formatter tmpBuf = new Formatter(genHTML); | |
1177 boolean found = false; | |
1178 tmpBuf.beginTag("tr"); | |
1179 tmpBuf.beginTag("td"); | |
1180 tmpBuf.append(type); | |
1181 for (; ! oms.isDone(); oms.next()) { | |
1182 OopMapValue omv = oms.getCurrent(); | |
1183 if (omv == null) { | |
1184 continue; | |
1185 } | |
1186 found = true; | |
1187 VMReg vmReg = omv.getReg(); | |
1188 int reg = vmReg.getValue(); | |
1189 if (reg < stack0) { | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1190 tmpBuf.append(VMRegImpl.getRegisterName(reg)); |
0 | 1191 } else { |
1192 tmpBuf.append('['); | |
1193 tmpBuf.append(Integer.toString((reg - stack0) * 4)); | |
1194 tmpBuf.append(']'); | |
1195 } | |
1196 if (printContentReg) { | |
1197 tmpBuf.append(" = "); | |
1198 VMReg vmContentReg = omv.getContentReg(); | |
1199 int contentReg = vmContentReg.getValue(); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1200 if (contentReg < stack0) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1201 tmpBuf.append(VMRegImpl.getRegisterName(contentReg)); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1202 } else { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1203 tmpBuf.append('['); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1204 tmpBuf.append(Integer.toString((contentReg - stack0) * 4)); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1205 tmpBuf.append(']'); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1206 } |
0 | 1207 } |
1208 tmpBuf.append(spaces); | |
1209 } | |
1210 tmpBuf.endTag("td"); | |
1211 tmpBuf.endTag("tr"); | |
1212 return found ? tmpBuf : new Formatter(genHTML); | |
1213 } | |
1214 } | |
1215 | |
1216 buf.beginTable(0); | |
1217 | |
1218 OopMapValueIterator omvIterator = new OopMapValueIterator(); | |
1219 OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1220 buf.append(omvIterator.iterate(oms, "Oops:", false)); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1221 |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1222 oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE); |
6782 | 1223 buf.append(omvIterator.iterate(oms, "NarrowOops:", false)); |
0 | 1224 |
1225 oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); | |
1226 buf.append(omvIterator.iterate(oms, "Callee saved:", true)); | |
1227 | |
1228 oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1229 buf.append(omvIterator.iterate(oms, "Derived oops:", true)); |
0 | 1230 |
1231 buf.endTag("table"); | |
1232 return buf.toString(); | |
1233 } | |
1234 | |
1235 | |
1236 protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) { | |
1237 OopMapSet mapSet = nmethod.getOopMaps(); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1238 if (mapSet == null || (mapSet.getSize() <= 0)) |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1239 return ""; |
0 | 1240 int pcOffset = pcDesc.getPCOffset(); |
1241 OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging()); | |
1242 if (map == null) { | |
1243 throw new IllegalArgumentException("no oopmap at safepoint!"); | |
1244 } | |
1245 | |
1246 return genOopMapInfo(map); | |
1247 } | |
1248 | |
1249 protected String genOopMapInfo(OopMap map) { | |
1250 Formatter buf = new Formatter(genHTML); | |
1251 buf.beginTag("pre"); | |
1252 buf.append("OopMap: "); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1253 buf.br(); |
0 | 1254 buf.append(genHTMLForOopMap(map)); |
1255 buf.endTag("pre"); | |
1256 | |
1257 return buf.toString(); | |
1258 } | |
1259 | |
1260 protected String locationAsString(Location loc) { | |
1261 Formatter buf = new Formatter(genHTML); | |
1262 if (loc.isIllegal()) { | |
1263 buf.append("illegal"); | |
1264 } else { | |
1265 Location.Where w = loc.getWhere(); | |
1266 Location.Type type = loc.getType(); | |
1267 | |
1268 if (w == Location.Where.ON_STACK) { | |
1269 buf.append("stack[" + loc.getStackOffset() + "]"); | |
1270 } else if (w == Location.Where.IN_REGISTER) { | |
1271 boolean isFloat = (type == Location.Type.FLOAT_IN_DBL || | |
1272 type == Location.Type.DBL); | |
1273 int regNum = loc.getRegisterNumber(); | |
1274 VMReg vmReg = new VMReg(regNum); | |
1275 buf.append(VMRegImpl.getRegisterName(vmReg.getValue())); | |
1276 } | |
1277 | |
1278 buf.append(", "); | |
1279 if (type == Location.Type.NORMAL) { | |
1280 buf.append("normal"); | |
1281 } else if (type == Location.Type.OOP) { | |
1282 buf.append("oop"); | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
196
diff
changeset
|
1283 } else if (type == Location.Type.NARROWOOP) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
196
diff
changeset
|
1284 buf.append("narrowoop"); |
0 | 1285 } else if (type == Location.Type.INT_IN_LONG) { |
1286 buf.append("int"); | |
1287 } else if (type == Location.Type.LNG) { | |
1288 buf.append("long"); | |
1289 } else if (type == Location.Type.FLOAT_IN_DBL) { | |
1290 buf.append("float"); | |
1291 } else if (type == Location.Type.DBL) { | |
1292 buf.append("double"); | |
1293 } else if (type == Location.Type.ADDR) { | |
1294 buf.append("address"); | |
1295 } else if (type == Location.Type.INVALID) { | |
1296 buf.append("invalid"); | |
1297 } | |
1298 } | |
1299 return buf.toString(); | |
1300 } | |
1301 | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1302 private String scopeValueAsString(ScopeDesc sd, ScopeValue sv) { |
0 | 1303 Formatter buf = new Formatter(genHTML); |
1304 if (sv.isConstantInt()) { | |
1305 buf.append("int "); | |
1306 ConstantIntValue intValue = (ConstantIntValue) sv; | |
1307 buf.append(Integer.toString(intValue.getValue())); | |
1308 } else if (sv.isConstantLong()) { | |
1309 buf.append("long "); | |
1310 ConstantLongValue longValue = (ConstantLongValue) sv; | |
1311 buf.append(Long.toString(longValue.getValue())); | |
1312 buf.append("L"); | |
1313 } else if (sv.isConstantDouble()) { | |
1314 buf.append("double "); | |
1315 ConstantDoubleValue dblValue = (ConstantDoubleValue) sv; | |
1316 buf.append(Double.toString(dblValue.getValue())); | |
1317 buf.append("D"); | |
1318 } else if (sv.isConstantOop()) { | |
1319 buf.append("oop "); | |
1320 ConstantOopReadValue oopValue = (ConstantOopReadValue) sv; | |
1321 OopHandle oopHandle = oopValue.getValue(); | |
1322 if (oopHandle != null) { | |
1323 buf.append(oopHandle.toString()); | |
1324 } else { | |
1325 buf.append("null"); | |
1326 } | |
1327 } else if (sv.isLocation()) { | |
1328 LocationValue lvalue = (LocationValue) sv; | |
1329 Location loc = lvalue.getLocation(); | |
1330 if (loc != null) { | |
1331 buf.append(locationAsString(loc)); | |
1332 } else { | |
1333 buf.append("null"); | |
1334 } | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1335 } else if (sv.isObject()) { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1336 ObjectValue ov = (ObjectValue)sv; |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1337 buf.append("#ScObj" + sd.getObjects().indexOf(ov)); |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1338 } else { |
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1339 buf.append("unknown scope value " + sv); |
0 | 1340 } |
1341 return buf.toString(); | |
1342 } | |
1343 | |
1344 protected String genHTMLForScopeValues(ScopeDesc sd, boolean locals, List values) { | |
1345 int length = values.size(); | |
1346 Formatter buf = new Formatter(genHTML); | |
1347 buf.append(locals? "locals " : "expressions "); | |
1348 for (int i = 0; i < length; i++) { | |
1349 ScopeValue sv = (ScopeValue) values.get(i); | |
1350 if (sv == null) { | |
1351 continue; | |
1352 } | |
1353 buf.append('('); | |
1354 if (locals) { | |
1355 Symbol name = sd.getMethod().getLocalVariableName(sd.getBCI(), i); | |
1356 if (name != null) { | |
1357 buf.append("'"); | |
1358 buf.append(name.asString()); | |
1359 buf.append('\''); | |
1360 } else { | |
1361 buf.append("["); | |
1362 buf.append(Integer.toString(i)); | |
1363 buf.append(']'); | |
1364 } | |
1365 } else { | |
1366 buf.append("["); | |
1367 buf.append(Integer.toString(i)); | |
1368 buf.append(']'); | |
1369 } | |
1370 | |
1371 buf.append(", "); | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1372 buf.append(scopeValueAsString(sd, sv)); |
0 | 1373 buf.append(") "); |
1374 } | |
1375 | |
1376 return buf.toString(); | |
1377 } | |
1378 | |
1379 protected String genHTMLForLocals(ScopeDesc sd, List locals) { | |
1380 return genHTMLForScopeValues(sd, true, locals); | |
1381 } | |
1382 | |
1383 protected String genHTMLForExpressions(ScopeDesc sd, List expressions) { | |
1384 return genHTMLForScopeValues(sd, false, expressions); | |
1385 } | |
1386 | |
1387 protected String genHTMLForMonitors(ScopeDesc sd, List monitors) { | |
1388 int length = monitors.size(); | |
1389 Formatter buf = new Formatter(genHTML); | |
1390 buf.append("monitors "); | |
1391 for (int i = 0; i < length; i++) { | |
1392 MonitorValue mv = (MonitorValue) monitors.get(i); | |
1393 if (mv == null) { | |
1394 continue; | |
1395 } | |
1396 buf.append("(owner = "); | |
1397 ScopeValue owner = mv.owner(); | |
1398 if (owner != null) { | |
1040
873ec3787992
6892186: SA does not dump debug info for scalar replaced objects
kvn
parents:
331
diff
changeset
|
1399 buf.append(scopeValueAsString(sd, owner)); |
0 | 1400 } else { |
1401 buf.append("null"); | |
1402 } | |
1403 buf.append(", lock = "); | |
1404 | |
1405 Location loc = mv.basicLock(); | |
1406 if (loc != null) { | |
1407 buf.append(locationAsString(loc)); | |
1408 } else { | |
1409 buf.append("null"); | |
1410 } | |
1411 buf.append(") "); | |
1412 } | |
1413 return buf.toString(); | |
1414 } | |
1415 | |
1416 public String genHTML(final NMethod nmethod) { | |
1417 try { | |
1418 final Formatter buf = new Formatter(genHTML); | |
1419 buf.genHTMLPrologue(genNMethodTitle(nmethod)); | |
1420 buf.h3("Method"); | |
1421 buf.append(genMethodAndKlassLink(nmethod.getMethod())); | |
1422 | |
1423 buf.h3("Compiled Code"); | |
6782 | 1424 Disassembler.decode(new HTMLDisassembler(buf, nmethod), nmethod); |
0 | 1425 buf.genHTMLEpilogue(); |
1426 return buf.toString(); | |
1427 } catch (Exception exp) { | |
1428 return genHTMLErrorMessage(exp); | |
1429 } | |
1430 } | |
1431 | |
1432 public String genHTML(final CodeBlob blob) { | |
1433 try { | |
1434 final Formatter buf = new Formatter(genHTML); | |
1435 buf.genHTMLPrologue(genCodeBlobTitle(blob)); | |
1436 buf.h3("CodeBlob"); | |
1437 | |
1438 buf.h3("Compiled Code"); | |
6782 | 1439 Disassembler.decode(new HTMLDisassembler(buf, blob), blob); |
0 | 1440 |
1441 buf.genHTMLEpilogue(); | |
1442 return buf.toString(); | |
1443 } catch (Exception exp) { | |
1444 return genHTMLErrorMessage(exp); | |
1445 } | |
1446 } | |
1447 | |
1448 protected String genInterpreterCodeletTitle(InterpreterCodelet codelet) { | |
1449 Formatter buf = new Formatter(genHTML); | |
1450 buf.append("Interpreter codelet ["); | |
1451 buf.append(codelet.codeBegin().toString()); | |
1452 buf.append(','); | |
1453 buf.append(codelet.codeEnd().toString()); | |
1454 buf.append(") - "); | |
1455 buf.append(codelet.getDescription()); | |
1456 return buf.toString(); | |
1457 } | |
1458 | |
1459 protected String genInterpreterCodeletLinkPageHref(StubQueue stubq) { | |
1460 return genBaseHref() + "interp_codelets"; | |
1461 } | |
1462 | |
1463 public String genInterpreterCodeletLinksPage() { | |
1464 Formatter buf = new Formatter(genHTML); | |
1465 buf.genHTMLPrologue("Interpreter Codelets"); | |
1466 buf.beginTag("ul"); | |
1467 | |
1468 Interpreter interp = VM.getVM().getInterpreter(); | |
1469 StubQueue code = interp.getCode(); | |
1470 InterpreterCodelet stub = (InterpreterCodelet) code.getFirst(); | |
1471 while (stub != null) { | |
1472 buf.beginTag("li"); | |
1473 sun.jvm.hotspot.debugger.Address addr = stub.codeBegin(); | |
1474 buf.link(genPCHref(addressToLong(addr)), stub.getDescription() + " @" + addr); | |
1475 buf.endTag("li"); | |
1476 stub = (InterpreterCodelet) code.getNext(stub); | |
1477 } | |
1478 | |
1479 buf.endTag("ul"); | |
1480 buf.genHTMLEpilogue(); | |
1481 return buf.toString(); | |
1482 } | |
1483 | |
1484 public String genHTML(InterpreterCodelet codelet) { | |
1485 Formatter buf = new Formatter(genHTML); | |
1486 buf.genHTMLPrologue(genInterpreterCodeletTitle(codelet)); | |
1487 Interpreter interp = VM.getVM().getInterpreter(); | |
1488 StubQueue stubq = interp.getCode(); | |
1489 | |
1490 if (genHTML) { | |
1491 buf.beginTag("h3"); | |
1492 buf.link(genInterpreterCodeletLinkPageHref(stubq), "View links for all codelets"); | |
1493 buf.endTag("h3"); | |
1494 buf.br(); | |
1495 } | |
1496 | |
1497 Stub prev = stubq.getPrev(codelet); | |
1498 if (prev != null) { | |
1499 if (genHTML) { | |
1500 buf.beginTag("h3"); | |
1501 buf.link(genPCHref(addressToLong(prev.codeBegin())), "View Previous Codelet"); | |
1502 buf.endTag("h3"); | |
1503 buf.br(); | |
1504 } else { | |
1505 buf.h3("Previous Codelet = 0x" + Long.toHexString(addressToLong(prev.codeBegin()))); | |
1506 } | |
1507 } | |
1508 | |
1509 buf.h3("Code"); | |
6782 | 1510 Disassembler.decode(new HTMLDisassembler(buf, null), null, |
1511 codelet.codeBegin(), codelet.codeEnd()); | |
0 | 1512 |
1513 Stub next = stubq.getNext(codelet); | |
1514 if (next != null) { | |
1515 if (genHTML) { | |
1516 buf.beginTag("h3"); | |
1517 buf.link(genPCHref(addressToLong(next.codeBegin())), "View Next Codelet"); | |
1518 buf.endTag("h3"); | |
1519 } else { | |
1520 buf.h3("Next Codelet = 0x" + Long.toHexString(addressToLong(next.codeBegin()))); | |
1521 } | |
1522 } | |
1523 | |
1524 buf.genHTMLEpilogue(); | |
1525 return buf.toString(); | |
1526 } | |
1527 | |
1528 protected String genDumpKlassesTitle(InstanceKlass[] klasses) { | |
1529 return (klasses.length == 1) ? "Create .class for this class" | |
1530 : "Create .class for all classes"; | |
1531 } | |
1532 | |
1533 protected String genDumpKlassesHref(InstanceKlass[] klasses) { | |
1534 StringBuffer buf = new StringBuffer(genBaseHref()); | |
1535 buf.append("jcore_multiple="); | |
1536 for (int k = 0; k < klasses.length; k++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1537 buf.append(klasses[k].getAddress().toString()); |
0 | 1538 buf.append(','); |
1539 } | |
1540 return buf.toString(); | |
1541 } | |
1542 | |
1543 protected String genDumpKlassesLink(InstanceKlass[] klasses) { | |
1544 if (!genHTML) return ""; | |
1545 | |
1546 Formatter buf = new Formatter(genHTML); | |
1547 buf.link(genDumpKlassesHref(klasses), genDumpKlassesTitle(klasses)); | |
1548 return buf.toString(); | |
1549 } | |
1550 | |
1551 public String genHTMLForKlassNames(InstanceKlass[] klasses) { | |
1552 try { | |
1553 Formatter buf = new Formatter(genHTML); | |
1554 buf.genHTMLPrologue(); | |
1555 buf.h3(genDumpKlassesLink(klasses)); | |
1556 | |
1557 buf.append(genHTMLListForKlassNames(klasses)); | |
1558 buf.genHTMLEpilogue(); | |
1559 return buf.toString(); | |
1560 } catch (Exception exp) { | |
1561 return genHTMLErrorMessage(exp); | |
1562 } | |
1563 } | |
1564 | |
1565 protected String genHTMLListForKlassNames(InstanceKlass[] klasses) { | |
1566 final Formatter buf = new Formatter(genHTML); | |
1567 buf.beginTable(0); | |
1568 for (int i = 0; i < klasses.length; i++) { | |
1569 InstanceKlass ik = klasses[i]; | |
1570 buf.beginTag("tr"); | |
1571 buf.cell(genKlassLink(ik)); | |
1572 buf.endTag("tr"); | |
1573 } | |
1574 | |
1575 buf.endTable(); | |
1576 return buf.toString(); | |
1577 } | |
1578 | |
1579 public String genHTMLForMethodNames(InstanceKlass klass) { | |
1580 try { | |
1581 Formatter buf = new Formatter(genHTML); | |
1582 buf.genHTMLPrologue(); | |
1583 buf.append(genHTMLListForMethods(klass)); | |
1584 buf.genHTMLEpilogue(); | |
1585 return buf.toString(); | |
1586 } catch (Exception exp) { | |
1587 return genHTMLErrorMessage(exp); | |
1588 } | |
1589 } | |
1590 | |
1591 protected String genHTMLListForMethods(InstanceKlass klass) { | |
1592 Formatter buf = new Formatter(genHTML); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1593 MethodArray methods = klass.getMethods(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1594 int numMethods = methods.length(); |
0 | 1595 if (numMethods != 0) { |
1596 buf.h3("Methods"); | |
1597 buf.beginTag("ul"); | |
1598 for (int m = 0; m < numMethods; m++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1599 Method mtd = methods.at(m); |
0 | 1600 buf.li(genMethodLink(mtd) + ";"); |
1601 } | |
1602 buf.endTag("ul"); | |
1603 } | |
1604 return buf.toString(); | |
1605 } | |
1606 | |
1607 protected String genHTMLListForInterfaces(InstanceKlass klass) { | |
1608 try { | |
1609 Formatter buf = new Formatter(genHTML); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1610 KlassArray interfaces = klass.getLocalInterfaces(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1611 int numInterfaces = interfaces.length(); |
0 | 1612 if (numInterfaces != 0) { |
1613 buf.h3("Interfaces"); | |
1614 buf.beginTag("ul"); | |
1615 for (int i = 0; i < numInterfaces; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1616 InstanceKlass inf = (InstanceKlass) interfaces.getAt(i); |
0 | 1617 buf.li(genKlassLink(inf)); |
1618 } | |
1619 buf.endTag("ul"); | |
1620 } | |
1621 return buf.toString(); | |
1622 } catch (Exception exp) { | |
1623 return genHTMLErrorMessage(exp); | |
1624 } | |
1625 } | |
1626 | |
1627 protected String genFieldModifierString(AccessFlags acc) { | |
1628 Formatter buf = new Formatter(genHTML); | |
1629 if (acc.isPrivate()) { | |
1630 buf.append("private "); | |
1631 } else if (acc.isProtected()) { | |
1632 buf.append("protected "); | |
1633 } else if (acc.isPublic()) { | |
1634 buf.append("public "); | |
1635 } | |
1636 | |
1637 if (acc.isStatic()) { | |
1638 buf.append("static "); | |
1639 } | |
1640 | |
1641 if (acc.isFinal()) { | |
1642 buf.append("final "); | |
1643 } | |
1644 if (acc.isVolatile()) { | |
1645 buf.append("volatile "); | |
1646 } | |
1647 if (acc.isTransient()) { | |
1648 buf.append("transient "); | |
1649 } | |
1650 | |
1651 // javac generated flags | |
1652 if (acc.isSynthetic()) { | |
1653 buf.append("[synthetic] "); | |
1654 } | |
1655 return buf.toString(); | |
1656 } | |
1657 | |
1658 public String genHTMLForFieldNames(InstanceKlass klass) { | |
1659 try { | |
1660 Formatter buf = new Formatter(genHTML); | |
1661 buf.genHTMLPrologue(); | |
1662 buf.append(genHTMLListForFields(klass)); | |
1663 buf.genHTMLEpilogue(); | |
1664 return buf.toString(); | |
1665 } catch (Exception exp) { | |
1666 return genHTMLErrorMessage(exp); | |
1667 } | |
1668 } | |
1669 | |
1670 protected String genHTMLListForFields(InstanceKlass klass) { | |
1671 Formatter buf = new Formatter(genHTML); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1672 U2Array fields = klass.getFields(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1673 int numFields = klass.getAllFieldsCount(); |
0 | 1674 if (numFields != 0) { |
1675 buf.h3("Fields"); | |
1676 buf.beginList(); | |
3938 | 1677 for (int f = 0; f < numFields; f++) { |
1385 | 1678 sun.jvm.hotspot.oops.Field field = klass.getFieldByIndex(f); |
1679 String f_name = ((NamedFieldIdentifier)field.getID()).getName(); | |
1680 Symbol f_sig = field.getSignature(); | |
1681 Symbol f_genSig = field.getGenericSignature(); | |
1682 AccessFlags acc = field.getAccessFlagsObj(); | |
0 | 1683 |
1385 | 1684 buf.beginListItem(); |
0 | 1685 buf.append(genFieldModifierString(acc)); |
1686 buf.append(' '); | |
1687 Formatter sigBuf = new Formatter(genHTML); | |
1688 new SignatureConverter(f_sig, sigBuf.getBuffer()).dispatchField(); | |
1689 buf.append(sigBuf.toString().replace('/', '.')); | |
1690 buf.append(' '); | |
1385 | 1691 buf.append(f_name); |
0 | 1692 buf.append(';'); |
1693 // is it generic? | |
1694 if (f_genSig != null) { | |
1695 buf.append(" [signature "); | |
1696 buf.append(escapeHTMLSpecialChars(f_genSig.asString())); | |
1697 buf.append("] "); | |
1698 } | |
1385 | 1699 buf.append(" (offset = " + field.getOffset() + ")"); |
1700 buf.endListItem(); | |
0 | 1701 } |
1702 buf.endList(); | |
1703 } | |
1704 return buf.toString(); | |
1705 } | |
1706 | |
1707 protected String genKlassHierarchyHref(InstanceKlass klass) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1708 return genBaseHref() + "hierarchy=" + klass.getAddress(); |
0 | 1709 } |
1710 | |
1711 protected String genKlassHierarchyTitle(InstanceKlass klass) { | |
1712 Formatter buf = new Formatter(genHTML); | |
1713 buf.append("Class Hierarchy of "); | |
1714 buf.append(genKlassTitle(klass)); | |
1715 return buf.toString(); | |
1716 } | |
1717 | |
1718 protected String genKlassHierarchyLink(InstanceKlass klass) { | |
1719 Formatter buf = new Formatter(genHTML); | |
1720 buf.link(genKlassHierarchyHref(klass), genKlassHierarchyTitle(klass)); | |
1721 return buf.toString(); | |
1722 } | |
1723 | |
1724 protected String genHTMLListForSubKlasses(InstanceKlass klass) { | |
1725 Formatter buf = new Formatter(genHTML); | |
1726 Klass subklass = klass.getSubklassKlass(); | |
1727 if (subklass != null) { | |
1728 buf.beginList(); | |
1729 while (subklass != null) { | |
1730 if (subklass instanceof InstanceKlass) { | |
1731 buf.li(genKlassLink((InstanceKlass)subklass)); | |
1732 } | |
1733 subklass = subklass.getNextSiblingKlass(); | |
1734 } | |
1735 buf.endList(); | |
1736 } | |
1737 return buf.toString(); | |
1738 } | |
1739 | |
1740 public String genHTMLForKlassHierarchy(InstanceKlass klass) { | |
1741 Formatter buf = new Formatter(genHTML); | |
1742 buf.genHTMLPrologue(genKlassHierarchyTitle(klass)); | |
1743 | |
1744 | |
1745 buf.beginTag("pre"); | |
1746 buf.append(genKlassLink(klass)); | |
1747 buf.br(); | |
1748 StringBuffer tabs = new StringBuffer(tab); | |
1749 InstanceKlass superKlass = klass; | |
1750 while ( (superKlass = (InstanceKlass) superKlass.getSuper()) != null ) { | |
1751 buf.append(tabs); | |
1752 buf.append(genKlassLink(superKlass)); | |
1753 tabs.append(tab); | |
1754 buf.br(); | |
1755 } | |
1756 buf.endTag("pre"); | |
1757 | |
1758 // generate subklass list | |
1759 Klass subklass = klass.getSubklassKlass(); | |
1760 if (subklass != null) { | |
1761 buf.h3("Direct Subclasses"); | |
1762 buf.append(genHTMLListForSubKlasses(klass)); | |
1763 } | |
1764 | |
1765 buf.genHTMLEpilogue(); | |
1766 return buf.toString(); | |
1767 } | |
1768 | |
1769 protected String genDumpKlassHref(InstanceKlass klass) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1770 return genBaseHref() + "jcore=" + klass.getAddress(); |
0 | 1771 } |
1772 | |
1773 protected String genDumpKlassLink(InstanceKlass klass) { | |
1774 if (!genHTML) return ""; | |
1775 | |
1776 Formatter buf = new Formatter(genHTML); | |
1777 buf.link(genDumpKlassHref(klass), "Create .class File"); | |
1778 return buf.toString(); | |
1779 } | |
1780 | |
1781 public String genHTML(InstanceKlass klass) { | |
1782 Formatter buf = new Formatter(genHTML); | |
1783 buf.genHTMLPrologue(genKlassTitle(klass)); | |
1784 InstanceKlass superKlass = (InstanceKlass) klass.getSuper(); | |
1785 | |
1786 if (genHTML) { | |
1787 // super class tree and subclass list | |
1788 buf.beginTag("h3"); | |
1789 buf.link(genKlassHierarchyHref(klass), "View Class Hierarchy"); | |
1790 buf.endTag("h3"); | |
1791 } | |
1792 | |
1793 // jcore - create .class link | |
1794 buf.h3(genDumpKlassLink(klass)); | |
1795 | |
1796 // super class | |
1797 if (superKlass != null) { | |
1798 buf.h3("Super Class"); | |
1799 buf.append(genKlassLink(superKlass)); | |
1800 } | |
1801 | |
1802 // interfaces | |
1803 buf.append(genHTMLListForInterfaces(klass)); | |
1804 | |
1805 // fields | |
1806 buf.append(genHTMLListForFields(klass)); | |
1807 | |
1808 // methods | |
1809 buf.append(genHTMLListForMethods(klass)); | |
1810 | |
1811 // constant pool link | |
1812 buf.h3("Constant Pool"); | |
1813 buf.append(genConstantPoolLink(klass.getConstants())); | |
1814 | |
1815 buf.genHTMLEpilogue(); | |
1816 return buf.toString(); | |
1817 } | |
1818 | |
1819 protected sun.jvm.hotspot.debugger.Address parseAddress(String address) { | |
1820 VM vm = VM.getVM(); | |
1821 sun.jvm.hotspot.debugger.Address addr = vm.getDebugger().parseAddress(address); | |
1822 return addr; | |
1823 } | |
1824 | |
1825 protected long addressToLong(sun.jvm.hotspot.debugger.Address addr) { | |
1826 return VM.getVM().getDebugger().getAddressValue(addr); | |
1827 } | |
1828 | |
1829 protected sun.jvm.hotspot.debugger.Address longToAddress(long addr) { | |
1830 return parseAddress("0x" + Long.toHexString(addr)); | |
1831 } | |
1832 | |
1833 protected Oop getOopAtAddress(sun.jvm.hotspot.debugger.Address addr) { | |
1834 OopHandle oopHandle = addr.addOffsetToAsOopHandle(0); | |
1835 return VM.getVM().getObjectHeap().newOop(oopHandle); | |
1836 } | |
1837 | |
1838 protected Oop getOopAtAddress(String address) { | |
1839 sun.jvm.hotspot.debugger.Address addr = parseAddress(address); | |
1840 return getOopAtAddress(addr); | |
1841 } | |
1842 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1843 protected Klass getKlassAtAddress(String address) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1844 sun.jvm.hotspot.debugger.Address addr = parseAddress(address); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1845 return (Klass)Metadata.instantiateWrapperFor(addr); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1846 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1847 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1848 protected Method getMethodAtAddress(String address) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1849 sun.jvm.hotspot.debugger.Address addr = parseAddress(address); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1850 return (Method)Metadata.instantiateWrapperFor(addr); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1851 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1852 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1853 protected ConstantPool getConstantPoolAtAddress(String address) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1854 sun.jvm.hotspot.debugger.Address addr = parseAddress(address); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1855 return (ConstantPool) Metadata.instantiateWrapperFor(addr); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1856 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1857 |
0 | 1858 private void dumpKlass(InstanceKlass kls) throws IOException { |
1859 String klassName = kls.getName().asString(); | |
1860 klassName = klassName.replace('/', File.separatorChar); | |
1861 int index = klassName.lastIndexOf(File.separatorChar); | |
1862 File dir = null; | |
1863 if (index != -1) { | |
1864 String dirName = klassName.substring(0, index); | |
1865 dir = new File(DUMP_KLASS_OUTPUT_DIR, dirName); | |
1866 } else { | |
1867 dir = new File(DUMP_KLASS_OUTPUT_DIR); | |
1868 } | |
1869 | |
1870 dir.mkdirs(); | |
1871 File f = new File(dir, klassName.substring(klassName.lastIndexOf(File.separatorChar) + 1) | |
1872 + ".class"); | |
1873 f.createNewFile(); | |
1874 FileOutputStream fis = new FileOutputStream(f); | |
1875 ClassWriter cw = new ClassWriter(kls, fis); | |
1876 cw.write(); | |
1877 } | |
1878 | |
1879 public String genDumpKlass(InstanceKlass kls) { | |
1880 try { | |
1881 dumpKlass(kls); | |
1882 Formatter buf = new Formatter(genHTML); | |
1883 buf.genHTMLPrologue(genKlassTitle(kls)); | |
1884 buf.append(".class created for "); | |
1885 buf.append(genKlassLink(kls)); | |
1886 buf.genHTMLEpilogue(); | |
1887 return buf.toString(); | |
1888 } catch(IOException exp) { | |
1889 return genHTMLErrorMessage(exp); | |
1890 } | |
1891 } | |
1892 | |
1893 protected String genJavaStackTraceTitle(JavaThread thread) { | |
1894 Formatter buf = new Formatter(genHTML); | |
1895 buf.append("Java Stack Trace for "); | |
1896 buf.append(thread.getThreadName()); | |
1897 return buf.toString(); | |
1898 } | |
1899 | |
1900 public String genHTMLForJavaStackTrace(JavaThread thread) { | |
1901 Formatter buf = new Formatter(genHTML); | |
1902 buf.genHTMLPrologue(genJavaStackTraceTitle(thread)); | |
1903 | |
1904 buf.append("Thread state = "); | |
1905 buf.append(thread.getThreadState().toString()); | |
1906 buf.br(); | |
1907 buf.beginTag("pre"); | |
1908 for (JavaVFrame vf = thread.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) { | |
1909 Method method = vf.getMethod(); | |
1910 buf.append(" - "); | |
1911 buf.append(genMethodLink(method)); | |
1912 buf.append(" @bci = " + vf.getBCI()); | |
1913 | |
1914 int lineNumber = method.getLineNumberFromBCI(vf.getBCI()); | |
1915 if (lineNumber != -1) { | |
1916 buf.append(", line = "); | |
1917 buf.append(lineNumber); | |
1918 } | |
1919 | |
1920 sun.jvm.hotspot.debugger.Address pc = vf.getFrame().getPC(); | |
1921 if (pc != null) { | |
1922 buf.append(", pc = "); | |
1923 buf.link(genPCHref(addressToLong(pc)), pc.toString()); | |
1924 } | |
1925 | |
1926 if (vf.isCompiledFrame()) { | |
1927 buf.append(" (Compiled"); | |
1928 } | |
1929 else if (vf.isInterpretedFrame()) { | |
1930 buf.append(" (Interpreted"); | |
1931 } | |
1932 | |
1933 if (vf.mayBeImpreciseDbg()) { | |
1934 buf.append("; information may be imprecise"); | |
1935 } | |
1936 buf.append(")"); | |
1937 buf.br(); | |
1938 } | |
1939 | |
1940 buf.endTag("pre"); | |
1941 buf.genHTMLEpilogue(); | |
1942 return buf.toString(); | |
1943 } | |
1944 | |
1945 public String genHTMLForHyperlink(String href) { | |
1946 if (href.startsWith("klass=")) { | |
1947 href = href.substring(href.indexOf('=') + 1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1948 Klass k = getKlassAtAddress(href); |
0 | 1949 if (Assert.ASSERTS_ENABLED) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1950 Assert.that(k instanceof InstanceKlass, "class= href with improper InstanceKlass!"); |
0 | 1951 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1952 return genHTML((InstanceKlass) k); |
0 | 1953 } else if (href.startsWith("method=")) { |
1954 href = href.substring(href.indexOf('=') + 1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1955 Method obj = getMethodAtAddress(href); |
0 | 1956 if (Assert.ASSERTS_ENABLED) { |
1957 Assert.that(obj instanceof Method, "method= href with improper Method!"); | |
1958 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1959 return genHTML(obj); |
0 | 1960 } else if (href.startsWith("nmethod=")) { |
1961 String addr = href.substring(href.indexOf('=') + 1); | |
1962 Object obj = VMObjectFactory.newObject(NMethod.class, parseAddress(addr)); | |
1963 if (Assert.ASSERTS_ENABLED) { | |
1964 Assert.that(obj instanceof NMethod, "nmethod= href with improper NMethod!"); | |
1965 } | |
1966 return genHTML((NMethod) obj); | |
1967 } else if (href.startsWith("pc=")) { | |
1968 String address = href.substring(href.indexOf('=') + 1); | |
1969 return genHTML(parseAddress(address)); | |
1970 } else if (href.startsWith("pc_multiple=")) { | |
1971 int indexOfComma = href.indexOf(','); | |
1972 if (indexOfComma == -1) { | |
1973 String firstPC = href.substring(href.indexOf('=') + 1); | |
1974 return genHTMLForRawDisassembly(parseAddress(firstPC), null); | |
1975 } else { | |
1976 String firstPC = href.substring(href.indexOf('=') + 1, indexOfComma); | |
1977 return genHTMLForRawDisassembly(parseAddress(firstPC), href.substring(indexOfComma + 1)); | |
1978 } | |
1979 } else if (href.startsWith("interp_codelets")) { | |
1980 return genInterpreterCodeletLinksPage(); | |
1981 } else if (href.startsWith("hierarchy=")) { | |
1982 href = href.substring(href.indexOf('=') + 1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1983 Klass obj = getKlassAtAddress(href); |
0 | 1984 if (Assert.ASSERTS_ENABLED) { |
1985 Assert.that(obj instanceof InstanceKlass, "class= href with improper InstanceKlass!"); | |
1986 } | |
1987 return genHTMLForKlassHierarchy((InstanceKlass) obj); | |
1988 } else if (href.startsWith("cpool=")) { | |
1989 href = href.substring(href.indexOf('=') + 1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1990 ConstantPool obj = getConstantPoolAtAddress(href); |
0 | 1991 if (Assert.ASSERTS_ENABLED) { |
1992 Assert.that(obj instanceof ConstantPool, "cpool= href with improper ConstantPool!"); | |
1993 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1994 return genHTML(obj); |
0 | 1995 } else if (href.startsWith("jcore=")) { |
1996 href = href.substring(href.indexOf('=') + 1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
1997 Klass obj = getKlassAtAddress(href); |
0 | 1998 if (Assert.ASSERTS_ENABLED) { |
1999 Assert.that(obj instanceof InstanceKlass, "jcore= href with improper InstanceKlass!"); | |
2000 } | |
2001 return genDumpKlass((InstanceKlass) obj); | |
2002 } else if (href.startsWith("jcore_multiple=")) { | |
2003 href = href.substring(href.indexOf('=') + 1); | |
2004 Formatter buf = new Formatter(genHTML); | |
2005 buf.genHTMLPrologue(); | |
2006 StringTokenizer st = new StringTokenizer(href, ","); | |
2007 while (st.hasMoreTokens()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6641
diff
changeset
|
2008 Klass obj = getKlassAtAddress(st.nextToken()); |
0 | 2009 if (Assert.ASSERTS_ENABLED) { |
2010 Assert.that(obj instanceof InstanceKlass, "jcore_multiple= href with improper InstanceKlass!"); | |
2011 } | |
2012 | |
2013 InstanceKlass kls = (InstanceKlass) obj; | |
2014 try { | |
2015 dumpKlass(kls); | |
2016 buf.append(".class created for "); | |
2017 buf.append(genKlassLink(kls)); | |
2018 } catch(Exception exp) { | |
2019 buf.bold("can't .class for " + | |
2020 genKlassTitle(kls) + | |
2021 " : " + | |
2022 exp.getMessage()); | |
2023 } | |
2024 buf.br(); | |
2025 } | |
2026 | |
2027 buf.genHTMLEpilogue(); | |
2028 return buf.toString(); | |
2029 } else { | |
2030 if (Assert.ASSERTS_ENABLED) { | |
2031 Assert.that(false, "unknown href link!"); | |
2032 } | |
2033 return null; | |
2034 } | |
2035 } | |
2036 } |