< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP

@@ -150,17 +150,18 @@
   if (signature == NULL) {
     return empty;  // no such signature exists in the VM
   }
   Handle resolved;
   int flags = java_lang_invoke_MemberName::flags(mname());
+  bool check_access = false;  // is this right?
   switch (flags & ALL_KINDS) {
     case IS_METHOD:
     case IS_CONSTRUCTOR:
       resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
       break;
     case IS_FIELD:
-      resolved = SystemDictionary::find_field_handle_type(signature, caller, CHECK_(empty));
+      resolved = SystemDictionary::find_java_mirror_for_type(signature, caller, SignatureStream::NCDFError, check_access, CHECK_(empty));
       break;
     default:
       THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
   }
   if (resolved.is_null()) {

@@ -1141,22 +1142,64 @@
 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
 // that intrinsic (non-JNI) native methods are defined in HotSpot.
 //
 
 #ifndef PRODUCT
+# ifndef ADVERTISE_CON_VALUES
+#   define ADVERTISE_CON_VALUES
+# endif
+#endif
+
+#ifdef ADVERTISE_CON_VALUES
+// The following macrology pushes a list of symbolic definitions,
+// all of integral type, up through getNamedCon, into the
+// verifyConstants method of jli.MethodHandleNatives.
+// In a debug build, and if the java -esa flag is thrown,
+// we make sure all of these names are kept in sync.
 #define EACH_NAMED_CON(template, requirement) \
     template(java_lang_invoke_MemberName,MN_IS_METHOD) \
     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
     template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
+    template(RefKind,REF_NONE) \
+    template(RefKind,REF_getField) \
+    template(RefKind,REF_getStatic) \
+    template(RefKind,REF_putField) \
+    template(RefKind,REF_putStatic) \
+    template(RefKind,REF_invokeVirtual) \
+    template(RefKind,REF_invokeStatic) \
+    template(RefKind,REF_invokeSpecial) \
+    template(RefKind,REF_newInvokeSpecial) \
+    template(RefKind,REF_invokeInterface) \
+    template(RefKind,REF_LIMIT) \
+    template(ConstantPool,R_IFPRESENT) \
+    template(ConstantPool,R_FORCE) \
+    template(ConstantPool,R_SYMREF) \
     /*end*/
 
+class RefKind {
+  public:
+  enum {
+    REF_NONE                    = 0,  // null value
+    REF_getField                = 1,
+    REF_getStatic               = 2,
+    REF_putField                = 3,
+    REF_putStatic               = 4,
+    REF_invokeVirtual           = 5,
+    REF_invokeStatic            = 6,
+    REF_invokeSpecial           = 7,
+    REF_newInvokeSpecial        = 8,
+    REF_invokeInterface         = 9,
+    REF_LIMIT                  = 10
+  };
+};
+
 #define IGNORE_REQ(req_expr) /* req_expr */
 #define ONE_PLUS(scope,value) 1+
 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0;
 #define VALUE_COMMA(scope,value) scope::value,
 static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 };

@@ -1182,14 +1225,15 @@
 
 #undef ONE_PLUS
 #undef VALUE_COMMA
 #undef STRING_NULL
 #undef EACH_NAMED_CON
-#endif // PRODUCT
+
+#endif // ADVERTISE_CON_VALUES
 
 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
-#ifndef PRODUCT
+#ifdef ADVERTISE_CON_VALUES
   if (advertise_con_value(which)) {
     assert(which >= 0 && which < con_value_count, "");
     int con = con_values[which];
     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
     if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {

@@ -1405,91 +1449,10 @@
     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
   }
 }
 JVM_END
 
-JVM_ENTRY(void, MHN_copyOutBootstrapArguments(JNIEnv* env, jobject igcls,
-                                              jobject caller_jh, jintArray index_info_jh,
-                                              jint start, jint end,
-                                              jobjectArray buf_jh, jint pos,
-                                              jboolean resolve, jobject ifna_jh)) {
-  Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller_jh));
-  if (caller_k == NULL || !caller_k->is_instance_klass()) {
-      THROW_MSG(vmSymbols::java_lang_InternalError(), "bad caller");
-  }
-  InstanceKlass* caller = InstanceKlass::cast(caller_k);
-  typeArrayOop index_info_oop = (typeArrayOop) JNIHandles::resolve(index_info_jh);
-  if (index_info_oop == NULL ||
-      index_info_oop->klass() != Universe::intArrayKlassObj() ||
-      typeArrayOop(index_info_oop)->length() < 2) {
-      THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (0)");
-  }
-  typeArrayHandle index_info(THREAD, index_info_oop);
-  int bss_index_in_pool = index_info->int_at(1);
-  // While we are here, take a quick look at the index info:
-  if (bss_index_in_pool <= 0 ||
-      bss_index_in_pool >= caller->constants()->length() ||
-      index_info->int_at(0)
-      != caller->constants()->invoke_dynamic_argument_count_at(bss_index_in_pool)) {
-      THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (1)");
-  }
-  objArrayHandle buf(THREAD, (objArrayOop) JNIHandles::resolve(buf_jh));
-  if (start < 0) {
-    for (int pseudo_index = -4; pseudo_index < 0; pseudo_index++) {
-      if (start == pseudo_index) {
-        if (start >= end || 0 > pos || pos >= buf->length())  break;
-        oop pseudo_arg = NULL;
-        switch (pseudo_index) {
-        case -4:  // bootstrap method
-          {
-            int bsm_index = caller->constants()->invoke_dynamic_bootstrap_method_ref_index_at(bss_index_in_pool);
-            pseudo_arg = caller->constants()->resolve_possibly_cached_constant_at(bsm_index, CHECK);
-            break;
-          }
-        case -3:  // name
-          {
-            Symbol* name = caller->constants()->name_ref_at(bss_index_in_pool);
-            Handle str = java_lang_String::create_from_symbol(name, CHECK);
-            pseudo_arg = str();
-            break;
-          }
-        case -2:  // type
-          {
-            Symbol* type = caller->constants()->signature_ref_at(bss_index_in_pool);
-            Handle th;
-            if (type->byte_at(0) == '(') {
-              th = SystemDictionary::find_method_handle_type(type, caller, CHECK);
-            } else {
-              th = SystemDictionary::find_java_mirror_for_type(type, caller, SignatureStream::NCDFError, CHECK);
-            }
-            pseudo_arg = th();
-            break;
-          }
-        case -1:  // argument count
-          {
-            int argc = caller->constants()->invoke_dynamic_argument_count_at(bss_index_in_pool);
-            jvalue argc_value; argc_value.i = (jint)argc;
-            pseudo_arg = java_lang_boxing_object::create(T_INT, &argc_value, CHECK);
-            break;
-          }
-        }
-
-        // Store the pseudo-argument, and advance the pointers.
-        buf->obj_at_put(pos++, pseudo_arg);
-        ++start;
-      }
-    }
-    // When we are done with this there may be regular arguments to process too.
-  }
-  Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
-  caller->constants()->
-    copy_bootstrap_arguments_at(bss_index_in_pool,
-                                start, end, buf, pos,
-                                (resolve == JNI_TRUE), ifna, CHECK);
-}
-JVM_END
-
 // It is called by a Cleaner object which ensures that dropped CallSites properly
 // deallocate their dependency information.
 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
   {

@@ -1565,11 +1528,10 @@
   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
   {CC "getMembers",                CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
   {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
   {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
   {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
-  {CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V",     FN_PTR(MHN_copyOutBootstrapArguments)},
   {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
   {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
   {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
   {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
 };
< prev index next >