hotspot/src/share/vm/prims/methodHandles.cpp
changeset 5420 586d3988e72b
parent 5050 47ecd86932ce
child 5421 e294db54fc0d
equal deleted inserted replaced
5419:f2e8cc8c12ea 5420:586d3988e72b
   364   SEARCH_INTERFACES   = sun_dyn_MemberName::MN_SEARCH_INTERFACES,
   364   SEARCH_INTERFACES   = sun_dyn_MemberName::MN_SEARCH_INTERFACES,
   365   ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
   365   ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
   366   VM_INDEX_UNINITIALIZED = sun_dyn_MemberName::VM_INDEX_UNINITIALIZED
   366   VM_INDEX_UNINITIALIZED = sun_dyn_MemberName::VM_INDEX_UNINITIALIZED
   367 };
   367 };
   368 
   368 
       
   369 Handle MethodHandles::new_MemberName(TRAPS) {
       
   370   Handle empty;
       
   371   instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass());
       
   372   if (!k->is_initialized())  k->initialize(CHECK_(empty));
       
   373   return Handle(THREAD, k->allocate_instance(THREAD));
       
   374 }
       
   375 
   369 void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
   376 void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
   370   if (target_oop->klass() == SystemDictionary::reflect_Field_klass()) {
   377   if (target_oop->klass() == SystemDictionary::reflect_Field_klass()) {
   371     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
   378     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
   372     int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
   379     int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
   373     int mods  = java_lang_reflect_Field::modifiers(target_oop);
   380     int mods  = java_lang_reflect_Field::modifiers(target_oop);
   392     vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
   399     vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
   393   assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
   400   assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
   394   sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
   401   sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
   395   sun_dyn_MemberName::set_vmindex(mname_oop,  vmindex);
   402   sun_dyn_MemberName::set_vmindex(mname_oop,  vmindex);
   396   sun_dyn_MemberName::set_flags(mname_oop,    flags);
   403   sun_dyn_MemberName::set_flags(mname_oop,    flags);
       
   404   sun_dyn_MemberName::set_clazz(mname_oop,    Klass::cast(m->method_holder())->java_mirror());
   397 }
   405 }
   398 
   406 
   399 void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
   407 void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
   400   int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ));
   408   int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ));
   401   oop vmtarget = field_holder;
   409   oop vmtarget = field_holder;
   402   int vmindex  = offset;  // implies no info yet
   410   int vmindex  = offset;  // determines the field uniquely when combined with static bit
   403   assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
   411   assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
   404   sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
   412   sun_dyn_MemberName::set_vmtarget(mname_oop, vmtarget);
   405   sun_dyn_MemberName::set_vmindex(mname_oop,  vmindex);
   413   sun_dyn_MemberName::set_vmindex(mname_oop,  vmindex);
   406   sun_dyn_MemberName::set_flags(mname_oop,    flags);
   414   sun_dyn_MemberName::set_flags(mname_oop,    flags);
       
   415   sun_dyn_MemberName::set_clazz(mname_oop,    Klass::cast(field_holder)->java_mirror());
   407 }
   416 }
   408 
   417 
   409 
   418 
   410 methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) {
   419 methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) {
   411   int flags  = sun_dyn_MemberName::flags(mname);
   420   int flags  = sun_dyn_MemberName::flags(mname);
   465   symbolHandle name(THREAD, java_lang_String::as_symbol_or_null(name_str));
   474   symbolHandle name(THREAD, java_lang_String::as_symbol_or_null(name_str));
   466   if (name.is_null())  return;  // no such name
   475   if (name.is_null())  return;  // no such name
   467   name_str = NULL;  // safety
   476   name_str = NULL;  // safety
   468 
   477 
   469   // convert the external string or reflective type to an internal signature
   478   // convert the external string or reflective type to an internal signature
   470   bool force_signature = (name() == vmSymbols::invoke_name());
   479   bool force_signature = methodOopDesc::is_method_handle_invoke_name(name());
   471   symbolHandle type; {
   480   symbolHandle type; {
   472     symbolOop type_sym = NULL;
   481     symbolOop type_sym = NULL;
   473     if (java_dyn_MethodType::is_instance(type_str)) {
   482     if (java_dyn_MethodType::is_instance(type_str)) {
   474       type_sym = java_dyn_MethodType::as_signature(type_str, force_signature, CHECK);
   483       type_sym = java_dyn_MethodType::as_signature(type_str, force_signature, CHECK);
   475     } else if (java_lang_Class::is_instance(type_str)) {
   484     } else if (java_lang_Class::is_instance(type_str)) {
   772 
   781 
   773   // return number of elements we at leasted wanted to initialize
   782   // return number of elements we at leasted wanted to initialize
   774   return rfill + overflow;
   783   return rfill + overflow;
   775 }
   784 }
   776 
   785 
       
   786 
       
   787 // Decode this java.lang.Class object into an instanceKlass, if possible.
       
   788 // Throw IAE if not
       
   789 instanceKlassHandle MethodHandles::resolve_instance_klass(oop java_mirror_oop, TRAPS) {
       
   790   instanceKlassHandle empty;
       
   791   klassOop caller = NULL;
       
   792   if (java_lang_Class::is_instance(java_mirror_oop)) {
       
   793     caller = java_lang_Class::as_klassOop(java_mirror_oop);
       
   794   }
       
   795   if (caller == NULL || !Klass::cast(caller)->oop_is_instance()) {
       
   796     THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not a class", empty);
       
   797   }
       
   798   return instanceKlassHandle(THREAD, caller);
       
   799 }
   777 
   800 
   778 
   801 
   779 
   802 
   780 // Decode the vmtarget field of a method handle.
   803 // Decode the vmtarget field of a method handle.
   781 // Sanitize out methodOops, klassOops, and any other non-Java data.
   804 // Sanitize out methodOops, klassOops, and any other non-Java data.
  2113   // access checks on behalf of the given caller.  But, we can verify this.
  2136   // access checks on behalf of the given caller.  But, we can verify this.
  2114   if (VerifyMethodHandles && caller_jh != NULL) {
  2137   if (VerifyMethodHandles && caller_jh != NULL) {
  2115     KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
  2138     KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
  2116     // If this were a bytecode, the first access check would be against
  2139     // If this were a bytecode, the first access check would be against
  2117     // the "reference class" mentioned in the CONSTANT_Methodref.
  2140     // the "reference class" mentioned in the CONSTANT_Methodref.
  2118     // For that class, we use the defining class of m,
  2141     // We don't know at this point which class that was, and if we
  2119     // or a more specific receiver limit if available.
  2142     // check against m.method_holder we might get the wrong answer.
  2120     klassOop reference_klass = m->method_holder();  // OK approximation
  2143     // So we just make sure to handle this check when the resolution
  2121     if (receiver_limit != NULL && receiver_limit != reference_klass) {
  2144     // happens, when we call resolve_MemberName.
  2122       if (!Klass::cast(receiver_limit)->is_subtype_of(reference_klass))
  2145     //
  2123         THROW_MSG(vmSymbols::java_lang_InternalError(), "receiver limit out of bounds");  // Java code bug
  2146     // (A public class can inherit public members from private supers,
  2124       reference_klass = receiver_limit;
  2147     // and it would be wrong to check access against the private super
  2125     }
  2148     // if the original symbolic reference was against the public class.)
  2126     // Emulate LinkResolver::check_klass_accessability.
  2149     //
  2127     if (!Reflection::verify_class_access(caller->as_klassOop(),
       
  2128                                          reference_klass,
       
  2129                                          true)) {
       
  2130       THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(m->method_holder())->external_name());
       
  2131     }
       
  2132     // If there were a bytecode, the next step would be to lookup the method
  2150     // If there were a bytecode, the next step would be to lookup the method
  2133     // in the reference class, then then check the method's access bits.
  2151     // in the reference class, then then check the method's access bits.
  2134     // Emulate LinkResolver::check_method_accessability.
  2152     // Emulate LinkResolver::check_method_accessability.
  2135     klassOop resolved_klass = m->method_holder();
  2153     klassOop resolved_klass = m->method_holder();
  2136     if (!Reflection::verify_field_access(caller->as_klassOop(),
  2154     if (!Reflection::verify_field_access(caller->as_klassOop(),
  2137                                          resolved_klass, reference_klass,
  2155                                          resolved_klass, resolved_klass,
  2138                                          m->access_flags(),
  2156                                          m->access_flags(),
  2139                                          true)) {
  2157                                          true)) {
  2140       // %%% following cutout belongs in Reflection::verify_field_access?
  2158       // %%% following cutout belongs in Reflection::verify_field_access?
  2141       bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
  2159       bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
  2142                                                         reference_klass, THREAD);
  2160                                                         resolved_klass, THREAD);
  2143       if (!same_pm) {
  2161       if (!same_pm) {
  2144         THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
  2162         THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
  2145       }
  2163       }
  2146     }
  2164     }
  2147   }
  2165   }
  2242               "MethodHandlePushLimit parameter must be in valid range");
  2260               "MethodHandlePushLimit parameter must be in valid range");
  2243     return MethodHandlePushLimit;
  2261     return MethodHandlePushLimit;
  2244   case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
  2262   case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
  2245     // return number of words per slot, signed according to stack direction
  2263     // return number of words per slot, signed according to stack direction
  2246     return MethodHandles::stack_move_unit();
  2264     return MethodHandles::stack_move_unit();
       
  2265   case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
       
  2266     return MethodHandles::adapter_conversion_ops_supported_mask();
  2247   }
  2267   }
  2248   return 0;
  2268   return 0;
  2249 }
  2269 }
  2250 JVM_END
  2270 JVM_END
  2251 
  2271 
  2340 
  2360 
  2341 // void resolve(MemberName self, Class<?> caller)
  2361 // void resolve(MemberName self, Class<?> caller)
  2342 JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
  2362 JVM_ENTRY(void, MHI_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
  2343   if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
  2363   if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
  2344   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2364   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
  2345   // %%% take caller into account!
  2365 
       
  2366   // The trusted Java code that calls this method should already have performed
       
  2367   // access checks on behalf of the given caller.  But, we can verify this.
       
  2368   if (VerifyMethodHandles && caller_jh != NULL) {
       
  2369     klassOop reference_klass = java_lang_Class::as_klassOop(sun_dyn_MemberName::clazz(mname()));
       
  2370     if (reference_klass != NULL) {
       
  2371       // Emulate LinkResolver::check_klass_accessability.
       
  2372       klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh));
       
  2373       if (!Reflection::verify_class_access(caller,
       
  2374                                            reference_klass,
       
  2375                                            true)) {
       
  2376         THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(reference_klass)->external_name());
       
  2377       }
       
  2378     }
       
  2379   }
       
  2380 
  2346   MethodHandles::resolve_MemberName(mname, CHECK);
  2381   MethodHandles::resolve_MemberName(mname, CHECK);
  2347 }
  2382 }
  2348 JVM_END
  2383 JVM_END
  2349 
  2384 
  2350 //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
  2385 //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
  2385   // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
  2420   // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
  2386   return res;
  2421   return res;
  2387 }
  2422 }
  2388 JVM_END
  2423 JVM_END
  2389 
  2424 
  2390 
  2425 JVM_ENTRY(void, MHI_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) {
  2391 JVM_ENTRY(void, MH_linkCallSite(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
  2426   instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
       
  2427   ik->link_class(CHECK);
       
  2428   if (!java_dyn_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) {
       
  2429     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle");
       
  2430   }
       
  2431   const char* err = NULL;
       
  2432   if (ik->is_initialized() || ik->is_in_error_state()) {
       
  2433     err = "too late: class is already initialized";
       
  2434   } else {
       
  2435     ObjectLocker ol(ik, THREAD);  // note:  this should be a recursive lock
       
  2436     if (ik->is_not_initialized() ||
       
  2437         (ik->is_being_initialized() && ik->is_reentrant_initialization(THREAD))) {
       
  2438       if (ik->bootstrap_method() != NULL) {
       
  2439         err = "class is already equipped with a bootstrap method";
       
  2440       } else {
       
  2441         ik->set_bootstrap_method(JNIHandles::resolve_non_null(bsm_jh));
       
  2442         err = NULL;
       
  2443       }
       
  2444     } else {
       
  2445       err = "class is already initialized";
       
  2446       if (ik->is_being_initialized())
       
  2447         err = "class is already being initialized in a different thread";
       
  2448     }
       
  2449   }
       
  2450   if (err != NULL) {
       
  2451     THROW_MSG(vmSymbols::java_lang_IllegalStateException(), err);
       
  2452   }
       
  2453 }
       
  2454 JVM_END
       
  2455 
       
  2456 JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
       
  2457   instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
       
  2458   return JNIHandles::make_local(THREAD, ik->bootstrap_method());
       
  2459 }
       
  2460 JVM_END
       
  2461 
       
  2462 JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
  2392   // No special action required, yet.
  2463   // No special action required, yet.
  2393   oop site_oop = JNIHandles::resolve(site_jh);
  2464   oop site_oop = JNIHandles::resolve(site_jh);
  2394   if (site_oop == NULL || site_oop->klass() != SystemDictionary::CallSite_klass())
  2465   if (!java_dyn_CallSite::is_instance(site_oop))
  2395     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "call site");
  2466     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "not a CallSite");
  2396   java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
  2467   java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
  2397 }
  2468 }
  2398 JVM_END
  2469 JVM_END
  2399 
  2470 
  2400 
  2471 
  2440   {CC"getMembers",              CC"("CLS""STRG""STRG"I"CLS"I["MEM")I",  FN_PTR(MHI_getMembers)}
  2511   {CC"getMembers",              CC"("CLS""STRG""STRG"I"CLS"I["MEM")I",  FN_PTR(MHI_getMembers)}
  2441 };
  2512 };
  2442 
  2513 
  2443 // More entry points specifically for EnableInvokeDynamic.
  2514 // More entry points specifically for EnableInvokeDynamic.
  2444 static JNINativeMethod methods2[] = {
  2515 static JNINativeMethod methods2[] = {
  2445   {CC"linkCallSite",            CC"("CST MH")V",                FN_PTR(MH_linkCallSite)}
  2516   {CC"registerBootstrap",       CC"("CLS MH")V",                FN_PTR(MHI_registerBootstrap)},
       
  2517   {CC"getBootstrap",            CC"("CLS")"MH,                  FN_PTR(MHI_getBootstrap)},
       
  2518   {CC"setCallSiteTarget",       CC"("CST MH")V",                FN_PTR(MHI_setCallSiteTarget)}
  2446 };
  2519 };
  2447 
  2520 
  2448 
  2521 
  2449 // This one function is exported, used by NativeLookup.
  2522 // This one function is exported, used by NativeLookup.
  2450 
  2523