Transition live proto messages to being instantiated
Change-Id: Ia5669fd7d0d656c6e56ffcb3076179cd3f4ce963
diff --git a/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java b/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java
index 2b55be8..8374410 100644
--- a/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java
@@ -15,6 +15,9 @@
/** Called when a class is found to be instantiated. */
public void processNewlyInstantiatedClass(DexProgramClass clazz, DexEncodedMethod context) {}
+ /** Called when a class is found to be live. */
+ public void processNewlyLiveClass(DexProgramClass clazz, EnqueuerWorklist worklist) {}
+
/** Called when a field is found to be live. */
public void processNewlyLiveField(DexEncodedField field) {}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
index 943d559..bf6c8b1 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
@@ -32,6 +33,7 @@
import com.android.tools.r8.ir.optimize.info.FieldOptimizationInfo;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.EnqueuerWorklist;
+import com.android.tools.r8.shaking.InstantiationReason;
import com.android.tools.r8.shaking.KeepReason;
import com.android.tools.r8.utils.BitUtils;
import com.android.tools.r8.utils.OptionalBool;
@@ -89,6 +91,34 @@
this.references = protoShrinker.references;
}
+ @Override
+ public void processNewlyLiveClass(DexProgramClass clazz, EnqueuerWorklist worklist) {
+ assert appView.appInfo().hasClassHierarchy();
+ AppInfoWithClassHierarchy appInfo = appView.appInfo().withClassHierarchy();
+ if (appInfo.isStrictSubtypeOf(clazz.type, references.generatedMessageLiteType)) {
+ markGeneratedMessageLiteSubtypeAsInstantiated(clazz, worklist);
+ }
+ }
+
+ private void markGeneratedMessageLiteSubtypeAsInstantiated(
+ DexProgramClass clazz, EnqueuerWorklist worklist) {
+ if (clazz.isAbstract()) {
+ assert clazz.type == references.extendableMessageType;
+ return;
+ }
+ DexEncodedMethod dynamicMethod = clazz.lookupVirtualMethod(references::isDynamicMethod);
+ if (dynamicMethod != null) {
+ worklist.enqueueMarkInstantiatedAction(
+ clazz,
+ dynamicMethod,
+ InstantiationReason.REFLECTION,
+ KeepReason.reflectiveUseIn(dynamicMethod));
+ } else {
+ assert false
+ : "Expected class `" + clazz.type.toSourceString() + "` to declare a dynamicMethod()";
+ }
+ }
+
/**
* When a dynamicMethod() of a proto message becomes live, then build the corresponding {@link
* ProtoMessageInfo} object, and create a mapping from the holder to it.
@@ -557,8 +587,10 @@
DexType baseMessageType = protoFieldInfo.getBaseMessageType(factory);
if (baseMessageType != null) {
ProtoMessageInfo protoMessageInfo = getOrCreateProtoMessageInfo(baseMessageType);
- assert protoMessageInfo != null;
- return reachesMapOrRequiredField(protoMessageInfo);
+ if (protoMessageInfo != null) {
+ return reachesMapOrRequiredField(protoMessageInfo);
+ }
+ assert false : "Unable to find proto message info for `" + baseMessageType + "`";
}
return false;
}
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 422ec43..200562d 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1325,6 +1325,8 @@
rootSet.forEachDependentStaticMember(holder, appView, this::enqueueDependentItem);
compatEnqueueHolderIfDependentNonStaticMember(
holder, rootSet.getDependentKeepClassCompatRule(holder.getType()));
+
+ analyses.forEach(analysis -> analysis.processNewlyLiveClass(holder, workList));
}
private void ensureMethodsContinueToWidenAccess(DexClass clazz) {
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
index 45e61a4..c795bcc 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
@@ -270,7 +270,7 @@
// TODO(b/142378367): Context is the containing method that is cause of the instantiation.
// Consider updating call sites with the context information to increase precision where possible.
- void enqueueMarkInstantiatedAction(
+ public void enqueueMarkInstantiatedAction(
DexProgramClass clazz,
DexEncodedMethod context,
InstantiationReason instantiationReason,
diff --git a/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
index 7d04499..183ee3e 100644
--- a/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
@@ -45,13 +45,14 @@
.addKeepRuleFiles(
Paths.get(base).resolve(BASE_PG_CONF),
Paths.get(ToolHelper.PROGUARD_SETTINGS_FOR_INTERNAL_APPS, PG_CONF))
- .allowDiagnosticInfoMessages()
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
.compile()
.assertAllInfoMessagesMatch(
anyOf(
equalTo("Ignoring option: -optimizations"),
- containsString("Proguard configuration rule does not match anything")));
+ containsString("Proguard configuration rule does not match anything")))
+ .assertAllWarningMessagesMatch(containsString("Ignoring option:"));
int appSize = compileResult.app.applicationSize();
assertTrue("Expected max size of " + MAX_SIZE+ ", got " + appSize, appSize < MAX_SIZE);
diff --git a/third_party/proguardsettings.tar.gz.sha1 b/third_party/proguardsettings.tar.gz.sha1
index d5c183a..af7dff0 100644
--- a/third_party/proguardsettings.tar.gz.sha1
+++ b/third_party/proguardsettings.tar.gz.sha1
@@ -1 +1 @@
-7bb1badb721635d2baa7b63aab1e3a67434f94dd
\ No newline at end of file
+12c2e310110cdccb6aa5a37c287456b8c4bfe3d6
\ No newline at end of file