7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path

Thu, 23 Jun 2011 17:14:06 -0700

author
jrose
date
Thu, 23 Jun 2011 17:14:06 -0700
changeset 2982
ddd894528dbc
parent 2981
aabf25fa3f05
child 2983
498c6cf70f7e

7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
Reviewed-by: never

src/cpu/sparc/vm/templateTable_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateTable_x86_32.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/templateTable_x86_64.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciEnv.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciEnv.hpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciField.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciMethod.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciMethodHandle.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciObjArrayKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciSignature.cpp file | annotate | diff | comparison | revisions
src/share/vm/ci/ciSignature.hpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/javaClasses.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/javaClasses.hpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/systemDictionary.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/linkResolver.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/constantPoolKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/constantPoolOop.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/constantPoolOop.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/cpCacheOop.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/cpCacheOop.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/methodOop.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/methodOop.hpp file | annotate | diff | comparison | revisions
src/share/vm/prims/methodHandleWalk.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/methodHandleWalk.hpp file | annotate | diff | comparison | revisions
src/share/vm/prims/methodHandles.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/methodHandles.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Wed Jun 22 14:45:37 2011 -0700
     1.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jun 23 17:14:06 2011 -0700
     1.3 @@ -266,7 +266,7 @@
     1.4  
     1.5  void TemplateTable::ldc(bool wide) {
     1.6    transition(vtos, vtos);
     1.7 -  Label call_ldc, notInt, notString, notClass, exit;
     1.8 +  Label call_ldc, notInt, isString, notString, notClass, exit;
     1.9  
    1.10    if (wide) {
    1.11      __ get_2_byte_integer_at_bcp(1, G3_scratch, O1, InterpreterMacroAssembler::Unsigned);
    1.12 @@ -317,8 +317,11 @@
    1.13  
    1.14    __ bind(notInt);
    1.15   // __ cmp(O2, JVM_CONSTANT_String);
    1.16 +  __ brx(Assembler::equal, true, Assembler::pt, isString);
    1.17 +  __ delayed()->cmp(O2, JVM_CONSTANT_Object);
    1.18    __ brx(Assembler::notEqual, true, Assembler::pt, notString);
    1.19    __ delayed()->ldf(FloatRegisterImpl::S, O0, O1, Ftos_f);
    1.20 +  __ bind(isString);
    1.21    __ ld_ptr(O0, O1, Otos_i);
    1.22    __ verify_oop(Otos_i);
    1.23    __ push(atos);
     2.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Wed Jun 22 14:45:37 2011 -0700
     2.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Jun 23 17:14:06 2011 -0700
     2.3 @@ -373,15 +373,17 @@
     2.4      __ jcc(Assembler::equal, L);
     2.5      __ cmpl(rdx, JVM_CONSTANT_String);
     2.6      __ jcc(Assembler::equal, L);
     2.7 +    __ cmpl(rdx, JVM_CONSTANT_Object);
     2.8 +    __ jcc(Assembler::equal, L);
     2.9      __ stop("unexpected tag type in ldc");
    2.10      __ bind(L);
    2.11    }
    2.12  #endif
    2.13    Label isOop;
    2.14    // atos and itos
    2.15 -  // String is only oop type we will see here
    2.16 -  __ cmpl(rdx, JVM_CONSTANT_String);
    2.17 -  __ jccb(Assembler::equal, isOop);
    2.18 +  // Integer is only non-oop type we will see here
    2.19 +  __ cmpl(rdx, JVM_CONSTANT_Integer);
    2.20 +  __ jccb(Assembler::notEqual, isOop);
    2.21    __ movl(rax, Address(rcx, rbx, Address::times_ptr, base_offset));
    2.22    __ push(itos);
    2.23    __ jmp(Done);
     3.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Wed Jun 22 14:45:37 2011 -0700
     3.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Jun 23 17:14:06 2011 -0700
     3.3 @@ -385,6 +385,8 @@
     3.4      __ jcc(Assembler::equal, L);
     3.5      __ cmpl(rdx, JVM_CONSTANT_String);
     3.6      __ jcc(Assembler::equal, L);
     3.7 +    __ cmpl(rdx, JVM_CONSTANT_Object);
     3.8 +    __ jcc(Assembler::equal, L);
     3.9      __ stop("unexpected tag type in ldc");
    3.10      __ bind(L);
    3.11    }
     4.1 --- a/src/share/vm/ci/ciEnv.cpp	Wed Jun 22 14:45:37 2011 -0700
     4.2 +++ b/src/share/vm/ci/ciEnv.cpp	Thu Jun 23 17:14:06 2011 -0700
     4.3 @@ -50,6 +50,7 @@
     4.4  #include "oops/oop.inline.hpp"
     4.5  #include "oops/oop.inline2.hpp"
     4.6  #include "prims/jvmtiExport.hpp"
     4.7 +#include "prims/methodHandleWalk.hpp"
     4.8  #include "runtime/init.hpp"
     4.9  #include "runtime/reflection.hpp"
    4.10  #include "runtime/sharedRuntime.hpp"
    4.11 @@ -371,6 +372,7 @@
    4.12  // ------------------------------------------------------------------
    4.13  // ciEnv::get_klass_by_name_impl
    4.14  ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
    4.15 +                                       constantPoolHandle cpool,
    4.16                                         ciSymbol* name,
    4.17                                         bool require_local) {
    4.18    ASSERT_IN_VM;
    4.19 @@ -386,7 +388,7 @@
    4.20                      sym->utf8_length()-2,
    4.21                      KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));
    4.22      ciSymbol* strippedname = get_symbol(strippedsym);
    4.23 -    return get_klass_by_name_impl(accessing_klass, strippedname, require_local);
    4.24 +    return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local);
    4.25    }
    4.26  
    4.27    // Check for prior unloaded klass.  The SystemDictionary's answers
    4.28 @@ -443,6 +445,7 @@
    4.29      // Get element ciKlass recursively.
    4.30      ciKlass* elem_klass =
    4.31        get_klass_by_name_impl(accessing_klass,
    4.32 +                             cpool,
    4.33                               get_symbol(elem_sym),
    4.34                               require_local);
    4.35      if (elem_klass != NULL && elem_klass->is_loaded()) {
    4.36 @@ -451,6 +454,19 @@
    4.37      }
    4.38    }
    4.39  
    4.40 +  if (found_klass() == NULL && !cpool.is_null() && cpool->has_preresolution()) {
    4.41 +    // Look inside the constant pool for pre-resolved class entries.
    4.42 +    for (int i = cpool->length() - 1; i >= 1; i--) {
    4.43 +      if (cpool->tag_at(i).is_klass()) {
    4.44 +        klassOop kls = cpool->resolved_klass_at(i);
    4.45 +        if (Klass::cast(kls)->name() == sym) {
    4.46 +          found_klass = KlassHandle(THREAD, kls);
    4.47 +          break;
    4.48 +        }
    4.49 +      }
    4.50 +    }
    4.51 +  }
    4.52 +
    4.53    if (found_klass() != NULL) {
    4.54      // Found it.  Build a CI handle.
    4.55      return get_object(found_klass())->as_klass();
    4.56 @@ -468,6 +484,7 @@
    4.57                                    ciSymbol* klass_name,
    4.58                                    bool require_local) {
    4.59    GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass,
    4.60 +                                                 constantPoolHandle(),
    4.61                                                   klass_name,
    4.62                                                   require_local);)
    4.63  }
    4.64 @@ -508,13 +525,14 @@
    4.65    if (klass.is_null()) {
    4.66      // Not found in constant pool.  Use the name to do the lookup.
    4.67      ciKlass* k = get_klass_by_name_impl(accessor,
    4.68 +                                        cpool,
    4.69                                          get_symbol(klass_name),
    4.70                                          false);
    4.71      // Calculate accessibility the hard way.
    4.72      if (!k->is_loaded()) {
    4.73        is_accessible = false;
    4.74      } else if (k->loader() != accessor->loader() &&
    4.75 -               get_klass_by_name_impl(accessor, k->name(), true) == NULL) {
    4.76 +               get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) {
    4.77        // Loaded only remotely.  Not linked yet.
    4.78        is_accessible = false;
    4.79      } else {
    4.80 @@ -565,7 +583,7 @@
    4.81      index = cpc_entry->constant_pool_index();
    4.82      oop obj = cpc_entry->f1();
    4.83      if (obj != NULL) {
    4.84 -      assert(obj->is_instance(), "must be an instance");
    4.85 +      assert(obj->is_instance() || obj->is_array(), "must be a Java reference");
    4.86        ciObject* ciobj = get_object(obj);
    4.87        return ciConstant(T_OBJECT, ciobj);
    4.88      }
    4.89 @@ -607,7 +625,7 @@
    4.90      return ciConstant(T_OBJECT, klass->java_mirror());
    4.91    } else if (tag.is_object()) {
    4.92      oop obj = cpool->object_at(index);
    4.93 -    assert(obj->is_instance(), "must be an instance");
    4.94 +    assert(obj->is_instance() || obj->is_array(), "must be a Java reference");
    4.95      ciObject* ciobj = get_object(obj);
    4.96      return ciConstant(T_OBJECT, ciobj);
    4.97    } else if (tag.is_method_type()) {
    4.98 @@ -729,9 +747,35 @@
    4.99    Symbol* name_sym = cpool->name_ref_at(index);
   4.100    Symbol* sig_sym  = cpool->signature_ref_at(index);
   4.101  
   4.102 +  if (cpool->has_preresolution()
   4.103 +      || (holder == ciEnv::MethodHandle_klass() &&
   4.104 +          methodOopDesc::is_method_handle_invoke_name(name_sym))) {
   4.105 +    // Short-circuit lookups for JSR 292-related call sites.
   4.106 +    // That is, do not rely only on name-based lookups, because they may fail
   4.107 +    // if the names are not resolvable in the boot class loader (7056328).
   4.108 +    switch (bc) {
   4.109 +    case Bytecodes::_invokevirtual:
   4.110 +    case Bytecodes::_invokeinterface:
   4.111 +    case Bytecodes::_invokespecial:
   4.112 +    case Bytecodes::_invokestatic:
   4.113 +      {
   4.114 +        methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index, bc);
   4.115 +        if (m != NULL) {
   4.116 +          return get_object(m)->as_method();
   4.117 +        }
   4.118 +      }
   4.119 +    }
   4.120 +  }
   4.121 +
   4.122    if (holder_is_accessible) { // Our declared holder is loaded.
   4.123      instanceKlass* lookup = declared_holder->get_instanceKlass();
   4.124      methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
   4.125 +    if (m != NULL &&
   4.126 +        (bc == Bytecodes::_invokestatic
   4.127 +         ?  instanceKlass::cast(m->method_holder())->is_not_initialized()
   4.128 +         : !instanceKlass::cast(m->method_holder())->is_loaded())) {
   4.129 +      m = NULL;
   4.130 +    }
   4.131      if (m != NULL) {
   4.132        // We found the method.
   4.133        return get_object(m)->as_method();
   4.134 @@ -1046,7 +1090,7 @@
   4.135  // ciEnv::find_system_klass
   4.136  ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) {
   4.137    VM_ENTRY_MARK;
   4.138 -  return get_klass_by_name_impl(NULL, klass_name, false);
   4.139 +  return get_klass_by_name_impl(NULL, constantPoolHandle(), klass_name, false);
   4.140  }
   4.141  
   4.142  // ------------------------------------------------------------------
     5.1 --- a/src/share/vm/ci/ciEnv.hpp	Wed Jun 22 14:45:37 2011 -0700
     5.2 +++ b/src/share/vm/ci/ciEnv.hpp	Thu Jun 23 17:14:06 2011 -0700
     5.3 @@ -137,6 +137,7 @@
     5.4  
     5.5    // Implementation methods for loading and constant pool access.
     5.6    ciKlass* get_klass_by_name_impl(ciKlass* accessing_klass,
     5.7 +                                  constantPoolHandle cpool,
     5.8                                    ciSymbol* klass_name,
     5.9                                    bool require_local);
    5.10    ciKlass*   get_klass_by_index_impl(constantPoolHandle cpool,
     6.1 --- a/src/share/vm/ci/ciField.cpp	Wed Jun 22 14:45:37 2011 -0700
     6.2 +++ b/src/share/vm/ci/ciField.cpp	Thu Jun 23 17:14:06 2011 -0700
     6.3 @@ -287,7 +287,7 @@
     6.4  }
     6.5  
     6.6  ciType* ciField::compute_type_impl() {
     6.7 -  ciKlass* type = CURRENT_ENV->get_klass_by_name_impl(_holder, _signature, false);
     6.8 +  ciKlass* type = CURRENT_ENV->get_klass_by_name_impl(_holder, constantPoolHandle(), _signature, false);
     6.9    if (!type->is_primitive_type() && is_shared()) {
    6.10      // We must not cache a pointer to an unshared type, in a shared field.
    6.11      bool type_is_also_shared = false;
     7.1 --- a/src/share/vm/ci/ciMethod.cpp	Wed Jun 22 14:45:37 2011 -0700
     7.2 +++ b/src/share/vm/ci/ciMethod.cpp	Thu Jun 23 17:14:06 2011 -0700
     7.3 @@ -125,7 +125,8 @@
     7.4    _name = env->get_symbol(h_m()->name());
     7.5    _holder = env->get_object(h_m()->method_holder())->as_instance_klass();
     7.6    ciSymbol* sig_symbol = env->get_symbol(h_m()->signature());
     7.7 -  _signature = new (env->arena()) ciSignature(_holder, sig_symbol);
     7.8 +  constantPoolHandle cpool = h_m()->constants();
     7.9 +  _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol);
    7.10    _method_data = NULL;
    7.11    // Take a snapshot of these values, so they will be commensurate with the MDO.
    7.12    if (ProfileInterpreter || TieredCompilation) {
    7.13 @@ -152,7 +153,7 @@
    7.14    // These fields are always filled in.
    7.15    _name = name;
    7.16    _holder = holder;
    7.17 -  _signature = new (CURRENT_ENV->arena()) ciSignature(_holder, signature);
    7.18 +  _signature = new (CURRENT_ENV->arena()) ciSignature(_holder, constantPoolHandle(), signature);
    7.19    _intrinsic_id = vmIntrinsics::_none;
    7.20    _liveness = NULL;
    7.21    _can_be_statically_bound = false;
     8.1 --- a/src/share/vm/ci/ciMethodHandle.cpp	Wed Jun 22 14:45:37 2011 -0700
     8.2 +++ b/src/share/vm/ci/ciMethodHandle.cpp	Thu Jun 23 17:14:06 2011 -0700
     8.3 @@ -41,6 +41,16 @@
     8.4    VM_ENTRY_MARK;
     8.5    Handle h(get_oop());
     8.6    methodHandle callee(_callee->get_methodOop());
     8.7 +  assert(callee->is_method_handle_invoke(), "");
     8.8 +  oop mt1 = callee->method_handle_type();
     8.9 +  oop mt2 = java_lang_invoke_MethodHandle::type(h());
    8.10 +  if (!java_lang_invoke_MethodType::equals(mt1, mt2)) {
    8.11 +    if (PrintMiscellaneous && (Verbose || WizardMode)) {
    8.12 +      tty->print_cr("ciMethodHandle::get_adapter: types not equal");
    8.13 +      mt1->print(); mt2->print();
    8.14 +    }
    8.15 +    return NULL;
    8.16 +  }
    8.17    // We catch all exceptions here that could happen in the method
    8.18    // handle compiler and stop the VM.
    8.19    MethodHandleCompiler mhc(h, callee->name(), callee->signature(), _profile.count(), is_invokedynamic, THREAD);
    8.20 @@ -53,7 +63,7 @@
    8.21    if (PrintMiscellaneous && (Verbose || WizardMode)) {
    8.22      tty->print("*** ciMethodHandle::get_adapter => ");
    8.23      PENDING_EXCEPTION->print();
    8.24 -    tty->print("*** get_adapter (%s): ", is_invokedynamic ? "indy" : "mh"); ((ciObject*)this)->print(); //@@
    8.25 +    tty->print("*** get_adapter (%s): ", is_invokedynamic ? "indy" : "mh"); ((ciObject*)this)->print();
    8.26    }
    8.27    CLEAR_PENDING_EXCEPTION;
    8.28    return NULL;
     9.1 --- a/src/share/vm/ci/ciObjArrayKlass.cpp	Wed Jun 22 14:45:37 2011 -0700
     9.2 +++ b/src/share/vm/ci/ciObjArrayKlass.cpp	Thu Jun 23 17:14:06 2011 -0700
     9.3 @@ -93,6 +93,7 @@
     9.4        // element klass by name.
     9.5        _element_klass = CURRENT_THREAD_ENV->get_klass_by_name_impl(
     9.6                            this,
     9.7 +                          constantPoolHandle(),
     9.8                            construct_array_name(base_element_klass()->name(),
     9.9                                                 dimension() - 1),
    9.10                            false);
    10.1 --- a/src/share/vm/ci/ciSignature.cpp	Wed Jun 22 14:45:37 2011 -0700
    10.2 +++ b/src/share/vm/ci/ciSignature.cpp	Thu Jun 23 17:14:06 2011 -0700
    10.3 @@ -35,7 +35,7 @@
    10.4  
    10.5  // ------------------------------------------------------------------
    10.6  // ciSignature::ciSignature
    10.7 -ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol) {
    10.8 +ciSignature::ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* symbol) {
    10.9    ASSERT_IN_VM;
   10.10    EXCEPTION_CONTEXT;
   10.11    _accessing_klass = accessing_klass;
   10.12 @@ -64,7 +64,7 @@
   10.13          CLEAR_PENDING_EXCEPTION;
   10.14        } else {
   10.15          ciSymbol* klass_name = env->get_symbol(name);
   10.16 -        type = env->get_klass_by_name_impl(_accessing_klass, klass_name, false);
   10.17 +        type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
   10.18        }
   10.19      }
   10.20      _types->append(type);
    11.1 --- a/src/share/vm/ci/ciSignature.hpp	Wed Jun 22 14:45:37 2011 -0700
    11.2 +++ b/src/share/vm/ci/ciSignature.hpp	Thu Jun 23 17:14:06 2011 -0700
    11.3 @@ -44,7 +44,7 @@
    11.4  
    11.5    friend class ciMethod;
    11.6  
    11.7 -  ciSignature(ciKlass* accessing_klass, ciSymbol* signature);
    11.8 +  ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
    11.9  
   11.10    void get_all_klasses();
   11.11  
    12.1 --- a/src/share/vm/classfile/javaClasses.cpp	Wed Jun 22 14:45:37 2011 -0700
    12.2 +++ b/src/share/vm/classfile/javaClasses.cpp	Thu Jun 23 17:14:06 2011 -0700
    12.3 @@ -2574,6 +2574,18 @@
    12.4    return name;
    12.5  }
    12.6  
    12.7 +bool java_lang_invoke_MethodType::equals(oop mt1, oop mt2) {
    12.8 +  if (rtype(mt1) != rtype(mt2))
    12.9 +    return false;
   12.10 +  if (ptype_count(mt1) != ptype_count(mt2))
   12.11 +    return false;
   12.12 +  for (int i = ptype_count(mt1) - 1; i >= 0; i--) {
   12.13 +    if (ptype(mt1, i) != ptype(mt2, i))
   12.14 +      return false;
   12.15 +  }
   12.16 +  return true;
   12.17 +}
   12.18 +
   12.19  oop java_lang_invoke_MethodType::rtype(oop mt) {
   12.20    assert(is_instance(mt), "must be a MethodType");
   12.21    return mt->obj_field(_rtype_offset);
    13.1 --- a/src/share/vm/classfile/javaClasses.hpp	Wed Jun 22 14:45:37 2011 -0700
    13.2 +++ b/src/share/vm/classfile/javaClasses.hpp	Thu Jun 23 17:14:06 2011 -0700
    13.3 @@ -1079,6 +1079,8 @@
    13.4      return obj != NULL && obj->klass() == SystemDictionary::MethodType_klass();
    13.5    }
    13.6  
    13.7 +  static bool equals(oop mt1, oop mt2);
    13.8 +
    13.9    // Accessors for code generation:
   13.10    static int rtype_offset_in_bytes()            { return _rtype_offset; }
   13.11    static int ptypes_offset_in_bytes()           { return _ptypes_offset; }
    14.1 --- a/src/share/vm/classfile/systemDictionary.cpp	Wed Jun 22 14:45:37 2011 -0700
    14.2 +++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Jun 23 17:14:06 2011 -0700
    14.3 @@ -2367,6 +2367,8 @@
    14.4          // Link m to his method type, if it is suitably generic.
    14.5          oop mtform = java_lang_invoke_MethodType::form(mt());
    14.6          if (mtform != NULL && mt() == java_lang_invoke_MethodTypeForm::erasedType(mtform)
    14.7 +            // vmlayout must be an invokeExact:
    14.8 +            && name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name)
    14.9              && java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) {
   14.10            java_lang_invoke_MethodTypeForm::init_vmlayout(mtform, m());
   14.11          }
    15.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Wed Jun 22 14:45:37 2011 -0700
    15.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Thu Jun 23 17:14:06 2011 -0700
    15.3 @@ -294,6 +294,16 @@
    15.4    Symbol*  method_signature  = pool->signature_ref_at(index);
    15.5    KlassHandle  current_klass(THREAD, pool->pool_holder());
    15.6  
    15.7 +  if (pool->has_preresolution()
    15.8 +      || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
    15.9 +          methodOopDesc::is_method_handle_invoke_name(method_name))) {
   15.10 +    methodOop result_oop = constantPoolOopDesc::method_at_if_loaded(pool, index);
   15.11 +    if (result_oop != NULL) {
   15.12 +      resolved_method = methodHandle(THREAD, result_oop);
   15.13 +      return;
   15.14 +    }
   15.15 +  }
   15.16 +
   15.17    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   15.18  }
   15.19  
    16.1 --- a/src/share/vm/oops/constantPoolKlass.cpp	Wed Jun 22 14:45:37 2011 -0700
    16.2 +++ b/src/share/vm/oops/constantPoolKlass.cpp	Thu Jun 23 17:14:06 2011 -0700
    16.3 @@ -310,10 +310,14 @@
    16.4      st->print(" - flags: 0x%x", cp->flags());
    16.5      if (cp->has_pseudo_string()) st->print(" has_pseudo_string");
    16.6      if (cp->has_invokedynamic()) st->print(" has_invokedynamic");
    16.7 +    if (cp->has_preresolution()) st->print(" has_preresolution");
    16.8      st->cr();
    16.9    }
   16.10 +  if (cp->pool_holder() != NULL) {
   16.11 +    bool extra = (instanceKlass::cast(cp->pool_holder())->constants() != cp);
   16.12 +    st->print_cr(" - holder: " INTPTR_FORMAT "%s", cp->pool_holder(), (extra? " (extra)" : ""));
   16.13 +  }
   16.14    st->print_cr(" - cache: " INTPTR_FORMAT, cp->cache());
   16.15 -
   16.16    for (int index = 1; index < cp->length(); index++) {      // Index 0 is unused
   16.17      st->print(" - %3d : ", index);
   16.18      cp->tag_at(index).print_on(st);
   16.19 @@ -414,10 +418,15 @@
   16.20    st->print("constant pool [%d]", cp->length());
   16.21    if (cp->has_pseudo_string()) st->print("/pseudo_string");
   16.22    if (cp->has_invokedynamic()) st->print("/invokedynamic");
   16.23 +  if (cp->has_preresolution()) st->print("/preresolution");
   16.24    if (cp->operands() != NULL)  st->print("/operands[%d]", cp->operands()->length());
   16.25    cp->print_address_on(st);
   16.26    st->print(" for ");
   16.27    cp->pool_holder()->print_value_on(st);
   16.28 +  if (cp->pool_holder() != NULL) {
   16.29 +    bool extra = (instanceKlass::cast(cp->pool_holder())->constants() != cp);
   16.30 +    if (extra)  st->print(" (extra)");
   16.31 +  }
   16.32    if (cp->cache() != NULL) {
   16.33      st->print(" cache=" PTR_FORMAT, cp->cache());
   16.34    }
    17.1 --- a/src/share/vm/oops/constantPoolOop.cpp	Wed Jun 22 14:45:37 2011 -0700
    17.2 +++ b/src/share/vm/oops/constantPoolOop.cpp	Thu Jun 23 17:14:06 2011 -0700
    17.3 @@ -266,6 +266,29 @@
    17.4  }
    17.5  
    17.6  
    17.7 +methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool,
    17.8 +                                                   int which, Bytecodes::Code invoke_code) {
    17.9 +  assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here");
   17.10 +  if (cpool->cache() == NULL)  return false;  // nothing to load yet
   17.11 +  int cache_index = which - CPCACHE_INDEX_TAG;
   17.12 +  if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
   17.13 +    if (PrintMiscellaneous && (Verbose||WizardMode)) {
   17.14 +      tty->print_cr("bad operand %d for %d in:", which, invoke_code); cpool->print();
   17.15 +    }
   17.16 +    return NULL;
   17.17 +  }
   17.18 +  ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
   17.19 +  if (invoke_code != Bytecodes::_illegal)
   17.20 +    return e->get_method_if_resolved(invoke_code, cpool);
   17.21 +  Bytecodes::Code bc;
   17.22 +  if ((bc = e->bytecode_1()) != (Bytecodes::Code)0)
   17.23 +    return e->get_method_if_resolved(bc, cpool);
   17.24 +  if ((bc = e->bytecode_2()) != (Bytecodes::Code)0)
   17.25 +    return e->get_method_if_resolved(bc, cpool);
   17.26 +  return NULL;
   17.27 +}
   17.28 +
   17.29 +
   17.30  Symbol* constantPoolOopDesc::impl_name_ref_at(int which, bool uncached) {
   17.31    int name_index = name_ref_index_at(impl_name_and_type_ref_index_at(which, uncached));
   17.32    return symbol_at(name_index);
    18.1 --- a/src/share/vm/oops/constantPoolOop.hpp	Wed Jun 22 14:45:37 2011 -0700
    18.2 +++ b/src/share/vm/oops/constantPoolOop.hpp	Thu Jun 23 17:14:06 2011 -0700
    18.3 @@ -103,7 +103,8 @@
    18.4  
    18.5    enum FlagBit {
    18.6      FB_has_invokedynamic = 1,
    18.7 -    FB_has_pseudo_string = 2
    18.8 +    FB_has_pseudo_string = 2,
    18.9 +    FB_has_preresolution = 3
   18.10    };
   18.11  
   18.12    int flags() const                         { return _flags; }
   18.13 @@ -179,8 +180,10 @@
   18.14  
   18.15    bool has_pseudo_string() const            { return flag_at(FB_has_pseudo_string); }
   18.16    bool has_invokedynamic() const            { return flag_at(FB_has_invokedynamic); }
   18.17 +  bool has_preresolution() const            { return flag_at(FB_has_preresolution); }
   18.18    void set_pseudo_string()                  {    set_flag_at(FB_has_pseudo_string); }
   18.19    void set_invokedynamic()                  {    set_flag_at(FB_has_invokedynamic); }
   18.20 +  void set_preresolution()                  {    set_flag_at(FB_has_preresolution); }
   18.21  
   18.22    // Klass holding pool
   18.23    klassOop pool_holder() const              { return _pool_holder; }
   18.24 @@ -663,6 +666,8 @@
   18.25    friend class SystemDictionary;
   18.26  
   18.27    // Used by compiler to prevent classloading.
   18.28 +  static methodOop method_at_if_loaded        (constantPoolHandle this_oop, int which,
   18.29 +                                               Bytecodes::Code bc = Bytecodes::_illegal);
   18.30    static klassOop klass_at_if_loaded          (constantPoolHandle this_oop, int which);
   18.31    static klassOop klass_ref_at_if_loaded      (constantPoolHandle this_oop, int which);
   18.32    // Same as above - but does LinkResolving.
    19.1 --- a/src/share/vm/oops/cpCacheOop.cpp	Wed Jun 22 14:45:37 2011 -0700
    19.2 +++ b/src/share/vm/oops/cpCacheOop.cpp	Thu Jun 23 17:14:06 2011 -0700
    19.3 @@ -295,6 +295,50 @@
    19.4  }
    19.5  
    19.6  
    19.7 +methodOop ConstantPoolCacheEntry::get_method_if_resolved(Bytecodes::Code invoke_code, constantPoolHandle cpool) {
    19.8 +  assert(invoke_code > (Bytecodes::Code)0, "bad query");
    19.9 +  if (is_secondary_entry()) {
   19.10 +    return cpool->cache()->entry_at(main_entry_index())->get_method_if_resolved(invoke_code, cpool);
   19.11 +  }
   19.12 +  // Decode the action of set_method and set_interface_call
   19.13 +  if (bytecode_1() == invoke_code) {
   19.14 +    oop f1 = _f1;
   19.15 +    if (f1 != NULL) {
   19.16 +      switch (invoke_code) {
   19.17 +      case Bytecodes::_invokeinterface:
   19.18 +        assert(f1->is_klass(), "");
   19.19 +        return klassItable::method_for_itable_index(klassOop(f1), (int) f2());
   19.20 +      case Bytecodes::_invokestatic:
   19.21 +      case Bytecodes::_invokespecial:
   19.22 +        assert(f1->is_method(), "");
   19.23 +        return methodOop(f1);
   19.24 +      }
   19.25 +    }
   19.26 +  }
   19.27 +  if (bytecode_2() == invoke_code) {
   19.28 +    switch (invoke_code) {
   19.29 +    case Bytecodes::_invokevirtual:
   19.30 +      if (is_vfinal()) {
   19.31 +        // invokevirtual
   19.32 +        methodOop m = methodOop((intptr_t) f2());
   19.33 +        assert(m->is_method(), "");
   19.34 +        return m;
   19.35 +      } else {
   19.36 +        int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
   19.37 +        if (cpool->tag_at(holder_index).is_klass()) {
   19.38 +          klassOop klass = cpool->resolved_klass_at(holder_index);
   19.39 +          if (!Klass::cast(klass)->oop_is_instance())
   19.40 +            klass = SystemDictionary::Object_klass();
   19.41 +          return instanceKlass::cast(klass)->method_at_vtable((int) f2());
   19.42 +        }
   19.43 +      }
   19.44 +    }
   19.45 +  }
   19.46 +  return NULL;
   19.47 +}
   19.48 +
   19.49 +
   19.50 +
   19.51  class LocalOopClosure: public OopClosure {
   19.52   private:
   19.53    void (*_f)(oop*);
    20.1 --- a/src/share/vm/oops/cpCacheOop.hpp	Wed Jun 22 14:45:37 2011 -0700
    20.2 +++ b/src/share/vm/oops/cpCacheOop.hpp	Thu Jun 23 17:14:06 2011 -0700
    20.3 @@ -194,6 +194,8 @@
    20.4      methodHandle signature_invoker               // determines signature information
    20.5    );
    20.6  
    20.7 +  methodOop get_method_if_resolved(Bytecodes::Code invoke_code, constantPoolHandle cpool);
    20.8 +
    20.9    // For JVM_CONSTANT_InvokeDynamic cache entries:
   20.10    void initialize_bootstrap_method_index_in_cache(int bsm_cache_index);
   20.11    int  bootstrap_method_index_in_cache();
    21.1 --- a/src/share/vm/oops/methodOop.cpp	Wed Jun 22 14:45:37 2011 -0700
    21.2 +++ b/src/share/vm/oops/methodOop.cpp	Thu Jun 23 17:14:06 2011 -0700
    21.3 @@ -928,14 +928,40 @@
    21.4    name->increment_refcount();
    21.5    signature->increment_refcount();
    21.6  
    21.7 +  // record non-BCP method types in the constant pool
    21.8 +  GrowableArray<KlassHandle>* extra_klasses = NULL;
    21.9 +  for (int i = -1, len = java_lang_invoke_MethodType::ptype_count(method_type()); i < len; i++) {
   21.10 +    oop ptype = (i == -1
   21.11 +                 ? java_lang_invoke_MethodType::rtype(method_type())
   21.12 +                 : java_lang_invoke_MethodType::ptype(method_type(), i));
   21.13 +    klassOop klass = check_non_bcp_klass(java_lang_Class::as_klassOop(ptype));
   21.14 +    if (klass != NULL) {
   21.15 +      if (extra_klasses == NULL)
   21.16 +        extra_klasses = new GrowableArray<KlassHandle>(len+1);
   21.17 +      bool dup = false;
   21.18 +      for (int j = 0; j < extra_klasses->length(); j++) {
   21.19 +        if (extra_klasses->at(j) == klass) { dup = true; break; }
   21.20 +      }
   21.21 +      if (!dup)
   21.22 +        extra_klasses->append(KlassHandle(THREAD, klass));
   21.23 +    }
   21.24 +  }
   21.25 +
   21.26 +  int extra_klass_count = (extra_klasses == NULL ? 0 : extra_klasses->length());
   21.27 +  int cp_length = _imcp_limit + extra_klass_count;
   21.28    constantPoolHandle cp;
   21.29    {
   21.30 -    constantPoolOop cp_oop = oopFactory::new_constantPool(_imcp_limit, IsSafeConc, CHECK_(empty));
   21.31 +    constantPoolOop cp_oop = oopFactory::new_constantPool(cp_length, IsSafeConc, CHECK_(empty));
   21.32      cp = constantPoolHandle(THREAD, cp_oop);
   21.33    }
   21.34    cp->symbol_at_put(_imcp_invoke_name,       name);
   21.35    cp->symbol_at_put(_imcp_invoke_signature,  signature);
   21.36    cp->string_at_put(_imcp_method_type_value, Universe::the_null_string());
   21.37 +  for (int j = 0; j < extra_klass_count; j++) {
   21.38 +    KlassHandle klass = extra_klasses->at(j);
   21.39 +    cp->klass_at_put(_imcp_limit + j, klass());
   21.40 +  }
   21.41 +  cp->set_preresolution();
   21.42    cp->set_pool_holder(holder());
   21.43  
   21.44    // set up the fancy stuff:
   21.45 @@ -984,6 +1010,14 @@
   21.46    return m;
   21.47  }
   21.48  
   21.49 +klassOop methodOopDesc::check_non_bcp_klass(klassOop klass) {
   21.50 +  if (klass != NULL && Klass::cast(klass)->class_loader() != NULL) {
   21.51 +    if (Klass::cast(klass)->oop_is_objArray())
   21.52 +      klass = objArrayKlass::cast(klass)->bottom_klass();
   21.53 +    return klass;
   21.54 +  }
   21.55 +  return NULL;
   21.56 +}
   21.57  
   21.58  
   21.59  methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
    22.1 --- a/src/share/vm/oops/methodOop.hpp	Wed Jun 22 14:45:37 2011 -0700
    22.2 +++ b/src/share/vm/oops/methodOop.hpp	Thu Jun 23 17:14:06 2011 -0700
    22.3 @@ -600,6 +600,7 @@
    22.4                                           Symbol* signature, //anything at all
    22.5                                           Handle method_type,
    22.6                                           TRAPS);
    22.7 +  static klassOop check_non_bcp_klass(klassOop klass);
    22.8    // these operate only on invoke methods:
    22.9    oop method_handle_type() const;
   22.10    static jint* method_type_offsets_chain();  // series of pointer-offsets, terminated by -1
    23.1 --- a/src/share/vm/prims/methodHandleWalk.cpp	Wed Jun 22 14:45:37 2011 -0700
    23.2 +++ b/src/share/vm/prims/methodHandleWalk.cpp	Thu Jun 23 17:14:06 2011 -0700
    23.3 @@ -425,6 +425,8 @@
    23.4          ArgToken arg = _outgoing.at(arg_slot);
    23.5          assert(dest == arg.basic_type(), "");
    23.6          arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty));
    23.7 +        // replace the object by the result of the cast, to make the compiler happy:
    23.8 +        change_argument(T_OBJECT, arg_slot, T_OBJECT, arg);
    23.9          debug_only(dest_klass = (klassOop)badOop);
   23.10          break;
   23.11        }
   23.12 @@ -467,7 +469,7 @@
   23.13          ArgToken arglist[2];
   23.14          arglist[0] = arg;         // outgoing 'this'
   23.15          arglist[1] = ArgToken();  // sentinel
   23.16 -        arg = make_invoke(NULL, unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_(empty));
   23.17 +        arg = make_invoke(methodHandle(), unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_(empty));
   23.18          change_argument(T_OBJECT, arg_slot, dest, arg);
   23.19          break;
   23.20        }
   23.21 @@ -483,7 +485,7 @@
   23.22          ArgToken arglist[2];
   23.23          arglist[0] = arg;         // outgoing value
   23.24          arglist[1] = ArgToken();  // sentinel
   23.25 -        arg = make_invoke(NULL, boxer, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty));
   23.26 +        arg = make_invoke(methodHandle(), boxer, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty));
   23.27          change_argument(src, arg_slot, T_OBJECT, arg);
   23.28          break;
   23.29        }
   23.30 @@ -599,8 +601,9 @@
   23.31            lose("bad vmlayout slot", CHECK_(empty));
   23.32          }
   23.33          // FIXME: consider inlining the invokee at the bytecode level
   23.34 -        ArgToken ret = make_invoke(methodOop(invoker), vmIntrinsics::_none,
   23.35 +        ArgToken ret = make_invoke(methodHandle(THREAD, methodOop(invoker)), vmIntrinsics::_invokeGeneric,
   23.36                                     Bytecodes::_invokevirtual, false, 1+argc, &arglist[0], CHECK_(empty));
   23.37 +        // The iid = _invokeGeneric really means to adjust reference types as needed.
   23.38          DEBUG_ONLY(invoker = NULL);
   23.39          if (rtype == T_OBJECT) {
   23.40            klassOop rklass = java_lang_Class::as_klassOop( java_lang_invoke_MethodType::rtype(recursive_mtype()) );
   23.41 @@ -657,7 +660,7 @@
   23.42          arglist[0] = array_arg;   // value to check
   23.43          arglist[1] = length_arg;  // length to check
   23.44          arglist[2] = ArgToken();  // sentinel
   23.45 -        make_invoke(NULL, vmIntrinsics::_checkSpreadArgument,
   23.46 +        make_invoke(methodHandle(), vmIntrinsics::_checkSpreadArgument,
   23.47                      Bytecodes::_invokestatic, false, 2, &arglist[0], CHECK_(empty));
   23.48  
   23.49          // Spread out the array elements.
   23.50 @@ -680,7 +683,7 @@
   23.51            ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_(empty));
   23.52            ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_(empty));
   23.53            change_argument(T_VOID, ap, element_type, element_arg);
   23.54 -          ap += type2size[element_type];
   23.55 +          //ap += type2size[element_type];  // don't do this; insert next arg to *right* of previous
   23.56          }
   23.57          break;
   23.58        }
   23.59 @@ -731,7 +734,7 @@
   23.60    }
   23.61    assert(ap == _outgoing_argc, "");
   23.62    arglist[ap] = ArgToken();  // add a sentinel, for the sake of asserts
   23.63 -  return make_invoke(chain().last_method_oop(),
   23.64 +  return make_invoke(chain().last_method(),
   23.65                       vmIntrinsics::_none,
   23.66                       chain().last_invoke_code(), true,
   23.67                       ap, arglist, THREAD);
   23.68 @@ -853,7 +856,6 @@
   23.69    if (src != dst) {
   23.70      if (MethodHandles::same_basic_type_for_returns(src, dst, /*raw*/ true)) {
   23.71        if (MethodHandles::is_float_fixed_reinterpretation_cast(src, dst)) {
   23.72 -        if (for_return)  Untested("MHW return raw conversion");  // still untested
   23.73          vmIntrinsics::ID iid = vmIntrinsics::for_raw_conversion(src, dst);
   23.74          if (iid == vmIntrinsics::_none) {
   23.75            lose("no raw conversion method", CHECK);
   23.76 @@ -865,18 +867,24 @@
   23.77            assert(arg.token_type() >= tt_symbolic || src == arg.basic_type(), "sanity");
   23.78            arglist[0] = arg;         // outgoing 'this'
   23.79            arglist[1] = ArgToken();  // sentinel
   23.80 -          arg = make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK);
   23.81 +          arg = make_invoke(methodHandle(), iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK);
   23.82            change_argument(src, slot, dst, arg);
   23.83          } else {
   23.84            // return type conversion
   23.85 -          klassOop arg_klass = NULL;
   23.86 -          arglist[0] = make_parameter(src, arg_klass, -1, CHECK);  // return value
   23.87 -          arglist[1] = ArgToken();                                 // sentinel
   23.88 -          (void) make_invoke(NULL, iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK);
   23.89 +          if (_return_conv == vmIntrinsics::_none) {
   23.90 +            _return_conv = iid;
   23.91 +          } else if (_return_conv == vmIntrinsics::for_raw_conversion(dst, src)) {
   23.92 +            _return_conv = vmIntrinsics::_none;
   23.93 +          } else if (_return_conv != zero_return_conv()) {
   23.94 +            lose(err_msg("requested raw return conversion not allowed: %s -> %s (before %s)", type2name(src), type2name(dst), vmIntrinsics::name_at(_return_conv)), CHECK);
   23.95 +          }
   23.96          }
   23.97        } else {
   23.98          // Nothing to do.
   23.99        }
  23.100 +    } else if (for_return && (!is_subword_type(src) || !is_subword_type(dst))) {
  23.101 +      // This can occur in exception-throwing MHs, which have a fictitious return value encoded as Void or Empty.
  23.102 +      _return_conv = zero_return_conv();
  23.103      } else if (src == T_OBJECT && is_java_primitive(dst)) {
  23.104        // ref-to-prim: discard ref, push zero
  23.105        lose("requested ref-to-prim conversion not expected", CHECK);
  23.106 @@ -896,6 +904,7 @@
  23.107      _thread(THREAD),
  23.108      _bytecode(THREAD, 50),
  23.109      _constants(THREAD, 10),
  23.110 +    _non_bcp_klasses(THREAD, 5),
  23.111      _cur_stack(0),
  23.112      _max_stack(0),
  23.113      _rtype(T_ILLEGAL)
  23.114 @@ -908,6 +917,15 @@
  23.115    _name_index      = cpool_symbol_put(name);
  23.116    _signature_index = cpool_symbol_put(signature);
  23.117  
  23.118 +  // To make the resulting methods more recognizable by
  23.119 +  // stack walkers and compiler heuristics,
  23.120 +  // we put them in holder class MethodHandle.
  23.121 +  // See klass_is_method_handle_adapter_holder
  23.122 +  // and methodOopDesc::is_method_handle_adapter.
  23.123 +  _target_klass = SystemDictionaryHandles::MethodHandle_klass();
  23.124 +
  23.125 +  check_non_bcp_klasses(java_lang_invoke_MethodHandle::type(root()), CHECK);
  23.126 +
  23.127    // Get return type klass.
  23.128    Handle first_mtype(THREAD, chain().method_type_oop());
  23.129    // _rklass is NULL for primitives.
  23.130 @@ -929,6 +947,7 @@
  23.131    assert(_thread == THREAD, "must be same thread");
  23.132    methodHandle nullHandle;
  23.133    (void) walk(CHECK_(nullHandle));
  23.134 +  record_non_bcp_klasses();
  23.135    return get_method_oop(CHECK_(nullHandle));
  23.136  }
  23.137  
  23.138 @@ -1197,10 +1216,18 @@
  23.139    }
  23.140    case T_OBJECT: {
  23.141      Handle value = arg.object();
  23.142 -    if (value.is_null())
  23.143 +    if (value.is_null()) {
  23.144        emit_bc(Bytecodes::_aconst_null);
  23.145 -    else
  23.146 -      emit_bc(Bytecodes::_ldc, cpool_object_put(value));
  23.147 +      break;
  23.148 +    }
  23.149 +    if (java_lang_Class::is_instance(value())) {
  23.150 +      klassOop k = java_lang_Class::as_klassOop(value());
  23.151 +      if (k != NULL) {
  23.152 +        emit_bc(Bytecodes::_ldc, cpool_klass_put(k));
  23.153 +        break;
  23.154 +      }
  23.155 +    }
  23.156 +    emit_bc(Bytecodes::_ldc, cpool_object_put(value));
  23.157      break;
  23.158    }
  23.159    default:
  23.160 @@ -1260,6 +1287,7 @@
  23.161        index = src.index();
  23.162      }
  23.163      emit_bc(op, cpool_klass_put(tk));
  23.164 +    check_non_bcp_klass(tk, CHECK_(src));
  23.165      // Allocate a new local for the type so that we don't hide the
  23.166      // previous type from the verifier.
  23.167      index = new_local_index(type);
  23.168 @@ -1292,15 +1320,15 @@
  23.169  
  23.170  // Emit bytecodes for the given invoke instruction.
  23.171  MethodHandleWalker::ArgToken
  23.172 -MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
  23.173 +MethodHandleCompiler::make_invoke(methodHandle m, vmIntrinsics::ID iid,
  23.174                                    Bytecodes::Code op, bool tailcall,
  23.175                                    int argc, MethodHandleWalker::ArgToken* argv,
  23.176                                    TRAPS) {
  23.177    ArgToken zero;
  23.178 -  if (m == NULL) {
  23.179 +  if (m.is_null()) {
  23.180      // Get the intrinsic methodOop.
  23.181 -    m = vmIntrinsics::method_for(iid);
  23.182 -    if (m == NULL) {
  23.183 +    m = methodHandle(THREAD, vmIntrinsics::method_for(iid));
  23.184 +    if (m.is_null()) {
  23.185        lose(vmIntrinsics::name_at(iid), CHECK_(zero));
  23.186      }
  23.187    }
  23.188 @@ -1309,18 +1337,46 @@
  23.189    Symbol*  name      = m->name();
  23.190    Symbol*  signature = m->signature();
  23.191  
  23.192 +  if (iid == vmIntrinsics::_invokeGeneric &&
  23.193 +      argc >= 1 && argv[0].token_type() == tt_constant) {
  23.194 +    assert(m->intrinsic_id() == vmIntrinsics::_invokeExact, "");
  23.195 +    Handle receiver = argv[0].object();
  23.196 +    Handle rtype(THREAD, java_lang_invoke_MethodHandle::type(receiver()));
  23.197 +    Handle mtype(THREAD, m->method_handle_type());
  23.198 +    if (rtype() != mtype()) {
  23.199 +      assert(java_lang_invoke_MethodType::form(rtype()) ==
  23.200 +             java_lang_invoke_MethodType::form(mtype()),
  23.201 +             "must be the same shape");
  23.202 +      // customize m to the exact required rtype
  23.203 +      bool has_non_bcp_klass = check_non_bcp_klasses(rtype(), CHECK_(zero));
  23.204 +      TempNewSymbol sig2 = java_lang_invoke_MethodType::as_signature(rtype(), true, CHECK_(zero));
  23.205 +      methodHandle m2;
  23.206 +      if (!has_non_bcp_klass) {
  23.207 +        methodOop m2_oop = SystemDictionary::find_method_handle_invoke(m->name(), sig2,
  23.208 +                                                                       KlassHandle(), CHECK_(zero));
  23.209 +        m2 = methodHandle(THREAD, m2_oop);
  23.210 +      }
  23.211 +      if (m2.is_null()) {
  23.212 +        // just build it fresh
  23.213 +        m2 = methodOopDesc::make_invoke_method(klass, m->name(), sig2, rtype, CHECK_(zero));
  23.214 +        if (m2.is_null())
  23.215 +          lose(err_msg("no customized invoker %s", sig2->as_utf8()), CHECK_(zero));
  23.216 +      }
  23.217 +      m = m2;
  23.218 +      signature = m->signature();
  23.219 +    }
  23.220 +  }
  23.221 +
  23.222 +  check_non_bcp_klass(klass, CHECK_(zero));
  23.223 +  if (m->is_method_handle_invoke()) {
  23.224 +    check_non_bcp_klasses(m->method_handle_type(), CHECK_(zero));
  23.225 +  }
  23.226 +
  23.227    // Count the number of arguments, not the size
  23.228    ArgumentCount asc(signature);
  23.229    assert(argc == asc.size() + ((op == Bytecodes::_invokestatic || op == Bytecodes::_invokedynamic) ? 0 : 1),
  23.230           "argc mismatch");
  23.231  
  23.232 -  if (tailcall) {
  23.233 -    // Actually, in order to make these methods more recognizable,
  23.234 -    // let's put them in holder class MethodHandle.  That way stack
  23.235 -    // walkers and compiler heuristics can recognize them.
  23.236 -    _target_klass = SystemDictionary::MethodHandle_klass();
  23.237 -  }
  23.238 -
  23.239    // Inline the method.
  23.240    InvocationCounter* ic = m->invocation_counter();
  23.241    ic->set_carry_flag();
  23.242 @@ -1353,7 +1409,7 @@
  23.243    int signature_index     = cpool_symbol_put(signature);
  23.244    int name_and_type_index = cpool_name_and_type_put(name_index, signature_index);
  23.245    int klass_index         = cpool_klass_put(klass);
  23.246 -  int methodref_index     = cpool_methodref_put(klass_index, name_and_type_index);
  23.247 +  int methodref_index     = cpool_methodref_put(op, klass_index, name_and_type_index, m);
  23.248  
  23.249    // Generate invoke.
  23.250    switch (op) {
  23.251 @@ -1380,6 +1436,20 @@
  23.252    stack_push(rbt);  // The return value is already pushed onto the stack.
  23.253    ArgToken ret;
  23.254    if (tailcall) {
  23.255 +    if (return_conv() == zero_return_conv()) {
  23.256 +      rbt = T_VOID;  // discard value
  23.257 +    } else if (return_conv() != vmIntrinsics::_none) {
  23.258 +      // return value conversion
  23.259 +      int index = new_local_index(rbt);
  23.260 +      emit_store(rbt, index);
  23.261 +      ArgToken arglist[2];
  23.262 +      arglist[0] = ArgToken(tt_temporary, rbt, index);
  23.263 +      arglist[1] = ArgToken();  // sentinel
  23.264 +      ret = make_invoke(methodHandle(), return_conv(), Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(zero));
  23.265 +      set_return_conv(vmIntrinsics::_none);
  23.266 +      rbt = ret.basic_type();
  23.267 +      emit_load(rbt, ret.index());
  23.268 +    }
  23.269      if (rbt != _rtype) {
  23.270        if (rbt == T_VOID) {
  23.271          // push a zero of the right sort
  23.272 @@ -1425,6 +1495,7 @@
  23.273      case T_OBJECT:
  23.274        if (_rklass.not_null() && _rklass() != SystemDictionary::Object_klass() && !Klass::cast(_rklass())->is_interface()) {
  23.275          emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass()));
  23.276 +        check_non_bcp_klass(_rklass(), CHECK_(zero));
  23.277        }
  23.278        emit_bc(Bytecodes::_areturn);
  23.279        break;
  23.280 @@ -1525,6 +1596,52 @@
  23.281    return index;
  23.282  }
  23.283  
  23.284 +bool MethodHandleCompiler::check_non_bcp_klasses(Handle method_type, TRAPS) {
  23.285 +  bool res = false;
  23.286 +  for (int i = -1, len = java_lang_invoke_MethodType::ptype_count(method_type()); i < len; i++) {
  23.287 +    oop ptype = (i == -1
  23.288 +                 ? java_lang_invoke_MethodType::rtype(method_type())
  23.289 +                 : java_lang_invoke_MethodType::ptype(method_type(), i));
  23.290 +    res |= check_non_bcp_klass(java_lang_Class::as_klassOop(ptype), CHECK_(false));
  23.291 +  }
  23.292 +  return res;
  23.293 +}
  23.294 +
  23.295 +bool MethodHandleCompiler::check_non_bcp_klass(klassOop klass, TRAPS) {
  23.296 +  klass = methodOopDesc::check_non_bcp_klass(klass);
  23.297 +  if (klass != NULL) {
  23.298 +    Symbol* name = Klass::cast(klass)->name();
  23.299 +    for (int i = _non_bcp_klasses.length() - 1; i >= 0; i--) {
  23.300 +      klassOop k2 = _non_bcp_klasses.at(i)();
  23.301 +      if (Klass::cast(k2)->name() == name) {
  23.302 +        if (k2 != klass) {
  23.303 +          lose(err_msg("unsupported klass name alias %s", name->as_utf8()), THREAD);
  23.304 +        }
  23.305 +        return true;
  23.306 +      }
  23.307 +    }
  23.308 +    _non_bcp_klasses.append(KlassHandle(THREAD, klass));
  23.309 +    return true;
  23.310 +  }
  23.311 +  return false;
  23.312 +}
  23.313 +
  23.314 +void MethodHandleCompiler::record_non_bcp_klasses() {
  23.315 +  // Append extra klasses to constant pool, to guide klass lookup.
  23.316 +  for (int k = 0; k < _non_bcp_klasses.length(); k++) {
  23.317 +    klassOop non_bcp_klass = _non_bcp_klasses.at(k)();
  23.318 +    bool add_to_cp = true;
  23.319 +    for (int j = 1; j < _constants.length(); j++) {
  23.320 +      ConstantValue* cv = _constants.at(j);
  23.321 +      if (cv != NULL && cv->tag() == JVM_CONSTANT_Class
  23.322 +          && cv->klass_oop() == non_bcp_klass) {
  23.323 +        add_to_cp = false;
  23.324 +        break;
  23.325 +      }
  23.326 +    }
  23.327 +    if (add_to_cp)  cpool_klass_put(non_bcp_klass);
  23.328 +  }
  23.329 +}
  23.330  
  23.331  constantPoolHandle MethodHandleCompiler::get_constant_pool(TRAPS) const {
  23.332    constantPoolHandle nullHandle;
  23.333 @@ -1544,6 +1661,8 @@
  23.334      case JVM_CONSTANT_Double:      cpool->double_at_put(       i, cv->get_jdouble()                    ); break;
  23.335      case JVM_CONSTANT_Class:       cpool->klass_at_put(        i, cv->klass_oop()                      ); break;
  23.336      case JVM_CONSTANT_Methodref:   cpool->method_at_put(       i, cv->first_index(), cv->second_index()); break;
  23.337 +    case JVM_CONSTANT_InterfaceMethodref:
  23.338 +                                cpool->interface_method_at_put(i, cv->first_index(), cv->second_index()); break;
  23.339      case JVM_CONSTANT_NameAndType: cpool->name_and_type_at_put(i, cv->first_index(), cv->second_index()); break;
  23.340      case JVM_CONSTANT_Object:      cpool->object_at_put(       i, cv->object_oop()                     ); break;
  23.341      default: ShouldNotReachHere();
  23.342 @@ -1558,6 +1677,8 @@
  23.343      }
  23.344    }
  23.345  
  23.346 +  cpool->set_preresolution();
  23.347 +
  23.348    // Set the constant pool holder to the target method's class.
  23.349    cpool->set_pool_holder(_target_klass());
  23.350  
  23.351 @@ -1606,6 +1727,33 @@
  23.352    Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(empty));  // Use fake class.
  23.353    Rewriter::relocate_and_link(_target_klass(), methods, CHECK_(empty));  // Use fake class.
  23.354  
  23.355 +  // Pre-resolve selected CP cache entries, to avoid problems with class loader scoping.
  23.356 +  constantPoolCacheHandle cpc(THREAD, cpool->cache());
  23.357 +  for (int i = 0; i < cpc->length(); i++) {
  23.358 +    ConstantPoolCacheEntry* e = cpc->entry_at(i);
  23.359 +    assert(!e->is_secondary_entry(), "no indy instructions in here, yet");
  23.360 +    int constant_pool_index = e->constant_pool_index();
  23.361 +    ConstantValue* cv = _constants.at(constant_pool_index);
  23.362 +    if (!cv->has_linkage())  continue;
  23.363 +    methodHandle m = cv->linkage();
  23.364 +    int index;
  23.365 +    switch (cv->tag()) {
  23.366 +    case JVM_CONSTANT_Methodref:
  23.367 +      index = m->vtable_index();
  23.368 +      if (m->is_static()) {
  23.369 +        e->set_method(Bytecodes::_invokestatic, m, index);
  23.370 +      } else {
  23.371 +        e->set_method(Bytecodes::_invokespecial, m, index);
  23.372 +        e->set_method(Bytecodes::_invokevirtual, m, index);
  23.373 +      }
  23.374 +      break;
  23.375 +    case JVM_CONSTANT_InterfaceMethodref:
  23.376 +      index = klassItable::compute_itable_index(m());
  23.377 +      e->set_interface_call(m, index);
  23.378 +      break;
  23.379 +    }
  23.380 +  }
  23.381 +
  23.382    // Set the invocation counter's count to the invoke count of the
  23.383    // original call site.
  23.384    InvocationCounter* ic = m->invocation_counter();
  23.385 @@ -1696,6 +1844,9 @@
  23.386        _param_state(0),
  23.387        _temp_num(0)
  23.388    {
  23.389 +    out->print("MethodHandle:");
  23.390 +    java_lang_invoke_MethodType::print_signature(java_lang_invoke_MethodHandle::type(root()), out);
  23.391 +    out->print(" : #");
  23.392      start_params();
  23.393    }
  23.394    virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) {
  23.395 @@ -1759,12 +1910,12 @@
  23.396      _strbuf.print(")");
  23.397      return maybe_make_temp("fetch", type, "x");
  23.398    }
  23.399 -  virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid,
  23.400 +  virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid,
  23.401                                 Bytecodes::Code op, bool tailcall,
  23.402                                 int argc, ArgToken* argv, TRAPS) {
  23.403      Symbol* name;
  23.404      Symbol* sig;
  23.405 -    if (m != NULL) {
  23.406 +    if (m.not_null()) {
  23.407        name = m->name();
  23.408        sig  = m->signature();
  23.409      } else {
    24.1 --- a/src/share/vm/prims/methodHandleWalk.hpp	Wed Jun 22 14:45:37 2011 -0700
    24.2 +++ b/src/share/vm/prims/methodHandleWalk.hpp	Thu Jun 23 17:14:06 2011 -0700
    24.3 @@ -98,6 +98,7 @@
    24.4    int       bound_arg_slot()    { assert(is_bound(), ""); return _arg_slot; }
    24.5    oop       bound_arg_oop()     { assert(is_bound(), ""); return BoundMethodHandle_argument_oop(); }
    24.6  
    24.7 +  methodHandle last_method()    { assert(is_last(), ""); return _last_method; }
    24.8    methodOop last_method_oop()   { assert(is_last(), ""); return _last_method(); }
    24.9    Bytecodes::Code last_invoke_code() { assert(is_last(), ""); return _last_invoke; }
   24.10  
   24.11 @@ -181,6 +182,8 @@
   24.12    GrowableArray<ArgToken>  _outgoing;       // current outgoing parameter slots
   24.13    int                      _outgoing_argc;  // # non-empty outgoing slots
   24.14  
   24.15 +  vmIntrinsics::ID _return_conv;            // Return conversion required by raw retypes.
   24.16 +
   24.17    // Replace a value of type old_type at slot (and maybe slot+1) with the new value.
   24.18    // If old_type != T_VOID, remove the old argument at that point.
   24.19    // If new_type != T_VOID, insert the new argument at that point.
   24.20 @@ -219,7 +222,8 @@
   24.21      : _chain(root, THREAD),
   24.22        _for_invokedynamic(for_invokedynamic),
   24.23        _outgoing(THREAD, 10),
   24.24 -      _outgoing_argc(0)
   24.25 +      _outgoing_argc(0),
   24.26 +      _return_conv(vmIntrinsics::_none)
   24.27    {
   24.28      _local_index = for_invokedynamic ? 0 : 1;
   24.29    }
   24.30 @@ -228,6 +232,10 @@
   24.31  
   24.32    bool for_invokedynamic() const { return _for_invokedynamic; }
   24.33  
   24.34 +  vmIntrinsics::ID return_conv() const { return _return_conv; }
   24.35 +  void set_return_conv(vmIntrinsics::ID c) { _return_conv = c; }
   24.36 +  static vmIntrinsics::ID zero_return_conv() { return vmIntrinsics::_min; }
   24.37 +
   24.38    int new_local_index(BasicType bt) {
   24.39      //int index = _for_invokedynamic ? _local_index : _local_index - 1;
   24.40      int index = _local_index;
   24.41 @@ -243,9 +251,9 @@
   24.42    virtual ArgToken make_oop_constant(oop con, TRAPS) = 0;
   24.43    virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS) = 0;
   24.44    virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS) = 0;
   24.45 -  virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS) = 0;
   24.46 +  virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS) = 0;
   24.47  
   24.48 -  // For make_invoke, the methodOop can be NULL if the intrinsic ID
   24.49 +  // For make_invoke, the methodHandle can be NULL if the intrinsic ID
   24.50    // is something other than vmIntrinsics::_none.
   24.51  
   24.52    // and in case anyone cares to related the previous actions to the chain:
   24.53 @@ -280,6 +288,7 @@
   24.54      JavaValue _value;
   24.55      Handle    _handle;
   24.56      Symbol*   _sym;
   24.57 +    methodHandle _method;  // pre-linkage
   24.58  
   24.59    public:
   24.60      // Constructor for oop types.
   24.61 @@ -328,11 +337,21 @@
   24.62      jlong     get_jlong()    const { return _value.get_jlong();   }
   24.63      jfloat    get_jfloat()   const { return _value.get_jfloat();  }
   24.64      jdouble   get_jdouble()  const { return _value.get_jdouble(); }
   24.65 +
   24.66 +    void set_linkage(methodHandle method) {
   24.67 +      assert(_method.is_null(), "");
   24.68 +      _method = method;
   24.69 +    }
   24.70 +    bool     has_linkage()   const { return _method.not_null(); }
   24.71 +    methodHandle linkage()   const { return _method; }
   24.72    };
   24.73  
   24.74    // Fake constant pool.
   24.75    GrowableArray<ConstantValue*> _constants;
   24.76  
   24.77 +  // Non-BCP classes that appear in associated MethodTypes (require special handling).
   24.78 +  GrowableArray<KlassHandle> _non_bcp_klasses;
   24.79 +
   24.80    // Accumulated compiler state:
   24.81    GrowableArray<unsigned char> _bytecode;
   24.82  
   24.83 @@ -368,15 +387,20 @@
   24.84      return _constants.append(cv);
   24.85    }
   24.86  
   24.87 -  int cpool_oop_reference_put(int tag, int first_index, int second_index) {
   24.88 +  int cpool_oop_reference_put(int tag, int first_index, int second_index, methodHandle method) {
   24.89      if (first_index == 0 && second_index == 0)  return 0;
   24.90      assert(first_index != 0 && second_index != 0, "no zero indexes");
   24.91      ConstantValue* cv = new ConstantValue(tag, first_index, second_index);
   24.92 +    if (method.not_null())  cv->set_linkage(method);
   24.93      return _constants.append(cv);
   24.94    }
   24.95  
   24.96    int cpool_primitive_put(BasicType type, jvalue* con);
   24.97  
   24.98 +  bool check_non_bcp_klasses(Handle method_type, TRAPS);
   24.99 +  bool check_non_bcp_klass(klassOop klass, TRAPS);
  24.100 +  void record_non_bcp_klasses();
  24.101 +
  24.102    int cpool_int_put(jint value) {
  24.103      jvalue con; con.i = value;
  24.104      return cpool_primitive_put(T_INT, &con);
  24.105 @@ -403,11 +427,12 @@
  24.106    int cpool_klass_put(klassOop klass) {
  24.107      return cpool_oop_put(JVM_CONSTANT_Class, klass);
  24.108    }
  24.109 -  int cpool_methodref_put(int class_index, int name_and_type_index) {
  24.110 -    return cpool_oop_reference_put(JVM_CONSTANT_Methodref, class_index, name_and_type_index);
  24.111 +  int cpool_methodref_put(Bytecodes::Code op, int class_index, int name_and_type_index, methodHandle method) {
  24.112 +    int tag = (op == Bytecodes::_invokeinterface ? JVM_CONSTANT_InterfaceMethodref : JVM_CONSTANT_Methodref);
  24.113 +    return cpool_oop_reference_put(tag, class_index, name_and_type_index, method);
  24.114    }
  24.115    int cpool_name_and_type_put(int name_index, int signature_index) {
  24.116 -    return cpool_oop_reference_put(JVM_CONSTANT_NameAndType, name_index, signature_index);
  24.117 +    return cpool_oop_reference_put(JVM_CONSTANT_NameAndType, name_index, signature_index, methodHandle());
  24.118    }
  24.119  
  24.120    void emit_bc(Bytecodes::Code op, int index = 0, int args_size = -1);
  24.121 @@ -428,7 +453,7 @@
  24.122  
  24.123    virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS);
  24.124    virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS);
  24.125 -  virtual ArgToken make_invoke(methodOop m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS);
  24.126 +  virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS);
  24.127  
  24.128    // Get a real constant pool.
  24.129    constantPoolHandle get_constant_pool(TRAPS) const;
    25.1 --- a/src/share/vm/prims/methodHandles.cpp	Wed Jun 22 14:45:37 2011 -0700
    25.2 +++ b/src/share/vm/prims/methodHandles.cpp	Thu Jun 23 17:14:06 2011 -0700
    25.3 @@ -24,12 +24,14 @@
    25.4  
    25.5  #include "precompiled.hpp"
    25.6  #include "classfile/symbolTable.hpp"
    25.7 +#include "compiler/compileBroker.hpp"
    25.8  #include "interpreter/interpreter.hpp"
    25.9  #include "interpreter/oopMapCache.hpp"
   25.10  #include "memory/allocation.inline.hpp"
   25.11  #include "memory/oopFactory.hpp"
   25.12  #include "prims/methodHandles.hpp"
   25.13  #include "prims/methodHandleWalk.hpp"
   25.14 +#include "runtime/compilationPolicy.hpp"
   25.15  #include "runtime/javaCalls.hpp"
   25.16  #include "runtime/reflection.hpp"
   25.17  #include "runtime/signature.hpp"
   25.18 @@ -767,7 +769,9 @@
   25.19          m = NULL;
   25.20          // try again with a different class loader...
   25.21        }
   25.22 -      if (m != NULL) {
   25.23 +      if (m != NULL &&
   25.24 +          m->is_method_handle_invoke() &&
   25.25 +          java_lang_invoke_MethodType::equals(polymorphic_method_type(), m->method_handle_type())) {
   25.26          int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
   25.27          java_lang_invoke_MemberName::set_vmtarget(mname(),  m);
   25.28          java_lang_invoke_MemberName::set_vmindex(mname(),   m->vtable_index());
   25.29 @@ -986,6 +990,48 @@
   25.30  // This is for debugging and reflection.
   25.31  oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
   25.32    assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH");
   25.33 +  if (format == ETF_FORCE_DIRECT_HANDLE ||
   25.34 +      format == ETF_COMPILE_DIRECT_HANDLE) {
   25.35 +    // Internal function for stress testing.
   25.36 +    Handle mt = java_lang_invoke_MethodHandle::type(mh());
   25.37 +    int invocation_count = 10000;
   25.38 +    TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK_NULL);
   25.39 +    bool omit_receiver_argument = true;
   25.40 +    MethodHandleCompiler mhc(mh, vmSymbols::invoke_name(), signature, invocation_count, omit_receiver_argument, CHECK_NULL);
   25.41 +    methodHandle m = mhc.compile(CHECK_NULL);
   25.42 +    if (StressMethodHandleWalk && Verbose || PrintMiscellaneous) {
   25.43 +      tty->print_cr("MethodHandleNatives.getTarget(%s)",
   25.44 +                    format == ETF_FORCE_DIRECT_HANDLE ? "FORCE_DIRECT" : "COMPILE_DIRECT");
   25.45 +      if (Verbose) {
   25.46 +        m->print_codes();
   25.47 +      }
   25.48 +    }
   25.49 +    if (StressMethodHandleWalk) {
   25.50 +      InterpreterOopMap mask;
   25.51 +      OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask);
   25.52 +    }
   25.53 +    if ((format == ETF_COMPILE_DIRECT_HANDLE ||
   25.54 +         CompilationPolicy::must_be_compiled(m))
   25.55 +        && !instanceKlass::cast(m->method_holder())->is_not_initialized()
   25.56 +        && CompilationPolicy::can_be_compiled(m)) {
   25.57 +      // Force compilation
   25.58 +      CompileBroker::compile_method(m, InvocationEntryBci,
   25.59 +                                    CompLevel_initial_compile,
   25.60 +                                    methodHandle(), 0, "MethodHandleNatives.getTarget",
   25.61 +                                    CHECK_NULL);
   25.62 +    }
   25.63 +    // Now wrap m in a DirectMethodHandle.
   25.64 +    instanceKlassHandle dmh_klass(THREAD, SystemDictionary::DirectMethodHandle_klass());
   25.65 +    Handle dmh = dmh_klass->allocate_instance_handle(CHECK_NULL);
   25.66 +    JavaValue ignore_result(T_VOID);
   25.67 +    Symbol* init_name = vmSymbols::object_initializer_name();
   25.68 +    Symbol* init_sig  = vmSymbols::notifyGenericMethodType_signature();
   25.69 +    JavaCalls::call_special(&ignore_result, dmh,
   25.70 +                            SystemDictionaryHandles::MethodHandle_klass(), init_name, init_sig,
   25.71 +                            java_lang_invoke_MethodHandle::type(mh()), CHECK_NULL);
   25.72 +    MethodHandles::init_DirectMethodHandle(dmh, m, false, CHECK_NULL);
   25.73 +    return dmh();
   25.74 +  }
   25.75    if (format == ETF_HANDLE_OR_METHOD_NAME) {
   25.76      oop target = java_lang_invoke_MethodHandle::vmtarget(mh());
   25.77      if (target == NULL) {
   25.78 @@ -1221,6 +1267,12 @@
   25.79            klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
   25.80            if (aklass_oop != NULL)
   25.81              aklass = KlassHandle(THREAD, aklass_oop);
   25.82 +          if (aklass.is_null() &&
   25.83 +              pklass.not_null() &&
   25.84 +              loader.is_null() &&
   25.85 +              pklass->name() == name)
   25.86 +            // accept name equivalence here, since that's the best we can do
   25.87 +            aklass = pklass;
   25.88          }
   25.89        } else {
   25.90          // for method handle invokers we don't look at the name in the signature
   25.91 @@ -2654,6 +2706,17 @@
   25.92      }
   25.93      InterpreterOopMap mask;
   25.94      OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask);
   25.95 +    // compile to object code if -Xcomp or WizardMode
   25.96 +    if ((WizardMode ||
   25.97 +         CompilationPolicy::must_be_compiled(m))
   25.98 +        && !instanceKlass::cast(m->method_holder())->is_not_initialized()
   25.99 +        && CompilationPolicy::can_be_compiled(m)) {
  25.100 +      // Force compilation
  25.101 +      CompileBroker::compile_method(m, InvocationEntryBci,
  25.102 +                                    CompLevel_initial_compile,
  25.103 +                                    methodHandle(), 0, "StressMethodHandleWalk",
  25.104 +                                    CHECK);
  25.105 +    }
  25.106    }
  25.107  }
  25.108  
  25.109 @@ -2773,7 +2836,12 @@
  25.110      // Build a BMH on top of a DMH or another BMH:
  25.111      MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK);
  25.112    }
  25.113 -  stress_method_handle_walk(mh, CHECK);
  25.114 +
  25.115 +  if (StressMethodHandleWalk) {
  25.116 +    if (mh->klass() == SystemDictionary::BoundMethodHandle_klass())
  25.117 +      stress_method_handle_walk(mh, CHECK);
  25.118 +    // else don't, since the subclass has not yet initialized its own fields
  25.119 +  }
  25.120  }
  25.121  JVM_END
  25.122  
    26.1 --- a/src/share/vm/prims/methodHandles.hpp	Wed Jun 22 14:45:37 2011 -0700
    26.2 +++ b/src/share/vm/prims/methodHandles.hpp	Thu Jun 23 17:14:06 2011 -0700
    26.3 @@ -588,6 +588,8 @@
    26.4      ETF_DIRECT_HANDLE         = 1, // ultimate method handle (will be a DMH, may be self)
    26.5      ETF_METHOD_NAME           = 2, // ultimate method as MemberName
    26.6      ETF_REFLECT_METHOD        = 3, // ultimate method as java.lang.reflect object (sans refClass)
    26.7 +    ETF_FORCE_DIRECT_HANDLE   = 64,
    26.8 +    ETF_COMPILE_DIRECT_HANDLE = 65,
    26.9  
   26.10      // ad hoc constants
   26.11      OP_ROT_ARGS_DOWN_LIMIT_BIAS = -1

mercurial