hotspot/src/share/vm/classfile/systemDictionary.cpp
changeset 5421 e294db54fc0d
parent 5420 586d3988e72b
child 5547 f4b087cbb361
equal deleted inserted replaced
5420:586d3988e72b 5421:e294db54fc0d
  2341 }
  2341 }
  2342 
  2342 
  2343 
  2343 
  2344 methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
  2344 methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
  2345                                                       symbolHandle signature,
  2345                                                       symbolHandle signature,
  2346                                                       Handle class_loader,
  2346                                                       KlassHandle accessing_klass,
  2347                                                       Handle protection_domain,
       
  2348                                                       TRAPS) {
  2347                                                       TRAPS) {
  2349   if (!EnableMethodHandles)  return NULL;
  2348   if (!EnableMethodHandles)  return NULL;
  2350   assert(class_loader.is_null() && protection_domain.is_null(),
       
  2351          "cannot load specialized versions of MethodHandle.invoke");
       
  2352   if (invoke_method_table() == NULL) {
  2349   if (invoke_method_table() == NULL) {
  2353     // create this side table lazily
  2350     // create this side table lazily
  2354     _invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
  2351     _invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
  2355   }
  2352   }
  2356   vmSymbols::SID name_id = vmSymbols::find_sid(name());
  2353   vmSymbols::SID name_id = vmSymbols::find_sid(name());
  2357   assert(name_id != vmSymbols::NO_SID, "must be a known name");
  2354   assert(name_id != vmSymbols::NO_SID, "must be a known name");
  2358   unsigned int hash  = invoke_method_table()->compute_hash(signature, name_id);
  2355   unsigned int hash  = invoke_method_table()->compute_hash(signature, name_id);
  2359   int          index = invoke_method_table()->hash_to_index(hash);
  2356   int          index = invoke_method_table()->hash_to_index(hash);
  2360   SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
  2357   SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
       
  2358   methodHandle non_cached_result;
  2361   if (spe == NULL || spe->property_oop() == NULL) {
  2359   if (spe == NULL || spe->property_oop() == NULL) {
       
  2360     spe = NULL;
  2362     // Must create lots of stuff here, but outside of the SystemDictionary lock.
  2361     // Must create lots of stuff here, but outside of the SystemDictionary lock.
  2363     if (THREAD->is_Compiler_thread())
  2362     if (THREAD->is_Compiler_thread())
  2364       return NULL;              // do not attempt from within compiler
  2363       return NULL;              // do not attempt from within compiler
  2365     Handle mt = find_method_handle_type(signature(),
  2364     bool found_on_bcp = false;
  2366                                         class_loader, protection_domain,
  2365     Handle mt = find_method_handle_type(signature(), accessing_klass, found_on_bcp, CHECK_NULL);
  2367                                         CHECK_NULL);
       
  2368     KlassHandle  mh_klass = SystemDictionaryHandles::MethodHandle_klass();
  2366     KlassHandle  mh_klass = SystemDictionaryHandles::MethodHandle_klass();
  2369     methodHandle m = methodOopDesc::make_invoke_method(mh_klass, name, signature,
  2367     methodHandle m = methodOopDesc::make_invoke_method(mh_klass, name, signature,
  2370                                                        mt, CHECK_NULL);
  2368                                                        mt, CHECK_NULL);
  2371     // Now grab the lock.  We might have to throw away the new method,
  2369     // Now grab the lock.  We might have to throw away the new method,
  2372     // if a racing thread has managed to install one at the same time.
  2370     // if a racing thread has managed to install one at the same time.
  2373     {
  2371     if (found_on_bcp) {
  2374       MutexLocker ml(SystemDictionary_lock, Thread::current());
  2372       MutexLocker ml(SystemDictionary_lock, Thread::current());
  2375       spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
  2373       spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
  2376       if (spe == NULL)
  2374       if (spe == NULL)
  2377         spe = invoke_method_table()->add_entry(index, hash, signature, name_id);
  2375         spe = invoke_method_table()->add_entry(index, hash, signature, name_id);
  2378       if (spe->property_oop() == NULL)
  2376       if (spe->property_oop() == NULL)
  2379         spe->set_property_oop(m());
  2377         spe->set_property_oop(m());
  2380     }
  2378     } else {
  2381   }
  2379       non_cached_result = m;
  2382   methodOop m = (methodOop) spe->property_oop();
  2380     }
  2383   assert(m->is_method(), "");
  2381   }
  2384   return m;
  2382   if (spe != NULL && spe->property_oop() != NULL) {
       
  2383     assert(spe->property_oop()->is_method(), "");
       
  2384     return (methodOop) spe->property_oop();
       
  2385   } else {
       
  2386     return non_cached_result();
       
  2387   }
  2385 }
  2388 }
  2386 
  2389 
  2387 // Ask Java code to find or construct a java.dyn.MethodType for the given
  2390 // Ask Java code to find or construct a java.dyn.MethodType for the given
  2388 // signature, as interpreted relative to the given class loader.
  2391 // signature, as interpreted relative to the given class loader.
  2389 // Because of class loader constraints, all method handle usage must be
  2392 // Because of class loader constraints, all method handle usage must be
  2390 // consistent with this loader.
  2393 // consistent with this loader.
  2391 Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
  2394 Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
  2392                                                  Handle class_loader,
  2395                                                  KlassHandle accessing_klass,
  2393                                                  Handle protection_domain,
  2396                                                  bool& return_bcp_flag,
  2394                                                  TRAPS) {
  2397                                                  TRAPS) {
       
  2398   Handle class_loader, protection_domain;
       
  2399   bool is_on_bcp = true;  // keep this true as long as we can materialize from the boot classloader
  2395   Handle empty;
  2400   Handle empty;
  2396   int npts = ArgumentCount(signature()).size();
  2401   int npts = ArgumentCount(signature()).size();
  2397   objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
  2402   objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
  2398   int arg = 0;
  2403   int arg = 0;
  2399   Handle rt;                            // the return type from the signature
  2404   Handle rt;                            // the return type from the signature
  2400   for (SignatureStream ss(signature()); !ss.is_done(); ss.next()) {
  2405   for (SignatureStream ss(signature()); !ss.is_done(); ss.next()) {
  2401     oop mirror;
  2406     oop mirror = NULL;
  2402     if (!ss.is_object()) {
  2407     if (is_on_bcp) {
  2403       mirror = Universe::java_mirror(ss.type());
  2408       mirror = ss.as_java_mirror(class_loader, protection_domain,
  2404     } else {
  2409                                  SignatureStream::ReturnNull, CHECK_(empty));
  2405       symbolOop    name_oop = ss.as_symbol(CHECK_(empty));
  2410       if (mirror == NULL) {
  2406       symbolHandle name(THREAD, name_oop);
  2411         // fall back from BCP to accessing_klass
  2407       klassOop klass = resolve_or_fail(name,
  2412         if (accessing_klass.not_null()) {
  2408                                        class_loader, protection_domain,
  2413           class_loader      = Handle(THREAD, instanceKlass::cast(accessing_klass())->class_loader());
  2409                                        true, CHECK_(empty));
  2414           protection_domain = Handle(THREAD, instanceKlass::cast(accessing_klass())->protection_domain());
  2410       mirror = Klass::cast(klass)->java_mirror();
  2415         }
       
  2416         is_on_bcp = false;
       
  2417       }
       
  2418     }
       
  2419     if (!is_on_bcp) {
       
  2420       // Resolve, throwing a real error if it doesn't work.
       
  2421       mirror = ss.as_java_mirror(class_loader, protection_domain,
       
  2422                                  SignatureStream::NCDFError, CHECK_(empty));
  2411     }
  2423     }
  2412     if (ss.at_return_type())
  2424     if (ss.at_return_type())
  2413       rt = Handle(THREAD, mirror);
  2425       rt = Handle(THREAD, mirror);
  2414     else
  2426     else
  2415       pts->obj_at_put(arg++, mirror);
  2427       pts->obj_at_put(arg++, mirror);
       
  2428     // Check accessibility.
       
  2429     if (ss.is_object() && accessing_klass.not_null()) {
       
  2430       klassOop sel_klass = java_lang_Class::as_klassOop(mirror);
       
  2431       // Emulate constantPoolOopDesc::verify_constant_pool_resolve.
       
  2432       if (Klass::cast(sel_klass)->oop_is_objArray())
       
  2433         sel_klass = objArrayKlass::cast(sel_klass)->bottom_klass();
       
  2434       if (Klass::cast(sel_klass)->oop_is_instance()) {
       
  2435         KlassHandle sel_kh(THREAD, sel_klass);
       
  2436         LinkResolver::check_klass_accessability(accessing_klass, sel_kh, CHECK_(empty));
       
  2437       }
       
  2438     }
  2416   }
  2439   }
  2417   assert(arg == npts, "");
  2440   assert(arg == npts, "");
  2418 
  2441 
  2419   // call sun.dyn.MethodHandleNatives::findMethodType(Class rt, Class[] pts) -> MethodType
  2442   // call sun.dyn.MethodHandleNatives::findMethodType(Class rt, Class[] pts) -> MethodType
  2420   JavaCallArguments args(Handle(THREAD, rt()));
  2443   JavaCallArguments args(Handle(THREAD, rt()));
  2423   JavaCalls::call_static(&result,
  2446   JavaCalls::call_static(&result,
  2424                          SystemDictionary::MethodHandleNatives_klass(),
  2447                          SystemDictionary::MethodHandleNatives_klass(),
  2425                          vmSymbols::findMethodHandleType_name(),
  2448                          vmSymbols::findMethodHandleType_name(),
  2426                          vmSymbols::findMethodHandleType_signature(),
  2449                          vmSymbols::findMethodHandleType_signature(),
  2427                          &args, CHECK_(empty));
  2450                          &args, CHECK_(empty));
       
  2451 
       
  2452   // report back to the caller with the MethodType and the "on_bcp" flag
       
  2453   return_bcp_flag = is_on_bcp;
  2428   return Handle(THREAD, (oop) result.get_jobject());
  2454   return Handle(THREAD, (oop) result.get_jobject());
  2429 }
  2455 }
  2430 
  2456 
  2431 
  2457 
  2432 // Ask Java code to find or construct a java.dyn.CallSite for the given
  2458 // Ask Java code to find or construct a java.dyn.CallSite for the given