1 /* |
1 /* |
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
37 // between critical sections. Use only pointer-comparison |
37 // between critical sections. Use only pointer-comparison |
38 // operations on the pointer, except within a critical section. |
38 // operations on the pointer, except within a critical section. |
39 // (Also, ensure that occasional false positives are benign.) |
39 // (Also, ensure that occasional false positives are benign.) |
40 methodOop _current_method; |
40 methodOop _current_method; |
41 bool _is_wide; |
41 bool _is_wide; |
|
42 Bytecodes::Code _code; |
42 address _next_pc; // current decoding position |
43 address _next_pc; // current decoding position |
43 |
44 |
44 void align() { _next_pc = (address)round_to((intptr_t)_next_pc, sizeof(jint)); } |
45 void align() { _next_pc = (address)round_to((intptr_t)_next_pc, sizeof(jint)); } |
45 int get_byte() { return *(jbyte*) _next_pc++; } // signed |
46 int get_byte() { return *(jbyte*) _next_pc++; } // signed |
46 short get_short() { short i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } |
47 short get_short() { short i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } |
47 int get_int() { int i=Bytes::get_Java_u4(_next_pc); _next_pc+=4; return i; } |
48 int get_int() { int i=Bytes::get_Java_u4(_next_pc); _next_pc+=4; return i; } |
48 |
49 |
49 int get_index() { return *(address)_next_pc++; } |
50 int get_index_u1() { return *(address)_next_pc++; } |
50 int get_big_index() { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } |
51 int get_index_u2() { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } |
51 int get_giant_index() { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; } |
52 int get_index_u2_cpcache() { int i=Bytes::get_native_u2(_next_pc); _next_pc+=2; return i + constantPoolOopDesc::CPCACHE_INDEX_TAG; } |
52 int get_index_special() { return (is_wide()) ? get_big_index() : get_index(); } |
53 int get_index_u4() { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; } |
|
54 int get_index_special() { return (is_wide()) ? get_index_u2() : get_index_u1(); } |
53 methodOop method() { return _current_method; } |
55 methodOop method() { return _current_method; } |
54 bool is_wide() { return _is_wide; } |
56 bool is_wide() { return _is_wide; } |
55 |
57 Bytecodes::Code raw_code() { return Bytecodes::Code(_code); } |
56 |
58 |
57 bool check_index(int i, bool in_cp_cache, int& cp_index, outputStream* st = tty); |
59 |
|
60 bool check_index(int i, int& cp_index, outputStream* st = tty); |
58 void print_constant(int i, outputStream* st = tty); |
61 void print_constant(int i, outputStream* st = tty); |
59 void print_field_or_method(int i, outputStream* st = tty); |
62 void print_field_or_method(int i, outputStream* st = tty); |
60 void print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty); |
63 void print_attributes(int bci, outputStream* st = tty); |
61 void bytecode_epilog(int bci, outputStream* st = tty); |
64 void bytecode_epilog(int bci, outputStream* st = tty); |
62 |
65 |
63 public: |
66 public: |
64 BytecodePrinter() { |
67 BytecodePrinter() { |
65 _is_wide = false; |
68 _is_wide = false; |
|
69 _code = Bytecodes::_illegal; |
66 } |
70 } |
67 |
71 |
68 // This method is called while executing the raw bytecodes, so none of |
72 // This method is called while executing the raw bytecodes, so none of |
69 // the adjustments that BytecodeStream performs applies. |
73 // the adjustments that BytecodeStream performs applies. |
70 void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) { |
74 void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) { |
87 // bcp wasn't advanced if previous bytecode was _wide. |
91 // bcp wasn't advanced if previous bytecode was _wide. |
88 code = Bytecodes::code_at(bcp+1); |
92 code = Bytecodes::code_at(bcp+1); |
89 } else { |
93 } else { |
90 code = Bytecodes::code_at(bcp); |
94 code = Bytecodes::code_at(bcp); |
91 } |
95 } |
92 int bci = bcp - method->code_base(); |
96 _code = code; |
|
97 int bci = bcp - method->code_base(); |
93 st->print("[%d] ", (int) Thread::current()->osthread()->thread_id()); |
98 st->print("[%d] ", (int) Thread::current()->osthread()->thread_id()); |
94 if (Verbose) { |
99 if (Verbose) { |
95 st->print("%8d %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s", |
100 st->print("%8d %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s", |
96 BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code)); |
101 BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code)); |
97 } else { |
102 } else { |
98 st->print("%8d %4d %s", |
103 st->print("%8d %4d %s", |
99 BytecodeCounter::counter_value(), bci, Bytecodes::name(code)); |
104 BytecodeCounter::counter_value(), bci, Bytecodes::name(code)); |
100 } |
105 } |
101 _next_pc = is_wide() ? bcp+2 : bcp+1; |
106 _next_pc = is_wide() ? bcp+2 : bcp+1; |
102 print_attributes(code, bci); |
107 print_attributes(bci); |
103 // Set is_wide for the next one, since the caller of this doesn't skip |
108 // Set is_wide for the next one, since the caller of this doesn't skip |
104 // the next bytecode. |
109 // the next bytecode. |
105 _is_wide = (code == Bytecodes::_wide); |
110 _is_wide = (code == Bytecodes::_wide); |
|
111 _code = Bytecodes::_illegal; |
106 } |
112 } |
107 |
113 |
108 // Used for methodOop::print_codes(). The input bcp comes from |
114 // Used for methodOop::print_codes(). The input bcp comes from |
109 // BytecodeStream, which will skip wide bytecodes. |
115 // BytecodeStream, which will skip wide bytecodes. |
110 void trace(methodHandle method, address bcp, outputStream* st) { |
116 void trace(methodHandle method, address bcp, outputStream* st) { |
114 // Set is_wide |
120 // Set is_wide |
115 _is_wide = (code == Bytecodes::_wide); |
121 _is_wide = (code == Bytecodes::_wide); |
116 if (is_wide()) { |
122 if (is_wide()) { |
117 code = Bytecodes::code_at(bcp+1); |
123 code = Bytecodes::code_at(bcp+1); |
118 } |
124 } |
|
125 _code = code; |
119 int bci = bcp - method->code_base(); |
126 int bci = bcp - method->code_base(); |
120 // Print bytecode index and name |
127 // Print bytecode index and name |
121 if (is_wide()) { |
128 if (is_wide()) { |
122 st->print("%d %s_w", bci, Bytecodes::name(code)); |
129 st->print("%d %s_w", bci, Bytecodes::name(code)); |
123 } else { |
130 } else { |
124 st->print("%d %s", bci, Bytecodes::name(code)); |
131 st->print("%d %s", bci, Bytecodes::name(code)); |
125 } |
132 } |
126 _next_pc = is_wide() ? bcp+2 : bcp+1; |
133 _next_pc = is_wide() ? bcp+2 : bcp+1; |
127 print_attributes(code, bci, st); |
134 print_attributes(bci, st); |
128 bytecode_epilog(bci, st); |
135 bytecode_epilog(bci, st); |
129 } |
136 } |
130 }; |
137 }; |
131 |
138 |
132 |
139 |
183 sym->print_on(st); st->cr(); |
190 sym->print_on(st); st->cr(); |
184 } |
191 } |
185 } |
192 } |
186 } |
193 } |
187 |
194 |
188 bool BytecodePrinter::check_index(int i, bool in_cp_cache, int& cp_index, outputStream* st) { |
195 bool BytecodePrinter::check_index(int i, int& cp_index, outputStream* st) { |
189 constantPoolOop constants = method()->constants(); |
196 constantPoolOop constants = method()->constants(); |
190 int ilimit = constants->length(), climit = 0; |
197 int ilimit = constants->length(), climit = 0; |
|
198 Bytecodes::Code code = raw_code(); |
191 |
199 |
192 constantPoolCacheOop cache = NULL; |
200 constantPoolCacheOop cache = NULL; |
193 if (in_cp_cache) { |
201 if (Bytecodes::uses_cp_cache(code)) { |
194 cache = constants->cache(); |
202 cache = constants->cache(); |
195 if (cache != NULL) { |
203 if (cache != NULL) { |
196 //climit = cache->length(); // %%% private! |
204 //climit = cache->length(); // %%% private! |
197 size_t size = cache->size() * HeapWordSize; |
205 size_t size = cache->size() * HeapWordSize; |
198 size -= sizeof(constantPoolCacheOopDesc); |
206 size -= sizeof(constantPoolCacheOopDesc); |
199 size /= sizeof(ConstantPoolCacheEntry); |
207 size /= sizeof(ConstantPoolCacheEntry); |
200 climit = (int) size; |
208 climit = (int) size; |
201 } |
209 } |
202 } |
210 } |
203 |
211 |
204 if (in_cp_cache && constantPoolCacheOopDesc::is_secondary_index(i)) { |
212 if (cache != NULL && constantPoolCacheOopDesc::is_secondary_index(i)) { |
205 i = constantPoolCacheOopDesc::decode_secondary_index(i); |
213 i = constantPoolCacheOopDesc::decode_secondary_index(i); |
206 st->print(" secondary cache[%d] of", i); |
214 st->print(" secondary cache[%d] of", i); |
207 if (i >= 0 && i < climit) { |
215 if (i >= 0 && i < climit) { |
208 if (!cache->entry_at(i)->is_secondary_entry()) { |
216 if (!cache->entry_at(i)->is_secondary_entry()) { |
209 st->print_cr(" not secondary entry?", i); |
217 st->print_cr(" not secondary entry?", i); |
301 symbolOop signature = constants->uncached_signature_ref_at(i); |
318 symbolOop signature = constants->uncached_signature_ref_at(i); |
302 st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); |
319 st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); |
303 } |
320 } |
304 |
321 |
305 |
322 |
306 void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci, outputStream* st) { |
323 void BytecodePrinter::print_attributes(int bci, outputStream* st) { |
307 // Show attributes of pre-rewritten codes |
324 // Show attributes of pre-rewritten codes |
308 code = Bytecodes::java_code(code); |
325 Bytecodes::Code code = Bytecodes::java_code(raw_code()); |
309 // If the code doesn't have any fields there's nothing to print. |
326 // If the code doesn't have any fields there's nothing to print. |
310 // note this is ==1 because the tableswitch and lookupswitch are |
327 // note this is ==1 because the tableswitch and lookupswitch are |
311 // zero size (for some reason) and we want to print stuff out for them. |
328 // zero size (for some reason) and we want to print stuff out for them. |
312 if (Bytecodes::length_for(code) == 1) { |
329 if (Bytecodes::length_for(code) == 1) { |
313 st->cr(); |
330 st->cr(); |
321 break; |
338 break; |
322 case Bytecodes::_sipush: |
339 case Bytecodes::_sipush: |
323 st->print_cr(" " INT32_FORMAT, get_short()); |
340 st->print_cr(" " INT32_FORMAT, get_short()); |
324 break; |
341 break; |
325 case Bytecodes::_ldc: |
342 case Bytecodes::_ldc: |
326 print_constant(get_index(), st); |
343 print_constant(get_index_u1(), st); |
327 break; |
344 break; |
328 |
345 |
329 case Bytecodes::_ldc_w: |
346 case Bytecodes::_ldc_w: |
330 case Bytecodes::_ldc2_w: |
347 case Bytecodes::_ldc2_w: |
331 print_constant(get_big_index(), st); |
348 print_constant(get_index_u2(), st); |
332 break; |
349 break; |
333 |
350 |
334 case Bytecodes::_iload: |
351 case Bytecodes::_iload: |
335 case Bytecodes::_lload: |
352 case Bytecodes::_lload: |
336 case Bytecodes::_fload: |
353 case Bytecodes::_fload: |
350 st->print_cr(" #%d " INT32_FORMAT, index, offset); |
367 st->print_cr(" #%d " INT32_FORMAT, index, offset); |
351 } |
368 } |
352 break; |
369 break; |
353 |
370 |
354 case Bytecodes::_newarray: { |
371 case Bytecodes::_newarray: { |
355 BasicType atype = (BasicType)get_index(); |
372 BasicType atype = (BasicType)get_index_u1(); |
356 const char* str = type2name(atype); |
373 const char* str = type2name(atype); |
357 if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) { |
374 if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) { |
358 assert(false, "Unidentified basic type"); |
375 assert(false, "Unidentified basic type"); |
359 } |
376 } |
360 st->print_cr(" %s", str); |
377 st->print_cr(" %s", str); |
361 } |
378 } |
362 break; |
379 break; |
363 case Bytecodes::_anewarray: { |
380 case Bytecodes::_anewarray: { |
364 int klass_index = get_big_index(); |
381 int klass_index = get_index_u2(); |
365 constantPoolOop constants = method()->constants(); |
382 constantPoolOop constants = method()->constants(); |
366 symbolOop name = constants->klass_name_at(klass_index); |
383 symbolOop name = constants->klass_name_at(klass_index); |
367 st->print_cr(" %s ", name->as_C_string()); |
384 st->print_cr(" %s ", name->as_C_string()); |
368 } |
385 } |
369 break; |
386 break; |
370 case Bytecodes::_multianewarray: { |
387 case Bytecodes::_multianewarray: { |
371 int klass_index = get_big_index(); |
388 int klass_index = get_index_u2(); |
372 int nof_dims = get_index(); |
389 int nof_dims = get_index_u1(); |
373 constantPoolOop constants = method()->constants(); |
390 constantPoolOop constants = method()->constants(); |
374 symbolOop name = constants->klass_name_at(klass_index); |
391 symbolOop name = constants->klass_name_at(klass_index); |
375 st->print_cr(" %s %d", name->as_C_string(), nof_dims); |
392 st->print_cr(" %s %d", name->as_C_string(), nof_dims); |
376 } |
393 } |
377 break; |
394 break; |
449 |
466 |
450 case Bytecodes::_putstatic: |
467 case Bytecodes::_putstatic: |
451 case Bytecodes::_getstatic: |
468 case Bytecodes::_getstatic: |
452 case Bytecodes::_putfield: |
469 case Bytecodes::_putfield: |
453 case Bytecodes::_getfield: |
470 case Bytecodes::_getfield: |
454 print_field_or_method(get_big_index(), st); |
471 print_field_or_method(get_index_u2_cpcache(), st); |
455 break; |
472 break; |
456 |
473 |
457 case Bytecodes::_invokevirtual: |
474 case Bytecodes::_invokevirtual: |
458 case Bytecodes::_invokespecial: |
475 case Bytecodes::_invokespecial: |
459 case Bytecodes::_invokestatic: |
476 case Bytecodes::_invokestatic: |
460 print_field_or_method(get_big_index(), st); |
477 print_field_or_method(get_index_u2_cpcache(), st); |
461 break; |
478 break; |
462 |
479 |
463 case Bytecodes::_invokeinterface: |
480 case Bytecodes::_invokeinterface: |
464 { int i = get_big_index(); |
481 { int i = get_index_u2_cpcache(); |
465 int n = get_index(); |
482 int n = get_index_u1(); |
466 get_index(); // ignore zero byte |
483 get_byte(); // ignore zero byte |
467 print_field_or_method(i, st); |
484 print_field_or_method(i, st); |
468 } |
485 } |
469 break; |
486 break; |
470 |
487 |
471 case Bytecodes::_invokedynamic: |
488 case Bytecodes::_invokedynamic: |
472 print_field_or_method(get_giant_index(), st); |
489 print_field_or_method(get_index_u4(), st); |
473 break; |
490 break; |
474 |
491 |
475 case Bytecodes::_new: |
492 case Bytecodes::_new: |
476 case Bytecodes::_checkcast: |
493 case Bytecodes::_checkcast: |
477 case Bytecodes::_instanceof: |
494 case Bytecodes::_instanceof: |
478 { int i = get_big_index(); |
495 { int i = get_index_u2(); |
479 constantPoolOop constants = method()->constants(); |
496 constantPoolOop constants = method()->constants(); |
480 symbolOop name = constants->klass_name_at(i); |
497 symbolOop name = constants->klass_name_at(i); |
481 st->print_cr(" %d <%s>", i, name->as_C_string()); |
498 st->print_cr(" %d <%s>", i, name->as_C_string()); |
482 } |
499 } |
483 break; |
500 break; |