提交 1b86b228 编写于 作者: V vlivanov

8033666: Make sure @ForceInline is everywhere it needs to be in sun.misc and java.lang.invoke

Reviewed-by: twisti, jrose
上级 df99a0f2
...@@ -48,6 +48,7 @@ import sun.invoke.util.VerifyType; ...@@ -48,6 +48,7 @@ import sun.invoke.util.VerifyType;
class InvokerBytecodeGenerator { class InvokerBytecodeGenerator {
/** Define class names for convenience. */ /** Define class names for convenience. */
private static final String MH = "java/lang/invoke/MethodHandle"; 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 LF = "java/lang/invoke/LambdaForm";
private static final String LFN = "java/lang/invoke/LambdaForm$Name"; private static final String LFN = "java/lang/invoke/LambdaForm$Name";
private static final String CLS = "java/lang/Class"; private static final String CLS = "java/lang/Class";
...@@ -57,6 +58,7 @@ class InvokerBytecodeGenerator { ...@@ -57,6 +58,7 @@ class InvokerBytecodeGenerator {
private static final String LF_SIG = "L" + LF + ";"; private static final String LF_SIG = "L" + LF + ";";
private static final String LFN_SIG = "L" + LFN + ";"; private static final String LFN_SIG = "L" + LFN + ";";
private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; 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*/ /** Name of its super class*/
private static final String superName = LF; private static final String superName = LF;
...@@ -433,7 +435,7 @@ class InvokerBytecodeGenerator { ...@@ -433,7 +435,7 @@ class InvokerBytecodeGenerator {
mv.visitLdcInsn(constantPlaceholder(pclass)); mv.visitLdcInsn(constantPlaceholder(pclass));
mv.visitTypeInsn(Opcodes.CHECKCAST, CLS); mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
mv.visitInsn(Opcodes.SWAP); mv.visitInsn(Opcodes.SWAP);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG); mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG);
if (pclass.isArray()) if (pclass.isArray())
mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY); mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
} }
......
...@@ -253,7 +253,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -253,7 +253,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
// Note: Do not check for a class hierarchy relation // Note: Do not check for a class hierarchy relation
// between src and dst. In all cases a 'null' argument // between src and dst. In all cases a 'null' argument
// will pass the cast conversion. // 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]); Name conv = new Name(fn, names[INARG_BASE + i]);
...@@ -293,6 +293,25 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -293,6 +293,25 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return SimpleMethodHandle.make(srcType, form); 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) { static MethodHandle makeReferenceIdentity(Class<?> refType) {
MethodType lambdaType = MethodType.genericMethodType(1).invokerType(); MethodType lambdaType = MethodType.genericMethodType(1).invokerType();
Name[] names = arguments(1, lambdaType); Name[] names = arguments(1, lambdaType);
...@@ -488,6 +507,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -488,6 +507,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static final NamedFunction NF_selectAlternative; static final NamedFunction NF_selectAlternative;
static final NamedFunction NF_throwException; static final NamedFunction NF_throwException;
static final MethodHandle MH_castReference;
static { static {
try { try {
NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
...@@ -501,6 +522,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -501,6 +522,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
NF_guardWithCatch.resolve(); NF_guardWithCatch.resolve();
NF_selectAlternative.resolve(); NF_selectAlternative.resolve();
NF_throwException.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) { } catch (ReflectiveOperationException ex) {
throw newInternalError(ex); throw newInternalError(ex);
} }
......
...@@ -443,20 +443,6 @@ public class ValueConversions { ...@@ -443,20 +443,6 @@ public class ValueConversions {
return x; 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) { private static ClassCastException newClassCastException(Class<?> t, Object obj) {
return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName()); return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
} }
...@@ -466,12 +452,10 @@ public class ValueConversions { ...@@ -466,12 +452,10 @@ public class ValueConversions {
static { static {
try { try {
MethodType idType = MethodType.genericMethodType(1); MethodType idType = MethodType.genericMethodType(1);
MethodType castType = idType.insertParameterTypes(0, Class.class);
MethodType ignoreType = idType.changeReturnType(void.class); MethodType ignoreType = idType.changeReturnType(void.class);
MethodType zeroObjectType = MethodType.genericMethodType(0); MethodType zeroObjectType = MethodType.genericMethodType(0);
IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType); IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
//CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType); CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType);
ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType); ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType); IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1)); EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
...@@ -509,6 +493,9 @@ public class ValueConversions { ...@@ -509,6 +493,9 @@ public class ValueConversions {
* and returns it as the given type. * and returns it as the given type.
*/ */
public static MethodHandle cast(Class<?> 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); if (type.isPrimitive()) throw new IllegalArgumentException("cannot cast primitive type "+type);
MethodHandle mh; MethodHandle mh;
Wrapper wrap = null; Wrapper wrap = null;
...@@ -519,7 +506,7 @@ public class ValueConversions { ...@@ -519,7 +506,7 @@ public class ValueConversions {
mh = cache.get(wrap); mh = cache.get(wrap);
if (mh != null) return mh; if (mh != null) return mh;
} }
mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type); mh = MethodHandles.insertArguments(castReference, 0, type);
if (cache != null) if (cache != null)
cache.put(wrap, mh); cache.put(wrap, mh);
return mh; return mh;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册