Mercurial > hg > truffle
annotate src/share/vm/compiler/disassembler.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | b9a918201d47 |
children | d8041d695d19 |
rev | line source |
---|---|
7066 | 1 /* |
2 * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. | |
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 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 #include "precompiled.hpp" | |
26 #include "classfile/javaClasses.hpp" | |
27 #include "code/codeCache.hpp" | |
28 #include "compiler/disassembler.hpp" | |
29 #include "gc_interface/collectedHeap.hpp" | |
30 #include "memory/cardTableModRefBS.hpp" | |
31 #include "runtime/fprofiler.hpp" | |
32 #include "runtime/handles.inline.hpp" | |
33 #include "runtime/stubCodeGenerator.hpp" | |
34 #include "runtime/stubRoutines.hpp" | |
35 #ifdef TARGET_ARCH_x86 | |
36 # include "depChecker_x86.hpp" | |
37 #endif | |
38 #ifdef TARGET_ARCH_sparc | |
39 # include "depChecker_sparc.hpp" | |
40 #endif | |
41 #ifdef TARGET_ARCH_zero | |
42 # include "depChecker_zero.hpp" | |
43 #endif | |
44 #ifdef TARGET_ARCH_arm | |
45 # include "depChecker_arm.hpp" | |
46 #endif | |
47 #ifdef TARGET_ARCH_ppc | |
48 # include "depChecker_ppc.hpp" | |
49 #endif | |
50 #ifdef SHARK | |
51 #include "shark/sharkEntry.hpp" | |
52 #endif | |
53 | |
54 void* Disassembler::_library = NULL; | |
55 bool Disassembler::_tried_to_load_library = false; | |
56 | |
57 // This routine is in the shared library: | |
58 Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL; | |
59 Disassembler::decode_func Disassembler::_decode_instructions = NULL; | |
60 | |
61 static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH; | |
62 static const char decode_instructions_virtual_name[] = "decode_instructions_virtual"; | |
63 static const char decode_instructions_name[] = "decode_instructions"; | |
64 static bool use_new_version = true; | |
65 #define COMMENT_COLUMN 40 LP64_ONLY(+8) /*could be an option*/ | |
66 #define BYTES_COMMENT ";..." /* funky byte display comment */ | |
67 | |
68 bool Disassembler::load_library() { | |
69 if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) { | |
70 // Already succeeded. | |
71 return true; | |
72 } | |
73 if (_tried_to_load_library) { | |
74 // Do not try twice. | |
75 // To force retry in debugger: assign _tried_to_load_library=0 | |
76 return false; | |
77 } | |
78 // Try to load it. | |
79 char ebuf[1024]; | |
80 char buf[JVM_MAXPATHLEN]; | |
81 os::jvm_path(buf, sizeof(buf)); | |
82 int jvm_offset = -1; | |
83 int lib_offset = -1; | |
84 { | |
85 // Match "jvm[^/]*" in jvm_path. | |
86 const char* base = buf; | |
87 const char* p = strrchr(buf, '/'); | |
88 if (p != NULL) lib_offset = p - base + 1; | |
89 p = strstr(p ? p : base, "jvm"); | |
90 if (p != NULL) jvm_offset = p - base; | |
91 } | |
92 // Find the disassembler shared library. | |
93 // Search for several paths derived from libjvm, in this order: | |
94 // 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so (for compatibility) | |
95 // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so | |
96 // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so | |
97 // 4. hsdis-<arch>.so (using LD_LIBRARY_PATH) | |
98 if (jvm_offset >= 0) { | |
99 // 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so | |
100 strcpy(&buf[jvm_offset], hsdis_library_name); | |
101 strcat(&buf[jvm_offset], os::dll_file_extension()); | |
102 _library = os::dll_load(buf, ebuf, sizeof ebuf); | |
103 if (_library == NULL) { | |
104 // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so | |
105 strcpy(&buf[lib_offset], hsdis_library_name); | |
106 strcat(&buf[lib_offset], os::dll_file_extension()); | |
107 _library = os::dll_load(buf, ebuf, sizeof ebuf); | |
108 } | |
109 if (_library == NULL) { | |
110 // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so | |
111 buf[lib_offset - 1] = '\0'; | |
112 const char* p = strrchr(buf, '/'); | |
113 if (p != NULL) { | |
114 lib_offset = p - buf + 1; | |
115 strcpy(&buf[lib_offset], hsdis_library_name); | |
116 strcat(&buf[lib_offset], os::dll_file_extension()); | |
117 _library = os::dll_load(buf, ebuf, sizeof ebuf); | |
118 } | |
119 } | |
120 } | |
121 if (_library == NULL) { | |
122 // 4. hsdis-<arch>.so (using LD_LIBRARY_PATH) | |
123 strcpy(&buf[0], hsdis_library_name); | |
124 strcat(&buf[0], os::dll_file_extension()); | |
125 _library = os::dll_load(buf, ebuf, sizeof ebuf); | |
126 } | |
127 if (_library != NULL) { | |
128 _decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual, | |
129 os::dll_lookup(_library, decode_instructions_virtual_name)); | |
130 } | |
131 if (_decode_instructions_virtual == NULL) { | |
132 // could not spot in new version, try old version | |
133 _decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func, | |
134 os::dll_lookup(_library, decode_instructions_name)); | |
135 use_new_version = false; | |
136 } else { | |
137 use_new_version = true; | |
138 } | |
139 _tried_to_load_library = true; | |
140 if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) { | |
141 tty->print_cr("Could not load %s; %s; %s", buf, | |
142 ((_library != NULL) | |
143 ? "entry point is missing" | |
144 : (WizardMode || PrintMiscellaneous) | |
145 ? (const char*)ebuf | |
146 : "library not loadable"), | |
147 "PrintAssembly is disabled"); | |
148 return false; | |
149 } | |
150 | |
151 // Success. | |
152 tty->print_cr("Loaded disassembler from %s", buf); | |
153 return true; | |
154 } | |
155 | |
156 | |
157 class decode_env { | |
158 private: | |
159 nmethod* _nm; | |
160 CodeBlob* _code; | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6983
diff
changeset
|
161 CodeStrings _strings; |
7066 | 162 outputStream* _output; |
163 address _start, _end; | |
164 | |
165 char _option_buf[512]; | |
166 char _print_raw; | |
167 bool _print_pc; | |
168 bool _print_bytes; | |
169 address _cur_insn; | |
170 int _total_ticks; | |
171 int _bytes_per_line; // arch-specific formatting option | |
172 | |
173 static bool match(const char* event, const char* tag) { | |
174 size_t taglen = strlen(tag); | |
175 if (strncmp(event, tag, taglen) != 0) | |
176 return false; | |
177 char delim = event[taglen]; | |
178 return delim == '\0' || delim == ' ' || delim == '/' || delim == '='; | |
179 } | |
180 | |
181 void collect_options(const char* p) { | |
182 if (p == NULL || p[0] == '\0') return; | |
183 size_t opt_so_far = strlen(_option_buf); | |
184 if (opt_so_far + 1 + strlen(p) + 1 > sizeof(_option_buf)) return; | |
185 char* fillp = &_option_buf[opt_so_far]; | |
186 if (opt_so_far > 0) *fillp++ = ','; | |
187 strcat(fillp, p); | |
188 // replace white space by commas: | |
189 char* q = fillp; | |
190 while ((q = strpbrk(q, " \t\n")) != NULL) | |
191 *q++ = ','; | |
192 // Note that multiple PrintAssemblyOptions flags accumulate with \n, | |
193 // which we want to be changed to a comma... | |
194 } | |
195 | |
196 void print_insn_labels(); | |
197 void print_insn_bytes(address pc0, address pc); | |
198 void print_address(address value); | |
199 | |
200 public: | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6983
diff
changeset
|
201 decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings()); |
7066 | 202 |
203 address decode_instructions(address start, address end); | |
204 | |
205 void start_insn(address pc) { | |
206 _cur_insn = pc; | |
207 output()->bol(); | |
208 print_insn_labels(); | |
209 } | |
210 | |
211 void end_insn(address pc) { | |
212 address pc0 = cur_insn(); | |
213 outputStream* st = output(); | |
214 if (_print_bytes && pc > pc0) | |
215 print_insn_bytes(pc0, pc); | |
216 if (_nm != NULL) { | |
217 _nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc); | |
218 // this calls reloc_string_for which calls oop::print_value_on | |
219 } | |
220 | |
221 // Output pc bucket ticks if we have any | |
222 if (total_ticks() != 0) { | |
223 address bucket_pc = FlatProfiler::bucket_start_for(pc); | |
224 if (bucket_pc != NULL && bucket_pc > pc0 && bucket_pc <= pc) { | |
225 int bucket_count = FlatProfiler::bucket_count_for(pc0); | |
226 if (bucket_count != 0) { | |
227 st->bol(); | |
228 st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count); | |
229 } | |
230 } | |
231 } | |
232 // follow each complete insn by a nice newline | |
233 st->cr(); | |
234 } | |
235 | |
236 address handle_event(const char* event, address arg); | |
237 | |
238 outputStream* output() { return _output; } | |
239 address cur_insn() { return _cur_insn; } | |
240 int total_ticks() { return _total_ticks; } | |
241 void set_total_ticks(int n) { _total_ticks = n; } | |
242 const char* options() { return _option_buf; } | |
243 }; | |
244 | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6983
diff
changeset
|
245 decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) { |
7066 | 246 memset(this, 0, sizeof(*this)); |
247 _output = output ? output : tty; | |
248 _code = code; | |
249 if (code != NULL && code->is_nmethod()) | |
250 _nm = (nmethod*) code; | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6983
diff
changeset
|
251 _strings.assign(c); |
7066 | 252 |
253 // by default, output pc but not bytes: | |
254 _print_pc = true; | |
255 _print_bytes = false; | |
256 _bytes_per_line = Disassembler::pd_instruction_alignment(); | |
257 | |
258 // parse the global option string: | |
259 collect_options(Disassembler::pd_cpu_opts()); | |
260 collect_options(PrintAssemblyOptions); | |
261 | |
262 if (strstr(options(), "hsdis-")) { | |
263 if (strstr(options(), "hsdis-print-raw")) | |
264 _print_raw = (strstr(options(), "xml") ? 2 : 1); | |
265 if (strstr(options(), "hsdis-print-pc")) | |
266 _print_pc = !_print_pc; | |
267 if (strstr(options(), "hsdis-print-bytes")) | |
268 _print_bytes = !_print_bytes; | |
269 } | |
270 if (strstr(options(), "help")) { | |
271 tty->print_cr("PrintAssemblyOptions help:"); | |
272 tty->print_cr(" hsdis-print-raw test plugin by requesting raw output"); | |
273 tty->print_cr(" hsdis-print-raw-xml test plugin by requesting raw xml"); | |
274 tty->print_cr(" hsdis-print-pc turn off PC printing (on by default)"); | |
275 tty->print_cr(" hsdis-print-bytes turn on instruction byte output"); | |
276 tty->print_cr("combined options: %s", options()); | |
277 } | |
278 } | |
279 | |
280 address decode_env::handle_event(const char* event, address arg) { | |
281 if (match(event, "insn")) { | |
282 start_insn(arg); | |
283 } else if (match(event, "/insn")) { | |
284 end_insn(arg); | |
285 } else if (match(event, "addr")) { | |
286 if (arg != NULL) { | |
287 print_address(arg); | |
288 return arg; | |
289 } | |
290 } else if (match(event, "mach")) { | |
291 static char buffer[32] = { 0, }; | |
292 if (strcmp(buffer, (const char*)arg) != 0 || | |
293 strlen((const char*)arg) > sizeof(buffer) - 1) { | |
294 // Only print this when the mach changes | |
295 strncpy(buffer, (const char*)arg, sizeof(buffer) - 1); | |
296 output()->print_cr("[Disassembling for mach='%s']", arg); | |
297 } | |
298 } else if (match(event, "format bytes-per-line")) { | |
299 _bytes_per_line = (int) (intptr_t) arg; | |
300 } else { | |
301 // ignore unrecognized markup | |
302 } | |
303 return NULL; | |
304 } | |
305 | |
306 // called by the disassembler to print out jump targets and data addresses | |
307 void decode_env::print_address(address adr) { | |
308 outputStream* st = _output; | |
309 | |
310 if (adr == NULL) { | |
311 st->print("NULL"); | |
312 return; | |
313 } | |
314 | |
315 int small_num = (int)(intptr_t)adr; | |
316 if ((intptr_t)adr == (intptr_t)small_num | |
317 && -1 <= small_num && small_num <= 9) { | |
318 st->print("%d", small_num); | |
319 return; | |
320 } | |
321 | |
322 if (Universe::is_fully_initialized()) { | |
323 if (StubRoutines::contains(adr)) { | |
324 StubCodeDesc* desc = StubCodeDesc::desc_for(adr); | |
325 if (desc == NULL) | |
326 desc = StubCodeDesc::desc_for(adr + frame::pc_return_offset); | |
327 if (desc != NULL) { | |
328 st->print("Stub::%s", desc->name()); | |
329 if (desc->begin() != adr) | |
330 st->print("%+d 0x%p",adr - desc->begin(), adr); | |
331 else if (WizardMode) st->print(" " PTR_FORMAT, adr); | |
332 return; | |
333 } | |
334 st->print("Stub::<unknown> " PTR_FORMAT, adr); | |
335 return; | |
336 } | |
337 | |
338 BarrierSet* bs = Universe::heap()->barrier_set(); | |
339 if (bs->kind() == BarrierSet::CardTableModRef && | |
340 adr == (address)((CardTableModRefBS*)(bs))->byte_map_base) { | |
341 st->print("word_map_base"); | |
342 if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr); | |
343 return; | |
344 } | |
345 | |
346 oop obj; | |
347 if (_nm != NULL | |
348 && (obj = _nm->embeddedOop_at(cur_insn())) != NULL | |
349 && (address) obj == adr | |
350 && Universe::heap()->is_in(obj) | |
351 && Universe::heap()->is_in(obj->klass())) { | |
352 julong c = st->count(); | |
353 obj->print_value_on(st); | |
354 if (st->count() == c) { | |
355 // No output. (Can happen in product builds.) | |
356 st->print("(a %s)", obj->klass()->external_name()); | |
357 } | |
358 return; | |
359 } | |
360 } | |
361 | |
362 // Fall through to a simple (hexadecimal) numeral. | |
363 st->print(PTR_FORMAT, adr); | |
364 } | |
365 | |
366 void decode_env::print_insn_labels() { | |
367 address p = cur_insn(); | |
368 outputStream* st = output(); | |
369 CodeBlob* cb = _code; | |
370 if (cb != NULL) { | |
371 cb->print_block_comment(st, p); | |
372 } | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
6983
diff
changeset
|
373 _strings.print_block_comment(st, (intptr_t)(p - _start)); |
7066 | 374 if (_print_pc) { |
375 st->print(" " PTR_FORMAT ": ", p); | |
376 } | |
377 } | |
378 | |
379 void decode_env::print_insn_bytes(address pc, address pc_limit) { | |
380 outputStream* st = output(); | |
381 size_t incr = 1; | |
382 size_t perline = _bytes_per_line; | |
383 if ((size_t) Disassembler::pd_instruction_alignment() >= sizeof(int) | |
384 && !((uintptr_t)pc % sizeof(int)) | |
385 && !((uintptr_t)pc_limit % sizeof(int))) { | |
386 incr = sizeof(int); | |
387 if (perline % incr) perline += incr - (perline % incr); | |
388 } | |
389 while (pc < pc_limit) { | |
390 // tab to the desired column: | |
391 st->move_to(COMMENT_COLUMN); | |
392 address pc0 = pc; | |
393 address pc1 = pc + perline; | |
394 if (pc1 > pc_limit) pc1 = pc_limit; | |
395 for (; pc < pc1; pc += incr) { | |
396 if (pc == pc0) | |
397 st->print(BYTES_COMMENT); | |
398 else if ((uint)(pc - pc0) % sizeof(int) == 0) | |
399 st->print(" "); // put out a space on word boundaries | |
400 if (incr == sizeof(int)) | |
401 st->print("%08lx", *(int*)pc); | |
402 else st->print("%02x", (*pc)&0xFF); | |
403 } | |
404 st->cr(); | |
405 } | |
406 } | |
407 | |
408 | |
409 static void* event_to_env(void* env_pv, const char* event, void* arg) { | |
410 decode_env* env = (decode_env*) env_pv; | |
411 return env->handle_event(event, (address) arg); | |
412 } | |
413 | |
414 static int printf_to_env(void* env_pv, const char* format, ...) { | |
415 decode_env* env = (decode_env*) env_pv; | |
416 outputStream* st = env->output(); | |
417 size_t flen = strlen(format); | |
418 const char* raw = NULL; | |
419 if (flen == 0) return 0; | |
420 if (flen == 1 && format[0] == '\n') { st->bol(); return 1; } | |
421 if (flen < 2 || | |
422 strchr(format, '%') == NULL) { | |
423 raw = format; | |
424 } else if (format[0] == '%' && format[1] == '%' && | |
425 strchr(format+2, '%') == NULL) { | |
426 // happens a lot on machines with names like %foo | |
427 flen--; | |
428 raw = format+1; | |
429 } | |
430 if (raw != NULL) { | |
431 st->print_raw(raw, (int) flen); | |
432 return (int) flen; | |
433 } | |
434 va_list ap; | |
435 va_start(ap, format); | |
436 julong cnt0 = st->count(); | |
437 st->vprint(format, ap); | |
438 julong cnt1 = st->count(); | |
439 va_end(ap); | |
440 return (int)(cnt1 - cnt0); | |
441 } | |
442 | |
443 address decode_env::decode_instructions(address start, address end) { | |
444 _start = start; _end = end; | |
445 | |
446 assert(((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment()) == 0), "misaligned insn addr"); | |
447 | |
448 const int show_bytes = false; // for disassembler debugging | |
449 | |
450 //_version = Disassembler::pd_cpu_version(); | |
451 | |
452 if (!Disassembler::can_decode()) { | |
453 return NULL; | |
454 } | |
455 | |
456 // decode a series of instructions and return the end of the last instruction | |
457 | |
458 if (_print_raw) { | |
459 // Print whatever the library wants to print, w/o fancy callbacks. | |
460 // This is mainly for debugging the library itself. | |
461 FILE* out = stdout; | |
462 FILE* xmlout = (_print_raw > 1 ? out : NULL); | |
463 return use_new_version ? | |
464 (address) | |
465 (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, | |
466 start, end - start, | |
467 NULL, (void*) xmlout, | |
468 NULL, (void*) out, | |
469 options(), 0/*nice new line*/) | |
470 : | |
471 (address) | |
472 (*Disassembler::_decode_instructions)(start, end, | |
473 NULL, (void*) xmlout, | |
474 NULL, (void*) out, | |
475 options()); | |
476 } | |
477 | |
478 return use_new_version ? | |
479 (address) | |
480 (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, | |
481 start, end - start, | |
482 &event_to_env, (void*) this, | |
483 &printf_to_env, (void*) this, | |
484 options(), 0/*nice new line*/) | |
485 : | |
486 (address) | |
487 (*Disassembler::_decode_instructions)(start, end, | |
488 &event_to_env, (void*) this, | |
489 &printf_to_env, (void*) this, | |
490 options()); | |
491 } | |
492 | |
493 | |
494 void Disassembler::decode(CodeBlob* cb, outputStream* st) { | |
495 if (!load_library()) return; | |
496 decode_env env(cb, st); | |
497 env.output()->print_cr("----------------------------------------------------------------------"); | |
498 env.output()->print_cr("%s at [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", cb->name(), cb->code_begin(), cb->code_end(), ((jlong)(cb->code_end() - cb->code_begin())) * sizeof(unsigned char*)); | |
499 env.decode_instructions(cb->code_begin(), cb->code_end()); | |
500 } | |
501 | |
8883 | 502 void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) { |
7066 | 503 if (!load_library()) return; |
504 decode_env env(CodeCache::find_blob_unsafe(start), st, c); | |
505 env.decode_instructions(start, end); | |
506 } | |
507 | |
508 void Disassembler::decode(nmethod* nm, outputStream* st) { | |
509 if (!load_library()) return; | |
510 decode_env env(nm, st); | |
511 env.output()->print_cr("----------------------------------------------------------------------"); | |
512 | |
513 #ifdef SHARK | |
514 SharkEntry* entry = (SharkEntry *) nm->code_begin(); | |
515 unsigned char* p = entry->code_start(); | |
516 unsigned char* end = entry->code_limit(); | |
517 #else | |
518 unsigned char* p = nm->code_begin(); | |
519 unsigned char* end = nm->code_end(); | |
520 #endif // SHARK | |
521 | |
7067 | 522 nm->method()->method_holder()->name()->print_symbol_on(env.output()); |
7062
8c5333c80cfd
increased CompileThreshold to increase reliability of profiling information
Christian Haeubl <haeubl@ssw.jku.at>
parents:
3794
diff
changeset
|
523 env.output()->print("."); |
8c5333c80cfd
increased CompileThreshold to increase reliability of profiling information
Christian Haeubl <haeubl@ssw.jku.at>
parents:
3794
diff
changeset
|
524 nm->method()->name()->print_symbol_on(env.output()); |
7066 | 525 env.output()->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", p, end, ((jlong)(end - p)) * sizeof(unsigned char*)); |
526 | |
527 // If there has been profiling, print the buckets. | |
528 if (FlatProfiler::bucket_start_for(p) != NULL) { | |
529 unsigned char* p1 = p; | |
530 int total_bucket_count = 0; | |
531 while (p1 < end) { | |
532 unsigned char* p0 = p1; | |
533 p1 += pd_instruction_alignment(); | |
534 address bucket_pc = FlatProfiler::bucket_start_for(p1); | |
535 if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p1) | |
536 total_bucket_count += FlatProfiler::bucket_count_for(p0); | |
537 } | |
538 env.set_total_ticks(total_bucket_count); | |
539 } | |
540 | |
541 // Print constant table. | |
542 if (nm->consts_size() > 0) { | |
543 nm->print_nmethod_labels(env.output(), nm->consts_begin()); | |
544 int offset = 0; | |
545 for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) { | |
546 if ((offset % 8) == 0) { | |
547 env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT " " PTR64_FORMAT, p, offset, *((int32_t*) p), *((int64_t*) p)); | |
548 } else { | |
549 env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT, p, offset, *((int32_t*) p)); | |
550 } | |
551 } | |
552 } | |
553 | |
554 env.decode_instructions(p, end); | |
555 } |