Rewrite ConstDynamic with ClassDesc
Change-Id: I8661e816eca91a42fc749633eb9a6948dbbf2a56
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
index 963df0f..b125b83 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstDynamic.java
@@ -150,7 +150,7 @@
for (int i = 0; i < rewrittenArguments.size(); i++) {
bsmArgs[i] =
CfInvokeDynamic.decodeBootstrapArgument(
- rewrittenArguments.get(i), namingLens, dexItemFactory);
+ rewrittenArguments.get(i), namingLens, appView, context);
}
ConstantDynamic constantDynamic =
new ConstantDynamic(
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
index a1fed4c..b8d79e9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.CfCodeDiagnostics;
import com.android.tools.r8.graph.CfCompareHelper;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClassAndMethod;
@@ -14,6 +15,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
+import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.graph.lens.GraphLens;
@@ -27,6 +29,7 @@
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.optimize.interfaces.analysis.CfAnalysisConfig;
import com.android.tools.r8.optimize.interfaces.analysis.CfFrameState;
+import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.structural.CompareToVisitor;
import com.android.tools.r8.utils.structural.HashingVisitor;
import java.util.ArrayList;
@@ -88,7 +91,7 @@
List<DexValue> bootstrapArgs = rewrittenCallSite.bootstrapArgs;
Object[] bsmArgs = new Object[bootstrapArgs.size()];
for (int i = 0; i < bootstrapArgs.size(); i++) {
- bsmArgs[i] = decodeBootstrapArgument(bootstrapArgs.get(i), namingLens, dexItemFactory);
+ bsmArgs[i] = decodeBootstrapArgument(bootstrapArgs.get(i), namingLens, appView, context);
}
Handle bsmHandle = bootstrapMethod.toAsmHandle(namingLens);
DexString methodName = namingLens.lookupMethodName(rewrittenCallSite, appView);
@@ -105,7 +108,7 @@
}
public static Object decodeBootstrapArgument(
- DexValue value, NamingLens lens, DexItemFactory factory) {
+ DexValue value, NamingLens lens, AppView<?> appView, ProgramMethod context) {
switch (value.getValueKind()) {
case DOUBLE:
return value.asDexValueDouble().getValue();
@@ -128,8 +131,11 @@
ConstantDynamicReference ref = value.asDexValueConstDynamic().getValue();
List<DexValue> bootstrapArgs = ref.getBootstrapMethodArguments();
Object[] bsmArgs = new Object[bootstrapArgs.size()];
- for (int i = 0; i < bootstrapArgs.size(); i++) {
- bsmArgs[i] = CfInvokeDynamic.decodeBootstrapArgument(bootstrapArgs.get(i), lens, factory);
+ DexItemFactory factory = appView.dexItemFactory();
+ if (ref.getType().isIdenticalTo(factory.classDescType)) {
+ decodeClassDescBootstrapArgs(lens, bootstrapArgs, bsmArgs, appView, context);
+ } else {
+ decodeBootstrapArgs(lens, bootstrapArgs, bsmArgs, appView, context);
}
return new ConstantDynamic(
ref.getName().toString(),
@@ -142,6 +148,49 @@
}
}
+ private static void decodeBootstrapArgs(
+ NamingLens lens,
+ List<DexValue> bootstrapArgs,
+ Object[] bsmArgs,
+ AppView<?> appView,
+ ProgramMethod context) {
+ for (int i = 0; i < bootstrapArgs.size(); i++) {
+ bsmArgs[i] =
+ CfInvokeDynamic.decodeBootstrapArgument(bootstrapArgs.get(i), lens, appView, context);
+ }
+ }
+
+ private static void decodeClassDescBootstrapArgs(
+ NamingLens lens,
+ List<DexValue> bootstrapArgs,
+ Object[] bsmArgs,
+ AppView<?> appView,
+ ProgramMethod context) {
+ if (bootstrapArgs.size() != 2 || !bootstrapArgs.get(1).isDexValueString()) {
+ appView
+ .reporter()
+ .warning(
+ new CfCodeDiagnostics(
+ context, "Unexpected ClassDesc bootstrap arguments " + bootstrapArgs));
+ decodeBootstrapArgs(lens, bootstrapArgs, bsmArgs, appView, context);
+ return;
+ }
+ bsmArgs[0] =
+ CfInvokeDynamic.decodeBootstrapArgument(bootstrapArgs.get(0), lens, appView, context);
+ DexValueString className = bootstrapArgs.get(1).asDexValueString();
+ DexItemFactory factory = appView.dexItemFactory();
+ DexType rewrittenType =
+ lens.lookupType(
+ factory.createType(
+ DescriptorUtils.javaTypeToDescriptor(className.getValue().toString())),
+ factory);
+ DexString rewrittenValue =
+ factory.createString(
+ DescriptorUtils.descriptorToJavaType(rewrittenType.getDescriptor().toString()));
+ assert rewrittenValue != null;
+ bsmArgs[1] = rewrittenValue.toString();
+ }
+
@Override
public void print(CfPrinter printer) {
printer.print(this);
diff --git a/src/main/java/com/android/tools/r8/graph/UseRegistry.java b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
index e3f2ba6..d138d31 100644
--- a/src/main/java/com/android/tools/r8/graph/UseRegistry.java
+++ b/src/main/java/com/android/tools/r8/graph/UseRegistry.java
@@ -269,12 +269,13 @@
.getValue()
.getType()
.isIdenticalTo(appView.dexItemFactory().enumDescType)) {
- DexField enumField =
- TypeSwitchDesugaringHelper.extractEnumField(
- arg.asDexValueConstDynamic(), getMethodContext(), appView);
- if (enumField != null) {
- registerStaticFieldRead(enumField);
- }
+ TypeSwitchDesugaringHelper.dispatchEnumField(
+ (type, fieldName) -> {
+ registerTypeReference(type);
+ },
+ arg.asDexValueConstDynamic().getValue(),
+ context,
+ dexItemFactory());
}
break;
default:
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
index 776debb..898f0f9 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaring.java
@@ -190,8 +190,7 @@
if (dexValue.isDexValueType()) {
dexTypeConsumer.accept(dexValue.asDexValueType().getValue());
} else if (dexValue.isDexValueString()) {
- enumConsumer.accept(
- factory.createString(enumType.getTypeName()), dexValue.asDexValueString().getValue());
+ enumConsumer.accept(enumType, dexValue.asDexValueString().getValue());
} else {
throw new CompilationError(
"Invalid bootstrap arg for enum switch " + dexValue, context.getOrigin());
@@ -227,7 +226,7 @@
dispatchBooleanField(context, dexValue, booleanConsumer, constDynamic);
} else {
assert constDynamic.getType().isIdenticalTo(factory.enumDescType);
- dispatchEnumField(enumConsumer, constDynamic, context, appView);
+ dispatchEnumField(enumConsumer, constDynamic, context, appView.dexItemFactory());
}
} else if (dexValue.isDexValueNumber()) {
assert dexValue.isDexValueDouble()
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java
index da7fc02..2780c66 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/typeswitch/TypeSwitchDesugaringHelper.java
@@ -5,12 +5,8 @@
package com.android.tools.r8.ir.desugar.typeswitch;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Definition;
import com.android.tools.r8.graph.DexCallSite;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
@@ -18,14 +14,12 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
-import com.android.tools.r8.graph.DexValue.DexValueConstDynamic;
import com.android.tools.r8.ir.desugar.constantdynamic.ConstantDynamicReference;
import com.android.tools.r8.utils.DescriptorUtils;
import java.util.function.BiConsumer;
public class TypeSwitchDesugaringHelper {
- private static CompilationError throwEnumFieldConstantDynamic(
- String msg, DexClassAndMethod context) {
+ private static CompilationError throwEnumFieldConstantDynamic(String msg, Definition context) {
throw new CompilationError(
"Unexpected ConstantDynamic in TypeSwitch: " + msg, context.getOrigin());
}
@@ -67,11 +61,10 @@
}
public static void dispatchEnumField(
- BiConsumer<DexString, DexString> enumConsumer,
+ BiConsumer<DexType, DexString> enumConsumer,
ConstantDynamicReference enumCstDynamic,
- DexClassAndMethod context,
- AppView<?> appView) {
- DexItemFactory factory = appView.dexItemFactory();
+ Definition context,
+ DexItemFactory factory) {
DexMethod bootstrapMethod = factory.constantDynamicBootstrapMethod;
if (!(enumCstDynamic.getType().isIdenticalTo(factory.enumDescType)
&& enumCstDynamic.getName().isIdenticalTo(bootstrapMethod.getName())
@@ -106,65 +99,7 @@
throw throwEnumFieldConstantDynamic("Class name " + dexValueClassName, context);
}
DexString className = dexValueClassName.asDexValueString().getValue();
- enumConsumer.accept(className, fieldName);
- }
-
- public static DexField extractEnumField(
- DexValueConstDynamic dexValueConstDynamic, DexClassAndMethod context, AppView<?> appView) {
- DexItemFactory factory = appView.dexItemFactory();
- ConstantDynamicReference enumCstDynamic = dexValueConstDynamic.getValue();
- DexMethod bootstrapMethod = factory.constantDynamicBootstrapMethod;
- if (!(enumCstDynamic.getType().isIdenticalTo(factory.enumDescType)
- && enumCstDynamic.getName().isIdenticalTo(bootstrapMethod.getName())
- && enumCstDynamic.getBootstrapMethod().asMethod().isIdenticalTo(bootstrapMethod)
- && enumCstDynamic.getBootstrapMethodArguments().size() == 3
- && methodHandleIsInvokeStaticTo(
- enumCstDynamic.getBootstrapMethodArguments().get(0), factory.enumDescMethod))) {
- throw throwEnumFieldConstantDynamic("Invalid EnumDesc", context);
- }
- DexValue dexValueFieldName = enumCstDynamic.getBootstrapMethodArguments().get(2);
- if (!dexValueFieldName.isDexValueString()) {
- throw throwEnumFieldConstantDynamic("Field name " + dexValueFieldName, context);
- }
- DexString fieldName = dexValueFieldName.asDexValueString().getValue();
-
- DexValue dexValueClassCstDynamic = enumCstDynamic.getBootstrapMethodArguments().get(1);
- if (!dexValueClassCstDynamic.isDexValueConstDynamic()) {
- throw throwEnumFieldConstantDynamic("Enum class " + dexValueClassCstDynamic, context);
- }
- ConstantDynamicReference classCstDynamic =
- dexValueClassCstDynamic.asDexValueConstDynamic().getValue();
- if (!(classCstDynamic.getType().isIdenticalTo(factory.classDescType)
- && classCstDynamic.getName().isIdenticalTo(bootstrapMethod.getName())
- && classCstDynamic.getBootstrapMethod().asMethod().isIdenticalTo(bootstrapMethod)
- && classCstDynamic.getBootstrapMethodArguments().size() == 2
- && methodHandleIsInvokeStaticTo(
- classCstDynamic.getBootstrapMethodArguments().get(0), factory.classDescMethod))) {
- throw throwEnumFieldConstantDynamic("Class descriptor " + classCstDynamic, context);
- }
- DexValue dexValueClassName = classCstDynamic.getBootstrapMethodArguments().get(1);
- if (!dexValueClassName.isDexValueString()) {
- throw throwEnumFieldConstantDynamic("Class name " + dexValueClassName, context);
- }
- DexString className = dexValueClassName.asDexValueString().getValue();
- DexType enumType =
- factory.createType(DescriptorUtils.javaTypeToDescriptor(className.toString()));
- return getEnumField(fieldName, enumType, appView);
- }
-
- public static DexField getEnumField(DexString fieldName, DexType enumType, AppView<?> appView) {
- DexClass enumClass = appView.appInfo().definitionForWithoutExistenceAssert(enumType);
- if (enumClass == null) {
- // If the enum class is missing, the case is (interestingly) considered unreachable and
- // effectively removed from the switch (base on jdk 21 behavior).
- return null;
- }
- DexEncodedField dexEncodedField = enumClass.lookupUniqueStaticFieldWithName(fieldName);
- if (dexEncodedField == null) {
- // If the field is missing, but the class is there, the case is considered unreachable and
- // effectively removed from the switch.
- return null;
- }
- return dexEncodedField.getReference();
+ DexType type = factory.createType(DescriptorUtils.javaTypeToDescriptor(className.toString()));
+ enumConsumer.accept(type, fieldName);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
index 0edb7aa..2b7c39c 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/TypeSwitchSyntheticCfCodeProvider.java
@@ -63,7 +63,7 @@
Consumer<DexType> dexTypeConsumer,
IntConsumer intValueConsumer,
Consumer<DexString> dexStringConsumer,
- BiConsumer<DexString, DexString> enumConsumer,
+ BiConsumer<DexType, DexString> enumConsumer,
Consumer<Boolean> booleanConsumer,
Consumer<DexValueNumber> numberConsumer);
}
@@ -186,7 +186,7 @@
instructions.add(new CfConstNumber(index.getAndIncrement(), ValueType.INT));
instructions.add(new CfReturn(ValueType.INT));
},
- (enumClass, enumField) -> {
+ (type, enumField) -> {
instructions.add(cfLabels.get(index.get()));
instructions.add(frame);
// TODO(b/399808482): In R8 release, we can analyze at compile-time program enum
@@ -197,15 +197,15 @@
instructions.add(new CfStaticFieldRead(enumFieldCache));
instructions.add(new CfConstNumber(enumIndex.getAndIncrement(), ValueType.INT));
if (appView.enableWholeProgramOptimizations()) {
- DexType type =
- factory.createType(
- DescriptorUtils.javaTypeToDescriptor(enumClass.toString()));
instructions.add(
new CfDexItemBasedConstString(
type,
ClassNameComputationInfo.create(NAME, type.getArrayTypeDimensions())));
} else {
- instructions.add(new CfConstString(enumClass));
+ DexString typeString =
+ factory.createString(
+ DescriptorUtils.descriptorToJavaType(type.toDescriptorString()));
+ instructions.add(new CfConstString(typeString));
}
instructions.add(new CfConstString(enumField));
assert enumEq != null;
diff --git a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
index 14877d0..1e92c88 100644
--- a/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
+++ b/src/main/java/com/android/tools/r8/shaking/DefaultEnqueuerUseRegistry.java
@@ -5,8 +5,6 @@
package com.android.tools.r8.shaking;
import static com.android.tools.r8.ir.desugar.records.RecordRewriterHelper.isInvokeDynamicOnRecord;
-import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.extractEnumField;
-import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.getEnumField;
import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isEnumSwitchCallSite;
import static com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper.isTypeSwitchCallSite;
import static com.android.tools.r8.utils.MapUtils.ignoreKey;
@@ -16,6 +14,7 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
+import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -23,13 +22,13 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.OriginalFieldWitness;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.InvokeType;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.desugar.typeswitch.TypeSwitchDesugaringHelper;
import com.google.common.collect.Sets;
import java.util.IdentityHashMap;
import java.util.ListIterator;
@@ -213,11 +212,6 @@
enqueuer.traceStaticFieldReadFromMethodHandle(field, getContext());
}
- private void registerStaticFieldReadFromSwitchMethodHandle(DexField field) {
- super.registerStaticFieldReadFromMethodHandle(field);
- enqueuer.traceStaticFieldReadFromSwitchMethodHandle(field, getContext());
- }
-
@Override
public void registerStaticFieldWrite(DexField field) {
super.registerStaticFieldWrite(field);
@@ -290,7 +284,16 @@
enqueuer.traceCallSite(callSite, getContext(), this);
}
- private void registerEnumMethods(DexType enumType) {
+ private void registerEnumReferencedInTypeSwitchBootstrapArguments(DexType enumType) {
+ DexClass dexClass = appView.definitionFor(enumType);
+ if (dexClass == null || dexClass.isNotProgramClass()) {
+ return;
+ }
+ // The enum class cannot be unboxed or class merged. It can however be renamed.
+ enqueuer
+ .getKeepInfo()
+ .joinClass(
+ dexClass.asProgramClass(), joiner -> joiner.disallowOptimization().disallowShrinking());
DexItemFactory factory = dexItemFactory();
DexMethod values =
factory.createMethod(
@@ -314,12 +317,13 @@
.getValue()
.getType()
.isIdenticalTo(appView.dexItemFactory().enumDescType)) {
- DexField enumField =
- extractEnumField(bootstrapArg.asDexValueConstDynamic(), getContext(), appView);
- if (enumField != null) {
- registerStaticFieldReadFromSwitchMethodHandle(enumField);
- registerEnumMethods(enumField.getHolderType());
- }
+ TypeSwitchDesugaringHelper.dispatchEnumField(
+ (type, fieldName) -> {
+ registerEnumReferencedInTypeSwitchBootstrapArguments(type);
+ },
+ bootstrapArg.asDexValueConstDynamic().getValue(),
+ getContext(),
+ dexItemFactory());
}
}
}
@@ -330,12 +334,7 @@
if (bootstrapArg.isDexValueType()) {
registerTypeReference(bootstrapArg.asDexValueType().value);
} else if (bootstrapArg.isDexValueString()) {
- DexString fieldName = bootstrapArg.asDexValueString().value;
- DexField enumField = getEnumField(fieldName, enumType, appView);
- if (enumField != null) {
- registerStaticFieldReadFromSwitchMethodHandle(enumField);
- registerEnumMethods(enumType);
- }
+ registerEnumReferencedInTypeSwitchBootstrapArguments(enumType);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 8cee863..7fb2bf6 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1803,15 +1803,12 @@
private static final int DEFERRED_MASK = 1;
private static final int FROM_METHOD_HANDLE_MASK = 2;
private static final int FROM_RECORD_METHOD_HANDLE_MASK = 4;
- private static final int FROM_SWITCH_METHOD_HANDLE_MASK = 8;
static FieldAccessMetadata DEFAULT = new FieldAccessMetadata(0);
static FieldAccessMetadata FROM_METHOD_HANDLE =
new FieldAccessMetadata(FROM_METHOD_HANDLE_MASK);
static FieldAccessMetadata FROM_RECORD_METHOD_HANDLE =
new FieldAccessMetadata(FROM_RECORD_METHOD_HANDLE_MASK);
- static FieldAccessMetadata FROM_SWITCH_METHOD_HANDLE =
- new FieldAccessMetadata(FROM_SWITCH_METHOD_HANDLE_MASK);
private final FieldAccessMetadata deferred;
private final int flags;
@@ -1833,10 +1830,6 @@
return (flags & FROM_RECORD_METHOD_HANDLE_MASK) != 0;
}
- boolean isFromSwitchMethodHandle() {
- return (flags & FROM_SWITCH_METHOD_HANDLE_MASK) != 0;
- }
-
public FieldAccessMetadata toDeferred() {
return deferred;
}
@@ -1948,11 +1941,6 @@
void traceStaticFieldReadFromMethodHandle(DexField field, ProgramMethod currentMethod) {
traceStaticFieldRead(field, currentMethod, FieldAccessMetadata.FROM_METHOD_HANDLE);
}
-
- void traceStaticFieldReadFromSwitchMethodHandle(DexField field, ProgramMethod currentMethod) {
- traceStaticFieldRead(field, currentMethod, FieldAccessMetadata.FROM_SWITCH_METHOD_HANDLE);
- }
-
void traceStaticFieldRead(
DexField fieldReference, ProgramMethod currentMethod, FieldAccessMetadata metadata) {
traceStaticFieldAccess(fieldReference, currentMethod, FieldAccessKind.STATIC_READ, metadata);
@@ -2033,16 +2021,6 @@
fieldAccessInfoCollection
.get(field.getReference())
.setAccessedFromMethodHandle(accessKind);
- } else if (metadata.isFromSwitchMethodHandle()) {
- assert accessKind.isRead();
- // TODO(b/340187630): This disables any optimization on such enum fields. We could
- // support rewriting fields in switch method handles instead.
- keepInfo.joinClass(
- field.getHolder(),
- joiner -> joiner.disallowMinification().disallowOptimization().disallowShrinking());
- keepInfo.joinField(
- field,
- joiner -> joiner.disallowMinification().disallowOptimization().disallowShrinking());
}
markFieldAsLive(field, currentMethod);
diff --git a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java
index 78bb2ef..9f63637 100644
--- a/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java
+++ b/src/test/java23/com/android/tools/r8/java23/switchpatternmatching/DexValueSwitchTest.java
@@ -80,6 +80,71 @@
static class Main {
+ // static void booleanSwitch(Boolean b) {
+ // switch (b) {
+ // case null -> {
+ // System.out.println("null");
+ // }
+ // case true -> {
+ // System.out.println("true");
+ // }
+ // default -> {
+ // System.out.println("false");
+ // }
+ // }
+ // }
+ //
+ // static void doubleSwitch(Double d) {
+ // switch (d) {
+ // case null -> {
+ // System.out.println("null");
+ // }
+ // case 42.0 -> {
+ // System.out.println("42");
+ // }
+ // case Double f2 when f2 > 0 -> {
+ // System.out.println("positif");
+ // }
+ // default -> {
+ // System.out.println("negatif");
+ // }
+ // }
+ // }
+ //
+ // static void floatSwitch(Float f) {
+ // switch (f) {
+ // case null -> {
+ // System.out.println("null");
+ // }
+ // case 42.0f -> {
+ // System.out.println("42");
+ // }
+ // case Float f2 when f2 > 0 -> {
+ // System.out.println("positif");
+ // }
+ // default -> {
+ // System.out.println("negatif");
+ // }
+ // }
+ // }
+ //
+ // static void longSwitch(Long l) {
+ // switch (l) {
+ // case null -> {
+ // System.out.println("null");
+ // }
+ // case 42L -> {
+ // System.out.println("42");
+ // }
+ // case Long i2 when i2 > 0 -> {
+ // System.out.println("positif");
+ // }
+ // default -> {
+ // System.out.println("negatif");
+ // }
+ // }
+ // }
+
static void intSwitch(Integer i) {
switch (i) {
case null -> {