2553 } |
2553 } |
2554 return call_site_oop; |
2554 return call_site_oop; |
2555 } |
2555 } |
2556 |
2556 |
2557 Handle SystemDictionary::find_bootstrap_method(methodHandle caller_method, int caller_bci, |
2557 Handle SystemDictionary::find_bootstrap_method(methodHandle caller_method, int caller_bci, |
2558 int cache_index, TRAPS) { |
2558 int cache_index, |
|
2559 Handle& argument_info_result, |
|
2560 TRAPS) { |
2559 Handle empty; |
2561 Handle empty; |
2560 |
2562 |
2561 constantPoolHandle pool; |
2563 constantPoolHandle pool; |
2562 { |
2564 { |
2563 klassOop caller = caller_method->method_holder(); |
2565 klassOop caller = caller_method->method_holder(); |
2567 |
2569 |
2568 int constant_pool_index = pool->cache()->entry_at(cache_index)->constant_pool_index(); |
2570 int constant_pool_index = pool->cache()->entry_at(cache_index)->constant_pool_index(); |
2569 constantTag tag = pool->tag_at(constant_pool_index); |
2571 constantTag tag = pool->tag_at(constant_pool_index); |
2570 |
2572 |
2571 if (tag.is_invoke_dynamic()) { |
2573 if (tag.is_invoke_dynamic()) { |
2572 // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type] |
2574 // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments |
2573 // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry. |
2575 // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry. |
2574 int bsm_index = pool->invoke_dynamic_bootstrap_method_ref_index_at(constant_pool_index); |
2576 int bsm_index = pool->invoke_dynamic_bootstrap_method_ref_index_at(constant_pool_index); |
2575 if (bsm_index != 0) { |
2577 if (bsm_index != 0) { |
2576 int bsm_index_in_cache = pool->cache()->entry_at(cache_index)->bootstrap_method_index_in_cache(); |
2578 int bsm_index_in_cache = pool->cache()->entry_at(cache_index)->bootstrap_method_index_in_cache(); |
2577 DEBUG_ONLY(int bsm_index_2 = pool->cache()->entry_at(bsm_index_in_cache)->constant_pool_index()); |
2579 DEBUG_ONLY(int bsm_index_2 = pool->cache()->entry_at(bsm_index_in_cache)->constant_pool_index()); |
2583 oop bsm_oop = pool->resolve_cached_constant_at(bsm_index_in_cache, CHECK_(empty)); |
2585 oop bsm_oop = pool->resolve_cached_constant_at(bsm_index_in_cache, CHECK_(empty)); |
2584 if (TraceMethodHandles) { |
2586 if (TraceMethodHandles) { |
2585 tty->print_cr("bootstrap method for "PTR_FORMAT" at %d retrieved as "PTR_FORMAT":", |
2587 tty->print_cr("bootstrap method for "PTR_FORMAT" at %d retrieved as "PTR_FORMAT":", |
2586 (intptr_t) caller_method(), caller_bci, (intptr_t) bsm_oop); |
2588 (intptr_t) caller_method(), caller_bci, (intptr_t) bsm_oop); |
2587 } |
2589 } |
2588 assert(bsm_oop->is_oop() |
2590 assert(bsm_oop->is_oop(), "must be sane"); |
2589 && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane"); |
2591 // caller must verify that it is of type MethodHandle |
2590 return Handle(THREAD, bsm_oop); |
2592 Handle bsm(THREAD, bsm_oop); |
|
2593 bsm_oop = NULL; // safety |
|
2594 |
|
2595 // Extract the optional static arguments. |
|
2596 Handle argument_info; // either null, or one arg, or Object[]{arg...} |
|
2597 int argc = pool->invoke_dynamic_argument_count_at(constant_pool_index); |
|
2598 if (TraceInvokeDynamic) { |
|
2599 tty->print_cr("find_bootstrap_method: [%d/%d] CONSTANT_InvokeDynamic: %d[%d]", |
|
2600 constant_pool_index, cache_index, bsm_index, argc); |
|
2601 } |
|
2602 if (argc > 0) { |
|
2603 objArrayHandle arg_array; |
|
2604 if (argc > 1) { |
|
2605 objArrayOop arg_array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), argc, CHECK_(empty)); |
|
2606 arg_array = objArrayHandle(THREAD, arg_array_oop); |
|
2607 argument_info = arg_array; |
|
2608 } |
|
2609 for (int arg_i = 0; arg_i < argc; arg_i++) { |
|
2610 int arg_index = pool->invoke_dynamic_argument_index_at(constant_pool_index, arg_i); |
|
2611 oop arg_oop = pool->resolve_possibly_cached_constant_at(arg_index, CHECK_(empty)); |
|
2612 if (arg_array.is_null()) { |
|
2613 argument_info = Handle(THREAD, arg_oop); |
|
2614 } else { |
|
2615 arg_array->obj_at_put(arg_i, arg_oop); |
|
2616 } |
|
2617 } |
|
2618 } |
|
2619 |
|
2620 argument_info_result = argument_info; // return argument_info to caller |
|
2621 return bsm; |
2591 } |
2622 } |
2592 // else null BSM; fall through |
2623 // else null BSM; fall through |
2593 } else if (tag.is_name_and_type()) { |
2624 } else if (tag.is_name_and_type()) { |
2594 // JSR 292 EDR does not have JVM_CONSTANT_InvokeDynamic |
2625 // JSR 292 EDR does not have JVM_CONSTANT_InvokeDynamic |
2595 // a bare name&type defaults its BSM to null, so fall through... |
2626 // a bare name&type defaults its BSM to null, so fall through... |
2598 } |
2629 } |
2599 |
2630 |
2600 // Fall through to pick up the per-class bootstrap method. |
2631 // Fall through to pick up the per-class bootstrap method. |
2601 // This mechanism may go away in the PFD. |
2632 // This mechanism may go away in the PFD. |
2602 assert(AllowTransitionalJSR292, "else the verifier should have stopped us already"); |
2633 assert(AllowTransitionalJSR292, "else the verifier should have stopped us already"); |
|
2634 argument_info_result = empty; // return no argument_info to caller |
2603 oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method(); |
2635 oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method(); |
2604 if (bsm_oop != NULL) { |
2636 if (bsm_oop != NULL) { |
2605 if (TraceMethodHandles) { |
2637 if (TraceMethodHandles) { |
2606 tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":", |
2638 tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":", |
2607 (intptr_t) caller_method(), (intptr_t) bsm_oop); |
2639 (intptr_t) caller_method(), (intptr_t) bsm_oop); |
2608 } |
2640 } |
2609 assert(bsm_oop->is_oop() |
2641 assert(bsm_oop->is_oop(), "must be sane"); |
2610 && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane"); |
|
2611 return Handle(THREAD, bsm_oop); |
2642 return Handle(THREAD, bsm_oop); |
2612 } |
2643 } |
2613 |
2644 |
2614 return empty; |
2645 return empty; |
2615 } |
2646 } |