Pin soft pinned classes when type becomes live
Bug: 189443104
Change-Id: I697b977ef50d104d894c8af231f3617e6ede741e
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 f6d9e6e..f3d898f 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1797,6 +1797,8 @@
enqueueFirstNonSerializableClassInitializer(clazz, reason);
}
+ checkDefinitionForSoftPinning(clazz);
+
processAnnotations(clazz);
// If this type has deferred annotations, we have to process those now, too.
@@ -2602,7 +2604,7 @@
// Add all dependent members to the workqueue.
enqueueRootItems(rootSet.getDependentItems(field.getDefinition()));
- checkMemberForSoftPinning(field);
+ checkDefinitionForSoftPinning(field);
// Notify analyses.
analyses.forEach(analysis -> analysis.processNewlyLiveField(field, context));
@@ -3851,7 +3853,7 @@
// Add all dependent members to the workqueue.
enqueueRootItems(rootSet.getDependentItems(definition));
- checkMemberForSoftPinning(method);
+ checkDefinitionForSoftPinning(method);
// Notify analyses.
analyses.forEach(analysis -> analysis.processNewlyLiveMethod(method, context));
@@ -3898,15 +3900,15 @@
method.registerCodeReferences(useRegistryFactory.create(appView, method, this));
}
- private void checkMemberForSoftPinning(ProgramMember<?, ?> member) {
- DexMember<?, ?> reference = member.getDefinition().getReference();
+ private void checkDefinitionForSoftPinning(ProgramDefinition definition) {
+ DexReference reference = definition.getReference();
Set<ProguardKeepRuleBase> softPinRules = rootSet.softPinned.getRulesForReference(reference);
if (softPinRules != null) {
assert softPinRules.stream().noneMatch(r -> r.getModifiers().allowsOptimization);
keepInfo.joinInfo(reference, appInfo, Joiner::pin);
}
// Identify dependent soft pinning.
- MutableItemsWithRules items = rootSet.dependentSoftPinned.get(member.getHolderType());
+ MutableItemsWithRules items = rootSet.dependentSoftPinned.get(definition.getContextType());
if (items != null && items.containsReference(reference)) {
assert items.getRulesForReference(reference).stream()
.noneMatch(r -> r.getModifiers().allowsOptimization);
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java
index 46e1a82..be24a34 100644
--- a/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/graph/genericsignature/GenericSignatureAllowShrinkingTest.java
@@ -46,7 +46,7 @@
.addKeepAttributes(ProguardKeepAttributes.SIGNATURE)
.addKeepMainRule(Main.class)
.run(parameters.getRuntime(), Main.class)
- .inspect(inspector -> inspect(inspector, true))
+ .inspect(this::inspect)
.assertSuccessWithOutputLines(EXPECTED);
}
@@ -62,26 +62,20 @@
+ " { *; }")
.addKeepAttributes(ProguardKeepAttributes.SIGNATURE)
.addKeepMainRule(Main.class)
- .compile()
- // TODO(b/189443104): Should keep signature.
- .inspect(inspector -> inspect(inspector, false))
.run(parameters.getRuntime(), Main.class)
- // TODO(b/189443104): Should succeed.
- .assertFailureWithErrorThatThrows(ClassCastException.class);
+ .inspect(this::inspect)
+ .assertSuccessWithOutputLines(EXPECTED);
}
- private void inspect(CodeInspector inspector, boolean keptSignature) {
+ private void inspect(CodeInspector inspector) {
ClassSubject foo = inspector.clazz(Foo.class);
assertThat(foo, isPresent());
- assertEquals(
- keptSignature ? "<T:Ljava/lang/Object;>Ljava/lang/Object;" : null,
- foo.getFinalSignatureAttribute());
+ assertEquals("<T:Ljava/lang/Object;>Ljava/lang/Object;", foo.getFinalSignatureAttribute());
ClassSubject main$1 = inspector.clazz(Main.class.getTypeName() + "$1");
assertThat(main$1, isPresent());
assertEquals(
- keptSignature ? "L" + binaryName(Foo.class) + "<Ljava/lang/String;>;" : null,
- main$1.getFinalSignatureAttribute());
+ "L" + binaryName(Foo.class) + "<Ljava/lang/String;>;", main$1.getFinalSignatureAttribute());
}
public static class Foo<T> {
diff --git a/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java b/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java
index 7dc40c3..5ee49f5 100644
--- a/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/allowshrinking/KeepClassAllowShrinkingCompatibilityTest.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.shaking.allowshrinking;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.TestBase;
@@ -54,11 +53,10 @@
.compile()
.inspect(
inspector -> {
- // TODO(b/189443104): Should keep A and B.
ClassSubject aSubject = inspector.clazz(A.class);
- assertThat(aSubject, shrinker.isR8() ? not(isPresent()) : isPresent());
+ assertThat(aSubject, isPresent());
ClassSubject bSubject = inspector.clazz(B.class);
- assertThat(bSubject, shrinker.isR8() ? not(isPresent()) : isPresent());
+ assertThat(bSubject, isPresent());
})
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithEmptyOutput();