8050887: Intrinsify constants for default values
Reviewed-by: vlivanov, psandoz
Contributed-by: john.r.rose@oracle.com
diff --git a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
index 6074df0..da78e44 100644
--- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
@@ -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;
diff --git a/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/src/share/classes/java/lang/invoke/MethodHandleImpl.java
index 568f3bf..419cecc 100644
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java
+++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java
@@ -1054,6 +1054,7 @@
ARRAY_LOAD,
ARRAY_STORE,
IDENTITY,
+ ZERO,
NONE // no intrinsic associated
}
diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java
index 8318fb6..1f8d0e9 100644
--- a/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -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];