< prev index next >

src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java

Print this page
rev 15353 : 8164044: Generate the corresponding BoundMethodHandle to all generated DirectMethodHandles
Reviewed-by: vlivanov, mhaupt

@@ -25,10 +25,11 @@
 
 package java.lang.invoke;
 
 import java.util.Arrays;
 import static java.lang.invoke.LambdaForm.*;
+import static java.lang.invoke.LambdaForm.Kind.*;
 import static java.lang.invoke.MethodHandleStatics.*;
 
 /**
  * A method handle whose invocation behavior is determined by a target.
  * The delegating MH itself can hold extra "intentions" beyond the simple behavior.

@@ -94,28 +95,26 @@
 
     static LambdaForm makeReinvokerForm(MethodHandle target,
                                         int whichCache,
                                         Object constraint,
                                         NamedFunction getTargetFn) {
-        String debugString;
-        switch(whichCache) {
-            case MethodTypeForm.LF_REBIND:            debugString = "BMH.reinvoke";      break;
-            case MethodTypeForm.LF_DELEGATE:          debugString = "MH.delegate";       break;
-            default:                                  debugString = "MH.reinvoke";       break;
-        }
         // No pre-action needed.
-        return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null);
+        return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null);
     }
     /** Create a LF which simply reinvokes a target of the given basic type. */
     static LambdaForm makeReinvokerForm(MethodHandle target,
                                         int whichCache,
                                         Object constraint,
                                         String debugString,
                                         boolean forceInline,
                                         NamedFunction getTargetFn,
                                         NamedFunction preActionFn) {
         MethodType mtype = target.type().basicType();
+        Kind kind = whichKind(whichCache);
+        if (debugString == null) {
+            debugString = kind.defaultLambdaName;
+        }
         boolean customized = (whichCache < 0 ||
                 mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY);
         boolean hasPreAction = (preActionFn != null);
         LambdaForm form;
         if (!customized) {

@@ -143,22 +142,38 @@
             names[NEXT_MH] = new LambdaForm.Name(getTargetFn, names[THIS_DMH]);
             targetArgs = Arrays.copyOfRange(names, THIS_DMH, ARG_LIMIT, Object[].class);
             targetArgs[0] = names[NEXT_MH];  // overwrite this MH with next MH
             names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs);
         }
-        form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline);
+        form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind);
         if (!customized) {
             form = mtype.form().setCachedLambdaForm(whichCache, form);
         }
         return form;
     }
 
+    private static Kind whichKind(int whichCache) {
+        switch(whichCache) {
+            case MethodTypeForm.LF_REBIND:            return BOUND_REINVOKER;
+            case MethodTypeForm.LF_DELEGATE:          return DELEGATE;
+            default:                                  return REINVOKER;
+        }
+    }
+
     static final NamedFunction NF_getTarget;
     static {
         try {
             NF_getTarget = new NamedFunction(DelegatingMethodHandle.class
                                              .getDeclaredMethod("getTarget"));
         } catch (ReflectiveOperationException ex) {
             throw newInternalError(ex);
         }
+        // The Holder class will contain pre-generated DelegatingMethodHandles resolved
+        // speculatively using MemberName.getFactory().resolveOrNull. However, that
+        // doesn't initialize the class, which subtly breaks inlining etc. By forcing
+        // initialization of the Holder class we avoid these issues.
+        UNSAFE.ensureClassInitialized(Holder.class);
     }
+
+    /* Placeholder class for DelegatingMethodHandles generated ahead of time */
+    final class Holder {}
 }
< prev index next >