Skip to content
Permalink
Browse files
8268124: Update java.lang to use switch expressions
Reviewed-by: naoto, darcy, mchung, iris, lancea, dfuchs
  • Loading branch information
pconcannon committed Jun 10, 2021
1 parent a187fcc commit d43c8a74b33692b3628c3c9c6c472ab1cf1fdeac
Showing with 422 additions and 552 deletions.
  1. +9 −17 src/java.base/share/classes/java/lang/CharacterData.java
  2. +8 −19 src/java.base/share/classes/java/lang/ConditionalSpecialCasing.java
  3. +21 −32 src/java.base/share/classes/java/lang/Long.java
  4. +35 −42 src/java.base/share/classes/java/lang/Math.java
  5. +33 −50 src/java.base/share/classes/java/lang/constant/DirectMethodHandleDescImpl.java
  6. +7 −9 src/java.base/share/classes/java/lang/constant/MethodHandleDesc.java
  7. +8 −13 src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java
  8. +8 −8 src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java
  9. +5 −5 src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java
  10. +23 −25 src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java
  11. +8 −14 src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
  12. +72 −83 src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
  13. +15 −24 src/java.base/share/classes/java/lang/invoke/Invokers.java
  14. +10 −15 src/java.base/share/classes/java/lang/invoke/LambdaForm.java
  15. +15 −13 src/java.base/share/classes/java/lang/invoke/MemberName.java
  16. +16 −26 src/java.base/share/classes/java/lang/invoke/MethodHandle.java
  17. +59 −68 src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
  18. +12 −12 src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java
  19. +16 −22 src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java
  20. +7 −7 src/java.base/share/classes/java/lang/invoke/MethodHandles.java
  21. +22 −34 src/java.base/share/classes/java/lang/invoke/VarHandle.java
  22. +13 −14 src/java.base/share/classes/java/lang/runtime/ObjectMethods.java
@@ -72,23 +72,15 @@ static final CharacterData of(int ch) {
if (ch >>> 8 == 0) { // fast-path
return CharacterDataLatin1.instance;
} else {
switch(ch >>> 16) { //plane 00-16
case(0):
return CharacterData00.instance;
case(1):
return CharacterData01.instance;
case(2):
return CharacterData02.instance;
case(3):
return CharacterData03.instance;
case(14):
return CharacterData0E.instance;
case(15): // Private Use
case(16): // Private Use
return CharacterDataPrivateUse.instance;
default:
return CharacterDataUndefined.instance;
}
return switch (ch >>> 16) { //plane 00-16
case 0 -> CharacterData00.instance;
case 1 -> CharacterData01.instance;
case 2 -> CharacterData02.instance;
case 3 -> CharacterData03.instance;
case 14 -> CharacterData0E.instance;
case 15, 16 -> CharacterDataPrivateUse.instance; // Both cases Private Use
default -> CharacterDataUndefined.instance;
};
}
}
}
@@ -170,25 +170,14 @@ static int toUpperCaseEx(String src, int index, Locale locale) {
}

private static boolean isConditionMet(String src, int index, Locale locale, int condition) {
switch (condition) {
case FINAL_CASED:
return isFinalCased(src, index, locale);

case AFTER_SOFT_DOTTED:
return isAfterSoftDotted(src, index);

case MORE_ABOVE:
return isMoreAbove(src, index);

case AFTER_I:
return isAfterI(src, index);

case NOT_BEFORE_DOT:
return !isBeforeDot(src, index);

default:
return true;
}
return switch (condition) {
case FINAL_CASED -> isFinalCased(src, index, locale);
case AFTER_SOFT_DOTTED -> isAfterSoftDotted(src, index);
case MORE_ABOVE -> isMoreAbove(src, index);
case AFTER_I -> isAfterI(src, index);
case NOT_BEFORE_DOT -> !isBeforeDot(src, index);
default -> true;
};
}

/**
@@ -213,38 +213,27 @@ public static String toUnsignedString(long i, int radix) {
if (i >= 0)
return toString(i, radix);
else {
switch (radix) {
case 2:
return toBinaryString(i);

case 4:
return toUnsignedString0(i, 2);

case 8:
return toOctalString(i);

case 10:
/*
* We can get the effect of an unsigned division by 10
* on a long value by first shifting right, yielding a
* positive value, and then dividing by 5. This
* allows the last digit and preceding digits to be
* isolated more quickly than by an initial conversion
* to BigInteger.
*/
long quot = (i >>> 1) / 5;
long rem = i - quot * 10;
return toString(quot) + rem;

case 16:
return toHexString(i);

case 32:
return toUnsignedString0(i, 5);

default:
return toUnsignedBigInteger(i).toString(radix);
}
return switch (radix) {
case 2 -> toBinaryString(i);
case 4 -> toUnsignedString0(i, 2);
case 8 -> toOctalString(i);
case 10 -> {
/*
* We can get the effect of an unsigned division by 10
* on a long value by first shifting right, yielding a
* positive value, and then dividing by 5. This
* allows the last digit and preceding digits to be
* isolated more quickly than by an initial conversion
* to BigInteger.
*/
long quot = (i >>> 1) / 5;
long rem = i - quot * 10;
yield toString(quot) + rem;
}
case 16 -> toHexString(i);
case 32 -> toUnsignedString0(i, 5);
default -> toUnsignedBigInteger(i).toString(radix);
};
}
}

@@ -1926,29 +1926,25 @@ public static float fma(float a, float b, float c) {
public static double ulp(double d) {
int exp = getExponent(d);

switch(exp) {
case Double.MAX_EXPONENT + 1: // NaN or infinity
return Math.abs(d);

case Double.MIN_EXPONENT - 1: // zero or subnormal
return Double.MIN_VALUE;

default:
assert exp <= Double.MAX_EXPONENT && exp >= Double.MIN_EXPONENT;

// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
if (exp >= Double.MIN_EXPONENT) {
return powerOfTwoD(exp);
}
else {
// return a subnormal result; left shift integer
// representation of Double.MIN_VALUE appropriate
// number of positions
return Double.longBitsToDouble(1L <<
(exp - (Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
return switch(exp) {
case Double.MAX_EXPONENT + 1 -> Math.abs(d); // NaN or infinity
case Double.MIN_EXPONENT - 1 -> Double.MIN_VALUE; // zero or subnormal
default -> {
assert exp <= Double.MAX_EXPONENT && exp >= Double.MIN_EXPONENT;

// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH - 1);
if (exp >= Double.MIN_EXPONENT) {
yield powerOfTwoD(exp);
} else {
// return a subnormal result; left shift integer
// representation of Double.MIN_VALUE appropriate
// number of positions
yield Double.longBitsToDouble(1L <<
(exp - (Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH - 1))));
}
}
}
};
}

/**
@@ -1977,28 +1973,25 @@ public static double ulp(double d) {
public static float ulp(float f) {
int exp = getExponent(f);

switch(exp) {
case Float.MAX_EXPONENT+1: // NaN or infinity
return Math.abs(f);
return switch(exp) {
case Float.MAX_EXPONENT + 1 -> Math.abs(f); // NaN or infinity
case Float.MIN_EXPONENT - 1 -> Float.MIN_VALUE; // zero or subnormal
default -> {
assert exp <= Float.MAX_EXPONENT && exp >= Float.MIN_EXPONENT;

case Float.MIN_EXPONENT-1: // zero or subnormal
return Float.MIN_VALUE;

default:
assert exp <= Float.MAX_EXPONENT && exp >= Float.MIN_EXPONENT;

// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
if (exp >= Float.MIN_EXPONENT) {
return powerOfTwoF(exp);
} else {
// return a subnormal result; left shift integer
// representation of FloatConsts.MIN_VALUE appropriate
// number of positions
return Float.intBitsToFloat(1 <<
(exp - (Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (FloatConsts.SIGNIFICAND_WIDTH - 1);
if (exp >= Float.MIN_EXPONENT) {
yield powerOfTwoF(exp);
} else {
// return a subnormal result; left shift integer
// representation of FloatConsts.MIN_VALUE appropriate
// number of positions
yield Float.intBitsToFloat(1 <<
(exp - (Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH - 1))));
}
}
}
};
}

/**
@@ -72,11 +72,11 @@
requireNonNull(type);

switch (kind) {
case CONSTRUCTOR: validateConstructor(type); break;
case GETTER: validateFieldType(type, false, true); break;
case SETTER: validateFieldType(type, true, true); break;
case STATIC_GETTER: validateFieldType(type, false, false); break;
case STATIC_SETTER: validateFieldType(type, true, false); break;
case CONSTRUCTOR -> validateConstructor(type);
case GETTER -> validateFieldType(type, false, true);
case SETTER -> validateFieldType(type, true, true);
case STATIC_GETTER -> validateFieldType(type, false, false);
case STATIC_SETTER -> validateFieldType(type, true, false);
}

this.kind = kind;
@@ -134,57 +134,40 @@ public MethodTypeDesc invocationType() {

@Override
public String lookupDescriptor() {
switch (kind) {
case VIRTUAL:
case SPECIAL:
case INTERFACE_VIRTUAL:
case INTERFACE_SPECIAL:
return invocationType.dropParameterTypes(0, 1).descriptorString();
case STATIC:
case INTERFACE_STATIC:
return invocationType.descriptorString();
case CONSTRUCTOR:
return invocationType.changeReturnType(CD_void).descriptorString();
case GETTER:
case STATIC_GETTER:
return invocationType.returnType().descriptorString();
case SETTER:
return invocationType.parameterType(1).descriptorString();
case STATIC_SETTER:
return invocationType.parameterType(0).descriptorString();
default:
throw new IllegalStateException(kind.toString());
}
return switch (kind) {
case VIRTUAL,
SPECIAL,
INTERFACE_VIRTUAL,
INTERFACE_SPECIAL -> invocationType.dropParameterTypes(0, 1).descriptorString();
case STATIC,
INTERFACE_STATIC -> invocationType.descriptorString();
case CONSTRUCTOR -> invocationType.changeReturnType(CD_void).descriptorString();
case GETTER,
STATIC_GETTER -> invocationType.returnType().descriptorString();
case SETTER -> invocationType.parameterType(1).descriptorString();
case STATIC_SETTER -> invocationType.parameterType(0).descriptorString();
default -> throw new IllegalStateException(kind.toString());
};
}

public MethodHandle resolveConstantDesc(MethodHandles.Lookup lookup)
throws ReflectiveOperationException {
Class<?> resolvedOwner = (Class<?>) owner.resolveConstantDesc(lookup);
MethodType invocationType = (MethodType) this.invocationType().resolveConstantDesc(lookup);
switch (kind) {
case STATIC:
case INTERFACE_STATIC:
return lookup.findStatic(resolvedOwner, name, invocationType);
case INTERFACE_VIRTUAL:
case VIRTUAL:
return lookup.findVirtual(resolvedOwner, name, invocationType.dropParameterTypes(0, 1));
case SPECIAL:
case INTERFACE_SPECIAL:
return lookup.findSpecial(resolvedOwner, name, invocationType.dropParameterTypes(0, 1),
lookup.lookupClass());
case CONSTRUCTOR:
return lookup.findConstructor(resolvedOwner, invocationType.changeReturnType(void.class));
case GETTER:
return lookup.findGetter(resolvedOwner, name, invocationType.returnType());
case STATIC_GETTER:
return lookup.findStaticGetter(resolvedOwner, name, invocationType.returnType());
case SETTER:
return lookup.findSetter(resolvedOwner, name, invocationType.parameterType(1));
case STATIC_SETTER:
return lookup.findStaticSetter(resolvedOwner, name, invocationType.parameterType(0));
default:
throw new IllegalStateException(kind.name());
}
return switch (kind) {
case STATIC,
INTERFACE_STATIC -> lookup.findStatic(resolvedOwner, name, invocationType);
case VIRTUAL,
INTERFACE_VIRTUAL -> lookup.findVirtual(resolvedOwner, name, invocationType.dropParameterTypes(0, 1));
case SPECIAL,
INTERFACE_SPECIAL -> lookup.findSpecial(resolvedOwner, name, invocationType.dropParameterTypes(0, 1), lookup.lookupClass());
case CONSTRUCTOR -> lookup.findConstructor(resolvedOwner, invocationType.changeReturnType(void.class));
case GETTER -> lookup.findGetter(resolvedOwner, name, invocationType.returnType());
case STATIC_GETTER -> lookup.findStaticGetter(resolvedOwner, name, invocationType.returnType());
case SETTER -> lookup.findSetter(resolvedOwner, name, invocationType.parameterType(1));
case STATIC_SETTER -> lookup.findStaticSetter(resolvedOwner, name, invocationType.parameterType(0));
default -> throw new IllegalStateException(kind.name());
};
}

/**
@@ -156,15 +156,13 @@ static DirectMethodHandleDesc ofField(DirectMethodHandleDesc.Kind kind,
ClassDesc owner,
String fieldName,
ClassDesc fieldType) {
MethodTypeDesc mtr;
switch (kind) {
case GETTER: mtr = MethodTypeDesc.of(fieldType, owner); break;
case SETTER: mtr = MethodTypeDesc.of(CD_void, owner, fieldType); break;
case STATIC_GETTER: mtr = MethodTypeDesc.of(fieldType); break;
case STATIC_SETTER: mtr = MethodTypeDesc.of(CD_void, fieldType); break;
default:
throw new IllegalArgumentException(kind.toString());
}
MethodTypeDesc mtr = switch (kind) {
case GETTER -> MethodTypeDesc.of(fieldType, owner);
case SETTER -> MethodTypeDesc.of(CD_void, owner, fieldType);
case STATIC_GETTER -> MethodTypeDesc.of(fieldType);
case STATIC_SETTER -> MethodTypeDesc.of(CD_void, fieldType);
default -> throw new IllegalArgumentException(kind.toString());
};
return new DirectMethodHandleDescImpl(kind, owner, fieldName, mtr);
}

@@ -64,19 +64,14 @@
static BoundMethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
// for some type signatures, there exist pre-defined concrete BMH classes
try {
switch (xtype) {
case L_TYPE:
return bindSingle(type, form, x); // Use known fast path.
case I_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(I_TYPE_NUM).factory().invokeBasic(type, form, ValueConversions.widenSubword(x));
case J_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(J_TYPE_NUM).factory().invokeBasic(type, form, (long) x);
case F_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(F_TYPE_NUM).factory().invokeBasic(type, form, (float) x);
case D_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(D_TYPE_NUM).factory().invokeBasic(type, form, (double) x);
default : throw newInternalError("unexpected xtype: " + xtype);
}
return switch (xtype) {
case L_TYPE -> bindSingle(type, form, x); // Use known fast path.
case I_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(I_TYPE_NUM).factory().invokeBasic(type, form, ValueConversions.widenSubword(x));
case J_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(J_TYPE_NUM).factory().invokeBasic(type, form, (long) x);
case F_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(F_TYPE_NUM).factory().invokeBasic(type, form, (float) x);
case D_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(D_TYPE_NUM).factory().invokeBasic(type, form, (double) x);
default -> throw newInternalError("unexpected xtype: " + xtype);
};
} catch (Throwable t) {
throw uncaughtException(t);
}
@@ -853,14 +853,14 @@ public void emitFieldInsn(int asmop, MethodVisitor mv) {
}

private int typeLoadOp(char t) {
switch (t) {
case 'L': return ALOAD;
case 'I': return ILOAD;
case 'J': return LLOAD;
case 'F': return FLOAD;
case 'D': return DLOAD;
default : throw newInternalError("unrecognized type " + t);
}
return switch (t) {
case 'L' -> ALOAD;
case 'I' -> ILOAD;
case 'J' -> LLOAD;
case 'F' -> FLOAD;
case 'D' -> DLOAD;
default -> throw newInternalError("unrecognized type " + t);
};
}

private void emitIntConstant(int con, MethodVisitor mv) {
Loading

1 comment on commit d43c8a7

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on d43c8a7 Jun 10, 2021

Please sign in to comment.