changeset 9992:2419b8500b27

8050887: Intrinsify constants for default values Reviewed-by: vlivanov, psandoz Contributed-by: john.r.rose@oracle.com
author vlivanov
date Wed, 10 Sep 2014 18:34:03 +0400
parents db52173c10e4
children 9d3feb922367
files src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java src/share/classes/java/lang/invoke/MethodHandleImpl.java src/share/classes/java/lang/invoke/MethodHandles.java
diffstat 3 files changed, 31 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Sep 10 18:34:03 2014 +0400
+++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Wed Sep 10 18:34:03 2014 +0400
@@ -668,6 +668,10 @@
                     assert(name.arguments.length == 1);
                     emitPushArguments(name);
                     continue;
+                case ZERO:
+                    assert(name.arguments.length == 0);
+                    emitConst(name.type.basicTypeWrapper().zero());
+                    continue;
                 case NONE:
                     // no intrinsic associated
                     break;
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Sep 10 18:34:03 2014 +0400
+++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Sep 10 18:34:03 2014 +0400
@@ -1054,6 +1054,7 @@
         ARRAY_LOAD,
         ARRAY_STORE,
         IDENTITY,
+        ZERO,
         NONE // no intrinsic associated
     }
 
--- a/src/share/classes/java/lang/invoke/MethodHandles.java	Wed Sep 10 18:34:03 2014 +0400
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java	Wed Sep 10 18:34:03 2014 +0400
@@ -2185,9 +2185,14 @@
             if (type == void.class)
                 throw newIllegalArgumentException("void type");
             Wrapper w = Wrapper.forPrimitiveType(type);
-            return insertArguments(identity(type), 0, w.convert(value, type));
+            value = w.convert(value, type);
+            if (w.zero().equals(value))
+                return zero(w, type);
+            return insertArguments(identity(type), 0, value);
         } else {
-            return identity(type).bindTo(type.cast(value));
+            if (value == null)
+                return zero(Wrapper.OBJECT, type);
+            return identity(type).bindTo(value);
         }
     }
 
@@ -2218,6 +2223,25 @@
         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
     }
+
+    private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
+        int pos = btw.ordinal();
+        MethodHandle zero = ZERO_MHS[pos];
+        if (zero == null) {
+            zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
+        }
+        if (zero.type().returnType() == rtype)
+            return zero;
+        assert(btw == Wrapper.OBJECT);
+        return makeZero(rtype);
+    }
+    private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.values().length];
+    private static MethodHandle makeZero(Class<?> rtype) {
+        MethodType mtype = MethodType.methodType(rtype);
+        LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
+        return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
+    }
+
     synchronized private static MethodHandle setCachedMethodHandle(MethodHandle[] cache, int pos, MethodHandle value) {
         // Simulate a CAS, to avoid racy duplication of results.
         MethodHandle prev = cache[pos];