src/share/vm/classfile/systemDictionary.cpp

changeset 1863
2ffde6cfe049
parent 1862
cd5dbf694d45
child 1907
c18cbe5936b8
     1.1 --- a/src/share/vm/classfile/systemDictionary.cpp	Sat May 01 02:42:18 2010 -0700
     1.2 +++ b/src/share/vm/classfile/systemDictionary.cpp	Sat May 01 21:57:35 2010 -0700
     1.3 @@ -2343,12 +2343,9 @@
     1.4  
     1.5  methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
     1.6                                                        symbolHandle signature,
     1.7 -                                                      Handle class_loader,
     1.8 -                                                      Handle protection_domain,
     1.9 +                                                      KlassHandle accessing_klass,
    1.10                                                        TRAPS) {
    1.11    if (!EnableMethodHandles)  return NULL;
    1.12 -  assert(class_loader.is_null() && protection_domain.is_null(),
    1.13 -         "cannot load specialized versions of MethodHandle.invoke");
    1.14    if (invoke_method_table() == NULL) {
    1.15      // create this side table lazily
    1.16      _invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
    1.17 @@ -2358,30 +2355,36 @@
    1.18    unsigned int hash  = invoke_method_table()->compute_hash(signature, name_id);
    1.19    int          index = invoke_method_table()->hash_to_index(hash);
    1.20    SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
    1.21 +  methodHandle non_cached_result;
    1.22    if (spe == NULL || spe->property_oop() == NULL) {
    1.23 +    spe = NULL;
    1.24      // Must create lots of stuff here, but outside of the SystemDictionary lock.
    1.25      if (THREAD->is_Compiler_thread())
    1.26        return NULL;              // do not attempt from within compiler
    1.27 -    Handle mt = find_method_handle_type(signature(),
    1.28 -                                        class_loader, protection_domain,
    1.29 -                                        CHECK_NULL);
    1.30 +    bool found_on_bcp = false;
    1.31 +    Handle mt = find_method_handle_type(signature(), accessing_klass, found_on_bcp, CHECK_NULL);
    1.32      KlassHandle  mh_klass = SystemDictionaryHandles::MethodHandle_klass();
    1.33      methodHandle m = methodOopDesc::make_invoke_method(mh_klass, name, signature,
    1.34                                                         mt, CHECK_NULL);
    1.35      // Now grab the lock.  We might have to throw away the new method,
    1.36      // if a racing thread has managed to install one at the same time.
    1.37 -    {
    1.38 +    if (found_on_bcp) {
    1.39        MutexLocker ml(SystemDictionary_lock, Thread::current());
    1.40        spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
    1.41        if (spe == NULL)
    1.42          spe = invoke_method_table()->add_entry(index, hash, signature, name_id);
    1.43        if (spe->property_oop() == NULL)
    1.44          spe->set_property_oop(m());
    1.45 +    } else {
    1.46 +      non_cached_result = m;
    1.47      }
    1.48    }
    1.49 -  methodOop m = (methodOop) spe->property_oop();
    1.50 -  assert(m->is_method(), "");
    1.51 -  return m;
    1.52 +  if (spe != NULL && spe->property_oop() != NULL) {
    1.53 +    assert(spe->property_oop()->is_method(), "");
    1.54 +    return (methodOop) spe->property_oop();
    1.55 +  } else {
    1.56 +    return non_cached_result();
    1.57 +  }
    1.58  }
    1.59  
    1.60  // Ask Java code to find or construct a java.dyn.MethodType for the given
    1.61 @@ -2389,30 +2392,50 @@
    1.62  // Because of class loader constraints, all method handle usage must be
    1.63  // consistent with this loader.
    1.64  Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
    1.65 -                                                 Handle class_loader,
    1.66 -                                                 Handle protection_domain,
    1.67 +                                                 KlassHandle accessing_klass,
    1.68 +                                                 bool& return_bcp_flag,
    1.69                                                   TRAPS) {
    1.70 +  Handle class_loader, protection_domain;
    1.71 +  bool is_on_bcp = true;  // keep this true as long as we can materialize from the boot classloader
    1.72    Handle empty;
    1.73    int npts = ArgumentCount(signature()).size();
    1.74    objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
    1.75    int arg = 0;
    1.76    Handle rt;                            // the return type from the signature
    1.77    for (SignatureStream ss(signature()); !ss.is_done(); ss.next()) {
    1.78 -    oop mirror;
    1.79 -    if (!ss.is_object()) {
    1.80 -      mirror = Universe::java_mirror(ss.type());
    1.81 -    } else {
    1.82 -      symbolOop    name_oop = ss.as_symbol(CHECK_(empty));
    1.83 -      symbolHandle name(THREAD, name_oop);
    1.84 -      klassOop klass = resolve_or_fail(name,
    1.85 -                                       class_loader, protection_domain,
    1.86 -                                       true, CHECK_(empty));
    1.87 -      mirror = Klass::cast(klass)->java_mirror();
    1.88 +    oop mirror = NULL;
    1.89 +    if (is_on_bcp) {
    1.90 +      mirror = ss.as_java_mirror(class_loader, protection_domain,
    1.91 +                                 SignatureStream::ReturnNull, CHECK_(empty));
    1.92 +      if (mirror == NULL) {
    1.93 +        // fall back from BCP to accessing_klass
    1.94 +        if (accessing_klass.not_null()) {
    1.95 +          class_loader      = Handle(THREAD, instanceKlass::cast(accessing_klass())->class_loader());
    1.96 +          protection_domain = Handle(THREAD, instanceKlass::cast(accessing_klass())->protection_domain());
    1.97 +        }
    1.98 +        is_on_bcp = false;
    1.99 +      }
   1.100 +    }
   1.101 +    if (!is_on_bcp) {
   1.102 +      // Resolve, throwing a real error if it doesn't work.
   1.103 +      mirror = ss.as_java_mirror(class_loader, protection_domain,
   1.104 +                                 SignatureStream::NCDFError, CHECK_(empty));
   1.105      }
   1.106      if (ss.at_return_type())
   1.107        rt = Handle(THREAD, mirror);
   1.108      else
   1.109        pts->obj_at_put(arg++, mirror);
   1.110 +    // Check accessibility.
   1.111 +    if (ss.is_object() && accessing_klass.not_null()) {
   1.112 +      klassOop sel_klass = java_lang_Class::as_klassOop(mirror);
   1.113 +      // Emulate constantPoolOopDesc::verify_constant_pool_resolve.
   1.114 +      if (Klass::cast(sel_klass)->oop_is_objArray())
   1.115 +        sel_klass = objArrayKlass::cast(sel_klass)->bottom_klass();
   1.116 +      if (Klass::cast(sel_klass)->oop_is_instance()) {
   1.117 +        KlassHandle sel_kh(THREAD, sel_klass);
   1.118 +        LinkResolver::check_klass_accessability(accessing_klass, sel_kh, CHECK_(empty));
   1.119 +      }
   1.120 +    }
   1.121    }
   1.122    assert(arg == npts, "");
   1.123  
   1.124 @@ -2425,6 +2448,9 @@
   1.125                           vmSymbols::findMethodHandleType_name(),
   1.126                           vmSymbols::findMethodHandleType_signature(),
   1.127                           &args, CHECK_(empty));
   1.128 +
   1.129 +  // report back to the caller with the MethodType and the "on_bcp" flag
   1.130 +  return_bcp_flag = is_on_bcp;
   1.131    return Handle(THREAD, (oop) result.get_jobject());
   1.132  }
   1.133  

mercurial