comparison src/share/vm/classfile/systemDictionary.cpp @ 1660:083fde3b838e

6964498: JSR 292 invokedynamic sites need local bootstrap methods Summary: Add JVM_CONSTANT_InvokeDynamic records to constant pool to determine per-instruction BSMs. Reviewed-by: twisti
author jrose
date Thu, 15 Jul 2010 18:40:45 -0700
parents 136b78722a08
children d257356e35f0
comparison
equal deleted inserted replaced
1649:a528509c992b 1660:083fde3b838e
2505 Handle info, 2505 Handle info,
2506 methodHandle caller_method, 2506 methodHandle caller_method,
2507 int caller_bci, 2507 int caller_bci,
2508 TRAPS) { 2508 TRAPS) {
2509 Handle empty; 2509 Handle empty;
2510 guarantee(bootstrap_method.not_null() &&
2511 java_dyn_MethodHandle::is_instance(bootstrap_method()),
2512 "caller must supply a valid BSM");
2513
2510 Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty)); 2514 Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty));
2511 MethodHandles::init_MemberName(caller_mname(), caller_method()); 2515 MethodHandles::init_MemberName(caller_mname(), caller_method());
2512 2516
2513 // call sun.dyn.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos) 2517 // call sun.dyn.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos)
2514 oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle! 2518 oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle!
2535 #endif //PRODUCT 2539 #endif //PRODUCT
2536 } 2540 }
2537 return call_site_oop; 2541 return call_site_oop;
2538 } 2542 }
2539 2543
2540 Handle SystemDictionary::find_bootstrap_method(KlassHandle caller, TRAPS) { 2544 Handle SystemDictionary::find_bootstrap_method(methodHandle caller_method, int caller_bci,
2545 int cache_index, TRAPS) {
2541 Handle empty; 2546 Handle empty;
2542 if (!caller->oop_is_instance()) return empty; 2547
2543 2548 constantPoolHandle pool;
2544 instanceKlassHandle ik(THREAD, caller()); 2549 {
2545 2550 klassOop caller = caller_method->method_holder();
2546 oop boot_method_oop = ik->bootstrap_method(); 2551 if (!Klass::cast(caller)->oop_is_instance()) return empty;
2547 if (boot_method_oop != NULL) { 2552 pool = constantPoolHandle(THREAD, instanceKlass::cast(caller)->constants());
2553 }
2554
2555 int constant_pool_index = pool->cache()->entry_at(cache_index)->constant_pool_index();
2556 constantTag tag = pool->tag_at(constant_pool_index);
2557
2558 if (tag.is_invoke_dynamic()) {
2559 // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type]
2560 // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry.
2561 int bsm_index = pool->invoke_dynamic_bootstrap_method_ref_index_at(constant_pool_index);
2562 if (bsm_index != 0) {
2563 int bsm_index_in_cache = pool->cache()->entry_at(cache_index)->bootstrap_method_index_in_cache();
2564 DEBUG_ONLY(int bsm_index_2 = pool->cache()->entry_at(bsm_index_in_cache)->constant_pool_index());
2565 assert(bsm_index == bsm_index_2, "BSM constant lifted to cache");
2566 if (TraceMethodHandles) {
2567 tty->print_cr("resolving bootstrap method for "PTR_FORMAT" at %d at cache[%d]CP[%d]...",
2568 (intptr_t) caller_method(), caller_bci, cache_index, constant_pool_index);
2569 }
2570 oop bsm_oop = pool->resolve_cached_constant_at(bsm_index_in_cache, CHECK_(empty));
2571 if (TraceMethodHandles) {
2572 tty->print_cr("bootstrap method for "PTR_FORMAT" at %d retrieved as "PTR_FORMAT":",
2573 (intptr_t) caller_method(), caller_bci, (intptr_t) bsm_oop);
2574 }
2575 assert(bsm_oop->is_oop()
2576 && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane");
2577 return Handle(THREAD, bsm_oop);
2578 }
2579 // else null BSM; fall through
2580 } else if (tag.is_name_and_type()) {
2581 // JSR 292 EDR does not have JVM_CONSTANT_InvokeDynamic
2582 // a bare name&type defaults its BSM to null, so fall through...
2583 } else {
2584 ShouldNotReachHere(); // verifier does not allow this
2585 }
2586
2587 // Fall through to pick up the per-class bootstrap method.
2588 // This mechanism may go away in the PFD.
2589 assert(AllowTransitionalJSR292, "else the verifier should have stopped us already");
2590 oop bsm_oop = instanceKlass::cast(caller_method->method_holder())->bootstrap_method();
2591 if (bsm_oop != NULL) {
2548 if (TraceMethodHandles) { 2592 if (TraceMethodHandles) {
2549 tty->print_cr("bootstrap method for "PTR_FORMAT" cached as "PTR_FORMAT":", ik(), boot_method_oop); 2593 tty->print_cr("bootstrap method for "PTR_FORMAT" registered as "PTR_FORMAT":",
2550 } 2594 (intptr_t) caller_method(), (intptr_t) bsm_oop);
2551 assert(boot_method_oop->is_oop() 2595 }
2552 && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane"); 2596 assert(bsm_oop->is_oop()
2553 return Handle(THREAD, boot_method_oop); 2597 && java_dyn_MethodHandle::is_instance(bsm_oop), "must be sane");
2598 return Handle(THREAD, bsm_oop);
2554 } 2599 }
2555 2600
2556 return empty; 2601 return empty;
2557 } 2602 }
2558 2603