Fix issue with <clinit> rewriting
Ensure that static initializer optimization only try to rewrite puts
to fields defined on the class for which the <clinit> is defined.
Tests will be in a separate CL.
Bug: 67468748
Change-Id: I61e9c046767b1655906f37f2217a7d1541fb8290
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index e454d89..e5d4a56 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -82,7 +82,6 @@
virtualMethods = MoreObjects.firstNonNull(values, NO_METHODS);
}
-
public void forEachMethod(Consumer<DexEncodedMethod> consumer) {
for (DexEncodedMethod method : directMethods()) {
consumer.accept(method);
@@ -130,6 +129,15 @@
staticFields = MoreObjects.firstNonNull(values, NO_FIELDS);
}
+ public boolean definesStaticField(DexField field) {
+ for (DexEncodedField encodedField : staticFields()) {
+ if (encodedField.field == field) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public DexEncodedField[] instanceFields() {
return instanceFields;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index c74a5a0..168dcf9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -845,6 +845,13 @@
if (code.computeNormalExitBlocks().isEmpty()) {
return;
}
+ DexClass clazz = appInfo.definitionFor(method.method.getHolder());
+ if (clazz == null) {
+ // TODO(67672280): Synthesized lambda classes are also optimized. However, they are not
+ // added to the AppInfo.
+ assert method.accessFlags.isSynthetic();
+ return;
+ }
DominatorTree dominatorTree = new DominatorTree(code);
Set<StaticPut> puts = Sets.newIdentityHashSet();
Map<DexField, StaticPut> dominatingPuts = Maps.newIdentityHashMap();
@@ -855,7 +862,7 @@
if (current.isStaticPut()) {
StaticPut put = current.asStaticPut();
DexField field = put.getField();
- if (field.getHolder() == method.method.getHolder()) {
+ if (clazz.definesStaticField(field)) {
if (put.inValue().isConstant()) {
if ((field.type.isClassType() || field.type.isArrayType())
&& put.inValue().isZero()) {
@@ -891,10 +898,6 @@
for (StaticPut put : dominatingPuts.values()) {
DexField field = put.getField();
DexEncodedField encodedField = appInfo.definitionFor(field);
- if (encodedField == null) {
- // See b/67468748.
- continue;
- }
if (field.type == dexItemFactory.stringType) {
if (put.inValue().isConstant()) {
if (put.inValue().isConstNumber()) {