Merge "Add bootstrapping test for testing compilation and sanity"
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index a662e1e..db0c983 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -643,6 +643,26 @@
}
}
+ public void optimizeMethodOnSynthesizedClass(DexProgramClass clazz, DexEncodedMethod method) {
+ if (!method.isProcessed()) {
+ try {
+ enterCachedClass(clazz);
+ // Process the generated method, but don't apply any outlining.
+ optimizeSynthesizedMethod(method);
+ } finally {
+ leaveCachedClass(clazz);
+ }
+ }
+ }
+
+ public void optimizeSynthesizedMethod(DexEncodedMethod method) {
+ if (!method.isProcessed()) {
+ // Process the generated method, but don't apply any outlining.
+ processMethod(method, ignoreOptimizationFeedback, x -> false, CallSiteInformation.empty(),
+ Outliner::noProcessing);
+ }
+ }
+
private void enterCachedClass(DexProgramClass clazz) {
DexProgramClass previous = cachedClasses.put(clazz.type, clazz);
assert previous == null;
@@ -653,12 +673,6 @@
assert existing == clazz;
}
- public void optimizeSynthesizedMethod(DexEncodedMethod method) {
- // Process the generated method, but don't apply any outlining.
- processMethod(method, ignoreOptimizationFeedback, x -> false, CallSiteInformation.empty(),
- Outliner::noProcessing);
- }
-
private String logCode(InternalOptions options, DexEncodedMethod method) {
return options.useSmaliSyntax ? method.toSmaliString(null) : method.codeToString();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 03a3818..01555da 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -128,6 +128,8 @@
}
private DexProgramClass synthesizeLambdaClass() {
+ DexMethod mainMethod = rewriter.factory
+ .createMethod(type, descriptor.erasedProto, descriptor.name);
DexProgramClass clazz =
new DexProgramClass(
type,
@@ -146,8 +148,11 @@
synthesizeStaticFields(),
synthesizeInstanceFields(),
synthesizeDirectMethods(),
- synthesizeVirtualMethods(),
+ synthesizeVirtualMethods(mainMethod),
rewriter.factory.getSkipNameValidationForTesting());
+ // Optimize main method.
+ rewriter.converter.optimizeMethodOnSynthesizedClass(
+ clazz, clazz.lookupVirtualMethod(mainMethod));
// The method addSynthesizedFrom() may be called concurrently. To avoid a Concurrent-
// ModificationException we must use synchronization.
synchronized (synthesizedFrom) {
@@ -177,13 +182,11 @@
}
// Synthesize virtual methods.
- private DexEncodedMethod[] synthesizeVirtualMethods() {
+ private DexEncodedMethod[] synthesizeVirtualMethods(DexMethod mainMethod) {
DexEncodedMethod[] methods = new DexEncodedMethod[1 + descriptor.bridges.size()];
int index = 0;
// Synthesize main method.
- DexMethod mainMethod = rewriter.factory
- .createMethod(type, descriptor.erasedProto, descriptor.name);
methods[index++] =
new DexEncodedMethod(
mainMethod,
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynthesizedLambdaClass.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynthesizedLambdaClass.java
new file mode 100644
index 0000000..dc1c40b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InlineSynthesizedLambdaClass.java
@@ -0,0 +1,58 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.optimize.inliner;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import org.junit.Test;
+
+public class InlineSynthesizedLambdaClass extends TestBase {
+
+ @Test
+ public void test() throws Exception {
+ AndroidApp input = readClasses(Lambda.class, Lambda.Consumer.class);
+ AndroidApp output =
+ compileWithR8(
+ input,
+ String.join(
+ System.lineSeparator(),
+ keepMainProguardConfiguration(Lambda.class),
+ "-allowaccessmodification"),
+ options -> options.enableMinification = false);
+
+ // Check that everything has been inlined into main.
+ CodeInspector inspector = new CodeInspector(output);
+ assertEquals(1, inspector.allClasses().size());
+
+ ClassSubject classSubject = inspector.clazz(Lambda.class);
+ assertThat(classSubject, isPresent());
+ assertEquals(1, classSubject.allMethods().size());
+
+ // Check that the program gives the expected result.
+ assertEquals(runOnJava(Lambda.class), runOnArt(output, Lambda.class));
+ }
+}
+
+class Lambda {
+
+ interface Consumer<T> {
+ void accept(T value);
+ }
+
+ public static void main(String... args) {
+ load(s -> System.out.println(s));
+ load(s -> System.out.println(s));
+ }
+
+ public static void load(Consumer<String> c) {
+ c.accept("Hello!");
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
index 6331f5d..90013b0 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/ClassSubject.java
@@ -17,6 +17,12 @@
public abstract void forAllMethods(Consumer<FoundMethodSubject> inspection);
+ public final List<FoundMethodSubject> allMethods() {
+ ImmutableList.Builder<FoundMethodSubject> builder = ImmutableList.builder();
+ forAllMethods(builder::add);
+ return builder.build();
+ }
+
public MethodSubject method(Method method) {
List<String> parameters = new ArrayList<>();
for (Class<?> parameterType : method.getParameterTypes()) {
diff --git a/tools/toolhelper.py b/tools/toolhelper.py
index dbf393b..1e6ebfd 100644
--- a/tools/toolhelper.py
+++ b/tools/toolhelper.py
@@ -3,6 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
import gradle
+import os
import subprocess
import utils
@@ -23,6 +24,9 @@
if profile:
cmd.append('-agentlib:hprof=cpu=samples,interval=1,depth=8')
cmd.extend(['-jar', utils.R8_JAR, tool])
+ lib, args = extract_lib_from_args(args)
+ if lib:
+ cmd.extend(["--lib", lib])
cmd.extend(args)
utils.PrintCmd(cmd)
return subprocess.call(cmd)
@@ -36,3 +40,15 @@
else:
args.append(arg)
return build, args
+
+def extract_lib_from_args(input_args):
+ lib = None
+ args = []
+ for arg in input_args:
+ if arg == '--lib-android':
+ lib = utils.get_android_jar(26)
+ elif arg == '--lib-java':
+ lib = utils.RT_JAR
+ else:
+ args.append(arg)
+ return lib, args