From 7010cf730d3f757ee24b1692c875031781b910aa Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Wed, 2 Dec 2015 12:28:24 +0100 Subject: [PATCH] 8143131: Remove unused code from java.lang.invoke Reviewed-by: vlivanov, jrose, mhaupt --- .../java/lang/invoke/DirectMethodHandle.java | 6 - .../lang/invoke/InvokerBytecodeGenerator.java | 32 ---- .../classes/java/lang/invoke/LambdaForm.java | 168 +++--------------- .../java/lang/invoke/LambdaFormEditor.java | 9 +- .../java/lang/invoke/MethodHandleStatics.java | 30 ---- .../classes/java/lang/invoke/MethodType.java | 12 +- .../invoke/TypeConvertingMethodAdapter.java | 13 +- .../sun/invoke/util/BytecodeDescriptor.java | 12 +- 8 files changed, 46 insertions(+), 236 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java index 23e0aa9410c..54cbb4b3038 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -108,12 +108,6 @@ class DirectMethodHandle extends MethodHandle { return makeAllocator(member); return make(member.getDeclaringClass(), member); } - static DirectMethodHandle make(Method method) { - return make(method.getDeclaringClass(), new MemberName(method)); - } - static DirectMethodHandle make(Field field) { - return make(field.getDeclaringClass(), new MemberName(field)); - } private static DirectMethodHandle makeAllocator(MemberName ctor) { assert(ctor.isConstructor() && ctor.getName().equals("")); Class instanceClass = ctor.getDeclaringClass(); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 0f062f59417..35100f1e5a2 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -56,7 +56,6 @@ class InvokerBytecodeGenerator { private static final String OBJ = "java/lang/Object"; private static final String OBJARY = "[Ljava/lang/Object;"; - private static final String MH_SIG = "L" + MH + ";"; 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 + ";"; @@ -77,7 +76,6 @@ class InvokerBytecodeGenerator { /** Info about local variables in compiled lambda form */ private final int[] localsMap; // index - private final BasicType[] localTypes; // basic type private final Class[] localClasses; // type /** ASM bytecode generation. */ @@ -105,7 +103,6 @@ class InvokerBytecodeGenerator { this.invokerType = invokerType; this.localsMap = new int[localsMapSize+1]; // last entry of localsMap is count of allocated local slots - this.localTypes = new BasicType[localsMapSize+1]; this.localClasses = new Class[localsMapSize+1]; } @@ -114,11 +111,8 @@ class InvokerBytecodeGenerator { this(null, invokerType.parameterCount(), className, invokerName, invokerType); // Create an array to map name indexes to locals indexes. - localTypes[localTypes.length - 1] = V_TYPE; for (int i = 0; i < localsMap.length; i++) { localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i); - if (i < invokerType.parameterCount()) - localTypes[i] = basicType(invokerType.parameterType(i)); } } @@ -133,7 +127,6 @@ class InvokerBytecodeGenerator { if (i < names.length) { BasicType type = names[i].type(); index += type.basicTypeSlots(); - localTypes[i] = type; } } } @@ -461,31 +454,6 @@ class InvokerBytecodeGenerator { return xas - Opcodes.AASTORE + aaop; } - - private void freeFrameLocal(int oldFrameLocal) { - int i = indexForFrameLocal(oldFrameLocal); - if (i < 0) return; - BasicType type = localTypes[i]; - int newFrameLocal = makeLocalTemp(type); - mv.visitVarInsn(loadInsnOpcode(type), oldFrameLocal); - mv.visitVarInsn(storeInsnOpcode(type), newFrameLocal); - assert(localsMap[i] == oldFrameLocal); - localsMap[i] = newFrameLocal; - assert(indexForFrameLocal(oldFrameLocal) < 0); - } - private int indexForFrameLocal(int frameLocal) { - for (int i = 0; i < localsMap.length; i++) { - if (localsMap[i] == frameLocal && localTypes[i] != V_TYPE) - return i; - } - return -1; - } - private int makeLocalTemp(BasicType type) { - int frameLocal = localsMap[localsMap.length - 1]; - localsMap[localsMap.length - 1] = frameLocal + type.basicTypeSlots(); - return frameLocal; - } - /** * Emit a boxing call. * diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java index 2023bfabfde..a95f7b11856 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java @@ -197,17 +197,6 @@ class LambdaForm { if (!type.isPrimitive()) return L_TYPE; return basicType(Wrapper.forPrimitiveType(type)); } - - static char basicTypeChar(Class type) { - return basicType(type).btChar; - } - static BasicType[] basicTypes(List> types) { - BasicType[] btypes = new BasicType[types.size()]; - for (int i = 0; i < btypes.length; i++) { - btypes[i] = basicType(types.get(i)); - } - return btypes; - } static BasicType[] basicTypes(String types) { BasicType[] btypes = new BasicType[types.length()]; for (int i = 0; i < btypes.length; i++) { @@ -215,13 +204,19 @@ class LambdaForm { } return btypes; } - static byte[] basicTypesOrd(BasicType[] btypes) { - byte[] ords = new byte[btypes.length]; - for (int i = 0; i < btypes.length; i++) { - ords[i] = (byte)btypes[i].ordinal(); + + static char basicTypeChar(Class type) { + return basicType(type).btChar; + } + + static byte[] basicTypesOrd(Class[] types) { + byte[] ords = new byte[types.length]; + for (int i = 0; i < ords.length; i++) { + ords[i] = (byte)basicType(types[i]).ordinal(); } return ords; } + static boolean isBasicTypeChar(char c) { return "LIJFDV".indexOf(c) >= 0; } @@ -929,99 +924,6 @@ class LambdaForm { return false; } - LambdaForm addArguments(int pos, BasicType... types) { - // names array has MH in slot 0; skip it. - int argpos = pos + 1; - assert(argpos <= arity); - int length = names.length; - int inTypes = types.length; - Name[] names2 = Arrays.copyOf(names, length + inTypes); - int arity2 = arity + inTypes; - int result2 = result; - if (result2 >= argpos) - result2 += inTypes; - // Note: The LF constructor will rename names2[argpos...]. - // Make space for new arguments (shift temporaries). - System.arraycopy(names, argpos, names2, argpos + inTypes, length - argpos); - for (int i = 0; i < inTypes; i++) { - names2[argpos + i] = new Name(types[i]); - } - return new LambdaForm(debugName, arity2, names2, result2); - } - - LambdaForm addArguments(int pos, List> types) { - return addArguments(pos, basicTypes(types)); - } - - LambdaForm permuteArguments(int skip, int[] reorder, BasicType[] types) { - // Note: When inArg = reorder[outArg], outArg is fed by a copy of inArg. - // The types are the types of the new (incoming) arguments. - int length = names.length; - int inTypes = types.length; - int outArgs = reorder.length; - assert(skip+outArgs == arity); - assert(permutedTypesMatch(reorder, types, names, skip)); - int pos = 0; - // skip trivial first part of reordering: - while (pos < outArgs && reorder[pos] == pos) pos += 1; - Name[] names2 = new Name[length - outArgs + inTypes]; - System.arraycopy(names, 0, names2, 0, skip+pos); - // copy the body: - int bodyLength = length - arity; - System.arraycopy(names, skip+outArgs, names2, skip+inTypes, bodyLength); - int arity2 = names2.length - bodyLength; - int result2 = result; - if (result2 >= 0) { - if (result2 < skip+outArgs) { - // return the corresponding inArg - result2 = reorder[result2-skip]; - } else { - result2 = result2 - outArgs + inTypes; - } - } - // rework names in the body: - for (int j = pos; j < outArgs; j++) { - Name n = names[skip+j]; - int i = reorder[j]; - // replace names[skip+j] by names2[skip+i] - Name n2 = names2[skip+i]; - if (n2 == null) - names2[skip+i] = n2 = new Name(types[i]); - else - assert(n2.type == types[i]); - for (int k = arity2; k < names2.length; k++) { - names2[k] = names2[k].replaceName(n, n2); - } - } - // some names are unused, but must be filled in - for (int i = skip+pos; i < arity2; i++) { - if (names2[i] == null) - names2[i] = argument(i, types[i - skip]); - } - for (int j = arity; j < names.length; j++) { - int i = j - arity + arity2; - // replace names2[i] by names[j] - Name n = names[j]; - Name n2 = names2[i]; - if (n != n2) { - for (int k = i+1; k < names2.length; k++) { - names2[k] = names2[k].replaceName(n, n2); - } - } - } - return new LambdaForm(debugName, arity2, names2, result2); - } - - static boolean permutedTypesMatch(int[] reorder, BasicType[] types, Name[] names, int skip) { - int inTypes = types.length; - int outArgs = reorder.length; - for (int i = 0; i < outArgs; i++) { - assert(names[skip+i].isParam()); - assert(names[skip+i].type == types[reorder[i]]); - } - return true; - } - static class NamedFunction { final MemberName member; private @Stable MethodHandle resolvedHandle; @@ -1054,19 +956,15 @@ class LambdaForm { "invokeBasic".equals(member.getName()); } - // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc. + // The next 2 constructors are used to break circular dependencies on MH.invokeStatic, etc. // Any LambdaForm containing such a member is not interpretable. // This is OK, since all such LFs are prepared with special primitive vmentry points. // And even without the resolvedHandle, the name can still be compiled and optimized. NamedFunction(Method method) { this(new MemberName(method)); } - NamedFunction(Field field) { - this(new MemberName(field)); - } NamedFunction(MemberName member) { - this.member = member; - this.resolvedHandle = null; + this(member, null); } MethodHandle resolvedHandle() { @@ -1408,9 +1306,7 @@ class LambdaForm { } Name(NamedFunction function, Object... arguments) { this(-1, function.returnType(), function, arguments = Arrays.copyOf(arguments, arguments.length, Object[].class)); - assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString(); - for (int i = 0; i < arguments.length; i++) - assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString(); + assert(typesMatch(function, arguments)); } /** Create a raw parameter of the given type, with an expected index. */ Name(int index, BasicType type) { @@ -1550,7 +1446,15 @@ class LambdaForm { return buf.toString(); } - static boolean typesMatch(BasicType parameterType, Object object) { + private boolean typesMatch(NamedFunction function, Object ... arguments) { + assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString(); + for (int i = 0; i < arguments.length; i++) { + assert (typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString(); + } + return true; + } + + private static boolean typesMatch(BasicType parameterType, Object object) { if (object instanceof Name) { return ((Name)object).type == parameterType; } @@ -1630,7 +1534,7 @@ class LambdaForm { /** Return the number of times n is used as an argument or return value. */ int useCount(Name n) { - int ni = n.index, nmax = names.length; + int nmax = names.length; int end = lastUseIndex(n); if (end < 0) return 0; int count = 0; @@ -1643,9 +1547,6 @@ class LambdaForm { return count; } - static Name argument(int which, char type) { - return argument(which, basicType(type)); - } static Name argument(int which, BasicType type) { if (which >= INTERNED_ARGUMENT_LIMIT) return new Name(which, type); @@ -1661,28 +1562,7 @@ class LambdaForm { int length = types.length(); Name[] names = new Name[length + extra]; for (int i = 0; i < length; i++) - names[i] = argument(i, types.charAt(i)); - return names; - } - static Name[] arguments(int extra, char... types) { - int length = types.length; - Name[] names = new Name[length + extra]; - for (int i = 0; i < length; i++) - names[i] = argument(i, types[i]); - return names; - } - static Name[] arguments(int extra, List> types) { - int length = types.size(); - Name[] names = new Name[length + extra]; - for (int i = 0; i < length; i++) - names[i] = argument(i, basicType(types.get(i))); - return names; - } - static Name[] arguments(int extra, Class... types) { - int length = types.length; - Name[] names = new Name[length + extra]; - for (int i = 0; i < length; i++) - names[i] = argument(i, basicType(types[i])); + names[i] = argument(i, basicType(types.charAt(i))); return names; } static Name[] arguments(int extra, MethodType types) { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java index 753b1988ebc..8cf5811e78d 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java @@ -565,12 +565,12 @@ class LambdaFormEditor { if (collectorArity == 1 && !dropResult) { return filterArgumentForm(pos, basicType(collectorType.parameterType(0))); } - BasicType[] newTypes = BasicType.basicTypes(collectorType.parameterList()); + byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray()); Transform.Kind kind = (dropResult ? Transform.Kind.COLLECT_ARGS_TO_VOID : Transform.Kind.COLLECT_ARGS); if (dropResult && collectorArity == 0) pos = 1; // pure side effect - Transform key = Transform.of(kind, pos, collectorArity, BasicType.basicTypesOrd(newTypes)); + Transform key = Transform.of(kind, pos, collectorArity, newTypes); LambdaForm form = getInCache(key); if (form != null) { assert(form.arity == lambdaForm.arity - (dropResult ? 0 : 1) + collectorArity); @@ -680,9 +680,8 @@ class LambdaFormEditor { combinerArgs, 1, combinerArity); } else { newParams = new Name[combinerArity]; - BasicType[] newTypes = basicTypes(combinerType.parameterList()); - for (int i = 0; i < newTypes.length; i++) { - newParams[i] = new Name(pos + i, newTypes[i]); + for (int i = 0; i < newParams.length; i++) { + newParams[i] = new Name(pos + i, basicType(combinerType.parameterType(i))); } System.arraycopy(newParams, 0, combinerArgs, 1, combinerArity); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java index c449f4cb591..9db2ad68f53 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java @@ -92,33 +92,6 @@ import jdk.internal.misc.Unsafe; TRACE_METHOD_LINKAGE); } - /*non-public*/ static String getNameString(MethodHandle target, MethodType type) { - if (type == null) - type = target.type(); - MemberName name = null; - if (target != null) - name = target.internalMemberName(); - if (name == null) - return "invoke" + type; - return name.getName() + type; - } - - /*non-public*/ static String getNameString(MethodHandle target, MethodHandle typeHolder) { - return getNameString(target, typeHolder == null ? (MethodType) null : typeHolder.type()); - } - - /*non-public*/ static String getNameString(MethodHandle target) { - return getNameString(target, (MethodType) null); - } - - /*non-public*/ static String addTypeString(Object obj, MethodHandle target) { - String str = String.valueOf(obj); - if (target == null) return str; - int paren = str.indexOf('('); - if (paren >= 0) str = str.substring(0, paren); - return str + target.type(); - } - // handy shared exception makers (they simplify the common case code) /*non-public*/ static InternalError newInternalError(String message) { return new InternalError(message); @@ -150,9 +123,6 @@ import jdk.internal.misc.Unsafe; if (ex instanceof RuntimeException) throw (RuntimeException) ex; throw newInternalError("uncaught exception", ex); } - static Error NYI() { - throw new AssertionError("NYI"); - } private static String message(String message, Object obj) { if (obj != null) message = message + ": " + obj; return message; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java index be3090a4451..d75bad58a36 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java @@ -179,9 +179,11 @@ class MethodType implements java.io.Serializable { checkSlotCount(ptypes.length + slots); return slots; } - static void checkSlotCount(int count) { - assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0); + static { // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work: + assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0); + } + static void checkSlotCount(int count) { if ((count & MAX_JVM_ARITY) != count) throw newIllegalArgumentException("bad parameter count "+count); } @@ -813,11 +815,6 @@ class MethodType implements java.io.Serializable { boolean isViewableAs(MethodType newType, boolean keepInterfaces) { if (!VerifyType.isNullConversion(returnType(), newType.returnType(), keepInterfaces)) return false; - return parametersAreViewableAs(newType, keepInterfaces); - } - /** True if the new parameters can be viewed (w/o casting) under the old parameter types. */ - /*non-public*/ - boolean parametersAreViewableAs(MethodType newType, boolean keepInterfaces) { if (form == newType.form && form.erasedType == this) return true; // my reference parameters are all Object if (ptypes == newType.ptypes) @@ -1088,7 +1085,6 @@ class MethodType implements java.io.Serializable { throw newIllegalArgumentException("not a method descriptor: "+descriptor); List> types = BytecodeDescriptor.parseMethod(descriptor, loader); Class rtype = types.remove(types.size() - 1); - checkSlotCount(types.size()); Class[] ptypes = listToArray(types); return makeImpl(rtype, ptypes, true); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java b/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java index c640d726ea2..38892d07f2a 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java @@ -52,7 +52,7 @@ class TypeConvertingMethodAdapter extends MethodVisitor { private static final Wrapper[] FROM_WRAPPER_NAME = new Wrapper[16]; // Table of wrappers for primitives, indexed by ASM type sorts - private static final Wrapper[] FROM_TYPE_SORT = new Wrapper[16]; + private static final Wrapper[] FROM_TYPE_SORT = new Wrapper[12]; static { for (Wrapper w : Wrapper.values()) { @@ -63,11 +63,8 @@ class TypeConvertingMethodAdapter extends MethodVisitor { } } - for (int i = 0; i < NUM_WRAPPERS; i++) { - for (int j = 0; j < NUM_WRAPPERS; j++) { - wideningOpcodes[i][j] = Opcodes.NOP; - } - } + // wideningOpcodes[][] will be NOP-initialized by default + assert(Opcodes.NOP == 0); initWidening(LONG, Opcodes.I2L, BYTE, SHORT, INT, CHAR); initWidening(LONG, Opcodes.F2L, FLOAT); @@ -192,10 +189,6 @@ class TypeConvertingMethodAdapter extends MethodVisitor { } } - private boolean isPrimitive(Wrapper w) { - return w != OBJECT; - } - private Wrapper toWrapper(String desc) { char first = desc.charAt(0); if (first == '[' || first == '(') { diff --git a/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java b/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java index bb1f3ec6275..af8ab324671 100644 --- a/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java +++ b/jdk/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java @@ -113,7 +113,7 @@ public class BytecodeDescriptor { } public static String unparse(MethodType type) { - return unparseMethod(type.returnType(), type.parameterList()); + return unparseMethod(type.returnType(), type.parameterArray()); } public static String unparse(Object type) { @@ -134,6 +134,16 @@ public class BytecodeDescriptor { return sb.toString(); } + public static String unparseMethod(Class rtype, Class[] ptypes) { + StringBuilder sb = new StringBuilder(); + sb.append('('); + for (Class pt : ptypes) + unparseSig(pt, sb); + sb.append(')'); + unparseSig(rtype, sb); + return sb.toString(); + } + private static void unparseSig(Class t, StringBuilder sb) { char c = Wrapper.forBasicType(t).basicTypeChar(); if (c != 'L') {