blob: 2e6fb4cc411054740a23db0a224e9b82283460f4 [file] [log] [blame]
// 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.outliner.b112247415;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.VmTestRunner;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.InvokeVirtual;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
class TestClass {
interface Act {
default String get(StringBuilder builder, String arg) {
builder.append(arg).append(arg).append(arg);
return builder.toString();
}
}
public static void main(String[] args) {
System.out.println(get(new TestClass().toActOverridden(), new StringBuilder(), "a"));
System.out.println(get(new TestClass().toActDefault(), new StringBuilder(), "b"));
}
static String get(Act act, StringBuilder builder, String arg) {
act.get(builder, arg);
return builder.toString();
}
Act toActOverridden() {
return new Act() {
@Override
public String get(StringBuilder builder, String arg) {
builder.append(arg).append(arg).append(arg);
return builder.toString();
}
};
}
Act toActDefault() {
return new Act() {
};
}
}
@RunWith(VmTestRunner.class)
public class B112247415 extends TestBase {
@Test
public void test() throws Exception {
String javaResult = runOnJava(TestClass.class);
R8Command.Builder builder = R8Command.builder();
builder.addProgramFiles(ToolHelper.getClassFilesForTestDirectory(
ToolHelper.getPackageDirectoryForTestPackage(TestClass.Act.class.getPackage()),
path -> path.getFileName().toString().startsWith("TestClass")));
builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
builder.setMinApiLevel(ToolHelper.getMinApiLevelForDexVm().getLevel());
String config = keepMainProguardConfiguration(TestClass.class);
builder.addProguardConfiguration(ImmutableList.of(config), Origin.unknown());
AndroidApp app = ToolHelper.runR8(builder.build(), options -> {
// To trigger outliner, set # of expected outline candidate as threshold.
options.outline.threshold = 2;
options.enableInlining = false;
options.enableMinification = false;
});
ProcessResult result = runOnArtRaw(app, TestClass.class);
assertEquals(0, result.exitCode);
assertEquals(javaResult, result.stdout);
CodeInspector inspector = new CodeInspector(app);
for (FoundClassSubject clazz : inspector.allClasses()) {
clazz.getDexClass().forEachMethod(encodedMethod -> {
Code code = encodedMethod.getCode();
if (code != null && !encodedMethod.method.name.toString().startsWith("outline")) {
verifyAbsenceOfStringBuilderAppend(code.asDexCode().instructions);
}
});
}
}
private void verifyAbsenceOfStringBuilderAppend(Instruction[] instructions) {
for (Instruction instr : instructions) {
if (instr instanceof InvokeVirtual) {
InvokeVirtual invokeVirtual = (InvokeVirtual) instr;
DexMethod invokedMethod = invokeVirtual.getMethod();
if (invokedMethod.getHolder().getName().endsWith("StringBuilder")) {
assertNotEquals("append", invokedMethod.name.toString());
}
}
}
}
}