Mercurial > hg > truffle
comparison src/share/vm/interpreter/bytecodeTracer.cpp @ 726:be93aad57795
6655646: dynamic languages need dynamically linked call sites
Summary: invokedynamic instruction (JSR 292 RI)
Reviewed-by: twisti, never
author | jrose |
---|---|
date | Tue, 21 Apr 2009 23:21:04 -0700 |
parents | a61af66fc99e |
children | 3672e1dac765 |
comparison
equal
deleted
inserted
replaced
725:928912ce8438 | 726:be93aad57795 |
---|---|
46 short get_short() { short i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } | 46 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; } | 47 int get_int() { int i=Bytes::get_Java_u4(_next_pc); _next_pc+=4; return i; } |
48 | 48 |
49 int get_index() { return *(address)_next_pc++; } | 49 int get_index() { return *(address)_next_pc++; } |
50 int get_big_index() { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } | 50 int get_big_index() { 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; } | |
51 int get_index_special() { return (is_wide()) ? get_big_index() : get_index(); } | 52 int get_index_special() { return (is_wide()) ? get_big_index() : get_index(); } |
52 methodOop method() { return _current_method; } | 53 methodOop method() { return _current_method; } |
53 bool is_wide() { return _is_wide; } | 54 bool is_wide() { return _is_wide; } |
54 | 55 |
55 | 56 |
57 bool check_index(int i, bool in_cp_cache, int& cp_index, outputStream* st = tty); | |
56 void print_constant(int i, outputStream* st = tty); | 58 void print_constant(int i, outputStream* st = tty); |
59 void print_field_or_method(int i, outputStream* st = tty); | |
57 void print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty); | 60 void print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty); |
58 void bytecode_epilog(int bci, outputStream* st = tty); | 61 void bytecode_epilog(int bci, outputStream* st = tty); |
59 | 62 |
60 public: | 63 public: |
61 BytecodePrinter() { | 64 BytecodePrinter() { |
180 sym->print_on(st); st->cr(); | 183 sym->print_on(st); st->cr(); |
181 } | 184 } |
182 } | 185 } |
183 } | 186 } |
184 | 187 |
188 bool BytecodePrinter::check_index(int i, bool in_cp_cache, int& cp_index, outputStream* st) { | |
189 constantPoolOop constants = method()->constants(); | |
190 int ilimit = constants->length(), climit = 0; | |
191 | |
192 constantPoolCacheOop cache = NULL; | |
193 if (in_cp_cache) { | |
194 cache = constants->cache(); | |
195 if (cache != NULL) { | |
196 //climit = cache->length(); // %%% private! | |
197 size_t size = cache->size() * HeapWordSize; | |
198 size -= sizeof(constantPoolCacheOopDesc); | |
199 size /= sizeof(ConstantPoolCacheEntry); | |
200 climit = (int) size; | |
201 } | |
202 } | |
203 | |
204 if (in_cp_cache && constantPoolCacheOopDesc::is_secondary_index(i)) { | |
205 i = constantPoolCacheOopDesc::decode_secondary_index(i); | |
206 st->print(" secondary cache[%d] of", i); | |
207 if (i >= 0 && i < climit) { | |
208 if (!cache->entry_at(i)->is_secondary_entry()) { | |
209 st->print_cr(" not secondary entry?", i); | |
210 return false; | |
211 } | |
212 i = cache->entry_at(i)->main_entry_index(); | |
213 goto check_cache_index; | |
214 } else { | |
215 st->print_cr(" not in cache[*]?", i); | |
216 return false; | |
217 } | |
218 } | |
219 | |
220 if (cache != NULL) { | |
221 i = Bytes::swap_u2(i); | |
222 if (WizardMode) st->print(" (swap=%d)", i); | |
223 goto check_cache_index; | |
224 } | |
225 | |
226 check_cp_index: | |
227 if (i >= 0 && i < ilimit) { | |
228 if (WizardMode) st->print(" cp[%d]", i); | |
229 cp_index = i; | |
230 return true; | |
231 } | |
232 | |
233 st->print_cr(" CP[%d] not in CP", i); | |
234 return false; | |
235 | |
236 check_cache_index: | |
237 if (i >= 0 && i < climit) { | |
238 if (cache->entry_at(i)->is_secondary_entry()) { | |
239 st->print_cr(" secondary entry?"); | |
240 return false; | |
241 } | |
242 i = cache->entry_at(i)->constant_pool_index(); | |
243 goto check_cp_index; | |
244 } | |
245 st->print_cr(" not in CP[*]?", i); | |
246 return false; | |
247 } | |
248 | |
185 void BytecodePrinter::print_constant(int i, outputStream* st) { | 249 void BytecodePrinter::print_constant(int i, outputStream* st) { |
250 int orig_i = i; | |
251 if (!check_index(orig_i, false, i, st)) return; | |
252 | |
186 constantPoolOop constants = method()->constants(); | 253 constantPoolOop constants = method()->constants(); |
187 constantTag tag = constants->tag_at(i); | 254 constantTag tag = constants->tag_at(i); |
188 | 255 |
189 if (tag.is_int()) { | 256 if (tag.is_int()) { |
190 st->print_cr(" " INT32_FORMAT, constants->int_at(i)); | 257 st->print_cr(" " INT32_FORMAT, constants->int_at(i)); |
201 st->print_cr(" <unresolved string at %d>", i); | 268 st->print_cr(" <unresolved string at %d>", i); |
202 } else if (tag.is_klass()) { | 269 } else if (tag.is_klass()) { |
203 st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name()); | 270 st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name()); |
204 } else if (tag.is_unresolved_klass()) { | 271 } else if (tag.is_unresolved_klass()) { |
205 st->print_cr(" <unresolved klass at %d>", i); | 272 st->print_cr(" <unresolved klass at %d>", i); |
206 } else ShouldNotReachHere(); | 273 } else { |
274 st->print_cr(" bad tag=%d at %d", tag.value(), i); | |
275 } | |
276 } | |
277 | |
278 void BytecodePrinter::print_field_or_method(int i, outputStream* st) { | |
279 int orig_i = i; | |
280 if (!check_index(orig_i, true, i, st)) return; | |
281 | |
282 constantPoolOop constants = method()->constants(); | |
283 constantTag tag = constants->tag_at(i); | |
284 | |
285 switch (tag.value()) { | |
286 case JVM_CONSTANT_InterfaceMethodref: | |
287 case JVM_CONSTANT_Methodref: | |
288 case JVM_CONSTANT_Fieldref: | |
289 break; | |
290 default: | |
291 st->print_cr(" bad tag=%d at %d", tag.value(), i); | |
292 return; | |
293 } | |
294 | |
295 symbolOop name = constants->name_ref_at(orig_i); | |
296 symbolOop signature = constants->signature_ref_at(orig_i); | |
297 st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); | |
207 } | 298 } |
208 | 299 |
209 | 300 |
210 void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci, outputStream* st) { | 301 void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci, outputStream* st) { |
211 // Show attributes of pre-rewritten codes | 302 // Show attributes of pre-rewritten codes |
212 code = Bytecodes::java_code(code); | |
213 // If the code doesn't have any fields there's nothing to print. | 303 // If the code doesn't have any fields there's nothing to print. |
214 // note this is ==1 because the tableswitch and lookupswitch are | 304 // note this is ==1 because the tableswitch and lookupswitch are |
215 // zero size (for some reason) and we want to print stuff out for them. | 305 // zero size (for some reason) and we want to print stuff out for them. |
216 if (Bytecodes::length_for(code) == 1) { | 306 if (Bytecodes::length_for(code) == 1) { |
217 st->cr(); | 307 st->cr(); |
352 break; | 442 break; |
353 | 443 |
354 case Bytecodes::_putstatic: | 444 case Bytecodes::_putstatic: |
355 case Bytecodes::_getstatic: | 445 case Bytecodes::_getstatic: |
356 case Bytecodes::_putfield: | 446 case Bytecodes::_putfield: |
357 case Bytecodes::_getfield: { | 447 case Bytecodes::_getfield: |
358 int i = get_big_index(); | 448 print_field_or_method(get_big_index(), st); |
359 constantPoolOop constants = method()->constants(); | |
360 symbolOop field = constants->name_ref_at(i); | |
361 st->print_cr(" %d <%s>", i, field->as_C_string()); | |
362 } | |
363 break; | 449 break; |
364 | 450 |
365 case Bytecodes::_invokevirtual: | 451 case Bytecodes::_invokevirtual: |
366 case Bytecodes::_invokespecial: | 452 case Bytecodes::_invokespecial: |
367 case Bytecodes::_invokestatic: | 453 case Bytecodes::_invokestatic: |
368 { int i = get_big_index(); | 454 print_field_or_method(get_big_index(), st); |
369 constantPoolOop constants = method()->constants(); | |
370 symbolOop name = constants->name_ref_at(i); | |
371 symbolOop signature = constants->signature_ref_at(i); | |
372 st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); | |
373 } | |
374 break; | 455 break; |
375 | 456 |
376 case Bytecodes::_invokeinterface: | 457 case Bytecodes::_invokeinterface: |
377 { int i = get_big_index(); | 458 { int i = get_big_index(); |
378 int n = get_index(); | 459 int n = get_index(); |
379 get_index(); | 460 get_index(); // ignore zero byte |
380 constantPoolOop constants = method()->constants(); | 461 print_field_or_method(i, st); |
381 symbolOop name = constants->name_ref_at(i); | 462 } |
382 symbolOop signature = constants->signature_ref_at(i); | 463 break; |
383 st->print_cr(" %d <%s> <%s> %d", i, name->as_C_string(), signature->as_C_string(), n); | 464 |
384 } | 465 case Bytecodes::_invokedynamic: |
466 print_field_or_method(get_giant_index(), st); | |
385 break; | 467 break; |
386 | 468 |
387 case Bytecodes::_new: | 469 case Bytecodes::_new: |
388 case Bytecodes::_checkcast: | 470 case Bytecodes::_checkcast: |
389 case Bytecodes::_instanceof: | 471 case Bytecodes::_instanceof: |