comparison src/share/vm/classfile/systemDictionary.cpp @ 1507:cd5dbf694d45

6939134: JSR 292 adjustments to method handle invocation Summary: split MethodHandle.invoke into invokeExact and invokeGeneric; also clean up JVM-to-Java interfaces Reviewed-by: twisti
author jrose
date Sat, 01 May 2010 02:42:18 -0700
parents 09ac706c2623
children 2ffde6cfe049
comparison
equal deleted inserted replaced
1506:2338d41fbd81 1507:cd5dbf694d45
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();
2383 2386
2384 // Ask Java code to find or construct a java.dyn.MethodType for the given 2387 // Ask Java code to find or construct a java.dyn.MethodType for the given
2385 // signature, as interpreted relative to the given class loader. 2388 // signature, as interpreted relative to the given class loader.
2386 // Because of class loader constraints, all method handle usage must be 2389 // Because of class loader constraints, all method handle usage must be
2387 // consistent with this loader. 2390 // consistent with this loader.
2388 Handle SystemDictionary::compute_method_handle_type(symbolHandle signature, 2391 Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
2389 Handle class_loader, 2392 Handle class_loader,
2390 Handle protection_domain, 2393 Handle protection_domain,
2391 TRAPS) { 2394 TRAPS) {
2392 Handle empty; 2395 Handle empty;
2393 int npts = ArgumentCount(signature()).size(); 2396 int npts = ArgumentCount(signature()).size();
2394 objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty)); 2397 objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
2395 int arg = 0; 2398 int arg = 0;
2396 Handle rt; // the return type from the signature 2399 Handle rt; // the return type from the signature
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