Support for startup instrumentating using Log.i
Change-Id: I9a2728211ab283a4853386afab9eff8ab55f13b0
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupInstrumentation.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupInstrumentation.java
index cb5389d..8995dbc 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupInstrumentation.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupInstrumentation.java
@@ -10,6 +10,8 @@
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfReturnVoid;
+import com.android.tools.r8.cf.code.CfStackInstruction;
+import com.android.tools.r8.cf.code.CfStackInstruction.Opcode;
import com.android.tools.r8.cf.code.CfStaticFieldRead;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
@@ -31,10 +33,12 @@
private final AppView<?> appView;
private final DexItemFactory dexItemFactory;
+ private final StartupOptions options;
public StartupInstrumentation(AppView<?> appView) {
this.appView = appView;
this.dexItemFactory = appView.dexItemFactory();
+ this.options = appView.options().getStartupOptions();
}
public void instrumentClasses(ExecutorService executorService) throws ExecutionException {
@@ -87,14 +91,25 @@
}
CfCode cfCode = code.asCfCode();
- List<CfInstruction> instructions = new ArrayList<>(3 + cfCode.getInstructions().size());
- instructions.add(new CfStaticFieldRead(dexItemFactory.javaLangSystemMembers.out));
- instructions.add(new CfConstString(classInitializer.getHolderType().getDescriptor()));
- instructions.add(
- new CfInvoke(
- Opcodes.INVOKEVIRTUAL,
- dexItemFactory.javaIoPrintStreamMembers.printlnWithString,
- false));
+ List<CfInstruction> instructions;
+ if (options.hasStartupInstrumentationTag()) {
+ instructions = new ArrayList<>(4 + cfCode.getInstructions().size());
+ instructions.add(
+ new CfConstString(dexItemFactory.createString(options.getStartupInstrumentationTag())));
+ instructions.add(new CfConstString(classInitializer.getHolderType().getDescriptor()));
+ instructions.add(
+ new CfInvoke(Opcodes.INVOKESTATIC, dexItemFactory.androidUtilLogMembers.i, false));
+ instructions.add(new CfStackInstruction(Opcode.Pop));
+ } else {
+ instructions = new ArrayList<>(3 + cfCode.getInstructions().size());
+ instructions.add(new CfStaticFieldRead(dexItemFactory.javaLangSystemMembers.out));
+ instructions.add(new CfConstString(classInitializer.getHolderType().getDescriptor()));
+ instructions.add(
+ new CfInvoke(
+ Opcodes.INVOKEVIRTUAL,
+ dexItemFactory.javaIoPrintStreamMembers.printlnWithString,
+ false));
+ }
instructions.addAll(cfCode.getInstructions());
classInitializer.setCode(
new CfCode(
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
index 0ebce64..7fad730 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.experimental.startup;
+import static com.android.tools.r8.utils.InternalOptions.getSystemPropertyForDevelopmentOrDefault;
import static com.android.tools.r8.utils.InternalOptions.isSystemPropertyForDevelopmentSet;
public class StartupOptions {
@@ -14,9 +15,20 @@
isSystemPropertyForDevelopmentSet("com.android.tools.r8.startup.completenesscheck");
private boolean enableStartupInstrumentation =
isSystemPropertyForDevelopmentSet("com.android.tools.r8.startup.instrument");
+ private String startupInstrumentationTag =
+ getSystemPropertyForDevelopmentOrDefault(
+ "com.android.tools.r8.startup.instrumentationtag", null);
private StartupConfiguration startupConfiguration;
+ public boolean hasStartupInstrumentationTag() {
+ return startupInstrumentationTag != null;
+ }
+
+ public String getStartupInstrumentationTag() {
+ return startupInstrumentationTag;
+ }
+
public boolean isMinimalStartupDexEnabled() {
return enableMinimalStartupDex;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 1d5a3a0..7c0e5d2 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -547,6 +547,7 @@
public final ClassMethods classMethods = new ClassMethods();
public final ConstructorMethods constructorMethods = new ConstructorMethods();
public final EnumMembers enumMembers = new EnumMembers();
+ public final AndroidUtilLogMembers androidUtilLogMembers = new AndroidUtilLogMembers();
public final JavaLangReflectArrayMembers javaLangReflectArrayMembers =
new JavaLangReflectArrayMembers();
public final JavaLangAnnotationRetentionPolicyMembers javaLangAnnotationRetentionPolicyMembers =
@@ -1703,6 +1704,14 @@
}
}
+ public class AndroidUtilLogMembers {
+
+ public final DexMethod i =
+ createMethod(androidUtilLogType, createProto(intType, stringType, stringType), "i");
+
+ private AndroidUtilLogMembers() {}
+ }
+
public class JavaLangAnnotationRetentionPolicyMembers {
public final DexField CLASS =
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 3839809..8942e41 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -873,6 +873,17 @@
return false;
}
+ public static String getSystemPropertyForDevelopmentOrDefault(
+ String propertyName, String defaultValue) {
+ if (Version.isDevelopmentVersion()) {
+ String propertyValue = System.getProperty(propertyName);
+ if (propertyValue != null) {
+ return propertyValue;
+ }
+ }
+ return defaultValue;
+ }
+
private static int parseSystemPropertyForDevelopmentOrDefault(
String propertyName, int defaultValue) {
if (Version.isDevelopmentVersion()) {