# HG changeset patch # User redestad # Date 1567863844 -7200 # Node ID aa37156558344d33d300668a247e2dff05689238 # Parent 378007c18687eb2289660a0a2225d7fa4ae08f9b 8230662: Remove dead code from MethodTypeForm Reviewed-by: vlivanov, mchung diff -r 378007c18687 -r aa3715655834 src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Sep 06 12:41:21 2019 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Sat Sep 07 15:44:04 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,9 +123,13 @@ private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) { this(null, invokerType.parameterCount(), className, invokerName, invokerType); + MethodType mt = invokerType.erase(); // Create an array to map name indexes to locals indexes. - for (int i = 0; i < localsMap.length; i++) { - localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i); + localsMap[0] = 0; // localsMap has at least one element + for (int i = 1, index = 0; i < localsMap.length; i++) { + Wrapper w = Wrapper.forBasicType(mt.parameterType(i - 1)); + index += w.stackSlots(); + localsMap[i] = index; } } diff -r 378007c18687 -r aa3715655834 src/java.base/share/classes/java/lang/invoke/MethodType.java --- a/src/java.base/share/classes/java/lang/invoke/MethodType.java Fri Sep 06 12:41:21 2019 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java Sat Sep 07 15:44:04 2019 +0200 @@ -926,8 +926,8 @@ return false; return true; } - if ((oldForm.primitiveParameterCount() == 0 && oldForm.erasedType == this) || - (newForm.primitiveParameterCount() == 0 && newForm.erasedType == newType)) { + if ((!oldForm.hasPrimitives() && oldForm.erasedType == this) || + (!newForm.hasPrimitives() && newForm.erasedType == newType)) { // Somewhat complicated test to avoid a loop of 2 or more trips. // If either type has only Object parameters, we know we can convert. assert(canConvertParameters(srcTypes, dstTypes)); @@ -1073,49 +1073,6 @@ return inv; } - /** Reports the number of JVM stack slots which carry all parameters including and after - * the given position, which must be in the range of 0 to - * {@code parameterCount} inclusive. Successive parameters are - * more shallowly stacked, and parameters are indexed in the bytecodes - * according to their trailing edge. Thus, to obtain the depth - * in the outgoing call stack of parameter {@code N}, obtain - * the {@code parameterSlotDepth} of its trailing edge - * at position {@code N+1}. - *

- * Parameters of type {@code long} and {@code double} occupy - * two stack slots (for historical reasons) and all others occupy one. - * Therefore, the number returned is the number of arguments - * including and after the given parameter, - * plus the number of long or double arguments - * at or after the argument for the given parameter. - *

- * This method is included for the benefit of applications that must - * generate bytecodes that process method handles and invokedynamic. - * @param num an index (zero-based, inclusive) within the parameter types - * @return the index of the (shallowest) JVM stack slot transmitting the - * given parameter - * @throws IllegalArgumentException if {@code num} is negative or greater than {@code parameterCount()} - */ - /*non-public*/ int parameterSlotDepth(int num) { - if (num < 0 || num > ptypes.length) - parameterType(num); // force a range check - return form.parameterToArgSlot(num-1); - } - - /** Reports the number of JVM stack slots required to receive a return value - * from a method of this type. - * If the {@link #returnType() return type} is void, it will be zero, - * else if the return type is long or double, it will be two, else one. - *

- * This method is included for the benefit of applications that must - * generate bytecodes that process method handles and invokedynamic. - * @return the number of JVM stack slots (0, 1, or 2) for this type's return value - * Will be removed for PFD. - */ - /*non-public*/ int returnSlotCount() { - return form.returnSlotCount(); - } - /** * Finds or creates an instance of a method type, given the spelling of its bytecode descriptor. * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}. diff -r 378007c18687 -r aa3715655834 src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java --- a/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java Fri Sep 06 12:41:21 2019 -0700 +++ b/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java Sat Sep 07 15:44:04 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,9 +46,8 @@ * @author John Rose */ final class MethodTypeForm { - final int[] argToSlotTable, slotToArgTable; - final long argCounts; // packed slot & value counts - final long primCounts; // packed prim & double counts + final short parameterSlotCount; + final short primitiveCount; final MethodType erasedType; // the canonical erasure final MethodType basicType; // the canonical erasure, with primitives simplified @@ -159,23 +158,18 @@ this.erasedType = erasedType; Class[] ptypes = erasedType.ptypes(); - int ptypeCount = ptypes.length; - int pslotCount = ptypeCount; // temp. estimate - int rtypeCount = 1; // temp. estimate - int rslotCount = 1; // temp. estimate - - int[] argToSlotTab = null, slotToArgTab = null; + int pslotCount = ptypes.length; // Walk the argument types, looking for primitives. - int pac = 0, lac = 0, prc = 0, lrc = 0; + short primitiveCount = 0, longArgCount = 0; Class[] epts = ptypes; Class[] bpts = epts; for (int i = 0; i < epts.length; i++) { Class pt = epts[i]; if (pt != Object.class) { - ++pac; + ++primitiveCount; Wrapper w = Wrapper.forPrimitiveType(pt); - if (w.isDoubleWord()) ++lac; + if (w.isDoubleWord()) ++longArgCount; if (w.isSubwordOrInt() && pt != int.class) { if (bpts == epts) bpts = bpts.clone(); @@ -183,20 +177,14 @@ } } } - pslotCount += lac; // #slots = #args + #longs + pslotCount += longArgCount; // #slots = #args + #longs Class rt = erasedType.returnType(); Class bt = rt; if (rt != Object.class) { - ++prc; // even void.class counts as a prim here + ++primitiveCount; // even void.class counts as a prim here Wrapper w = Wrapper.forPrimitiveType(rt); - if (w.isDoubleWord()) ++lrc; if (w.isSubwordOrInt() && rt != int.class) bt = int.class; - // adjust #slots, #args - if (rt == void.class) - rtypeCount = rslotCount = 0; - else - rslotCount += lrc; } if (epts == bpts && bt == rt) { this.basicType = erasedType; @@ -205,112 +193,32 @@ // fill in rest of data from the basic type: MethodTypeForm that = this.basicType.form(); assert(this != that); - this.primCounts = that.primCounts; - this.argCounts = that.argCounts; - this.argToSlotTable = that.argToSlotTable; - this.slotToArgTable = that.slotToArgTable; + this.parameterSlotCount = that.parameterSlotCount; + this.primitiveCount = that.primitiveCount; this.methodHandles = null; this.lambdaForms = null; return; } - if (lac != 0) { - int slot = ptypeCount + lac; - slotToArgTab = new int[slot+1]; - argToSlotTab = new int[1+ptypeCount]; - argToSlotTab[0] = slot; // argument "-1" is past end of slots - for (int i = 0; i < epts.length; i++) { - Class pt = epts[i]; - Wrapper w = Wrapper.forBasicType(pt); - if (w.isDoubleWord()) --slot; - --slot; - slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note - argToSlotTab[1+i] = slot; - } - assert(slot == 0); // filled the table - } else if (pac != 0) { - // have primitives but no long primitives; share slot counts with generic - assert(ptypeCount == pslotCount); - MethodTypeForm that = MethodType.genericMethodType(ptypeCount).form(); - assert(this != that); - slotToArgTab = that.slotToArgTable; - argToSlotTab = that.argToSlotTable; - } else { - int slot = ptypeCount; // first arg is deepest in stack - slotToArgTab = new int[slot+1]; - argToSlotTab = new int[1+ptypeCount]; - argToSlotTab[0] = slot; // argument "-1" is past end of slots - for (int i = 0; i < ptypeCount; i++) { - --slot; - slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note - argToSlotTab[1+i] = slot; - } - } - this.primCounts = pack(lrc, prc, lac, pac); - this.argCounts = pack(rslotCount, rtypeCount, pslotCount, ptypeCount); - this.argToSlotTable = argToSlotTab; - this.slotToArgTable = slotToArgTab; if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments"); + this.primitiveCount = primitiveCount; + this.parameterSlotCount = (short)pslotCount; + // Initialize caches, but only for basic types assert(basicType == erasedType); this.lambdaForms = new SoftReference[LF_LIMIT]; this.methodHandles = new SoftReference[MH_LIMIT]; } - private static long pack(int a, int b, int c, int d) { - assert(((a|b|c|d) & ~0xFFFF) == 0); - long hw = ((a << 16) | b), lw = ((c << 16) | d); - return (hw << 32) | lw; - } - private static char unpack(long packed, int word) { // word==0 => return a, ==3 => return d - assert(word <= 3); - return (char)(packed >> ((3-word) * 16)); - } - public int parameterCount() { // # outgoing values - return unpack(argCounts, 3); + return erasedType.parameterCount(); } public int parameterSlotCount() { // # outgoing interpreter slots - return unpack(argCounts, 2); - } - public int returnCount() { // = 0 (V), or 1 - return unpack(argCounts, 1); - } - public int returnSlotCount() { // = 0 (V), 2 (J/D), or 1 - return unpack(argCounts, 0); - } - public int primitiveParameterCount() { - return unpack(primCounts, 3); - } - public int longPrimitiveParameterCount() { - return unpack(primCounts, 2); - } - public int primitiveReturnCount() { // = 0 (obj), or 1 - return unpack(primCounts, 1); - } - public int longPrimitiveReturnCount() { // = 1 (J/D), or 0 - return unpack(primCounts, 0); + return parameterSlotCount; } public boolean hasPrimitives() { - return primCounts != 0; - } - public boolean hasNonVoidPrimitives() { - if (primCounts == 0) return false; - if (primitiveParameterCount() != 0) return true; - return (primitiveReturnCount() != 0 && returnCount() != 0); - } - public boolean hasLongPrimitives() { - return (longPrimitiveParameterCount() | longPrimitiveReturnCount()) != 0; - } - public int parameterToArgSlot(int i) { - return argToSlotTable[1+i]; - } - public int argSlotToParameter(int argSlot) { - // Note: Empty slots are represented by zero in this table. - // Valid arguments slots contain incremented entries, so as to be non-zero. - // We return -1 the caller to mean an empty slot. - return slotToArgTable[argSlot] - 1; + return primitiveCount != 0; } static MethodTypeForm findForm(MethodType mt) { @@ -334,7 +242,7 @@ * (assumed to be a return type) to int if it is smaller than an int, * or if it is void. */ - public static final int NO_CHANGE = 0, ERASE = 1, WRAP = 2, UNWRAP = 3, INTS = 4, LONGS = 5, RAW_RETURN = 6; + public static final int ERASE = 1, WRAP = 2, UNWRAP = 3, INTS = 4, LONGS = 5, RAW_RETURN = 6; /** Canonicalize the types in the given method type. * If any types change, intern the new type, and return it. @@ -342,9 +250,9 @@ */ public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) { Class[] ptypes = mt.ptypes(); - Class[] ptc = MethodTypeForm.canonicalizeAll(ptypes, howArgs); + Class[] ptc = canonicalizeAll(ptypes, howArgs); Class rtype = mt.returnType(); - Class rtc = MethodTypeForm.canonicalize(rtype, howRet); + Class rtc = canonicalize(rtype, howRet); if (ptc == null && rtc == null) { // It is already canonical. return null; @@ -414,9 +322,8 @@ Class[] cs = null; for (int imax = ts.length, i = 0; i < imax; i++) { Class c = canonicalize(ts[i], how); - if (c == void.class) - c = null; // a Void parameter was unwrapped to void; ignore - if (c != null) { + // Void parameters may be unwrapped to void; ignore those + if (c != null && c != void.class) { if (cs == null) cs = ts.clone(); cs[i] = c;