changeset 9283:9651848cd4f6

8033666: Make sure @ForceInline is everywhere it needs to be in sun.misc and java.lang.invoke Reviewed-by: twisti, jrose
author vlivanov
date Tue, 25 Mar 2014 20:48:26 +0400
parents 34171d196322
children 977e36a8142d
files src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java src/share/classes/java/lang/invoke/MethodHandleImpl.java src/share/classes/sun/invoke/util/ValueConversions.java
diffstat 3 files changed, 33 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Mar 25 20:46:22 2014 +0400
+++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Mar 25 20:48:26 2014 +0400
@@ -48,6 +48,7 @@
 class InvokerBytecodeGenerator {
     /** Define class names for convenience. */
     private static final String MH      = "java/lang/invoke/MethodHandle";
+    private static final String MHI     = "java/lang/invoke/MethodHandleImpl";
     private static final String LF      = "java/lang/invoke/LambdaForm";
     private static final String LFN     = "java/lang/invoke/LambdaForm$Name";
     private static final String CLS     = "java/lang/Class";
@@ -57,6 +58,7 @@
     private static final String LF_SIG  = "L" + LF + ";";
     private static final String LFN_SIG = "L" + LFN + ";";
     private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
+    private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
 
     /** Name of its super class*/
     private static final String superName = LF;
@@ -433,7 +435,7 @@
                 mv.visitLdcInsn(constantPlaceholder(pclass));
                 mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
                 mv.visitInsn(Opcodes.SWAP);
-                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG);
+                mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG);
                 if (pclass.isArray())
                     mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
             }
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Mar 25 20:46:22 2014 +0400
+++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Mar 25 20:48:26 2014 +0400
@@ -253,7 +253,7 @@
                     // Note:  Do not check for a class hierarchy relation
                     // between src and dst.  In all cases a 'null' argument
                     // will pass the cast conversion.
-                    fn = ValueConversions.cast(dst);
+                    fn = ValueConversions.cast(dst, Lazy.MH_castReference);
                 }
             }
             Name conv = new Name(fn, names[INARG_BASE + i]);
@@ -293,6 +293,25 @@
         return SimpleMethodHandle.make(srcType, form);
     }
 
+    /**
+     * Identity function, with reference cast.
+     * @param t an arbitrary reference type
+     * @param x an arbitrary reference value
+     * @return the same value x
+     */
+    @ForceInline
+    @SuppressWarnings("unchecked")
+    static <T,U> T castReference(Class<? extends T> t, U x) {
+        // inlined Class.cast because we can't ForceInline it
+        if (x != null && !t.isInstance(x))
+            throw newClassCastException(t, x);
+        return (T) x;
+    }
+
+    private static ClassCastException newClassCastException(Class<?> t, Object obj) {
+        return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
+    }
+
     static MethodHandle makeReferenceIdentity(Class<?> refType) {
         MethodType lambdaType = MethodType.genericMethodType(1).invokerType();
         Name[] names = arguments(1, lambdaType);
@@ -488,6 +507,8 @@
         static final NamedFunction NF_selectAlternative;
         static final NamedFunction NF_throwException;
 
+        static final MethodHandle MH_castReference;
+
         static {
             try {
                 NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
@@ -501,6 +522,9 @@
                 NF_guardWithCatch.resolve();
                 NF_selectAlternative.resolve();
                 NF_throwException.resolve();
+
+                MethodType mt = MethodType.methodType(Object.class, Class.class, Object.class);
+                MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference", mt);
             } catch (ReflectiveOperationException ex) {
                 throw newInternalError(ex);
             }
--- a/src/share/classes/sun/invoke/util/ValueConversions.java	Tue Mar 25 20:46:22 2014 +0400
+++ b/src/share/classes/sun/invoke/util/ValueConversions.java	Tue Mar 25 20:48:26 2014 +0400
@@ -443,20 +443,6 @@
         return x;
     }
 
-    /**
-     * Identity function, with reference cast.
-     * @param t an arbitrary reference type
-     * @param x an arbitrary reference value
-     * @return the same value x
-     */
-    @SuppressWarnings("unchecked")
-    static <T,U> T castReference(Class<? extends T> t, U x) {
-        // inlined Class.cast because we can't ForceInline it
-        if (x != null && !t.isInstance(x))
-            throw newClassCastException(t, x);
-        return (T) x;
-    }
-
     private static ClassCastException newClassCastException(Class<?> t, Object obj) {
         return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
     }
@@ -466,12 +452,10 @@
     static {
         try {
             MethodType idType = MethodType.genericMethodType(1);
-            MethodType castType = idType.insertParameterTypes(0, Class.class);
             MethodType ignoreType = idType.changeReturnType(void.class);
             MethodType zeroObjectType = MethodType.genericMethodType(0);
             IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
-            //CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
-            CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType);
+            CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
             ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
             IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
             EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
@@ -509,6 +493,9 @@
      *  and returns it as the given type.
      */
     public static MethodHandle cast(Class<?> type) {
+        return cast(type, CAST_REFERENCE);
+    }
+    public static MethodHandle cast(Class<?> type, MethodHandle castReference) {
         if (type.isPrimitive())  throw new IllegalArgumentException("cannot cast primitive type "+type);
         MethodHandle mh;
         Wrapper wrap = null;
@@ -519,7 +506,7 @@
             mh = cache.get(wrap);
             if (mh != null)  return mh;
         }
-        mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
+        mh = MethodHandles.insertArguments(castReference, 0, type);
         if (cache != null)
             cache.put(wrap, mh);
         return mh;