2339 } |
2339 } |
2340 return NULL; |
2340 return NULL; |
2341 } |
2341 } |
2342 |
2342 |
2343 |
2343 |
2344 methodOop SystemDictionary::find_method_handle_invoke(symbolHandle signature, |
2344 methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name, |
|
2345 symbolHandle signature, |
2345 Handle class_loader, |
2346 Handle class_loader, |
2346 Handle protection_domain, |
2347 Handle protection_domain, |
2347 TRAPS) { |
2348 TRAPS) { |
2348 if (!EnableMethodHandles) return NULL; |
2349 if (!EnableMethodHandles) return NULL; |
2349 assert(class_loader.is_null() && protection_domain.is_null(), |
2350 assert(class_loader.is_null() && protection_domain.is_null(), |
2350 "cannot load specialized versions of MethodHandle.invoke"); |
2351 "cannot load specialized versions of MethodHandle.invoke"); |
2351 if (invoke_method_table() == NULL) { |
2352 if (invoke_method_table() == NULL) { |
2352 // create this side table lazily |
2353 // create this side table lazily |
2353 _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); |
2354 _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); |
2354 } |
2355 } |
2355 unsigned int hash = invoke_method_table()->compute_hash(signature); |
2356 vmSymbols::SID name_id = vmSymbols::find_sid(name()); |
|
2357 assert(name_id != vmSymbols::NO_SID, "must be a known name"); |
|
2358 unsigned int hash = invoke_method_table()->compute_hash(signature, name_id); |
2356 int index = invoke_method_table()->hash_to_index(hash); |
2359 int index = invoke_method_table()->hash_to_index(hash); |
2357 SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature); |
2360 SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, name_id); |
2358 if (spe == NULL || spe->property_oop() == NULL) { |
2361 if (spe == NULL || spe->property_oop() == NULL) { |
2359 // Must create lots of stuff here, but outside of the SystemDictionary lock. |
2362 // Must create lots of stuff here, but outside of the SystemDictionary lock. |
2360 if (THREAD->is_Compiler_thread()) |
2363 if (THREAD->is_Compiler_thread()) |
2361 return NULL; // do not attempt from within compiler |
2364 return NULL; // do not attempt from within compiler |
2362 Handle mt = compute_method_handle_type(signature(), |
2365 Handle mt = find_method_handle_type(signature(), |
2363 class_loader, protection_domain, |
2366 class_loader, protection_domain, |
2364 CHECK_NULL); |
2367 CHECK_NULL); |
2365 KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass(); |
2368 KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass(); |
2366 methodHandle m = methodOopDesc::make_invoke_method(mh_klass, signature, |
2369 methodHandle m = methodOopDesc::make_invoke_method(mh_klass, name, signature, |
2367 mt, CHECK_NULL); |
2370 mt, CHECK_NULL); |
2368 // Now grab the lock. We might have to throw away the new method, |
2371 // Now grab the lock. We might have to throw away the new method, |
2369 // if a racing thread has managed to install one at the same time. |
2372 // if a racing thread has managed to install one at the same time. |
2370 { |
2373 { |
2371 MutexLocker ml(SystemDictionary_lock, Thread::current()); |
2374 MutexLocker ml(SystemDictionary_lock, Thread::current()); |
2372 spe = invoke_method_table()->find_entry(index, hash, signature); |
2375 spe = invoke_method_table()->find_entry(index, hash, signature, name_id); |
2373 if (spe == NULL) |
2376 if (spe == NULL) |
2374 spe = invoke_method_table()->add_entry(index, hash, signature); |
2377 spe = invoke_method_table()->add_entry(index, hash, signature, name_id); |
2375 if (spe->property_oop() == NULL) |
2378 if (spe->property_oop() == NULL) |
2376 spe->set_property_oop(m()); |
2379 spe->set_property_oop(m()); |
2377 } |
2380 } |
2378 } |
2381 } |
2379 methodOop m = (methodOop) spe->property_oop(); |
2382 methodOop m = (methodOop) spe->property_oop(); |
2411 else |
2414 else |
2412 pts->obj_at_put(arg++, mirror); |
2415 pts->obj_at_put(arg++, mirror); |
2413 } |
2416 } |
2414 assert(arg == npts, ""); |
2417 assert(arg == npts, ""); |
2415 |
2418 |
2416 // call MethodType java.dyn.MethodType::makeImpl(Class rt, Class[] pts, false, true) |
2419 // call sun.dyn.MethodHandleNatives::findMethodType(Class rt, Class[] pts) -> MethodType |
2417 bool varargs = false, trusted = true; |
|
2418 JavaCallArguments args(Handle(THREAD, rt())); |
2420 JavaCallArguments args(Handle(THREAD, rt())); |
2419 args.push_oop(pts()); |
2421 args.push_oop(pts()); |
2420 args.push_int(false); |
|
2421 args.push_int(trusted); |
|
2422 JavaValue result(T_OBJECT); |
2422 JavaValue result(T_OBJECT); |
2423 JavaCalls::call_static(&result, |
2423 JavaCalls::call_static(&result, |
2424 SystemDictionary::MethodType_klass(), |
2424 SystemDictionary::MethodHandleNatives_klass(), |
2425 vmSymbols::makeImpl_name(), vmSymbols::makeImpl_signature(), |
2425 vmSymbols::findMethodHandleType_name(), |
|
2426 vmSymbols::findMethodHandleType_signature(), |
2426 &args, CHECK_(empty)); |
2427 &args, CHECK_(empty)); |
2427 return Handle(THREAD, (oop) result.get_jobject()); |
2428 return Handle(THREAD, (oop) result.get_jobject()); |
2428 } |
2429 } |
2429 |
2430 |
2430 |
2431 |
2431 // Ask Java code to find or construct a java.dyn.CallSite for the given |
2432 // Ask Java code to find or construct a java.dyn.CallSite for the given |
2432 // name and signature, as interpreted relative to the given class loader. |
2433 // name and signature, as interpreted relative to the given class loader. |
2433 Handle SystemDictionary::make_dynamic_call_site(KlassHandle caller, |
2434 Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method, |
2434 int caller_method_idnum, |
2435 symbolHandle name, |
|
2436 methodHandle signature_invoker, |
|
2437 Handle info, |
|
2438 methodHandle caller_method, |
2435 int caller_bci, |
2439 int caller_bci, |
2436 symbolHandle name, |
|
2437 methodHandle mh_invdyn, |
|
2438 TRAPS) { |
2440 TRAPS) { |
2439 Handle empty; |
2441 Handle empty; |
2440 // call java.dyn.CallSite::makeSite(caller, name, mtype, cmid, cbci) |
2442 Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty)); |
|
2443 MethodHandles::init_MemberName(caller_mname(), caller_method()); |
|
2444 |
|
2445 // call sun.dyn.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos) |
2441 oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle! |
2446 oop name_str_oop = StringTable::intern(name(), CHECK_(empty)); // not a handle! |
2442 JavaCallArguments args(Handle(THREAD, caller->java_mirror())); |
2447 JavaCallArguments args(Handle(THREAD, bootstrap_method())); |
2443 args.push_oop(name_str_oop); |
2448 args.push_oop(name_str_oop); |
2444 args.push_oop(mh_invdyn->method_handle_type()); |
2449 args.push_oop(signature_invoker->method_handle_type()); |
2445 args.push_int(caller_method_idnum); |
2450 args.push_oop(info()); |
|
2451 args.push_oop(caller_mname()); |
2446 args.push_int(caller_bci); |
2452 args.push_int(caller_bci); |
2447 JavaValue result(T_OBJECT); |
2453 JavaValue result(T_OBJECT); |
2448 JavaCalls::call_static(&result, |
2454 JavaCalls::call_static(&result, |
2449 SystemDictionary::CallSite_klass(), |
2455 SystemDictionary::MethodHandleNatives_klass(), |
2450 vmSymbols::makeSite_name(), vmSymbols::makeSite_signature(), |
2456 vmSymbols::makeDynamicCallSite_name(), |
|
2457 vmSymbols::makeDynamicCallSite_signature(), |
2451 &args, CHECK_(empty)); |
2458 &args, CHECK_(empty)); |
2452 oop call_site_oop = (oop) result.get_jobject(); |
2459 oop call_site_oop = (oop) result.get_jobject(); |
2453 assert(call_site_oop->is_oop() |
2460 assert(call_site_oop->is_oop() |
2454 /*&& java_dyn_CallSite::is_instance(call_site_oop)*/, "must be sane"); |
2461 /*&& java_dyn_CallSite::is_instance(call_site_oop)*/, "must be sane"); |
2455 java_dyn_CallSite::set_vmmethod(call_site_oop, mh_invdyn()); |
|
2456 if (TraceMethodHandles) { |
2462 if (TraceMethodHandles) { |
2457 #ifndef PRODUCT |
2463 #ifndef PRODUCT |
2458 tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop); |
2464 tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop); |
2459 call_site_oop->print(); |
2465 call_site_oop->print(); |
2460 tty->cr(); |
2466 tty->cr(); |
2461 #endif //PRODUCT |
2467 #endif //PRODUCT |
2462 } |
2468 } |
2463 return call_site_oop; |
2469 return call_site_oop; |
2464 } |
2470 } |
2465 |
2471 |
2466 Handle SystemDictionary::find_bootstrap_method(KlassHandle caller, |
2472 Handle SystemDictionary::find_bootstrap_method(KlassHandle caller, TRAPS) { |
2467 KlassHandle search_bootstrap_klass, |
|
2468 TRAPS) { |
|
2469 Handle empty; |
2473 Handle empty; |
2470 if (!caller->oop_is_instance()) return empty; |
2474 if (!caller->oop_is_instance()) return empty; |
2471 |
2475 |
2472 instanceKlassHandle ik(THREAD, caller()); |
2476 instanceKlassHandle ik(THREAD, caller()); |
2473 |
2477 |
2474 oop boot_method_oop = ik->bootstrap_method(); |
2478 oop boot_method_oop = ik->bootstrap_method(); |
2475 if (boot_method_oop != NULL) { |
2479 if (boot_method_oop != NULL) { |
2476 if (TraceMethodHandles) { |
2480 if (TraceMethodHandles) { |
2477 tty->print_cr("bootstrap method for "PTR_FORMAT" cached as "PTR_FORMAT":", ik(), boot_method_oop); |
2481 tty->print_cr("bootstrap method for "PTR_FORMAT" cached as "PTR_FORMAT":", ik(), boot_method_oop); |
2478 } |
2482 } |
2479 NOT_PRODUCT(if (!boot_method_oop->is_oop()) { tty->print_cr("*** boot MH of "PTR_FORMAT" = "PTR_FORMAT, ik(), boot_method_oop); ik()->print(); }); |
|
2480 assert(boot_method_oop->is_oop() |
2483 assert(boot_method_oop->is_oop() |
2481 && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane"); |
2484 && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane"); |
2482 return Handle(THREAD, boot_method_oop); |
2485 return Handle(THREAD, boot_method_oop); |
2483 } |
2486 } |
2484 boot_method_oop = NULL; // GC safety |
2487 |
2485 |
2488 return empty; |
2486 // call java.dyn.Linkage::findBootstrapMethod(caller, sbk) |
|
2487 JavaCallArguments args(Handle(THREAD, ik->java_mirror())); |
|
2488 if (search_bootstrap_klass.is_null()) |
|
2489 args.push_oop(Handle()); |
|
2490 else |
|
2491 args.push_oop(search_bootstrap_klass->java_mirror()); |
|
2492 JavaValue result(T_OBJECT); |
|
2493 JavaCalls::call_static(&result, |
|
2494 SystemDictionary::Linkage_klass(), |
|
2495 vmSymbols::findBootstrapMethod_name(), |
|
2496 vmSymbols::findBootstrapMethod_signature(), |
|
2497 &args, CHECK_(empty)); |
|
2498 boot_method_oop = (oop) result.get_jobject(); |
|
2499 |
|
2500 if (boot_method_oop != NULL) { |
|
2501 if (TraceMethodHandles) { |
|
2502 #ifndef PRODUCT |
|
2503 tty->print_cr("--------"); |
|
2504 tty->print_cr("bootstrap method for "PTR_FORMAT" computed as "PTR_FORMAT":", ik(), boot_method_oop); |
|
2505 ik()->print(); |
|
2506 boot_method_oop->print(); |
|
2507 tty->print_cr("========"); |
|
2508 #endif //PRODUCT |
|
2509 } |
|
2510 assert(boot_method_oop->is_oop() |
|
2511 && java_dyn_MethodHandle::is_instance(boot_method_oop), "must be sane"); |
|
2512 // probably no race conditions, but let's be careful: |
|
2513 if (Atomic::cmpxchg_ptr(boot_method_oop, ik->adr_bootstrap_method(), NULL) == NULL) |
|
2514 ik->set_bootstrap_method(boot_method_oop); |
|
2515 else |
|
2516 boot_method_oop = ik->bootstrap_method(); |
|
2517 } else { |
|
2518 if (TraceMethodHandles) { |
|
2519 #ifndef PRODUCT |
|
2520 tty->print_cr("--------"); |
|
2521 tty->print_cr("bootstrap method for "PTR_FORMAT" computed as NULL:", ik()); |
|
2522 ik()->print(); |
|
2523 tty->print_cr("========"); |
|
2524 #endif //PRODUCT |
|
2525 } |
|
2526 boot_method_oop = ik->bootstrap_method(); |
|
2527 } |
|
2528 |
|
2529 return Handle(THREAD, boot_method_oop); |
|
2530 } |
2489 } |
2531 |
2490 |
2532 // Since the identity hash code for symbols changes when the symbols are |
2491 // Since the identity hash code for symbols changes when the symbols are |
2533 // moved from the regular perm gen (hash in the mark word) to the shared |
2492 // moved from the regular perm gen (hash in the mark word) to the shared |
2534 // spaces (hash is the address), the classes loaded into the dictionary |
2493 // spaces (hash is the address), the classes loaded into the dictionary |