265 } |
265 } |
266 } |
266 } |
267 |
267 |
268 |
268 |
269 methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool, |
269 methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool, |
270 int which, Bytecodes::Code invoke_code) { |
270 int which) { |
271 assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here"); |
271 assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here"); |
272 if (cpool->cache() == NULL) return NULL; // nothing to load yet |
272 if (cpool->cache() == NULL) return NULL; // nothing to load yet |
273 int cache_index = which - CPCACHE_INDEX_TAG; |
273 int cache_index = get_cpcache_index(which); |
274 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { |
274 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { |
275 if (PrintMiscellaneous && (Verbose||WizardMode)) { |
275 if (PrintMiscellaneous && (Verbose||WizardMode)) { |
276 tty->print_cr("bad operand %d for %d in:", which, invoke_code); cpool->print(); |
276 tty->print_cr("bad operand %d in:", which); cpool->print(); |
277 } |
277 } |
278 return NULL; |
278 return NULL; |
279 } |
279 } |
280 ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); |
280 ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index); |
281 if (invoke_code != Bytecodes::_illegal) |
281 return e->method_if_resolved(cpool); |
282 return e->get_method_if_resolved(invoke_code, cpool); |
282 } |
283 Bytecodes::Code bc; |
283 |
284 if ((bc = e->bytecode_1()) != (Bytecodes::Code)0) |
284 |
285 return e->get_method_if_resolved(bc, cpool); |
285 bool constantPoolOopDesc::has_appendix_at_if_loaded(constantPoolHandle cpool, int which) { |
286 if ((bc = e->bytecode_2()) != (Bytecodes::Code)0) |
286 if (cpool->cache() == NULL) return false; // nothing to load yet |
287 return e->get_method_if_resolved(bc, cpool); |
287 // XXX Is there a simpler way to get to the secondary entry? |
288 return NULL; |
288 ConstantPoolCacheEntry* e; |
|
289 if (constantPoolCacheOopDesc::is_secondary_index(which)) { |
|
290 e = cpool->cache()->secondary_entry_at(which); |
|
291 } else { |
|
292 int cache_index = get_cpcache_index(which); |
|
293 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { |
|
294 if (PrintMiscellaneous && (Verbose||WizardMode)) { |
|
295 tty->print_cr("bad operand %d in:", which); cpool->print(); |
|
296 } |
|
297 return false; |
|
298 } |
|
299 e = cpool->cache()->entry_at(cache_index); |
|
300 } |
|
301 return e->has_appendix(); |
|
302 } |
|
303 |
|
304 |
|
305 oop constantPoolOopDesc::appendix_at_if_loaded(constantPoolHandle cpool, int which) { |
|
306 if (cpool->cache() == NULL) return NULL; // nothing to load yet |
|
307 // XXX Is there a simpler way to get to the secondary entry? |
|
308 ConstantPoolCacheEntry* e; |
|
309 if (constantPoolCacheOopDesc::is_secondary_index(which)) { |
|
310 e = cpool->cache()->secondary_entry_at(which); |
|
311 } else { |
|
312 int cache_index = get_cpcache_index(which); |
|
313 if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) { |
|
314 if (PrintMiscellaneous && (Verbose||WizardMode)) { |
|
315 tty->print_cr("bad operand %d in:", which); cpool->print(); |
|
316 } |
|
317 return NULL; |
|
318 } |
|
319 e = cpool->cache()->entry_at(cache_index); |
|
320 } |
|
321 if (!e->has_appendix()) { |
|
322 return NULL; |
|
323 } |
|
324 return e->f1_as_instance(); |
289 } |
325 } |
290 |
326 |
291 |
327 |
292 Symbol* constantPoolOopDesc::impl_name_ref_at(int which, bool uncached) { |
328 Symbol* constantPoolOopDesc::impl_name_ref_at(int which, bool uncached) { |
293 int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached)); |
329 int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached)); |
479 assert(index == _no_index_sentinel || index >= 0, ""); |
515 assert(index == _no_index_sentinel || index >= 0, ""); |
480 |
516 |
481 if (cache_index >= 0) { |
517 if (cache_index >= 0) { |
482 assert(index == _no_index_sentinel, "only one kind of index at a time"); |
518 assert(index == _no_index_sentinel, "only one kind of index at a time"); |
483 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); |
519 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); |
484 result_oop = cpc_entry->f1(); |
520 result_oop = cpc_entry->f1_as_instance(); |
485 if (result_oop != NULL) { |
521 if (result_oop != NULL) { |
486 return decode_exception_from_f1(result_oop, THREAD); |
522 return decode_exception_from_f1(result_oop, THREAD); |
487 // That was easy... |
523 // That was easy... |
488 } |
524 } |
489 index = cpc_entry->constant_pool_index(); |
525 index = cpc_entry->constant_pool_index(); |
551 if (PrintMiscellaneous) |
587 if (PrintMiscellaneous) |
552 tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s", |
588 tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s", |
553 index, this_oop->method_type_index_at(index), |
589 index, this_oop->method_type_index_at(index), |
554 signature->as_C_string()); |
590 signature->as_C_string()); |
555 KlassHandle klass(THREAD, this_oop->pool_holder()); |
591 KlassHandle klass(THREAD, this_oop->pool_holder()); |
556 bool ignore_is_on_bcp = false; |
592 Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD); |
557 Handle value = SystemDictionary::find_method_handle_type(signature, |
|
558 klass, |
|
559 false, |
|
560 ignore_is_on_bcp, |
|
561 THREAD); |
|
562 if (HAS_PENDING_EXCEPTION) { |
593 if (HAS_PENDING_EXCEPTION) { |
563 throw_exception = Handle(THREAD, PENDING_EXCEPTION); |
594 throw_exception = Handle(THREAD, PENDING_EXCEPTION); |
564 CLEAR_PENDING_EXCEPTION; |
595 CLEAR_PENDING_EXCEPTION; |
565 break; |
596 break; |
566 } |
597 } |
606 } |
637 } |
607 Handle result_handle(THREAD, result_oop); |
638 Handle result_handle(THREAD, result_oop); |
608 result_oop = NULL; // safety |
639 result_oop = NULL; // safety |
609 ObjectLocker ol(this_oop, THREAD); |
640 ObjectLocker ol(this_oop, THREAD); |
610 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); |
641 ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); |
611 result_oop = cpc_entry->f1(); |
642 result_oop = cpc_entry->f1_as_instance(); |
612 // Benign race condition: f1 may already be filled in while we were trying to lock. |
643 // Benign race condition: f1 may already be filled in while we were trying to lock. |
613 // The important thing here is that all threads pick up the same result. |
644 // The important thing here is that all threads pick up the same result. |
614 // It doesn't matter which racing thread wins, as long as only one |
645 // It doesn't matter which racing thread wins, as long as only one |
615 // result is used by all threads, and all future queries. |
646 // result is used by all threads, and all future queries. |
616 // That result may be either a resolved constant or a failure exception. |
647 // That result may be either a resolved constant or a failure exception. |
623 if (throw_exception.not_null()) { |
654 if (throw_exception.not_null()) { |
624 THROW_HANDLE_(throw_exception, NULL); |
655 THROW_HANDLE_(throw_exception, NULL); |
625 } |
656 } |
626 return result_oop; |
657 return result_oop; |
627 } |
658 } |
|
659 } |
|
660 |
|
661 |
|
662 oop constantPoolOopDesc::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS) { |
|
663 assert(this_oop->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool"); |
|
664 |
|
665 Handle bsm; |
|
666 int argc; |
|
667 { |
|
668 // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments |
|
669 // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry. |
|
670 // It is accompanied by the optional arguments. |
|
671 int bsm_index = this_oop->invoke_dynamic_bootstrap_method_ref_index_at(index); |
|
672 oop bsm_oop = this_oop->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL); |
|
673 if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) { |
|
674 THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle"); |
|
675 } |
|
676 |
|
677 // Extract the optional static arguments. |
|
678 argc = this_oop->invoke_dynamic_argument_count_at(index); |
|
679 if (argc == 0) return bsm_oop; |
|
680 |
|
681 bsm = Handle(THREAD, bsm_oop); |
|
682 } |
|
683 |
|
684 objArrayHandle info; |
|
685 { |
|
686 objArrayOop info_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1+argc, CHECK_NULL); |
|
687 info = objArrayHandle(THREAD, info_oop); |
|
688 } |
|
689 |
|
690 info->obj_at_put(0, bsm()); |
|
691 for (int i = 0; i < argc; i++) { |
|
692 int arg_index = this_oop->invoke_dynamic_argument_index_at(index, i); |
|
693 oop arg_oop = this_oop->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL); |
|
694 info->obj_at_put(1+i, arg_oop); |
|
695 } |
|
696 |
|
697 return info(); |
628 } |
698 } |
629 |
699 |
630 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { |
700 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { |
631 oop str = NULL; |
701 oop str = NULL; |
632 CPSlot entry = this_oop->slot_at(which); |
702 CPSlot entry = this_oop->slot_at(which); |