mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8230662: Remove dead code from MethodTypeForm
Reviewed-by: vlivanov, mchung
This commit is contained in:
parent
9c3ff105df
commit
c788d9841c
3 changed files with 31 additions and 163 deletions
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -123,9 +123,13 @@ class InvokerBytecodeGenerator {
|
||||||
private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) {
|
private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) {
|
||||||
this(null, invokerType.parameterCount(),
|
this(null, invokerType.parameterCount(),
|
||||||
className, invokerName, invokerType);
|
className, invokerName, invokerType);
|
||||||
|
MethodType mt = invokerType.erase();
|
||||||
// Create an array to map name indexes to locals indexes.
|
// Create an array to map name indexes to locals indexes.
|
||||||
for (int i = 0; i < localsMap.length; i++) {
|
localsMap[0] = 0; // localsMap has at least one element
|
||||||
localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i);
|
for (int i = 1, index = 0; i < localsMap.length; i++) {
|
||||||
|
Wrapper w = Wrapper.forBasicType(mt.parameterType(i - 1));
|
||||||
|
index += w.stackSlots();
|
||||||
|
localsMap[i] = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -926,8 +926,8 @@ class MethodType
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((oldForm.primitiveParameterCount() == 0 && oldForm.erasedType == this) ||
|
if ((!oldForm.hasPrimitives() && oldForm.erasedType == this) ||
|
||||||
(newForm.primitiveParameterCount() == 0 && newForm.erasedType == newType)) {
|
(!newForm.hasPrimitives() && newForm.erasedType == newType)) {
|
||||||
// Somewhat complicated test to avoid a loop of 2 or more trips.
|
// Somewhat complicated test to avoid a loop of 2 or more trips.
|
||||||
// If either type has only Object parameters, we know we can convert.
|
// If either type has only Object parameters, we know we can convert.
|
||||||
assert(canConvertParameters(srcTypes, dstTypes));
|
assert(canConvertParameters(srcTypes, dstTypes));
|
||||||
|
@ -1073,49 +1073,6 @@ class MethodType
|
||||||
return inv;
|
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}.
|
|
||||||
* <p>
|
|
||||||
* 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
|
|
||||||
* <em>including</em> and <em>after</em> the given parameter,
|
|
||||||
* <em>plus</em> the number of long or double arguments
|
|
||||||
* at or after the argument for the given parameter.
|
|
||||||
* <p>
|
|
||||||
* 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.
|
|
||||||
* <p>
|
|
||||||
* 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.
|
* 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}.
|
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
|
||||||
|
|
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -46,9 +46,8 @@ import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
|
||||||
* @author John Rose
|
* @author John Rose
|
||||||
*/
|
*/
|
||||||
final class MethodTypeForm {
|
final class MethodTypeForm {
|
||||||
final int[] argToSlotTable, slotToArgTable;
|
final short parameterSlotCount;
|
||||||
final long argCounts; // packed slot & value counts
|
final short primitiveCount;
|
||||||
final long primCounts; // packed prim & double counts
|
|
||||||
final MethodType erasedType; // the canonical erasure
|
final MethodType erasedType; // the canonical erasure
|
||||||
final MethodType basicType; // the canonical erasure, with primitives simplified
|
final MethodType basicType; // the canonical erasure, with primitives simplified
|
||||||
|
|
||||||
|
@ -159,23 +158,18 @@ final class MethodTypeForm {
|
||||||
this.erasedType = erasedType;
|
this.erasedType = erasedType;
|
||||||
|
|
||||||
Class<?>[] ptypes = erasedType.ptypes();
|
Class<?>[] ptypes = erasedType.ptypes();
|
||||||
int ptypeCount = ptypes.length;
|
int pslotCount = ptypes.length;
|
||||||
int pslotCount = ptypeCount; // temp. estimate
|
|
||||||
int rtypeCount = 1; // temp. estimate
|
|
||||||
int rslotCount = 1; // temp. estimate
|
|
||||||
|
|
||||||
int[] argToSlotTab = null, slotToArgTab = null;
|
|
||||||
|
|
||||||
// Walk the argument types, looking for primitives.
|
// 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<?>[] epts = ptypes;
|
||||||
Class<?>[] bpts = epts;
|
Class<?>[] bpts = epts;
|
||||||
for (int i = 0; i < epts.length; i++) {
|
for (int i = 0; i < epts.length; i++) {
|
||||||
Class<?> pt = epts[i];
|
Class<?> pt = epts[i];
|
||||||
if (pt != Object.class) {
|
if (pt != Object.class) {
|
||||||
++pac;
|
++primitiveCount;
|
||||||
Wrapper w = Wrapper.forPrimitiveType(pt);
|
Wrapper w = Wrapper.forPrimitiveType(pt);
|
||||||
if (w.isDoubleWord()) ++lac;
|
if (w.isDoubleWord()) ++longArgCount;
|
||||||
if (w.isSubwordOrInt() && pt != int.class) {
|
if (w.isSubwordOrInt() && pt != int.class) {
|
||||||
if (bpts == epts)
|
if (bpts == epts)
|
||||||
bpts = bpts.clone();
|
bpts = bpts.clone();
|
||||||
|
@ -183,20 +177,14 @@ final class MethodTypeForm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pslotCount += lac; // #slots = #args + #longs
|
pslotCount += longArgCount; // #slots = #args + #longs
|
||||||
Class<?> rt = erasedType.returnType();
|
Class<?> rt = erasedType.returnType();
|
||||||
Class<?> bt = rt;
|
Class<?> bt = rt;
|
||||||
if (rt != Object.class) {
|
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);
|
Wrapper w = Wrapper.forPrimitiveType(rt);
|
||||||
if (w.isDoubleWord()) ++lrc;
|
|
||||||
if (w.isSubwordOrInt() && rt != int.class)
|
if (w.isSubwordOrInt() && rt != int.class)
|
||||||
bt = int.class;
|
bt = int.class;
|
||||||
// adjust #slots, #args
|
|
||||||
if (rt == void.class)
|
|
||||||
rtypeCount = rslotCount = 0;
|
|
||||||
else
|
|
||||||
rslotCount += lrc;
|
|
||||||
}
|
}
|
||||||
if (epts == bpts && bt == rt) {
|
if (epts == bpts && bt == rt) {
|
||||||
this.basicType = erasedType;
|
this.basicType = erasedType;
|
||||||
|
@ -205,112 +193,32 @@ final class MethodTypeForm {
|
||||||
// fill in rest of data from the basic type:
|
// fill in rest of data from the basic type:
|
||||||
MethodTypeForm that = this.basicType.form();
|
MethodTypeForm that = this.basicType.form();
|
||||||
assert(this != that);
|
assert(this != that);
|
||||||
this.primCounts = that.primCounts;
|
this.parameterSlotCount = that.parameterSlotCount;
|
||||||
this.argCounts = that.argCounts;
|
this.primitiveCount = that.primitiveCount;
|
||||||
this.argToSlotTable = that.argToSlotTable;
|
|
||||||
this.slotToArgTable = that.slotToArgTable;
|
|
||||||
this.methodHandles = null;
|
this.methodHandles = null;
|
||||||
this.lambdaForms = null;
|
this.lambdaForms = null;
|
||||||
return;
|
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");
|
if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
|
||||||
|
|
||||||
|
this.primitiveCount = primitiveCount;
|
||||||
|
this.parameterSlotCount = (short)pslotCount;
|
||||||
|
|
||||||
// Initialize caches, but only for basic types
|
// Initialize caches, but only for basic types
|
||||||
assert(basicType == erasedType);
|
assert(basicType == erasedType);
|
||||||
this.lambdaForms = new SoftReference[LF_LIMIT];
|
this.lambdaForms = new SoftReference[LF_LIMIT];
|
||||||
this.methodHandles = new SoftReference[MH_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
|
public int parameterCount() { // # outgoing values
|
||||||
return unpack(argCounts, 3);
|
return erasedType.parameterCount();
|
||||||
}
|
}
|
||||||
public int parameterSlotCount() { // # outgoing interpreter slots
|
public int parameterSlotCount() { // # outgoing interpreter slots
|
||||||
return unpack(argCounts, 2);
|
return parameterSlotCount;
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
public boolean hasPrimitives() {
|
public boolean hasPrimitives() {
|
||||||
return primCounts != 0;
|
return primitiveCount != 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodTypeForm findForm(MethodType mt) {
|
static MethodTypeForm findForm(MethodType mt) {
|
||||||
|
@ -334,7 +242,7 @@ final class MethodTypeForm {
|
||||||
* (assumed to be a return type) to int if it is smaller than an int,
|
* (assumed to be a return type) to int if it is smaller than an int,
|
||||||
* or if it is void.
|
* 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.
|
/** Canonicalize the types in the given method type.
|
||||||
* If any types change, intern the new type, and return it.
|
* If any types change, intern the new type, and return it.
|
||||||
|
@ -342,9 +250,9 @@ final class MethodTypeForm {
|
||||||
*/
|
*/
|
||||||
public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) {
|
public static MethodType canonicalize(MethodType mt, int howRet, int howArgs) {
|
||||||
Class<?>[] ptypes = mt.ptypes();
|
Class<?>[] ptypes = mt.ptypes();
|
||||||
Class<?>[] ptc = MethodTypeForm.canonicalizeAll(ptypes, howArgs);
|
Class<?>[] ptc = canonicalizeAll(ptypes, howArgs);
|
||||||
Class<?> rtype = mt.returnType();
|
Class<?> rtype = mt.returnType();
|
||||||
Class<?> rtc = MethodTypeForm.canonicalize(rtype, howRet);
|
Class<?> rtc = canonicalize(rtype, howRet);
|
||||||
if (ptc == null && rtc == null) {
|
if (ptc == null && rtc == null) {
|
||||||
// It is already canonical.
|
// It is already canonical.
|
||||||
return null;
|
return null;
|
||||||
|
@ -414,9 +322,8 @@ final class MethodTypeForm {
|
||||||
Class<?>[] cs = null;
|
Class<?>[] cs = null;
|
||||||
for (int imax = ts.length, i = 0; i < imax; i++) {
|
for (int imax = ts.length, i = 0; i < imax; i++) {
|
||||||
Class<?> c = canonicalize(ts[i], how);
|
Class<?> c = canonicalize(ts[i], how);
|
||||||
if (c == void.class)
|
// Void parameters may be unwrapped to void; ignore those
|
||||||
c = null; // a Void parameter was unwrapped to void; ignore
|
if (c != null && c != void.class) {
|
||||||
if (c != null) {
|
|
||||||
if (cs == null)
|
if (cs == null)
|
||||||
cs = ts.clone();
|
cs = ts.clone();
|
||||||
cs[i] = c;
|
cs[i] = c;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue