blob: bce5a5b1e479b63131d75aedfc907e742bf63ea7 [file] [log] [blame]
// Copyright (c) 2022, 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.regress;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class Regress214340258 extends TestBase {
// Generate this many classes to not overflow instruction limit.
static final int NUMBER_OF_FILES = 50;
private final TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withDexRuntimes().withAllApiLevels().build();
}
public Regress214340258(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void testR8() throws Exception {
Path compiledJumbo = getZipWithJumboString();
R8TestRunResult r8TestRunResult =
testForR8(parameters.getBackend())
.addDontOptimize()
.addKeepAllClassesRule()
.addProgramFiles(compiledJumbo)
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), "TestClass0");
r8TestRunResult.assertSuccessWithOutputLines("foobar");
assertTrue(hasJumboString(r8TestRunResult));
}
private boolean hasJumboString(R8TestRunResult r8TestRunResult)
throws IOException, ExecutionException {
for (FoundClassSubject classSubject : r8TestRunResult.inspector().allClasses()) {
for (FoundMethodSubject foundMethodSubject : classSubject.allMethods()) {
for (InstructionSubject instruction : foundMethodSubject.instructions()) {
if (instruction.isJumboString()) {
return true;
}
}
}
}
return false;
}
public Path getZipWithJumboString() throws IOException {
List<Path> javaFiles = new ArrayList<>();
for (int i = 0; i < NUMBER_OF_FILES; i++) {
String name = "TestClass" + i;
Path file = temp.newFile(name + ".java").toPath();
Files.write(file, getClassWithManyStrings(name, i).getBytes(StandardCharsets.UTF_8));
javaFiles.add(file);
}
Path compiledJumbo = javac(CfRuntime.getCheckedInJdk9()).addSourceFiles(javaFiles).compile();
return compiledJumbo;
}
private String getClassWithManyStrings(String className, int index) {
String file =
""
+ "public class "
+ className
+ " {\n"
+ " public static void use(String s) { }\n"
+ "\n"
+ " public static void main(String[] args) {\n"
+ " String s = \"foobar\";\n";
StringBuilder builder = new StringBuilder();
for (int i = 0; i < Constants.MAX_NON_JUMBO_INDEX / NUMBER_OF_FILES; i++) {
builder.append(" s = \"foobar" + i + "_" + index + "\";\n");
builder.append(" System.getenv(s);\n");
}
file += builder.toString();
file += "" + " s = \"foobar\";\n" + " System.out.println(s);\n" + " }\n" + "}";
return file;
}
}