aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-07-16 07:37:16 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-07-16 07:37:16 +0000
commit5a59612a39e9a2b27cbacc2e4a252227be9aed35 (patch)
tree0e46f083cf6dfa76bad446e38675aec3a968a706
parente9e6d3d3613a0454638d0097ec9ced3ca400c6ac (diff)
parent4b9460ad97b53249b353cebe58b59117822d07b2 (diff)
downloadr8-5a59612a39e9a2b27cbacc2e4a252227be9aed35.tar.gz
release-request-05263112-375a-4b1f-a657-a14bb2a5c5a3-for-git_oc-mr1-release-4185249 snap-temp-L63000000082739046
Change-Id: Ie4ab9077b5e69284fee1abc96d1aea9140f0bcfd
-rw-r--r--src/main/java/com/android/tools/r8/R8Command.java3
-rw-r--r--src/main/java/com/android/tools/r8/ReadMainDexList.java34
-rw-r--r--src/main/java/com/android/tools/r8/dex/DexFileReader.java3
-rw-r--r--src/main/java/com/android/tools/r8/dex/FileWriter.java18
-rw-r--r--src/main/java/com/android/tools/r8/dex/VirtualFile.java2
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexAnnotation.java3
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexClass.java11
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java46
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexItemFactory.java40
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexMethodHandle.java2
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexType.java2
-rw-r--r--src/main/java/com/android/tools/r8/graph/DexValue.java8
-rw-r--r--src/main/java/com/android/tools/r8/graph/JarClassFileReader.java3
-rw-r--r--src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java3
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/Value.java4
-rw-r--r--src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java85
-rw-r--r--src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java48
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java4
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java18
-rw-r--r--src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java16
-rw-r--r--src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java3
-rw-r--r--src/main/java/com/android/tools/r8/ir/optimize/Inliner.java46
-rw-r--r--src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java26
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java62
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java2
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervalsUse.java10
-rw-r--r--src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java48
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java28
-rw-r--r--src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java22
-rw-r--r--src/main/java/com/android/tools/r8/shaking/TreePruner.java21
-rw-r--r--src/main/java/com/android/tools/r8/utils/AndroidApp.java9
-rw-r--r--src/main/java/com/android/tools/r8/utils/FileUtils.java7
-rw-r--r--src/main/java/com/android/tools/r8/utils/InternalOptions.java2
-rw-r--r--src/main/java/com/android/tools/r8/utils/OutputMode.java10
-rw-r--r--src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java22
-rw-r--r--src/test/java/com/android/tools/r8/JctfTestSpecifications.java234
-rw-r--r--src/test/java/com/android/tools/r8/R8RunArtTestsTest.java48
-rw-r--r--src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java13
-rw-r--r--src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java38
-rw-r--r--src/test/java/com/android/tools/r8/debug/DebugTestBase.java39
-rw-r--r--src/test/java/com/android/tools/r8/ir/deterministic/DeterministicProcessingTest.java2
-rw-r--r--src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java74
-rw-r--r--src/test/java/com/android/tools/r8/utils/D8CommandTest.java6
-rw-r--r--src/test/java/com/android/tools/r8/utils/OutputModeTest.java34
-rw-r--r--src/test/java/com/android/tools/r8/utils/R8CommandTest.java6
-rw-r--r--src/test/proguard/valid/dontshrink.flags5
-rw-r--r--src/test/proguard/valid/printusage-to-file.flags5
-rw-r--r--src/test/proguard/valid/printusage.flags5
-rw-r--r--third_party/gradle/gradle.tar.gz.sha12
-rw-r--r--third_party/jctf.tar.gz.sha12
-rwxr-xr-xtools/proguard.py9
-rwxr-xr-xtools/run_on_app.py59
-rwxr-xr-xtools/run_proguard_dx_on_gmscore.py34
-rwxr-xr-xtools/test_framework.py22
-rw-r--r--tools/utils.py23
55 files changed, 824 insertions, 507 deletions
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index a71091252..aed488649 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -363,6 +363,9 @@ public class R8Command extends BaseCommand {
internal.skipMinification = !useMinification();
assert internal.useTreeShaking;
internal.useTreeShaking = useTreeShaking();
+ assert !internal.printUsage;
+ internal.printUsage = proguardConfiguration.isPrintUsage();
+ internal.printUsageFile = proguardConfiguration.getPrintUsageFile();
assert !internal.ignoreMissingClasses;
internal.ignoreMissingClasses = ignoreMissingClasses;
diff --git a/src/main/java/com/android/tools/r8/ReadMainDexList.java b/src/main/java/com/android/tools/r8/ReadMainDexList.java
index 3a76c1fbb..a0c47895e 100644
--- a/src/main/java/com/android/tools/r8/ReadMainDexList.java
+++ b/src/main/java/com/android/tools/r8/ReadMainDexList.java
@@ -6,7 +6,11 @@ package com.android.tools.r8;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.ProguardMapReader;
import com.android.tools.r8.utils.FileUtils;
+import com.google.common.collect.Iterators;
+import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Iterator;
+import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -20,8 +24,12 @@ public class ReadMainDexList {
return name.endsWith(DOT_CLASS) ? name.substring(0, name.length() - DOT_CLASS.length()) : name;
}
- private String addDotClass(String name) {
- return name + DOT_CLASS;
+ private String toClassFilePath(String name) {
+ return name.replace('.', '/') + DOT_CLASS;
+ }
+
+ private String toKeepRule(String className) {
+ return "-keep class " + className + " {}";
}
private String deobfuscateClassName(String name, ClassNameMapper mapper) {
@@ -32,21 +40,31 @@ public class ReadMainDexList {
}
private void run(String[] args) throws Exception {
- if (args.length != 1 && args.length != 2) {
- System.out.println("Usage: command <main_dex_list> [<proguard_map>]");
+ if (args.length < 1 || args.length > 3) {
+ System.out.println("Usage: command [-k] <main_dex_list> [<proguard_map>]");
System.exit(0);
}
+ Iterator<String> arguments = Iterators.forArray(args);
+ Function<String, String> outputGenerator;
+ String arg = arguments.next();
+ if (arg.equals("-k")) {
+ outputGenerator = this::toKeepRule;
+ arg = arguments.next();
+ } else {
+ outputGenerator = this::toClassFilePath;
+ }
+ Path mainDexList = Paths.get(arg);
+
final ClassNameMapper mapper =
- args.length == 2 ? ProguardMapReader.mapperFromFile(Paths.get(args[1])) : null;
+ arguments.hasNext() ? ProguardMapReader.mapperFromFile(Paths.get(arguments.next())) : null;
- FileUtils.readTextFile(Paths.get(args[0]))
+ FileUtils.readTextFile(mainDexList)
.stream()
.map(this::stripDotClass)
.map(name -> name.replace('/', '.'))
.map(name -> deobfuscateClassName(name, mapper))
- .map(name -> name.replace('.', '/'))
- .map(this::addDotClass)
+ .map(outputGenerator)
.sorted()
.collect(Collectors.toList())
.forEach(System.out::println);
diff --git a/src/main/java/com/android/tools/r8/dex/DexFileReader.java b/src/main/java/com/android/tools/r8/dex/DexFileReader.java
index a0644948f..1c3707337 100644
--- a/src/main/java/com/android/tools/r8/dex/DexFileReader.java
+++ b/src/main/java/com/android/tools/r8/dex/DexFileReader.java
@@ -47,6 +47,7 @@ import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueMethodHandle;
import com.android.tools.r8.graph.DexValue.DexValueMethodType;
+import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.OffsetToObjectMapping;
import com.android.tools.r8.logging.Log;
@@ -226,7 +227,7 @@ public class DexFileReader {
}
case DexValue.VALUE_NULL: {
assert valueArg == 0;
- return DexValue.NULL;
+ return DexValueNull.NULL;
}
case DexValue.VALUE_BOOLEAN: {
// 0 is false, and 1 is true.
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index 6c6c3e16a..00eea7cb0 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -215,18 +215,16 @@ public class FileWriter {
this::writeStringData);
writeItems(mixedSectionOffsets.getAnnotations(), layout::setAnnotationsOffset,
this::writeAnnotation);
+ writeItems(mixedSectionOffsets.getClassesWithData(), layout::setClassDataOffset,
+ this::writeClassData);
+ writeItems(mixedSectionOffsets.getEncodedArrays(), layout::setEncodedArrarysOffset,
+ this::writeEncodedArray);
writeItems(mixedSectionOffsets.getAnnotationSets(), layout::setAnnotationSetsOffset,
this::writeAnnotationSet, 4);
writeItems(mixedSectionOffsets.getAnnotationSetRefLists(),
layout::setAnnotationSetRefListsOffset, this::writeAnnotationSetRefList, 4);
- // Write the annotation directories.
writeItems(mixedSectionOffsets.getAnnotationDirectories(),
layout::setAnnotationDirectoriesOffset, this::writeAnnotationDirectory, 4);
- // Write the rest.
- writeItems(mixedSectionOffsets.getClassesWithData(), layout::setClassDataOffset,
- this::writeClassData);
- writeItems(mixedSectionOffsets.getEncodedArrays(), layout::setEncodedArrarysOffset,
- this::writeEncodedArray);
// Add the map at the end
layout.setMapOffset(dest.align(4));
@@ -760,6 +758,10 @@ public class FileWriter {
mixedSectionOffsets.getStringData().size());
size += writeMapItem(Constants.TYPE_ANNOTATION_ITEM, layout.getAnnotationsOffset(),
mixedSectionOffsets.getAnnotations().size());
+ size += writeMapItem(Constants.TYPE_CLASS_DATA_ITEM, layout.getClassDataOffset(),
+ mixedSectionOffsets.getClassesWithData().size());
+ size += writeMapItem(Constants.TYPE_ENCODED_ARRAY_ITEM, layout.getEncodedArrarysOffset(),
+ mixedSectionOffsets.getEncodedArrays().size());
size += writeMapItem(Constants.TYPE_ANNOTATION_SET_ITEM, layout.getAnnotationSetsOffset(),
mixedSectionOffsets.getAnnotationSets().size());
size += writeMapItem(Constants.TYPE_ANNOTATION_SET_REF_LIST,
@@ -768,10 +770,6 @@ public class FileWriter {
size += writeMapItem(Constants.TYPE_ANNOTATIONS_DIRECTORY_ITEM,
layout.getAnnotationDirectoriesOffset(),
mixedSectionOffsets.getAnnotationDirectories().size());
- size += writeMapItem(Constants.TYPE_CLASS_DATA_ITEM, layout.getClassDataOffset(),
- mixedSectionOffsets.getClassesWithData().size());
- size += writeMapItem(Constants.TYPE_ENCODED_ARRAY_ITEM, layout.getEncodedArrarysOffset(),
- mixedSectionOffsets.getEncodedArrays().size());
size += writeMapItem(Constants.TYPE_MAP_LIST, layout.getMapOffset(), 1);
dest.moveTo(startOfMap);
dest.putInt(size);
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index 0e89d4a10..f336a3d2d 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -67,7 +67,7 @@ public class VirtualFile {
// TODO(sgjesse): Does "minimal main dex" combined with "leave space for growth" make sense?
}
- private static final int MAX_ENTRIES = (Short.MAX_VALUE << 1) + 1;
+ private static final int MAX_ENTRIES = Constants.U16BIT_MAX + 1;
/**
* When distributing classes across files we aim to leave some space. The amount of space left is
* driven by this constant.
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index 66d977418..55aa9868a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -9,6 +9,7 @@ import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueInt;
import com.android.tools.r8.graph.DexValue.DexValueMethod;
+import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.DexValue.DexValueType;
import java.util.ArrayList;
@@ -111,7 +112,7 @@ public class DexAnnotation extends DexItem {
new DexAnnotationElement(
factory.createString("name"),
(clazz == null)
- ? DexValue.NULL
+ ? DexValueNull.NULL
: new DexValueString(factory.createString(clazz)))
}));
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 3bcf6e749..023cfb0e4 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -7,8 +7,11 @@ import com.android.tools.r8.Resource;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
+
import com.google.common.base.MoreObjects;
+import java.util.function.Consumer;
+
public abstract class DexClass extends DexItem {
private static final DexEncodedMethod[] NO_METHODS = {};
@@ -71,6 +74,14 @@ public abstract class DexClass extends DexItem {
return MoreObjects.firstNonNull(virtualMethods, NO_METHODS);
}
+ public void forEachMethod(Consumer<DexEncodedMethod> consumer) {
+ for (DexEncodedMethod method : directMethods()) {
+ consumer.accept(method);
+ }
+ for (DexEncodedMethod method : virtualMethods()) {
+ consumer.accept(method);
+ }
+ }
public DexEncodedField[] staticFields() {
return MoreObjects.firstNonNull(staticFields, NO_FIELDS);
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 3df2fabe7..c8fbbeadf 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -12,9 +12,12 @@ import com.android.tools.r8.code.Const;
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.ConstStringJumbo;
import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.code.InvokeDirect;
import com.android.tools.r8.code.InvokeStatic;
+import com.android.tools.r8.code.InvokeSuper;
import com.android.tools.r8.code.NewInstance;
import com.android.tools.r8.code.Throw;
+import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.ir.code.IRCode;
@@ -30,6 +33,7 @@ import com.android.tools.r8.logging.Log;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.utils.InternalOptions;
public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
@@ -238,7 +242,7 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
* templates might incur a size overhead.
*/
private DexCode generateCodeFromTemplate(
- int numberOfRegisters, int outRegisters, Instruction[] instructions) {
+ int numberOfRegisters, int outRegisters, Instruction... instructions) {
int offset = 0;
for (Instruction instruction : instructions) {
assert !(instruction instanceof ConstString);
@@ -276,21 +280,33 @@ public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
.createMethod(itemFactory.createType("Landroid/util/Log;"), proto,
itemFactory.createString("e"));
DexType exceptionType = itemFactory.createType("Ljava/lang/RuntimeException;");
- DexType[] exceptionArgs = {exceptionType, itemFactory.stringType};
- DexMethod initMethod = itemFactory
- .createMethod(exceptionType, itemFactory.createProto(itemFactory.voidType, exceptionArgs),
+ DexMethod exceptionInitMethod = itemFactory
+ .createMethod(exceptionType, itemFactory.createProto(itemFactory.voidType,
+ itemFactory.stringType),
itemFactory.constructorMethodName);
- // These methods might not get registered for jumbo string processing, therefore we always
- // use the jumbo string encoding for the const string instruction.
- Instruction insn[] = {
- new ConstStringJumbo(0, tag),
- new ConstStringJumbo(1, message),
- new InvokeStatic(2, logMethod, 0, 1, 0, 0, 0),
- new NewInstance(0, exceptionType),
- new InvokeStatic(2, initMethod, 0, 1, 0, 0, 0),
- new Throw(0)
- };
- DexCode code = generateCodeFromTemplate(2, 2, insn);
+ DexCode code;
+ if (accessFlags.isConstructor() && !accessFlags.isStatic()) {
+ // The Java VM Spec requires that a constructor calls an initializer from the super class
+ // or another constructor from the current class. For simplicity we do the latter by just
+ // calling outself. This is ok, as the constructor always throws before the recursive call.
+ code = generateCodeFromTemplate(3, 2, new ConstStringJumbo(0, tag),
+ new ConstStringJumbo(1, message),
+ new InvokeStatic(2, logMethod, 0, 1, 0, 0, 0),
+ new NewInstance(0, exceptionType),
+ new InvokeDirect(2, exceptionInitMethod, 0, 1, 0, 0, 0),
+ new Throw(0),
+ new InvokeDirect(1, method, 2, 0, 0, 0, 0));
+
+ } else {
+ // These methods might not get registered for jumbo string processing, therefore we always
+ // use the jumbo string encoding for the const string instruction.
+ code = generateCodeFromTemplate(2, 2, new ConstStringJumbo(0, tag),
+ new ConstStringJumbo(1, message),
+ new InvokeStatic(2, logMethod, 0, 1, 0, 0, 0),
+ new NewInstance(0, exceptionType),
+ new InvokeDirect(2, exceptionInitMethod, 0, 1, 0, 0, 0),
+ new Throw(0));
+ }
Builder builder = builder(this);
builder.setCode(code);
return builder.build();
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 984215b80..5dff4b432 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -222,32 +222,22 @@ public class DexItemFactory {
DexString toStringMethodName = createString("toString");
- appendBoolean =
- createMethod(receiver, createProto(receiver, new DexType[]{booleanType}), append);
- appendChar = createMethod(receiver, createProto(receiver, new DexType[]{charType}), append);
- appendCharArray =
- createMethod(receiver, createProto(receiver, new DexType[]{charArrayType}), append);
+ appendBoolean = createMethod(receiver, createProto(receiver, booleanType), append);
+ appendChar = createMethod(receiver, createProto(receiver, charType), append);
+ appendCharArray = createMethod(receiver, createProto(receiver, charArrayType), append);
appendSubCharArray =
- createMethod(receiver,
- createProto(receiver, new DexType[]{charArrayType, intType, intType}), append);
- appendCharSequence =
- createMethod(receiver, createProto(receiver, new DexType[]{charSequenceType}), append);
+ createMethod(receiver, createProto(receiver, charArrayType, intType, intType), append);
+ appendCharSequence = createMethod(receiver, createProto(receiver, charSequenceType), append);
appendSubCharSequence =
- createMethod(receiver,
- createProto(receiver, new DexType[]{charSequenceType, intType, intType}), append);
- appendInt = createMethod(receiver, createProto(receiver, new DexType[]{intType}), append);
- appendDouble =
- createMethod(receiver, createProto(receiver, new DexType[]{doubleType}), append);
- appendFloat = createMethod(receiver, createProto(receiver, new DexType[]{floatType}), append);
- appendLong = createMethod(receiver, createProto(receiver, new DexType[]{longType}), append);
- appendObject =
- createMethod(receiver, createProto(receiver, new DexType[]{objectType}), append);
- appendString =
- createMethod(receiver, createProto(receiver, new DexType[]{stringType}), append);
- appendStringBuffer =
- createMethod(receiver, createProto(receiver, new DexType[]{sbufType}), append);
- toString =
- createMethod(receiver, createProto(stringType, DexType.EMPTY_ARRAY), toStringMethodName);
+ createMethod(receiver, createProto(receiver, charSequenceType, intType, intType), append);
+ appendInt = createMethod(receiver, createProto(receiver, intType), append);
+ appendDouble = createMethod(receiver, createProto(receiver, doubleType), append);
+ appendFloat = createMethod(receiver, createProto(receiver, floatType), append);
+ appendLong = createMethod(receiver, createProto(receiver, longType), append);
+ appendObject = createMethod(receiver, createProto(receiver, objectType), append);
+ appendString = createMethod(receiver, createProto(receiver, stringType), append);
+ appendStringBuffer = createMethod(receiver, createProto(receiver, sbufType), append);
+ toString = createMethod(receiver, createProto(stringType), toStringMethodName);
}
public void forEachAppendMethod(Consumer<DexMethod> consumer) {
@@ -322,7 +312,7 @@ public class DexItemFactory {
parameters.length == 0 ? DexTypeList.empty() : new DexTypeList(parameters));
}
- public DexProto createProto(DexType returnType, DexType[] parameters) {
+ public DexProto createProto(DexType returnType, DexType... parameters) {
return createProto(createShorty(returnType, parameters), returnType, parameters);
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java b/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java
index e59e7c97a..d2237352f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java
@@ -132,7 +132,7 @@ public class DexMethodHandle extends IndexedDexItem {
public boolean computeEquals(Object other) {
if (other instanceof DexMethodHandle) {
DexMethodHandle o = (DexMethodHandle) other;
- return type.equals(o.type) && fieldOrMethod.computeEquals(o.fieldOrMethod);
+ return type.equals(o.type) && fieldOrMethod.equals(o.fieldOrMethod);
}
return false;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexType.java b/src/main/java/com/android/tools/r8/graph/DexType.java
index 4d3d8cb25..234773f96 100644
--- a/src/main/java/com/android/tools/r8/graph/DexType.java
+++ b/src/main/java/com/android/tools/r8/graph/DexType.java
@@ -19,8 +19,6 @@ import java.util.function.Function;
public class DexType extends IndexedDexItem implements PresortedComparable<DexType> {
- public static final DexType[] EMPTY_ARRAY = new DexType[]{};
-
private final static int ROOT_LEVEL = 0;
private final static int UNKNOWN_LEVEL = -1;
private final static int INTERFACE_LEVEL = -2;
diff --git a/src/main/java/com/android/tools/r8/graph/DexValue.java b/src/main/java/com/android/tools/r8/graph/DexValue.java
index 5430d6e1e..a0cfa7c3a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexValue.java
+++ b/src/main/java/com/android/tools/r8/graph/DexValue.java
@@ -36,8 +36,6 @@ public abstract class DexValue extends DexItem {
public static final byte VALUE_NULL = 0x1e;
public static final byte VALUE_BOOLEAN = 0x1f;
- public static final DexValue NULL = new DexValueNull();
-
private static void writeHeader(byte type, int arg, DexOutputBuffer dest) {
dest.putByte((byte) ((arg << 5) | type));
}
@@ -87,7 +85,7 @@ public abstract class DexValue extends DexItem {
return DexValueDouble.DEFAULT;
}
if (type.isArrayType() || type.isClassType()) {
- return DexValue.NULL;
+ return DexValueNull.NULL;
}
throw new Unreachable("No default value for unexpected type " + type);
}
@@ -688,7 +686,9 @@ public abstract class DexValue extends DexItem {
static public class DexValueNull extends SimpleDexValue {
- // See DexValue.NULL
+ public static final DexValue NULL = new DexValueNull();
+
+ // See DexValueNull.NULL
private DexValueNull() {
}
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 59f187f0c..ce38bc967 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -20,6 +20,7 @@ import com.android.tools.r8.graph.DexValue.DexValueEnum;
import com.android.tools.r8.graph.DexValue.DexValueFloat;
import com.android.tools.r8.graph.DexValue.DexValueInt;
import com.android.tools.r8.graph.DexValue.DexValueLong;
+import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.DexValue.DexValueShort;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.DexValue.DexValueType;
@@ -699,7 +700,7 @@ public class JarClassFileReader {
private DexValue getDexValue(Object value) {
if (value == null) {
- return DexValue.NULL;
+ return DexValueNull.NULL;
}
if (value instanceof Byte) {
return DexValueByte.create((Byte) value);
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java b/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java
index 7dab70aff..74a08003e 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java
@@ -88,7 +88,7 @@ public class ObjectToOffsetMapping {
private void setIndexes(IndexedDexItem[] items) {
int index = 0;
for (IndexedDexItem item : items) {
- item.assignVirtualFileIndex(virtualFileId, index++);
+ item.assignVirtualFileIndex(virtualFileId, index);
// For strings collect the first jumbo string (if any).
if (index > Constants.MAX_NON_JUMBO_INDEX) {
assert item instanceof DexString;
@@ -96,6 +96,7 @@ public class ObjectToOffsetMapping {
firstJumboString = (DexString) item;
}
}
+ index++;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 92bb7b20a..e0bfdd0c9 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -57,7 +57,7 @@ public class Value {
public static final Value UNDEFINED = new Value(-1, MoveType.OBJECT, null);
protected final int number;
- protected MoveType type;
+ protected final MoveType type;
public Instruction definition = null;
private LinkedList<Instruction> users = new LinkedList<>();
private Set<Instruction> uniqueUsers = null;
@@ -71,7 +71,7 @@ public class Value {
private boolean isThis = false;
private boolean isArgument = false;
private LongInterval valueRange;
- private DebugData debugData;
+ private final DebugData debugData;
public Value(int number, MoveType type, DebugInfo debugInfo) {
this.number = number;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
index c5068678f..4d8eee148 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
@@ -20,6 +20,7 @@ import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -48,13 +49,13 @@ public class CallGraph {
public final DexEncodedMethod method;
private int invokeCount = 0;
- private boolean isRecursive = false;
+ private boolean isSelfRecursive = false;
// Outgoing calls from this method.
- public final Set<Node> calls = new LinkedHashSet<>();
+ public final Set<Node> callees = new LinkedHashSet<>();
// Incoming calls to this method.
- public final Set<Node> callees = new LinkedHashSet<>();
+ public final Set<Node> callers = new LinkedHashSet<>();
private Node(DexEncodedMethod method) {
this.method = method;
@@ -64,24 +65,24 @@ public class CallGraph {
return method.accessFlags.isBridge();
}
- private void addCalls(Node method) {
- calls.add(method);
+ private void addCallee(Node method) {
+ callees.add(method);
}
private void addCaller(Node method) {
- callees.add(method);
+ callers.add(method);
}
- boolean isRecursive() {
- return isRecursive;
+ boolean isSelfRecursive() {
+ return isSelfRecursive;
}
boolean isLeaf() {
- return calls.isEmpty();
+ return callees.isEmpty();
}
int callDegree() {
- return calls.size();
+ return callees.size();
}
@Override
@@ -100,31 +101,31 @@ public class CallGraph {
builder.append("MethodNode for: ");
builder.append(method.qualifiedName());
builder.append(" (");
- builder.append(calls.size());
- builder.append(" calls, ");
builder.append(callees.size());
- builder.append(" callees");
+ builder.append(" callees, ");
+ builder.append(callers.size());
+ builder.append(" callers");
if (isBridge()) {
builder.append(", bridge");
}
- if (isRecursive()) {
+ if (isSelfRecursive()) {
builder.append(", recursive");
}
builder.append(", invoke count " + invokeCount);
builder.append(").\n");
- if (calls.size() > 0) {
- builder.append("Calls:\n");
- for (Node call : calls) {
+ if (callees.size() > 0) {
+ builder.append("Callees:\n");
+ for (Node call : callees) {
builder.append(" ");
builder.append(call.method.qualifiedName());
builder.append("\n");
}
}
- if (callees.size() > 0) {
- builder.append("Callees:\n");
- for (Node callee : callees) {
+ if (callers.size() > 0) {
+ builder.append("Callers:\n");
+ for (Node caller : callers) {
builder.append(" ");
- builder.append(callee.method.qualifiedName());
+ builder.append(caller.method.qualifiedName());
builder.append("\n");
}
}
@@ -154,7 +155,7 @@ public class CallGraph {
return leaves;
}
- public boolean brokeCycles() {
+ public boolean hasBrokeCycles() {
return brokeCycles;
}
@@ -182,6 +183,8 @@ public class CallGraph {
}
private final Map<DexEncodedMethod, Node> nodes = new LinkedHashMap<>();
+ private final Map<DexEncodedMethod, Set<DexEncodedMethod>> breakers = new HashMap<>();
+
private List<Node> leaves = null;
private Set<DexEncodedMethod> singleCallSite = Sets.newIdentityHashSet();
private Set<DexEncodedMethod> doubleCallSite = Sets.newIdentityHashSet();
@@ -190,22 +193,15 @@ public class CallGraph {
GraphLense graphLense) {
CallGraph graph = new CallGraph();
-
for (DexClass clazz : application.classes()) {
- for (DexEncodedMethod method : clazz.directMethods()) {
- Node node = graph.ensureMethodNode(method);
- InvokeExtractor extractor = new InvokeExtractor(appInfo, graphLense, node, graph);
- method.registerReachableDefinitions(extractor);
- }
- for (DexEncodedMethod method : clazz.virtualMethods()) {
+ clazz.forEachMethod( method -> {
Node node = graph.ensureMethodNode(method);
InvokeExtractor extractor = new InvokeExtractor(appInfo, graphLense, node, graph);
method.registerReachableDefinitions(extractor);
- }
+ });
}
assert allMethodsExists(application, graph);
-
graph.fillCallSiteSets(appInfo);
graph.fillInitialLeaves();
return graph;
@@ -255,12 +251,7 @@ public class CallGraph {
private static boolean allMethodsExists(DexApplication application, CallGraph graph) {
for (DexProgramClass clazz : application.classes()) {
- for (DexEncodedMethod method : clazz.directMethods()) {
- assert graph.nodes.get(method) != null;
- }
- for (DexEncodedMethod method : clazz.virtualMethods()) {
- assert graph.nodes.get(method) != null;
- }
+ clazz.forEachMethod( method -> { assert graph.nodes.get(method) != null; });
}
return true;
}
@@ -275,7 +266,7 @@ public class CallGraph {
List<DexEncodedMethod> result = new ArrayList<>();
List<Node> newLeaves = new ArrayList<>();
for (Node leaf : leaves) {
- assert nodes.containsKey(leaf.method) && nodes.get(leaf.method).calls.isEmpty();
+ assert nodes.containsKey(leaf.method) && nodes.get(leaf.method).callees.isEmpty();
remove(leaf, newLeaves);
result.add(leaf.method);
}
@@ -368,30 +359,30 @@ public class CallGraph {
assert caller != null;
assert callee != null;
if (caller != callee) {
- caller.addCalls(callee);
+ caller.addCallee(callee);
callee.addCaller(caller);
} else {
- caller.isRecursive = true;
+ caller.isSelfRecursive = true;
}
callee.invokeCount++;
}
private Set<DexEncodedMethod> removeAllCalls(Node node) {
Set<DexEncodedMethod> calls = Sets.newIdentityHashSet();
- for (Node call : node.calls) {
+ for (Node call : node.callees) {
calls.add(call.method);
- call.callees.remove(node);
+ call.callers.remove(node);
}
- node.calls.clear();
+ node.callees.clear();
return calls;
}
private void remove(Node node, List<Node> leaves) {
assert node != null;
- for (Node callee : node.callees) {
- boolean removed = callee.calls.remove(node);
- if (callee.isLeaf()) {
- leaves.add(callee);
+ for (Node caller : node.callers) {
+ boolean removed = caller.callees.remove(node);
+ if (caller.isLeaf()) {
+ leaves.add(caller);
}
assert removed;
}
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 1586496c1..98a261914 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
@@ -40,7 +40,6 @@ import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -277,11 +276,9 @@ public class IRConverter {
// Process the application identifying outlining candidates.
timing.begin("IR conversion phase 1");
- int count = 0;
OptimizationFeedback directFeedback = new OptimizationFeedbackDirect();
OptimizationFeedbackDelayed delayedFeedback = new OptimizationFeedbackDelayed();
while (!callGraph.isEmpty()) {
- count++;
CallGraph.Leaves leaves = callGraph.pickLeaves();
List<DexEncodedMethod> methods = leaves.getLeaves();
assert methods.size() > 0;
@@ -297,15 +294,26 @@ public class IRConverter {
// optimization feedback to reprocess methods affected by it. This is required to get
// deterministic behaviour, as the processing order within each set of leaves is
// non-deterministic.
- for (DexEncodedMethod method : methods) {
- futures.add(executorService.submit(() -> {
+
+ // Due to a race condition, we serialize processing of methods if cycles are broken.
+ // TODO(bak)
+ if (leaves.hasBrokeCycles()) {
+ for (DexEncodedMethod method : methods) {
processMethod(method,
- leaves.brokeCycles() ? delayedFeedback : directFeedback,
+ leaves.hasBrokeCycles() ? delayedFeedback : directFeedback,
outliner == null ? Outliner::noProcessing : outliner::identifyCandidates);
- }));
+ }
+ } else {
+ for (DexEncodedMethod method : methods) {
+ futures.add(executorService.submit(() -> {
+ processMethod(method,
+ leaves.hasBrokeCycles() ? delayedFeedback : directFeedback,
+ outliner == null ? Outliner::noProcessing : outliner::identifyCandidates);
+ }));
+ }
+ ThreadUtils.awaitFutures(futures);
}
- ThreadUtils.awaitFutures(futures);
- if (leaves.brokeCycles()) {
+ if (leaves.hasBrokeCycles()) {
// If cycles in the call graph were broken, then re-process all methods which are
// affected by the optimization feedback of other methods in this group.
methods = delayedFeedback.applyAndClear(methods, leaves);
@@ -320,13 +328,9 @@ public class IRConverter {
Builder builder = new Builder(application);
builder.setHighestSortingString(highestSortingString);
- // Second inlining pass.
- if ((inliner != null) && (inliner.doubleInlineCallers.size() > 0)) {
- inliner.applyDoubleInlining = true;
- for (DexEncodedMethod method : inliner.doubleInlineCallers) {
- processMethod(method, ignoreOptimizationFeedback, Outliner::noProcessing);
- assert method.isProcessed();
- }
+ // Second inlining pass for dealing with double inline callers.
+ if (inliner != null) {
+ inliner.processDoubleInlineCallers(this, ignoreOptimizationFeedback);
}
synthesizeLambdaClasses(builder);
@@ -363,8 +367,7 @@ public class IRConverter {
}
private void clearDexMethodCompilationState(DexProgramClass clazz) {
- Arrays.stream(clazz.directMethods()).forEach(DexEncodedMethod::markNotProcessed);
- Arrays.stream(clazz.virtualMethods()).forEach(DexEncodedMethod::markNotProcessed);
+ clazz.forEachMethod(DexEncodedMethod::markNotProcessed);
}
/**
@@ -413,12 +416,7 @@ public class IRConverter {
public void optimizeSynthesizedClass(DexProgramClass clazz) {
// Process the generated class, but don't apply any outlining.
- for (DexEncodedMethod method : clazz.directMethods()) {
- optimizeSynthesizedMethod(method);
- }
- for (DexEncodedMethod method : clazz.virtualMethods()) {
- optimizeSynthesizedMethod(method);
- }
+ clazz.forEachMethod(this::optimizeSynthesizedMethod);
}
public void optimizeSynthesizedMethod(DexEncodedMethod method) {
@@ -430,7 +428,7 @@ public class IRConverter {
return options.useSmaliSyntax ? method.toSmaliString(null) : method.codeToString();
}
- private void processMethod(DexEncodedMethod method,
+ public void processMethod(DexEncodedMethod method,
OptimizationFeedback feedback,
BiConsumer<IRCode, DexEncodedMethod> outlineHandler) {
Code code = method.getCode();
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 cb518a3d0..c2600b4e4 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
@@ -23,7 +23,7 @@ import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
-import com.android.tools.r8.graph.DexValue;
+import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import java.util.List;
@@ -219,7 +219,7 @@ final class LambdaClass {
new DexAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_FINAL
| Constants.ACC_SYNTHETIC | Constants.ACC_STATIC),
DexAnnotationSet.empty(),
- DexValue.NULL);
+ DexValueNull.NULL);
return fields;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
index 2355e5eb5..9ec776f47 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaMainMethodSourceCode.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.ir.desugar;
-import static com.android.tools.r8.ir.desugar.LambdaRewriter.EMPTY_TYPE_ARRAY;
-
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
@@ -421,28 +419,28 @@ final class LambdaMainMethodSourceCode extends SynthesizedLambdaSourceCode {
DexProto proto;
switch (primitive) {
case 'Z': // byte
- proto = factory.createProto(factory.booleanType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.booleanType);
return factory.createMethod(boxType, proto, factory.unboxBooleanMethodName);
case 'B': // byte
- proto = factory.createProto(factory.byteType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.byteType);
return factory.createMethod(boxType, proto, factory.unboxByteMethodName);
case 'S': // short
- proto = factory.createProto(factory.shortType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.shortType);
return factory.createMethod(boxType, proto, factory.unboxShortMethodName);
case 'C': // char
- proto = factory.createProto(factory.charType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.charType);
return factory.createMethod(boxType, proto, factory.unboxCharMethodName);
case 'I': // int
- proto = factory.createProto(factory.intType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.intType);
return factory.createMethod(boxType, proto, factory.unboxIntMethodName);
case 'J': // long
- proto = factory.createProto(factory.longType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.longType);
return factory.createMethod(boxType, proto, factory.unboxLongMethodName);
case 'F': // float
- proto = factory.createProto(factory.floatType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.floatType);
return factory.createMethod(boxType, proto, factory.unboxFloatMethodName);
case 'D': // double
- proto = factory.createProto(factory.doubleType, EMPTY_TYPE_ARRAY);
+ proto = factory.createProto(factory.doubleType);
return factory.createMethod(boxType, proto, factory.unboxDoubleMethodName);
default:
throw new Unreachable("Invalid primitive type descriptor: " + primitive);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
index 10908f038..7d3bc336d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
@@ -54,7 +54,6 @@ public class LambdaRewriter {
static final String LAMBDA_CLASS_NAME_PREFIX = "-$$Lambda$";
static final String EXPECTED_LAMBDA_METHOD_PREFIX = "lambda$";
- static final DexType[] EMPTY_TYPE_ARRAY = new DexType[0];
static final String LAMBDA_INSTANCE_FIELD_NAME = "INSTANCE";
final IRConverter converter;
@@ -103,20 +102,17 @@ public class LambdaRewriter {
DexType objectArrayType = factory.createType(OBJECT_ARRAY_TYPE_DESCR);
this.metafactoryMethod = factory.createMethod(metafactoryType,
- factory.createProto(callSiteType, new DexType[] {
- lookupType, factory.stringType, methodTypeType,
- methodTypeType, methodHandleType, methodTypeType
- }),
+ factory.createProto(callSiteType, lookupType, factory.stringType, methodTypeType,
+ methodTypeType, methodHandleType, methodTypeType),
factory.createString(METAFACTORY_METHOD_NAME));
this.metafactoryAltMethod = factory.createMethod(metafactoryType,
- factory.createProto(callSiteType, new DexType[] {
- lookupType, factory.stringType, methodTypeType, objectArrayType
- }),
+ factory.createProto(callSiteType, lookupType, factory.stringType, methodTypeType,
+ objectArrayType),
factory.createString(METAFACTORY_ALT_METHOD_NAME));
this.constructorName = factory.createString(Constants.INSTANCE_INITIALIZER_NAME);
- DexProto initProto = factory.createProto(factory.voidType, EMPTY_TYPE_ARRAY);
+ DexProto initProto = factory.createProto(factory.voidType);
this.objectInitMethod = factory.createMethod(factory.objectType, initProto, constructorName);
this.classConstructorName = factory.createString(Constants.CLASS_INITIALIZER_NAME);
this.instanceFieldName = factory.createString(LAMBDA_INSTANCE_FIELD_NAME);
@@ -124,7 +120,7 @@ public class LambdaRewriter {
this.deserializeLambdaMethodName = factory.createString(DESERIALIZE_LAMBDA_METHOD_NAME);
this.deserializeLambdaMethodProto = factory.createProto(
- factory.objectType, new DexType[] { factory.createType(SERIALIZED_LAMBDA_TYPE_DESCR) });
+ factory.objectType, factory.createType(SERIALIZED_LAMBDA_TYPE_DESCR));
}
/**
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 2364668ab..203ca80a3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -66,6 +66,7 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -853,7 +854,7 @@ public class CodeRewriter {
private void splitPhiConstants(IRCode code, BasicBlock block) {
for (int i = 0; i < block.getPredecessors().size(); i++) {
- Map<ConstNumber, ConstNumber> oldToNew = new HashMap<>();
+ Map<ConstNumber, ConstNumber> oldToNew = new IdentityHashMap<>();
BasicBlock predecessor = block.getPredecessors().get(i);
for (Phi phi : block.getPhis()) {
Value operand = phi.getOperand(i);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 1f21f5245..6d6981757 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -19,7 +19,9 @@ import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.ir.conversion.CallGraph;
+import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.conversion.LensCodeRewriter;
+import com.android.tools.r8.ir.conversion.OptimizationFeedback;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.Sets;
@@ -39,10 +41,10 @@ public class Inliner {
private final InternalOptions options;
// State for inlining methods which are known to be called twice.
- public boolean applyDoubleInlining = false;
- public final Set<DexEncodedMethod> doubleInlineCallers = Sets.newIdentityHashSet();
- public final Set<DexEncodedMethod> doubleInlineSelectedTargets = Sets.newIdentityHashSet();
- public final Map<DexEncodedMethod, DexEncodedMethod> doubleInlineeCandidates = new HashMap<>();
+ private boolean applyDoubleInlining = false;
+ private final Set<DexEncodedMethod> doubleInlineCallers = Sets.newIdentityHashSet();
+ private final Set<DexEncodedMethod> doubleInlineSelectedTargets = Sets.newIdentityHashSet();
+ private final Map<DexEncodedMethod, DexEncodedMethod> doubleInlineeCandidates = new HashMap<>();
public Inliner(AppInfoWithSubtyping appInfo, GraphLense graphLense, InternalOptions options) {
this.appInfo = appInfo;
@@ -89,7 +91,7 @@ public class Inliner {
return result;
}
- protected boolean hasInliningAccess(DexEncodedMethod method, DexEncodedMethod target) {
+ boolean hasInliningAccess(DexEncodedMethod method, DexEncodedMethod target) {
if (target.accessFlags.isPublic()) {
return true;
}
@@ -105,6 +107,40 @@ public class Inliner {
return methodHolder.isSamePackage(targetHolder);
}
+ synchronized DexEncodedMethod doubleInlining(DexEncodedMethod method,
+ DexEncodedMethod target) {
+ if (!applyDoubleInlining) {
+ if (doubleInlineeCandidates.containsKey(target)) {
+ // Both calls can be inlined.
+ doubleInlineCallers.add(doubleInlineeCandidates.get(target));
+ doubleInlineCallers.add(method);
+ doubleInlineSelectedTargets.add(target);
+ } else {
+ // First call can be inlined.
+ doubleInlineeCandidates.put(target, method);
+ }
+ // Just preparing for double inlining.
+ return null;
+ } else {
+ // Don't perform the actual inlining if this was not selected.
+ if (!doubleInlineSelectedTargets.contains(target)) {
+ return null;
+ }
+ }
+ return target;
+ }
+
+ public synchronized void processDoubleInlineCallers(IRConverter converter,
+ OptimizationFeedback feedback) {
+ if (doubleInlineCallers.size() > 0) {
+ applyDoubleInlining = true;
+ for (DexEncodedMethod method : doubleInlineCallers) {
+ converter.processMethod(method, feedback, Outliner::noProcessing);
+ assert method.isProcessed();
+ }
+ }
+ }
+
public enum Constraint {
// The ordinal values are important so please do not reorder.
NEVER, // Never inline this.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java
index febef8206..4b93d8d77 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/InliningOracle.java
@@ -82,28 +82,6 @@ public class InliningOracle {
return candidate;
}
- private synchronized DexEncodedMethod doubleInlining(DexEncodedMethod candidate) {
- if (!inliner.applyDoubleInlining) {
- if (inliner.doubleInlineeCandidates.containsKey(candidate)) {
- // Both calls can be inlined.
- inliner.doubleInlineCallers.add(inliner.doubleInlineeCandidates.get(candidate));
- inliner.doubleInlineCallers.add(method);
- inliner.doubleInlineSelectedTargets.add(candidate);
- } else {
- // First call can be inlined.
- inliner.doubleInlineeCandidates.put(candidate, method);
- }
- // Just preparing for double inlining.
- return null;
- } else {
- // Don't perform the actual inlining if this was not selected.
- if (!inliner.doubleInlineSelectedTargets.contains(candidate)) {
- return null;
- }
- }
- return candidate;
- }
-
private Reason computeInliningReason(DexEncodedMethod target) {
if (target.getOptimizationInfo().forceInline()) {
return Reason.FORCE;
@@ -185,7 +163,7 @@ public class InliningOracle {
}
// Attempt to inline a candidate that is only called twice.
- if ((reason == Reason.DUAL_CALLER) && (doubleInlining(target) == null)) {
+ if ((reason == Reason.DUAL_CALLER) && (inliner.doubleInlining(method, target) == null)) {
if (info != null) {
info.exclude(invoke, "target is not ready for double inlining");
}
@@ -253,7 +231,7 @@ public class InliningOracle {
}
// Attempt to inline a candidate that is only called twice.
- if ((reason == Reason.DUAL_CALLER) && (doubleInlining(candidate) == null)) {
+ if ((reason == Reason.DUAL_CALLER) && (inliner.doubleInlining(method, candidate) == null)) {
if (info != null) {
info.exclude(invoke, "target is not ready for double inlining");
}
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index 13f2d2953..fe59b791b 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -38,6 +38,8 @@ import it.unimi.dsi.fastutil.ints.IntArraySet;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
@@ -136,7 +138,7 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
private List<LiveIntervals> inactive = new LinkedList<>();
// List of intervals that no register has been allocated to sorted by first live range.
private PriorityQueue<LiveIntervals> unhandled =
- new PriorityQueue<>((o1, o2) -> Integer.compare(o1.getStart(), o2.getStart()));
+ new PriorityQueue<>(Comparator.comparingInt(LiveIntervals::getStart));
// The first register used for parallel moves. After register allocation the parallel move
// temporary registers are [firstParallelMoveTemporary, maxRegisterNumber].
@@ -1354,10 +1356,6 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
unhandled.add(split);
} else if (blockedPosition > unhandledInterval.getEnd()) {
// Spilling can make a register available for the entire interval.
- // It would have been nice to use assignRegisterToUnhandledInterval here, but unfortunately
- // the order of the operations are extremely important here. updateRegisterState has to
- // happen before spillOverlappingActiveIntervals and takeRegistersForIntervals has to happen
- // after.
assignRegisterAndSpill(unhandledInterval, needsRegisterPair, candidate);
} else {
// Spilling only makes a register available for the first part of current.
@@ -1390,7 +1388,9 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
}
private void assignRegisterAndSpill(
- LiveIntervals unhandledInterval, boolean needsRegisterPair, int candidate) {
+ LiveIntervals unhandledInterval,
+ boolean needsRegisterPair,
+ int candidate) {
assignRegister(unhandledInterval, candidate);
updateRegisterState(candidate, needsRegisterPair);
// Split and spill intersecting active intervals for this register.
@@ -1402,14 +1402,21 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
splitOverlappingInactiveIntervals(unhandledInterval, needsRegisterPair, candidate);
}
- private void splitOverlappingInactiveIntervals(LiveIntervals unhandledInterval,
- boolean needsRegisterPair, int candidate) {
+ private void splitOverlappingInactiveIntervals(
+ LiveIntervals unhandledInterval,
+ boolean needsRegisterPair,
+ int candidate) {
Iterator<LiveIntervals> inactiveIterator = inactive.iterator();
while (inactiveIterator.hasNext()) {
LiveIntervals intervals = inactiveIterator.next();
if ((intervals.usesRegister(candidate) ||
(needsRegisterPair && intervals.usesRegister(candidate + 1))) &&
intervals.overlaps(unhandledInterval)) {
+ // If these assertions trigger we have changed the way blocked parts of intervals
+ // are handled. If we ever get intervals with fixed registers in here, we need
+ // to split them before the first use in the same way that we do when spilling
+ // overlapping active intervals.
+ assert !intervals.isLinked() || intervals.isArgumentInterval();
if (intervals.getStart() > unhandledInterval.getStart()) {
// The inactive live intervals hasn't started yet. Clear the temporary register
// assignment and move back to unhandled for register reassignment.
@@ -1426,8 +1433,10 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
}
}
- private void spillOverlappingActiveIntervals(LiveIntervals unhandledInterval,
- boolean needsRegisterPair, int candidate) {
+ private void spillOverlappingActiveIntervals(
+ LiveIntervals unhandledInterval,
+ boolean needsRegisterPair,
+ int candidate) {
List<LiveIntervals> newActive = new ArrayList<>();
Iterator<LiveIntervals> activeIterator = active.iterator();
while (activeIterator.hasNext()) {
@@ -1844,8 +1853,6 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
live.add(use);
addLiveRange(use, block, number);
}
- LiveIntervals useIntervals = use.getLiveIntervals();
- useIntervals.addUse(new LiveIntervalsUse(number, Constants.U16BIT_MAX, true));
}
Value use = instruction.getPreviousLocalValue();
if (use != null) {
@@ -1854,8 +1861,6 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
live.add(use);
addLiveRange(use, block, number);
}
- LiveIntervals useIntervals = use.getLiveIntervals();
- useIntervals.addUse(new LiveIntervalsUse(number, Constants.U16BIT_MAX, true));
}
}
}
@@ -1887,14 +1892,27 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
Value previous = null;
for (int i = 0; i < arguments.size(); i++) {
Value argument = arguments.get(i);
- // TODO(ager): Conditionally create a new argument if it is not already a move.
- // Reverted optimization from CL: https://r8-review.googlesource.com/c/1985/
- // Not considering debug-uses causes a unlinked/non-consecutive register in some cases.
- Value newArgument = createValue(argument.outType());
- Move move = new Move(newArgument, argument);
- move.setBlock(invoke.getBlock());
- replaceArgument(invoke, i, newArgument);
- insertAt.add(move);
+ Value newArgument = argument;
+ // In debug mode, we have debug instructions that are also moves. Do not generate another
+ // move if there already is a move instruction that we can use. We generate moves if:
+ //
+ // 1. the argument is not defined by a move,
+ //
+ // 2. the argument is already linked or would cause a cycle if linked, or
+ //
+ // 3. the argument has a register constraint (the argument moves are there to make the
+ // input value to a ranged invoke unconstrained.)
+ if (argument.definition == null ||
+ !argument.definition.isMove() ||
+ argument.isLinked() ||
+ argument == previous ||
+ argument.hasRegisterConstraint()) {
+ newArgument = createValue(argument.outType());
+ Move move = new Move(newArgument, argument);
+ move.setBlock(invoke.getBlock());
+ replaceArgument(invoke, i, newArgument);
+ insertAt.add(move);
+ }
if (previous != null) {
previous.linkTo(newArgument);
}
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java
index 9c28724a7..06b33f473 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java
@@ -319,7 +319,7 @@ public class LiveIntervals {
public int firstUseAfter(int unhandledStart) {
for (LiveIntervalsUse use : uses) {
- if (use.getPosition() >= unhandledStart && !use.isDebugUse()) {
+ if (use.getPosition() >= unhandledStart) {
return use.getPosition();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervalsUse.java b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervalsUse.java
index edf876ded..db8e48de6 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervalsUse.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervalsUse.java
@@ -8,16 +8,10 @@ import static com.android.tools.r8.dex.Constants.U16BIT_MAX;
public class LiveIntervalsUse implements Comparable<LiveIntervalsUse> {
private final int position;
private final int limit;
- private final boolean debugUse;
public LiveIntervalsUse(int position, int limit) {
- this(position, limit, false);
- }
-
- public LiveIntervalsUse(int position, int limit, boolean debugUse) {
this.position = position;
this.limit = limit;
- this.debugUse = debugUse;
}
public int getPosition() {
@@ -53,8 +47,4 @@ public class LiveIntervalsUse implements Comparable<LiveIntervalsUse> {
public boolean hasConstraint() {
return limit < U16BIT_MAX;
}
-
- public boolean isDebugUse() {
- return debugUse;
- }
}
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index de8033808..7c12590b3 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -22,16 +22,6 @@ import java.util.Set;
public class ClassNameMinifier {
- /**
- * We ban classes from these prefixes from minification. This is needed as some classes
- * in the android sdk are given a @hide annotation, which will remove them from the
- * sdk we tree-shake and minify against. Thus, the class will not be available and hence
- * we won't find out that it is a library class.
- * To save space, we by default minify classes we do not have an implementation for.
- */
- private static final Set<String> BANNED_CLASS_PREFIXES = ImmutableSet
- .of("Ljava", "Landroid", "Ldalvik");
-
private final AppInfoWithLiveness appInfo;
private final RootSet rootSet;
private final String packagePrefix;
@@ -65,17 +55,13 @@ public class ClassNameMinifier {
renaming.put(clazz.type, state.nextTypeName());
}
}
- renameTypesInProtosOf(appInfo.staticInvokes);
- renameTypesInProtosOf(appInfo.superInvokes);
- renameTypesInProtosOf(appInfo.directInvokes);
- renameTypesInProtosOf(appInfo.virtualInvokes);
appInfo.dexItemFactory.forAllTypes(this::renameArrayTypeIfNeeded);
return Collections.unmodifiableMap(renaming);
}
private String getPackageNameFor(DexClass clazz) {
- if (packagePrefix == null || rootSet.keepPackageName.contains(clazz)) {
+ if ((packagePrefix == null) || rootSet.keepPackageName.contains(clazz)) {
return clazz.type.getPackageDescriptor();
} else {
return packagePrefix;
@@ -86,38 +72,6 @@ public class ClassNameMinifier {
return states.computeIfAbsent(packageName, NamingState::new);
}
- private void renameTypesInProtosOf(Iterable<DexMethod> methods) {
- for (DexMethod method : methods) {
- renameTypeWithoutClassDefinition(method.proto.returnType);
- for (DexType type : method.proto.parameters.values) {
- renameTypeWithoutClassDefinition(type);
- }
- }
- }
-
- private void renameTypeWithoutClassDefinition(DexType type) {
- if (type.isArrayType()) {
- type = type.toBaseType(appInfo.dexItemFactory);
- }
- if (type.isClassType() && !renaming.containsKey(type)) {
- DexClass clazz = appInfo.definitionFor(type);
- if (clazz == null || !clazz.isLibraryClass()) {
- if (!classIsBannedFromRenaming(type)) {
- String packageName = packagePrefix == null ? type.getPackageDescriptor() : packagePrefix;
- NamingState state = getStateFor(packageName);
- renaming.put(type, state.nextTypeName());
- }
- }
- }
- }
-
- private boolean classIsBannedFromRenaming(DexType type) {
- String desc = type.toDescriptorString();
- int index = desc.indexOf('/');
- String prefix = desc.substring(0, index);
- return index != -1 && BANNED_CLASS_PREFIXES.contains(prefix);
- }
-
private void renameArrayTypeIfNeeded(DexType type) {
if (type.isArrayType()) {
DexType base = type.toBaseType(appInfo.dexItemFactory);
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
index 9a6300800..71a4dc634 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -24,6 +24,8 @@ public class ProguardConfiguration {
private boolean ignoreWarnings = false;
private boolean obfuscating = true;
private boolean shrinking = true;
+ private boolean printUsage = false;
+ private Path printUsageFile;
private boolean printMapping;
private Path printMappingOutput;
private boolean verbose = false;
@@ -69,6 +71,14 @@ public class ProguardConfiguration {
this.shrinking = shrinking;
}
+ public void setPrintUsage(boolean printUsage) {
+ this.printUsage = printUsage;
+ }
+
+ public void setPrintUsageFile(Path printUsageFile) {
+ this.printUsageFile = printUsageFile;
+ }
+
public void setPrintMapping(boolean printMapping) {
this.printMapping = printMapping;
}
@@ -123,6 +133,8 @@ public class ProguardConfiguration {
ignoreWarnings,
obfuscating,
shrinking,
+ printUsage,
+ printUsageFile,
printMapping,
printMappingOutput,
verbose,
@@ -145,6 +157,8 @@ public class ProguardConfiguration {
private final boolean ignoreWarnings;
private final boolean obfuscating;
private final boolean shrinking;
+ private final boolean printUsage;
+ private final Path printUsageFile;
private final boolean printMapping;
private final Path printMappingOutput;
private final boolean verbose;
@@ -166,6 +180,8 @@ public class ProguardConfiguration {
boolean ignoreWarnings,
boolean obfuscating,
boolean shrinking,
+ boolean printUsage,
+ Path printUsageFile,
boolean printMapping,
Path printMappingOutput,
boolean verbose,
@@ -185,6 +201,8 @@ public class ProguardConfiguration {
this.ignoreWarnings = ignoreWarnings;
this.obfuscating = obfuscating;
this.shrinking = shrinking;
+ this.printUsage = printUsage;
+ this.printUsageFile = printUsageFile;
this.printMapping = printMapping;
this.printMappingOutput = printMappingOutput;
this.verbose = verbose;
@@ -249,6 +267,14 @@ public class ProguardConfiguration {
return shrinking;
}
+ public boolean isPrintUsage() {
+ return printUsage;
+ }
+
+ public Path getPrintUsageFile() {
+ return printUsageFile;
+ }
+
public boolean isVerbose() {
return verbose;
}
@@ -293,6 +319,8 @@ public class ProguardConfiguration {
false /* ignoreWarnings */,
false /* obfuscating */,
false /* shrinking */,
+ false /* printUsage */,
+ null /* printUsageFile */,
false /* printMapping */,
null /* outputMapping */,
false /* verbose */,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 9fcb50a92..3b78e1b56 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -55,8 +55,7 @@ public class ProguardConfigurationParser {
"alwaysinline", "identifiernamestring", "whyarenotsimple");
private static final List<String> warnedSingleArgOptions = ImmutableList
- .of("printusage",
- "renamesourcefileattribute",
+ .of("renamesourcefileattribute",
"dontnote",
"printconfiguration",
// TODO -outjars (http://b/37137994) and -adaptresourcefilecontents (http://b/37139570)
@@ -154,6 +153,14 @@ public class ProguardConfigurationParser {
configurationBuilder.setObfuscating(false);
} else if (acceptString("dontshrink")) {
configurationBuilder.setShrinking(false);
+ } else if (acceptString("printusage")) {
+ configurationBuilder.setPrintUsage(true);
+ skipWhitespace();
+ if (isOptionalArgumentGiven()) {
+ configurationBuilder.setPrintUsageFile(parseFileName());
+ }
+ // TODO(b/36799826): once fully implemented, no longer necessary to warn.
+ System.out.println("WARNING: Ignoring option: -printusage");
} else if (acceptString("verbose")) {
configurationBuilder.setVerbose(true);
} else if (acceptString("ignorewarnings")) {
@@ -177,7 +184,7 @@ public class ProguardConfigurationParser {
} else if (acceptString("printmapping")) {
configurationBuilder.setPrintMapping(true);
skipWhitespace();
- if (!eof() && peekChar() != '-') {
+ if (isOptionalArgumentGiven()) {
configurationBuilder.setPrintMappingOutput(parseFileName());
}
} else if (acceptString("assumenosideeffects")) {
@@ -199,7 +206,7 @@ public class ProguardConfigurationParser {
} else if (acceptString("printseeds")) {
configurationBuilder.setPrintSeed(true);
skipWhitespace();
- if (!eof() && peekChar() != '-') {
+ if (isOptionalArgumentGiven()) {
configurationBuilder.setSeedFile(parseFileName());
}
} else if (acceptString("obfuscationdictionary")) {
@@ -271,7 +278,7 @@ public class ProguardConfigurationParser {
Log.debug(ProguardConfigurationParser.class, "Skipping '-%s` option", name);
}
skipWhitespace();
- if (!eof() && peekChar() != '-') {
+ if (isOptionalArgumentGiven()) {
skipSingleArgument();
}
return true;
@@ -794,6 +801,10 @@ public class ProguardConfigurationParser {
return peekChar() == c;
}
+ private boolean isOptionalArgumentGiven() {
+ return !eof() && !hasNextChar('-');
+ }
+
private boolean acceptChar(char c) {
if (hasNextChar(c)) {
position++;
@@ -938,7 +949,6 @@ public class ProguardConfigurationParser {
}
}
-
private void checkNotNegatedPattern() throws ProguardRuleParserException {
skipWhitespace();
if (acceptChar('!')) {
diff --git a/src/main/java/com/android/tools/r8/shaking/TreePruner.java b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
index 04f67864d..3968c9ae0 100644
--- a/src/main/java/com/android/tools/r8/shaking/TreePruner.java
+++ b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
@@ -55,14 +55,15 @@ public class TreePruner {
private List<DexProgramClass> getNewProgramClasses(List<DexProgramClass> classes) {
List<DexProgramClass> newClasses = new ArrayList<>();
for (DexProgramClass clazz : classes) {
- if (!appInfo.liveTypes.contains(clazz.type) && !options.debugKeepRules) {
+ if (!appInfo.liveTypes.contains(clazz.type)) {
// The class is completely unused and we can remove it.
if (Log.ENABLED) {
Log.debug(getClass(), "Removing class: " + clazz);
}
} else {
newClasses.add(clazz);
- if (!appInfo.instantiatedTypes.contains(clazz.type) && !options.debugKeepRules) {
+ if (!appInfo.instantiatedTypes.contains(clazz.type) &&
+ (!options.debugKeepRules || !hasDefaultConstructor(clazz))) {
// The class is only needed as a type but never instantiated. Make it abstract to reflect
// this.
if (clazz.accessFlags.isFinal()) {
@@ -86,6 +87,15 @@ public class TreePruner {
return newClasses;
}
+ private boolean hasDefaultConstructor(DexProgramClass clazz) {
+ for (DexEncodedMethod method : clazz.directMethods()) {
+ if (isDefaultConstructor(method)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private <S extends PresortedComparable<S>, T extends KeyedDexItem<S>> int firstUnreachableIndex(
T[] items, Set<S> live) {
for (int i = 0; i < items.length; i++) {
@@ -96,6 +106,11 @@ public class TreePruner {
return -1;
}
+ private boolean isDefaultConstructor(DexEncodedMethod method) {
+ return method.accessFlags.isConstructor() && !method.accessFlags.isStatic()
+ && method.method.proto.parameters.isEmpty();
+ }
+
private DexEncodedMethod[] reachableMethods(DexEncodedMethod[] methods, DexClass clazz) {
int firstUnreachable = firstUnreachableIndex(methods, appInfo.liveMethods);
// Return the original array if all methods are used.
@@ -109,7 +124,7 @@ public class TreePruner {
for (int i = firstUnreachable; i < methods.length; i++) {
if (appInfo.liveMethods.contains(methods[i].getKey())) {
reachableMethods.add(methods[i]);
- } else if (options.debugKeepRules) {
+ } else if (options.debugKeepRules && isDefaultConstructor(methods[i])) {
// Keep the method but rewrite its body, if it has one.
reachableMethods.add(methods[i].accessFlags.isAbstract()
? methods[i]
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index 7b9d45d45..e5088347f 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -278,8 +278,11 @@ public class AndroidApp {
try (Closer closer = Closer.create()) {
List<Resource> dexProgramSources = getDexProgramResources();
for (int i = 0; i < dexProgramSources.size(); i++) {
- Path fileName = directory.resolve(outputMode.getFileName(dexProgramSources.get(i), i));
- Files.copy(dexProgramSources.get(i).getStream(closer), fileName, options);
+ Path filePath = directory.resolve(outputMode.getOutputPath(dexProgramSources.get(i), i));
+ if (!Files.exists(filePath.getParent())) {
+ Files.createDirectories(filePath.getParent());
+ }
+ Files.copy(dexProgramSources.get(i).getStream(closer), filePath, options);
}
}
}
@@ -333,7 +336,7 @@ public class AndroidApp {
try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(archive, options))) {
List<Resource> dexProgramSources = getDexProgramResources();
for (int i = 0; i < dexProgramSources.size(); i++) {
- ZipEntry zipEntry = new ZipEntry(outputMode.getFileName(dexProgramSources.get(i), i));
+ ZipEntry zipEntry = new ZipEntry(outputMode.getOutputPath(dexProgramSources.get(i), i));
byte[] bytes = ByteStreams.toByteArray(dexProgramSources.get(i).getStream(closer));
zipEntry.setSize(bytes.length);
out.putNextEntry(zipEntry);
diff --git a/src/main/java/com/android/tools/r8/utils/FileUtils.java b/src/main/java/com/android/tools/r8/utils/FileUtils.java
index 47a72a38a..16f41cc04 100644
--- a/src/main/java/com/android/tools/r8/utils/FileUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/FileUtils.java
@@ -75,9 +75,12 @@ public class FileUtils {
public static Path validateOutputFile(Path path) throws CompilationException {
if (path != null) {
- if (!isZipFile(path) && !(Files.exists(path) && Files.isDirectory(path))) {
+ boolean isJarOrZip = isZipFile(path) || isJarFile(path);
+ if (!isJarOrZip && !(Files.exists(path) && Files.isDirectory(path))) {
throw new CompilationException(
- "Invalid output: " + path + "\nOutput must be a zip archive or an existing directory");
+ "Invalid output: "
+ + path +
+ "\nOutput must be a .zip or .jar archive or an existing directory");
}
}
return path;
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 01d8c2692..9d6cfa5ea 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -59,6 +59,8 @@ public class InternalOptions {
public OutputMode outputMode = OutputMode.Indexed;
public boolean useTreeShaking = true;
+ public boolean printUsage = false;
+ public Path printUsageFile = null;
public boolean printCfg = false;
public String printCfgFile;
diff --git a/src/main/java/com/android/tools/r8/utils/OutputMode.java b/src/main/java/com/android/tools/r8/utils/OutputMode.java
index ce743e82e..1bdf50174 100644
--- a/src/main/java/com/android/tools/r8/utils/OutputMode.java
+++ b/src/main/java/com/android/tools/r8/utils/OutputMode.java
@@ -10,21 +10,21 @@ import java.util.Set;
public enum OutputMode {
Indexed {
@Override
- String getFileName(Resource resource, int index) {
+ String getOutputPath(Resource resource, int index) {
return index == 0 ? "classes.dex" : ("classes" + (index + 1) + ".dex");
}
},
FilePerClass {
@Override
- String getFileName(Resource resource, int index) {
+ String getOutputPath(Resource resource, int index) {
Set<String> classDescriptors = resource.getClassDescriptors();
assert classDescriptors != null;
assert classDescriptors.size() == 1;
String classDescriptor = classDescriptors.iterator().next();
- assert !classDescriptor.contains(".");
- return DescriptorUtils.descriptorToJavaType(classDescriptor) + ".dex";
+ assert DescriptorUtils.isClassDescriptor(classDescriptor);
+ return classDescriptor.substring(1, classDescriptor.length() - 1) + ".dex";
}
};
- abstract String getFileName(Resource resource, int index);
+ abstract String getOutputPath(Resource resource, int index);
}
diff --git a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
index db81f17a1..d8b9bbc07 100644
--- a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
@@ -5,6 +5,7 @@
package com.android.tools.r8;
import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+import static org.junit.Assert.assertEquals;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InternalCompilerError;
@@ -264,18 +265,25 @@ public abstract class D8IncrementalRunExamplesAndroidOTest
D8IncrementalTestRunner test = test(testName, testPackage, mainClass);
test.compileClassesTogether(inputJarFile, out);
- String[] dexFiles = out.toFile().list();
+
+ String[] topLevelDir = out.toFile().list();
+ assert topLevelDir != null;
+ assertEquals(1, topLevelDir.length);
+ assertEquals("incremental", topLevelDir[0]);
+
+ String[] dexFiles = out.resolve(topLevelDir[0]).toFile().list();
assert dexFiles != null;
Arrays.sort(dexFiles);
String[] expectedFileNames = {
- "incremental.IncrementallyCompiled$A$AB.dex",
- "incremental.IncrementallyCompiled$A.dex",
- "incremental.IncrementallyCompiled$B$BA.dex",
- "incremental.IncrementallyCompiled$B.dex",
- "incremental.IncrementallyCompiled$C.dex",
- "incremental.IncrementallyCompiled.dex"
+ "IncrementallyCompiled$A$AB.dex",
+ "IncrementallyCompiled$A.dex",
+ "IncrementallyCompiled$B$BA.dex",
+ "IncrementallyCompiled$B.dex",
+ "IncrementallyCompiled$C.dex",
+ "IncrementallyCompiled.dex"
};
+ Arrays.sort(expectedFileNames);
Assert.assertArrayEquals(expectedFileNames, dexFiles);
}
diff --git a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
index 8dc725508..eba8db600 100644
--- a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
+++ b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
@@ -138,7 +138,7 @@ public class JctfTestSpecifications {
// 1) t01
// org.junit.ComparisonFailure: expected:<get[]StackTrace> but was:<get[Thread]StackTrace>
- .put("lang.Thread.enumerate$Ljava_lang_Thread.Thread_enumerate_A02", any())
+ .put("lang.Thread.enumerate_Ljava_lang_Thread.Thread_enumerate_A02", any())
// 1) t01
// java.lang.AssertionError: test failed with error:java.lang.SecurityException
@@ -153,7 +153,7 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Expected exception: java.lang.IllegalThreadStateException
.put("lang.Thread.getAllStackTraces.Thread_getAllStackTraces_A01",
- match(runtimes(DexVm.ART_DEFAULT, DexVm.ART_7_0_0)))
+ match(runtimes(DexVm.ART_7_0_0)))
// 1) t01
// java.lang.AssertionError
@@ -195,7 +195,7 @@ public class JctfTestSpecifications {
// java.lang.UnsupportedOperationException
.put("lang.Thread.getContextClassLoader.Thread_getContextClassLoader_A03",
- match(runtimes(DexVm.ART_DEFAULT, DexVm.ART_7_0_0)))
+ match(runtimes(DexVm.ART_7_0_0)))
// 1) t01
// java.lang.AssertionError: improper ClassLoader expected same:<null> was not:<dalvik.system.PathClassLoader[DexPathList[[dex file "/tmp/junit7794202178392390143/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]]>
@@ -316,8 +316,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructors.Class_getDeclaredConstructors_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 3) t03
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor$Ljava_lang_Class/Class_getDeclaredConstructor_A03;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor$Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor_Ljava_lang_Class/Class_getDeclaredConstructor_A03;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor_Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 4) t04
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
// Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredFields/Class_getDeclaredFields_A02;
@@ -332,8 +332,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethods.Class_getDeclaredMethods_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 7) t07
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String$Ljava_lang_Class/Class_getDeclaredMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String$Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String_Ljava_lang_Class/Class_getDeclaredMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String_Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 8) t08
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredClasses/Class_getDeclaredClasses_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredClasses.Class_getDeclaredClasses_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -341,8 +341,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructors/Class_getDeclaredConstructors_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructors.Class_getDeclaredConstructors_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 10) t10
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor$Ljava_lang_Class/Class_getDeclaredConstructor_A03;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor$Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor_Ljava_lang_Class/Class_getDeclaredConstructor_A03;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor_Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 11) t11
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredFields/Class_getDeclaredFields_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredFields.Class_getDeclaredFields_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -353,8 +353,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethods/Class_getDeclaredMethods_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethods.Class_getDeclaredMethods_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 14) t14
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String$Ljava_lang_Class/Class_getDeclaredMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String$Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String_Ljava_lang_Class/Class_getDeclaredMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String_Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 15) t15
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/newInstance/Class_newInstance_A07;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.newInstance.Class_newInstance_A07" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -372,8 +372,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructors.Class_getConstructors_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 19) t19
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor$Ljava_lang_Class/Class_getConstructor_A04;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor$Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor_Ljava_lang_Class/Class_getConstructor_A04;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor_Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 20) t20
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
// Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getFields/Class_getFields_A02;
@@ -388,8 +388,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethods.Class_getMethods_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 23) t23
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String$Ljava_lang_Class/Class_getMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String_Ljava_lang_Class/Class_getMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 24) t24
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getClasses/Class_getClasses_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getClasses.Class_getClasses_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -397,8 +397,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructors/Class_getConstructors_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructors.Class_getConstructors_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 26) t26
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor$Ljava_lang_Class/Class_getConstructor_A04;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor$Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor_Ljava_lang_Class/Class_getConstructor_A04;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor_Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 27) t27
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getFields/Class_getFields_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getFields.Class_getFields_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -409,8 +409,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethods/Class_getMethods_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethods.Class_getMethods_A02" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 30) t30
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String$Ljava_lang_Class/Class_getMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String_Ljava_lang_Class/Class_getMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit2603421343038865741/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 31) t31
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
// Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/SecurityManager/checkMemberAccessLjava_lang_ClassI/SecurityManager_checkMemberAccess_A02;
@@ -593,8 +593,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructors.Class_getDeclaredConstructors_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 3) t03
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor$Ljava_lang_Class/Class_getDeclaredConstructor_A03;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor$Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor_Ljava_lang_Class/Class_getDeclaredConstructor_A03;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor_Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 4) t04
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
// Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredFields/Class_getDeclaredFields_A02;
@@ -609,8 +609,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethods.Class_getDeclaredMethods_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 7) t07
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String$Ljava_lang_Class/Class_getDeclaredMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String$Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String_Ljava_lang_Class/Class_getDeclaredMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String_Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 8) t08
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredClasses/Class_getDeclaredClasses_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredClasses.Class_getDeclaredClasses_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -618,8 +618,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructors/Class_getDeclaredConstructors_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructors.Class_getDeclaredConstructors_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 10) t10
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor$Ljava_lang_Class/Class_getDeclaredConstructor_A03;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor$Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredConstructor_Ljava_lang_Class/Class_getDeclaredConstructor_A03;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredConstructor_Ljava_lang_Class.Class_getDeclaredConstructor_A03" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 11) t11
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredFields/Class_getDeclaredFields_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredFields.Class_getDeclaredFields_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -630,8 +630,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethods/Class_getDeclaredMethods_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethods.Class_getDeclaredMethods_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 14) t14
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String$Ljava_lang_Class/Class_getDeclaredMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String$Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getDeclaredMethodLjava_lang_String_Ljava_lang_Class/Class_getDeclaredMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getDeclaredMethodLjava_lang_String_Ljava_lang_Class.Class_getDeclaredMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 15) t15
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/newInstance/Class_newInstance_A07;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.newInstance.Class_newInstance_A07" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -649,8 +649,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructors.Class_getConstructors_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 19) t19
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor$Ljava_lang_Class/Class_getConstructor_A04;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor$Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor_Ljava_lang_Class/Class_getConstructor_A04;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor_Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 20) t20
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
// Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getFields/Class_getFields_A02;
@@ -665,8 +665,8 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethods.Class_getMethods_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 23) t23
// java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NoClassDefFoundError>
- // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String$Ljava_lang_Class/Class_getMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String_Ljava_lang_Class/Class_getMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 24) t24
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getClasses/Class_getClasses_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getClasses.Class_getClasses_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -674,8 +674,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructors/Class_getConstructors_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructors.Class_getConstructors_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 26) t26
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor$Ljava_lang_Class/Class_getConstructor_A04;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor$Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getConstructor_Ljava_lang_Class/Class_getConstructor_A04;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getConstructor_Ljava_lang_Class.Class_getConstructor_A04" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 27) t27
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getFields/Class_getFields_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getFields.Class_getFields_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -686,8 +686,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethods/Class_getMethods_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethods.Class_getMethods_A02" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 30) t30
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String$Ljava_lang_Class/Class_getMethod_A05;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/Class/getMethodLjava_lang_String_Ljava_lang_Class/Class_getMethod_A05;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A05" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 31) t32
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/SecurityManager/checkPackageAccessLjava_lang_String/SecurityManager_checkPackageAccess_A01;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.SecurityManager.checkPackageAccessLjava_lang_String.SecurityManager_checkPackageAccess_A01" on path: DexPathList[[dex file "/tmp/junit7609456538458065688/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -745,7 +745,7 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ClassLoader/ConstructorLjava_lang_ClassLoader/ClassLoader_Constructor_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ClassLoader.ConstructorLjava_lang_ClassLoader.ClassLoader_Constructor_A02" on path: DexPathList[[dex file "/tmp/junit6765412840574788386/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
- .put("lang.ClassLoader.defineClassLjava_lang_String$BII.ClassLoader_defineClass_A06",
+ .put("lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A06",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -775,8 +775,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ThreadGroup/getParent/ThreadGroup_getParent_A03;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ThreadGroup.getParent.ThreadGroup_getParent_A03" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 8) t08
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ThreadGroup/enumerate$ThreadGroup/ThreadGroup_enumerate_A03;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ThreadGroup.enumerate$ThreadGroup.ThreadGroup_enumerate_A03" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ThreadGroup/enumerate_ThreadGroup/ThreadGroup_enumerate_A03;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ThreadGroup.enumerate_ThreadGroup.ThreadGroup_enumerate_A03" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 9) t09
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ThreadGroup/interrupt/ThreadGroup_interrupt_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ThreadGroup.interrupt.ThreadGroup_interrupt_A02" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -799,8 +799,8 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ThreadGroup/getParent/ThreadGroup_getParent_A02;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ThreadGroup.getParent.ThreadGroup_getParent_A02" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 16) t16
- // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ThreadGroup/enumerate$ThreadGroup/ThreadGroup_enumerate_A03;
- // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ThreadGroup.enumerate$ThreadGroup.ThreadGroup_enumerate_A03" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
+ // java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/ThreadGroup/enumerate_ThreadGroup/ThreadGroup_enumerate_A03;
+ // Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ThreadGroup.enumerate_ThreadGroup.ThreadGroup_enumerate_A03" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
// 17) t17
// java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/SecurityManager/checkAccessLjava_lang_ThreadGroup/SecurityManager_checkAccess_A01;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.SecurityManager.checkAccessLjava_lang_ThreadGroup.SecurityManager_checkAccess_A01" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
@@ -809,12 +809,12 @@ public class JctfTestSpecifications {
// Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/jctf/test/lib/java/lang/SecurityManager/checkAccessLjava_lang_ThreadGroup/SecurityManager_checkAccess_A01;
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.SecurityManager.checkAccessLjava_lang_ThreadGroup.SecurityManager_checkAccess_A01" on path: DexPathList[[dex file "/tmp/junit7453598412317397853/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
- .put("lang.ClassLoader.defineClassLjava_lang_String$BII.ClassLoader_defineClass_A05",
+ .put("lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A05",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClassLjava_lang_String$BII.ClassLoader_defineClass_A02",
+ .put("lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A02",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -823,26 +823,26 @@ public class JctfTestSpecifications {
// 3) t03
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClassLjava_lang_String$BII.ClassLoader_defineClass_A04",
+ .put("lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A04",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
// 2) t02
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClassLjava_lang_String$BII.ClassLoader_defineClass_A03",
+ .put("lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A03",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClassLjava_lang_String$BII.ClassLoader_defineClass_A01",
+ .put("lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A01",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
// 2) t02
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClassLjava_lang_String$BII.ClassLoader_defineClass_A07",
+ .put("lang.ClassLoader.defineClassLjava_lang_String_BII.ClassLoader_defineClass_A07",
any())
// 1) t01
// java.lang.Exception: Unexpected exception, expected<java.lang.NullPointerException> but was<java.lang.UnsupportedOperationException>
@@ -969,7 +969,7 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.ClassLoader.setSignersLjava_lang_Class$Ljava_lang_Object.ClassLoader_setSigners_A01",
+ "lang.ClassLoader.setSignersLjava_lang_Class_Ljava_lang_Object.ClassLoader_setSigners_A01",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -1025,7 +1025,7 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.ClassLoader.findLoadedClassLjava_lang_String.TestLoader" on path: DexPathList[[dex file "/tmp/junit1789265657215742712/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A02",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A02",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -1047,7 +1047,7 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A05",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A05",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -1055,7 +1055,7 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A01",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A01",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -1063,7 +1063,7 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A06",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A06",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -1071,14 +1071,14 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A08",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A08",
any())
// 1) t01
// java.lang.Exception: Unexpected exception, expected<java.lang.NullPointerException> but was<java.lang.UnsupportedOperationException>
// Caused by: java.lang.UnsupportedOperationException: can't load this type of class file
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A03",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A03",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -1098,25 +1098,25 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Resource not found:
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A07",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A07",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A09",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A09",
any())
// 1) t01
// java.lang.Exception: Unexpected exception, expected<java.lang.NullPointerException> but was<java.lang.UnsupportedOperationException>
// Caused by: java.lang.UnsupportedOperationException: can't load this type of class file
.put(
- "lang.ClassLoader.defineClassLjava_lang_String$BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A04",
+ "lang.ClassLoader.defineClassLjava_lang_String_BIILjava_security_ProtectionDomain.ClassLoader_defineClass_A04",
any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClass$BII.ClassLoader_defineClass_A02", any())
+ .put("lang.ClassLoader.defineClass_BII.ClassLoader_defineClass_A02", any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
// 2) t02
@@ -1155,19 +1155,19 @@ public class JctfTestSpecifications {
// 2) t02
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClass$BII.ClassLoader_defineClass_A03", any())
+ .put("lang.ClassLoader.defineClass_BII.ClassLoader_defineClass_A03", any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
// 2) t02
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClass$BII.ClassLoader_defineClass_A01", any())
+ .put("lang.ClassLoader.defineClass_BII.ClassLoader_defineClass_A01", any())
// 1) t01
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
// 2) t02
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.ClassLoader.defineClass$BII.ClassLoader_defineClass_A04", any())
+ .put("lang.ClassLoader.defineClass_BII.ClassLoader_defineClass_A04", any())
// 1) t01
// java.lang.Exception: Unexpected exception, expected<java.lang.NullPointerException> but was<java.lang.UnsupportedOperationException>
// Caused by: java.lang.UnsupportedOperationException: can't load this type of class file
@@ -1293,16 +1293,16 @@ public class JctfTestSpecifications {
// 2) t02
// java.lang.AssertionError
- .put("lang.Runtime.exec$Ljava_lang_String.Runtime_exec_A02", any())
+ .put("lang.Runtime.exec_Ljava_lang_String.Runtime_exec_A02", any())
// 1) t01
- // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.exec$Ljava_lang_String.Runtime_exec_A02$T01
+ // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.exec_Ljava_lang_String.Runtime_exec_A02$T01
// ]>
- .put("lang.Runtime.exec$Ljava_lang_String.Runtime_exec_A03", any())
+ .put("lang.Runtime.exec_Ljava_lang_String.Runtime_exec_A03", any())
// 1) t01
// java.lang.AssertionError: expected:<0> but was:<1>
- .put("lang.Runtime.exec$Ljava_lang_String.Runtime_exec_A01", any())
+ .put("lang.Runtime.exec_Ljava_lang_String.Runtime_exec_A01", any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[com google jctf test lib java lang Runtime]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoArgs
// ]>
@@ -1408,19 +1408,19 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Bad exit code of spawned java proccess, err=Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.addShutdownHookLjava_lang_Thread.Runtime_addShutdownHook_A06$T02
// expected:<0> but was:<1>
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_String.Runtime_exec_A03", any())
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_String.Runtime_exec_A03", any())
// 1) t01
// java.lang.AssertionError: expected:<0> but was:<1>
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_String.Runtime_exec_A02", any())
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_String.Runtime_exec_A02", any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[t01]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoEnv
// ]>
// 2) t02
- // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.execLjava_lang_String$Ljava_lang_String.Runtime_exec_A02$T02
+ // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.execLjava_lang_String_Ljava_lang_String.Runtime_exec_A02$T02
// ]>
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_String.Runtime_exec_A01", any())
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_String.Runtime_exec_A01", any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[com google jctf test lib java lang Runtime]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoArgs
// ]>
@@ -1434,7 +1434,7 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Bad exit code of spawned java proccess, err=Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.removeShutdownHookLjava_lang_Thread.Runtime_removeShutdownHook_A02$T02
// expected:<0> but was:<1>
- .put("lang.Runtime.exec$Ljava_lang_String$Ljava_lang_String.Runtime_exec_A01", any())
+ .put("lang.Runtime.exec_Ljava_lang_String_Ljava_lang_String.Runtime_exec_A01", any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[com google jctf test lib java lang Runtime]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoArgs
// ]>
@@ -1444,12 +1444,12 @@ public class JctfTestSpecifications {
// 1) t01
// java.lang.SecurityException
- .put("lang.Runtime.exec$Ljava_lang_String$Ljava_lang_String.Runtime_exec_A02", any())
+ .put("lang.Runtime.exec_Ljava_lang_String_Ljava_lang_String.Runtime_exec_A02", any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[t01]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoEnv
// ]>
// 2) t02
- // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.exec$Ljava_lang_String$Ljava_lang_String.Runtime_exec_A02$T02
+ // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.exec_Ljava_lang_String$Ljava_lang_String.Runtime_exec_A02$T02
// ]>
.put("lang.Runtime.removeShutdownHookLjava_lang_Thread.Runtime_removeShutdownHook_A03",
@@ -1459,24 +1459,24 @@ public class JctfTestSpecifications {
// expected:<0> but was:<1>
.put(
- "lang.Runtime.exec$Ljava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A01",
+ "lang.Runtime.exec_Ljava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A01",
any())
// 1) t01
// java.lang.AssertionError: actual=Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoArgs
// : array lengths differed, expected.length=8 actual.length=9
- .put("lang.Runtime.exec$Ljava_lang_String$Ljava_lang_String.Runtime_exec_A03", any())
+ .put("lang.Runtime.exec_Ljava_lang_String_Ljava_lang_String.Runtime_exec_A03", any())
// 1) t01
// java.lang.AssertionError: expected:<0> but was:<1>
.put(
- "lang.Runtime.exec$Ljava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A02",
+ "lang.Runtime.exec_Ljava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A02",
any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[t01]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoEnv
// ]>
// 2) t02
- // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.exec$Ljava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A02$T02
+ // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.exec_Ljava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A02$T02
// ]>
.put("lang.Runtime.haltI.Runtime_halt_A02", any())
@@ -1488,7 +1488,7 @@ public class JctfTestSpecifications {
// expected:<0> but was:<1>
.put(
- "lang.Runtime.exec$Ljava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A03",
+ "lang.Runtime.exec_Ljava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A03",
any())
// 1) t02
// java.lang.AssertionError: expected:<0> but was:<1>
@@ -1541,12 +1541,12 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Bad exit code of spawned java proccess, err=Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.runFinalizersOnExitZ.Runtime_runFinalizersOnExit_A03$T03
// expected:<0> but was:<1>
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A03",
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A03",
any())
// 1) t02
// java.lang.AssertionError: expected:<0> but was:<1>
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A01",
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A01",
any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[com google jctf test lib java lang Runtime]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoArgs
@@ -1568,13 +1568,13 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Process did not block but exited with code 1;
// err=Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.exitI.Runtime_exit_A03$T03
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A02",
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A02",
any())
// 1) t01
// org.junit.ComparisonFailure: expected:<[t01]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.EchoEnv
// ]>
// 2) t02
- // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.execLjava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A02$T02
+ // org.junit.ComparisonFailure: expected:<[t02]> but was:<[Error: Could not find or load main class com.google.jctf.test.lib.java.lang.Runtime.execLjava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A02$T02
// ]>
.put("lang.Runtime.exitI.Runtime_exit_A04", any())
@@ -2178,7 +2178,7 @@ public class JctfTestSpecifications {
// 2) t02
// java.lang.UnsupportedOperationException
- .put("lang.ThreadGroup.enumerate$Thread.ThreadGroup_enumerate_A01", any())
+ .put("lang.ThreadGroup.enumerate_Thread.ThreadGroup_enumerate_A01", any())
// 1) t05
// java.lang.UnsupportedOperationException
@@ -2200,7 +2200,7 @@ public class JctfTestSpecifications {
// 1) t01
// java.lang.SecurityException
- .put("lang.ThreadGroup.enumerate$ThreadZ.ThreadGroup_enumerate_A01", any())
+ .put("lang.ThreadGroup.enumerate_ThreadZ.ThreadGroup_enumerate_A01", any())
// 1) t06
// java.lang.UnsupportedOperationException
@@ -2299,7 +2299,7 @@ public class JctfTestSpecifications {
// 6) t07
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.Class.getConstructor$Ljava_lang_Class.Class_getConstructor_A03", any())
+ .put("lang.Class.getConstructor_Ljava_lang_Class.Class_getConstructor_A03", any())
// 1) t03
// java.lang.AssertionError: Vague error message
@@ -2324,7 +2324,7 @@ public class JctfTestSpecifications {
// java.lang.ClassNotFoundException: [[[Lcom.google.jctf.test.lib.java.lang.Class.forNameLjava_lang_StringZLjava_lang_ClassLoader.Class_forName_A01$TestFixture;
// Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
- .put("lang.Class.getConstructor$Ljava_lang_Class.Class_getConstructor_A04", any())
+ .put("lang.Class.getConstructor_Ljava_lang_Class.Class_getConstructor_A04", any())
// 1) t01
// java.lang.SecurityException
// 2) t03
@@ -2347,7 +2347,7 @@ public class JctfTestSpecifications {
// java.lang.SecurityException
.put(
- "lang.Class.getDeclaredMethodLjava_lang_String$Ljava_lang_Class.Class_getDeclaredMethod_A05",
+ "lang.Class.getDeclaredMethodLjava_lang_String_Ljava_lang_Class.Class_getDeclaredMethod_A05",
any())
// 1) t01
// java.lang.SecurityException
@@ -2365,7 +2365,7 @@ public class JctfTestSpecifications {
// java.lang.SecurityException
.put(
- "lang.Class.getDeclaredMethodLjava_lang_String$Ljava_lang_Class.Class_getDeclaredMethod_A03",
+ "lang.Class.getDeclaredMethodLjava_lang_String_Ljava_lang_Class.Class_getDeclaredMethod_A03",
any())
// 1) t05
// java.lang.AssertionError: Vague error message
@@ -2546,10 +2546,10 @@ public class JctfTestSpecifications {
// java.lang.NoClassDefFoundError: sun.security.jca.Providers
// Caused by: java.lang.AssertionError: Unable to configure default providers
- .put("lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A01",
+ .put("lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A01",
match(runtimes(DexVm.ART_DEFAULT, DexVm.ART_7_0_0)))
// 1) t04
- // java.lang.AssertionError: expected:<interface com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A01$I1> but was:<interface com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A01$I2>
+ // java.lang.AssertionError: expected:<interface com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A01$I1> but was:<interface com.google.jctf.test.lib.java.lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A01$I2>
.put("lang.Class.getGenericSuperclass.Class_getGenericSuperclass_A01", any())
// 1) t03
@@ -2570,12 +2570,12 @@ public class JctfTestSpecifications {
// java.lang.SecurityException
.put(
- "lang.Class.getDeclaredConstructor$Ljava_lang_Class.Class_getDeclaredConstructor_A02",
+ "lang.Class.getDeclaredConstructor_Ljava_lang_Class.Class_getDeclaredConstructor_A02",
any())
// 1) t03
// java.lang.AssertionError: Vague error message
- .put("lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A05", any())
+ .put("lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A05", any())
// 1) t01
// java.lang.SecurityException
// 2) t03
@@ -2590,7 +2590,7 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.Class.getDeclaredConstructor$Ljava_lang_Class.Class_getDeclaredConstructor_A03",
+ "lang.Class.getDeclaredConstructor_Ljava_lang_Class.Class_getDeclaredConstructor_A03",
any())
// 1) t01
// java.lang.SecurityException
@@ -2599,7 +2599,7 @@ public class JctfTestSpecifications {
// 3) t04
// java.lang.SecurityException
- .put("lang.Class.getMethodLjava_lang_String$Ljava_lang_Class.Class_getMethod_A03", any())
+ .put("lang.Class.getMethodLjava_lang_String_Ljava_lang_Class.Class_getMethod_A03", any())
// 1) t03
// java.lang.AssertionError: Vague error message
@@ -2648,7 +2648,7 @@ public class JctfTestSpecifications {
// 1) t09
// org.junit.ComparisonFailure: Incorrect double string returned expected:<0.001[0]> but was:<0.001[]>
- .put("lang.String.Constructor$BLjava_nio_charset_Charset.String_Constructor_A01", any())
+ .put("lang.String.Constructor_BLjava_nio_charset_Charset.String_Constructor_A01", any())
// 1) t02
// org.junit.ComparisonFailure: expected:<�[]> but was:<�[�]>
// 2) t03
@@ -2701,13 +2701,13 @@ public class JctfTestSpecifications {
// 1) t06
// java.lang.AssertionError: array lengths differed, expected.length=1 actual.length=2
- .put("lang.String.getBytesII$BI.String_getBytes_A03", any())
+ .put("lang.String.getBytesII_BI.String_getBytes_A03", any())
// 1) t04
// java.lang.AssertionError: Should throws IndexOutOfBoundsException: 0
// 2) t05
// java.lang.AssertionError: Should throws IndexOutOfBoundsException: 0
- .put("lang.String.getBytesII$BI.String_getBytes_A02", any())
+ .put("lang.String.getBytesII_BI.String_getBytes_A02", any())
// 1) t01
// java.lang.AssertionError: Expected exception: java.lang.NullPointerException
@@ -2715,7 +2715,7 @@ public class JctfTestSpecifications {
// 1) t02
// org.junit.ComparisonFailure: expected:<i[]> but was:<i[̇]>
- .put("lang.String.Constructor$BIILjava_nio_charset_Charset.String_Constructor_A01", any())
+ .put("lang.String.Constructor_BIILjava_nio_charset_Charset.String_Constructor_A01", any())
// 1) t02
// org.junit.ComparisonFailure: expected:<�[]> but was:<�[�]>
// 2) t03
@@ -3609,7 +3609,7 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
.put(
- "lang.reflect.Proxy.getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class.Proxy_getProxyClass_A01",
+ "lang.reflect.Proxy.getProxyClassLjava_lang_ClassLoader_Ljava_lang_Class.Proxy_getProxyClass_A01",
any())
// 1) t01
// java.lang.AssertionError: expected same:<null> was not:<java.lang.BootClassLoader@ecc20b9>
@@ -3617,7 +3617,7 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: expected same:<null> was not:<java.lang.BootClassLoader@ecc20b9>
.put(
- "lang.reflect.Proxy.getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class.Proxy_getProxyClass_A03",
+ "lang.reflect.Proxy.getProxyClassLjava_lang_ClassLoader_Ljava_lang_Class.Proxy_getProxyClass_A03",
any())
// 1) t03
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -3648,7 +3648,7 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Failed to load serialization resource file: serialization/com/google/jctf/test/lib/java/lang/reflect/GenericSignatureFormatError/serialization/GenericSignatureFormatError_serialization_A01.golden.0.ser
.put(
- "lang.reflect.Proxy.newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler.Proxy_newProxyInstance_A02",
+ "lang.reflect.Proxy.newProxyInstanceLjava_lang_ClassLoader_Ljava_lang_ClassLjava_lang_reflect_InvocationHandler.Proxy_newProxyInstance_A02",
any())
// 1) t03
// java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.available()' on a null object reference
@@ -3660,7 +3660,7 @@ public class JctfTestSpecifications {
// java.lang.NullPointerException
.put(
- "lang.reflect.Proxy.newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler.Proxy_newProxyInstance_A01",
+ "lang.reflect.Proxy.newProxyInstanceLjava_lang_ClassLoader_Ljava_lang_ClassLjava_lang_reflect_InvocationHandler.Proxy_newProxyInstance_A01",
any())
// 1) t01
// java.lang.AssertionError: Bad classloader expected:<null> but was:<java.lang.BootClassLoader@fda9ca7>
@@ -3719,7 +3719,7 @@ public class JctfTestSpecifications {
// java.lang.ClassNotFoundException: com.google.jctf.test.lib.java.lang.reflect.Method.getGenericExceptionTypes.Method_getGenericExceptionTypes_A01$Fourth
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.reflect.Method.getGenericExceptionTypes.Method_getGenericExceptionTypes_A01$Fourth" on path: DexPathList[[dex file "/tmp/junit8600081041276641493/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
- .put("lang.reflect.Method.invokeLjava_lang_Object$Ljava_lang_Object.Method_invoke_A07",
+ .put("lang.reflect.Method.invokeLjava_lang_Object_Ljava_lang_Object.Method_invoke_A07",
any())
// 1) t01
// java.lang.AssertionError: Expected exception: java.lang.IllegalAccessException
@@ -3772,7 +3772,7 @@ public class JctfTestSpecifications {
// Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.jctf.test.lib.java.lang.reflect.Method.MissingParameterTypeMethod" on path: DexPathList[[dex file "/tmp/junit3534060116722105133/classes.dex"],nativeLibraryDirectories=[r8/tools/linux/art/bin/../lib, r8/tools/linux/art/bin/../lib]]
.put(
- "lang.reflect.InvocationHandler.invokeLjava_lang_ObjectLjava_lang_reflect_Method$Ljava_lang_Object.InvocationHandler_invoke_A02",
+ "lang.reflect.InvocationHandler.invokeLjava_lang_ObjectLjava_lang_reflect_Method_Ljava_lang_Object.InvocationHandler_invoke_A02",
any())
// 1) t04
// java.lang.AssertionError: ClassCastException should be thrown
@@ -4005,7 +4005,7 @@ public class JctfTestSpecifications {
// 1) t02
// java.lang.AssertionError: Exception is not thrown: field: shortPublicField, object: com.google.jctf.test.lib.java.lang.reflect.Field.TestStaticFinalPrimitiveField@bf7ecde
- .put("lang.reflect.Constructor.newInstance$Ljava_lang_Object.Constructor_newInstance_A06",
+ .put("lang.reflect.Constructor.newInstance_Ljava_lang_Object.Constructor_newInstance_A06",
any())
// 1) t05
// java.lang.AssertionError: Expected exception: java.lang.IllegalArgumentException
@@ -4125,7 +4125,7 @@ public class JctfTestSpecifications {
// java.lang.SecurityException
.put(
- "lang.reflect.AccessibleObject.setAccessible$Ljava_lang_reflect_AccessibleObjectZ.AccessibleObject_setAccessible_A03",
+ "lang.reflect.AccessibleObject.setAccessible_Ljava_lang_reflect_AccessibleObjectZ.AccessibleObject_setAccessible_A03",
any())
// 1) t01
// java.lang.SecurityException
@@ -4139,7 +4139,7 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Misconfiguration: MissingAntn should not be accessible
.put(
- "lang.reflect.AccessibleObject.setAccessible$Ljava_lang_reflect_AccessibleObjectZ.AccessibleObject_setAccessible_A02",
+ "lang.reflect.AccessibleObject.setAccessible_Ljava_lang_reflect_AccessibleObjectZ.AccessibleObject_setAccessible_A02",
any())
// 1) t01
// java.lang.SecurityException
@@ -4452,7 +4452,7 @@ public class JctfTestSpecifications {
// 2) t02(com.google.jctf.test.lib.java.util.concurrent.CopyOnWriteArrayList.lastIndexOfLjava_lang_ObjectI.CopyOnWriteArrayList_lastIndexOf_A01)
// java.lang.ArrayIndexOutOfBoundsException: length=3; index=2147483647
- .put("lang.StringBuffer.getCharsII$CI.StringBuffer_getChars_A03",
+ .put("lang.StringBuffer.getCharsII_CI.StringBuffer_getChars_A03",
match(runtimes(DexVm.ART_6_0_1, DexVm.ART_5_1_1)))
// 1) t03
// java.lang.NullPointerException: dst == null
@@ -4462,7 +4462,7 @@ public class JctfTestSpecifications {
// 1) t02
// java.lang.AssertionError: Buffer is invalid length after append expected:<26> but was:<25>
- .put("lang.StringBuffer.insertI$CII.StringBuffer_insert_A02",
+ .put("lang.StringBuffer.insertI_CII.StringBuffer_insert_A02",
match(runtimes(DexVm.ART_6_0_1, DexVm.ART_5_1_1)))
// 1) t01
// java.lang.NullPointerException: Attempt to get length of null array
@@ -4623,7 +4623,7 @@ public class JctfTestSpecifications {
// java.lang.AssertionError: Invalid length of created builder expected:<14> but was:<13>
.put(
- "lang.reflect.AccessibleObject.setAccessible$Ljava_lang_reflect_AccessibleObjectZ.AccessibleObject_setAccessible_A04",
+ "lang.reflect.AccessibleObject.setAccessible_Ljava_lang_reflect_AccessibleObjectZ.AccessibleObject_setAccessible_A04",
match(runtimes(DexVm.ART_6_0_1, DexVm.ART_5_1_1)))
// 1) t01
// java.lang.AssertionError: SecurityException expected.
@@ -4745,34 +4745,34 @@ public class JctfTestSpecifications {
any())
.put("lang.Thread.setPriorityI.Thread_setPriority_A02", any())
.put("lang.Thread.stopLjava_lang_Throwable.Thread_stop_A02", any())
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A04",
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A04",
any())
.put("lang.Thread.getContextClassLoader.Thread_getContextClassLoader_A02", any())
.put("lang.ThreadGroup.suspend.ThreadGroup_suspend_A02", any())
.put("lang.Thread.setDaemonZ.Thread_setDaemon_A03", any())
.put("lang.ProcessBuilder.environment.ProcessBuilder_environment_A07", any())
.put(
- "lang.Runtime.exec$Ljava_lang_String$Ljava_lang_StringLjava_io_File.Runtime_exec_A04",
+ "lang.Runtime.exec_Ljava_lang_String_Ljava_lang_StringLjava_io_File.Runtime_exec_A04",
any())
- .put("lang.Runtime.execLjava_lang_String$Ljava_lang_String.Runtime_exec_A04", any())
- .put("lang.Runtime.exec$Ljava_lang_String.Runtime_exec_A04", any())
+ .put("lang.Runtime.execLjava_lang_String_Ljava_lang_String.Runtime_exec_A04", any())
+ .put("lang.Runtime.exec_Ljava_lang_String.Runtime_exec_A04", any())
.put("lang.Runtime.execLjava_lang_String.Runtime_exec_A04", any())
.put("lang.System.clearPropertyLjava_lang_String.System_clearProperty_A03", any())
.put("lang.System.getSecurityManager.System_getSecurityManager_A01", any())
.put("lang.System.setInLjava_io_InputStream.System_setIn_A02", any())
.put("lang.System.setOutLjava_io_PrintStream.System_setOut_A02", any())
.put("lang.ThreadGroup.destroy.ThreadGroup_destroy_A04", any())
- .put("lang.ThreadGroup.enumerate$ThreadGroupZ.ThreadGroup_enumerate_A03", any())
- .put("lang.ThreadGroup.enumerate$Thread.ThreadGroup_enumerate_A03", any())
- .put("lang.ThreadGroup.enumerate$ThreadZ.ThreadGroup_enumerate_A03", any())
+ .put("lang.ThreadGroup.enumerate_ThreadGroupZ.ThreadGroup_enumerate_A03", any())
+ .put("lang.ThreadGroup.enumerate_Thread.ThreadGroup_enumerate_A03", any())
+ .put("lang.ThreadGroup.enumerate_ThreadZ.ThreadGroup_enumerate_A03", any())
.put("lang.ThreadGroup.interrupt.ThreadGroup_interrupt_A02", any())
.put("lang.ThreadGroup.resume.ThreadGroup_resume_A02", any())
.put("lang.ThreadGroup.setMaxPriorityI.ThreadGroup_setMaxPriority_A02", any())
- .put("lang.Runtime.exec$Ljava_lang_String$Ljava_lang_String.Runtime_exec_A04", any())
+ .put("lang.Runtime.exec_Ljava_lang_String_Ljava_lang_String.Runtime_exec_A04", any())
.put("lang.System.getenvLjava_lang_String.System_getenv_A03", any())
.put("lang.System.setPropertyLjava_lang_StringLjava_lang_String.System_setProperty_A02",
any())
- .put("lang.ThreadGroup.enumerate$ThreadGroup.ThreadGroup_enumerate_A03", any())
+ .put("lang.ThreadGroup.enumerate_ThreadGroup.ThreadGroup_enumerate_A03", any())
.put("lang.ThreadGroup.getParent.ThreadGroup_getParent_A02", any())
.put("lang.ThreadGroup.setDaemonZ.ThreadGroup_setDaemon_A02", any())
.put("lang.ThreadGroup.stop.ThreadGroup_stop_A02", any())
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 0d0446d85..22278e2aa 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -96,6 +96,7 @@ public abstract class R8RunArtTestsTest {
private static Map<String, Integer> needMinSdkVersion =
new ImmutableMap.Builder<String, Integer>()
// Android O
+ .put("952-invoke-custom", Constants.ANDROID_O_API)
.put("953-invoke-polymorphic-compiler", Constants.ANDROID_O_API)
.put("957-methodhandle-transforms", Constants.ANDROID_O_API)
.put("958-methodhandle-stackframe", Constants.ANDROID_O_API)
@@ -218,37 +219,25 @@ public abstract class R8RunArtTestsTest {
"073-mismatched-field"
);
- // Tests that make use of Java 8 features.
- private static List<String> usesJava8 = ImmutableList.of(
- "914-hello-obsolescence",
- "915-obsolete-2",
- "916-obsolete-jit",
- "919-obsolete-fields",
- "926-multi-obsolescence",
- "936-search-onload",
- "940-recursive-obsolete",
- "941-recurive-obsolete-jit",
- "942-private-recursive",
- "943-private-recursive-jit",
- "946-obsolete-throw",
- "951-threaded-obsolete",
- "952-invoke-custom"
- );
-
// Tests that make use of agents/native code. Our test setup does handle flags/linking of these.
private static List<String> usesNativeAgentCode = ImmutableList.of(
"497-inlining-and-class-loader",
"626-const-class-linking",
"642-fp-callees",
"909-attach-agent",
+ "914-hello-obsolescence",
+ "915-obsolete-2",
+ "916-obsolete-jit",
"917-fields-transformation",
"918-fields",
+ "919-obsolete-fields",
"920-objects",
"921-hello-failure",
"922-properties",
"923-monitors",
"924-threads",
"925-threadgroups",
+ "926-multi-obsolescence",
"927-timers",
"928-jni-table",
"929-search",
@@ -262,12 +251,18 @@ public abstract class R8RunArtTestsTest {
"937-hello-retransform-package",
"938-load-transform-bcp",
"939-hello-transformation-bcp",
+ "940-recursive-obsolete",
+ "941-recurive-obsolete-jit",
+ "942-private-recursive",
+ "943-private-recursive-jit",
"944-transform-classloaders",
"945-obsolete-native",
+ "946-obsolete-throw",
"947-reflect-method",
"948-change-annotations",
"949-in-memory-transform",
"950-redefine-intrinsic",
+ "951-threaded-obsolete",
"980-redefine-object"
);
@@ -630,6 +625,9 @@ public abstract class R8RunArtTestsTest {
// is in dex code which D8 does not convert. Therefore the error is a verification error
// at runtime and that is expected.
.put("142-classloader2", TestCondition.match(TestCondition.D8_COMPILER))
+ // Invoke-custom is supported by D8 and R8, but it can only run on our newest version
+ // of art.
+ .put("952-invoke-custom", beforeAndroidO)
// Invoke-polymorphic is supported by D8 and R8, but it can only run on our newest version
// of art.
.put("953-invoke-polymorphic-compiler", beforeAndroidO)
@@ -734,6 +732,17 @@ public abstract class R8RunArtTestsTest {
.build())
.build();
+ // Tests to skip on some conditions
+ private static final Multimap<String, TestCondition> testToSkip =
+ new ImmutableListMultimap.Builder<String, TestCondition>()
+ // Old runtimes used the legacy test directory which does not contain input for tools
+ // NONE and DX.
+ .put("952-invoke-custom", TestCondition.match(
+ TestCondition.tools(DexTool.NONE, DexTool.DX),
+ TestCondition.runtimes(
+ DexVm.ART_4_4_4, DexVm.ART_5_1_1, DexVm.ART_6_0_1, DexVm.ART_7_0_0)))
+ .build();
+
private static List<String> failuresToTriage = ImmutableList.of(
// This is flaky.
"104-growth-limit",
@@ -896,7 +905,6 @@ public abstract class R8RunArtTestsTest {
skipArt.addAll(customRun);
Set<String> skipTest = Sets.newHashSet(skipAltogether);
- skipTest.addAll(usesJava8);
skipTest.addAll(usesNativeAgentCode);
skipTest.addAll(failuresToTriage);
@@ -915,6 +923,10 @@ public abstract class R8RunArtTestsTest {
skipTest.addAll(noInputJar);
}
+ // Collect the test that we should skip in this configuration
+ skipTest.addAll(collectTestsMatchingConditions(
+ dexTool, compilerUnderTest, dexVm, compilationMode, testToSkip));
+
// Collect the test that we should skip in this configuration.
skipArt.addAll(
collectTestsMatchingConditions(
diff --git a/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java b/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java
index b3d31c54c..5af5c0c1d 100644
--- a/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java
+++ b/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java
@@ -100,10 +100,21 @@ public class CompatDxTests {
}
@Test
+ public void singleDexProgramFull() throws IOException, ExecutionException {
+ // Generate an application that fills the whole dex file.
+ AndroidApp generated =
+ MainDexListTests.generateApplication(
+ ImmutableList.of("A"), Constants.ANDROID_L_API, Constants.U16BIT_MAX + 1);
+ Path applicationJar = temp.newFile("application.jar").toPath();
+ generated.write(applicationJar, OutputMode.Indexed);
+ runDexer(applicationJar.toString());
+ }
+
+ @Test
public void singleDexProgramIsTooLarge() throws IOException, ExecutionException {
// Generate an application that will not fit into a single dex file.
AndroidApp generated = MainDexListTests.generateApplication(
- ImmutableList.of("A", "B"), Constants.ANDROID_L_API, Constants.U16BIT_MAX / 2 + 1);
+ ImmutableList.of("A", "B"), Constants.ANDROID_L_API, Constants.U16BIT_MAX / 2 + 2);
Path applicationJar = temp.newFile("application.jar").toPath();
generated.write(applicationJar, OutputMode.Indexed);
thrown.expect(CompilationError.class);
diff --git a/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
new file mode 100644
index 000000000..ad94a531b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
@@ -0,0 +1,38 @@
+// Copyright (c) 2017, 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.debug;
+
+import java.util.Map;
+import org.apache.harmony.jpda.tests.framework.jdwp.Value;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ContinuousSteppingTest extends DebugTestBase {
+
+ @Test
+ public void testArithmetic() throws Throwable {
+ runContinuousTest("Arithmetic");
+ }
+
+ @Test
+ public void testLocals() throws Throwable {
+ runContinuousTest("Locals");
+ }
+
+ private void runContinuousTest(String debuggeeClassName) throws Throwable {
+ runDebugTest(debuggeeClassName,
+ breakpoint(debuggeeClassName, "main"),
+ run(),
+ stepUntil(StepKind.OVER, StepLevel.INSTRUCTION, debuggeeState -> {
+ // Fetch local variables.
+ Map<String, Value> localValues = debuggeeState.getLocalValues();
+ Assert.assertNotNull(localValues);
+
+ // Always step until we actually exit the program.
+ return false;
+ }));
+ }
+
+}
diff --git a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
index a272eca6c..be2509780 100644
--- a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
+++ b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
@@ -18,10 +18,10 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.Queue;
import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -341,7 +341,7 @@ public abstract class DebugTestBase {
*/
private DebuggeeState debuggeeState = null;
- private final Queue<Command> commandsQueue;
+ private final Deque<Command> commandsQueue;
// Active event requests.
private final Map<Integer, EventHandler> events = new TreeMap<>();
@@ -473,6 +473,9 @@ public abstract class DebugTestBase {
artCommandBuilder.appendArtOption("-Xcompiler-option");
artCommandBuilder.appendArtOption("--compiler-filter=interpret-only");
}
+ if (DEBUG_TESTS) {
+ artCommandBuilder.appendArtOption("-verbose:jdwp");
+ }
setProperty("jpda.settings.debuggeeJavaPath", artCommandBuilder.build());
}
@@ -1031,8 +1034,8 @@ public abstract class DebugTestBase {
stepRequestID = replyPacket.getNextValueAsInt();
testBase.assertAllDataRead(replyPacket);
}
- testBase.events.put(stepRequestID, new StepEventHandler(stepRequestID, stepFilter,
- stepUntil));
+ testBase.events
+ .put(stepRequestID, new StepEventHandler(this, stepRequestID, stepFilter, stepUntil));
// Resume all threads.
testBase.resume();
@@ -1092,13 +1095,17 @@ public abstract class DebugTestBase {
private static class StepEventHandler extends DefaultEventHandler {
+ private final JUnit3Wrapper.Command.StepCommand stepCommand;
private final int stepRequestID;
private final StepFilter stepFilter;
private final Function<DebuggeeState, Boolean> stepUntil;
- private StepEventHandler(int stepRequestID,
+ private StepEventHandler(
+ JUnit3Wrapper.Command.StepCommand stepCommand,
+ int stepRequestID,
StepFilter stepFilter,
Function<DebuggeeState, Boolean> stepUntil) {
+ this.stepCommand = stepCommand;
this.stepRequestID = stepRequestID;
this.stepFilter = stepFilter;
this.stepUntil = stepUntil;
@@ -1106,19 +1113,23 @@ public abstract class DebugTestBase {
@Override
public void handle(JUnit3Wrapper testBase) {
+ // Clear step event.
+ testBase.getMirror().clearEvent(EventKind.SINGLE_STEP, stepRequestID);
+ testBase.events.remove(Integer.valueOf(stepRequestID));
+
+ // Do we need to step again ?
+ boolean repeatStep = false;
if (stepFilter
.skipLocation(testBase.getMirror(), testBase.getDebuggeeState().getLocation())) {
- // Keep the step active and resume so that we do another step.
- testBase.resume();
+ repeatStep = true;
} else if (stepUntil.apply(testBase.getDebuggeeState()) == Boolean.FALSE) {
- // We must not stop yet.
- testBase.resume();
- } else {
- // When hit, the single step must be cleared.
- testBase.getMirror().clearEvent(EventKind.SINGLE_STEP, stepRequestID);
- testBase.events.remove(Integer.valueOf(stepRequestID));
- super.handle(testBase);
+ repeatStep = true;
+ }
+ if (repeatStep) {
+ // In order to repeat the step now, we need to add it at the beginning of the queue.
+ testBase.commandsQueue.addFirst(stepCommand);
}
+ super.handle(testBase);
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/deterministic/DeterministicProcessingTest.java b/src/test/java/com/android/tools/r8/ir/deterministic/DeterministicProcessingTest.java
index 6acacdaee..d5f70cce6 100644
--- a/src/test/java/com/android/tools/r8/ir/deterministic/DeterministicProcessingTest.java
+++ b/src/test/java/com/android/tools/r8/ir/deterministic/DeterministicProcessingTest.java
@@ -70,7 +70,7 @@ public class DeterministicProcessingTest extends SmaliTestBase {
public List<DexEncodedMethod> permutationsOfTwo(
List<DexEncodedMethod> methods, CallGraph.Leaves leaves) {
- if (!leaves.brokeCycles()) {
+ if (!leaves.hasBrokeCycles()) {
return methods;
}
methods.sort(Comparator.comparing(DexEncodedMethod::qualifiedName));
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index 05b06af78..242a7d5a4 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -18,9 +18,7 @@ import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
public class ProguardConfigurationParserTest extends TestBase {
@@ -47,7 +45,7 @@ public class ProguardConfigurationParserTest extends TestBase {
private static final String LIBRARY_JARS =
VALID_PROGUARD_DIR + "library-jars.flags";
private static final String LIBRARY_JARS_WIN =
- VALID_PROGUARD_DIR + "library-jars-win.flags";
+ VALID_PROGUARD_DIR + "library-jars-win.flags";
private static final String SEEDS =
VALID_PROGUARD_DIR + "seeds.flags";
private static final String SEEDS_2 =
@@ -58,6 +56,8 @@ public class ProguardConfigurationParserTest extends TestBase {
VALID_PROGUARD_DIR + "keepdirectories.flags";
private static final String DONT_OBFUSCATE =
VALID_PROGUARD_DIR + "dontobfuscate.flags";
+ private static final String DONT_SHRINK =
+ VALID_PROGUARD_DIR + "dontshrink.flags";
private static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES =
VALID_PROGUARD_DIR + "dontskipnonpubliclibraryclasses.flags";
private static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS =
@@ -70,12 +70,13 @@ public class ProguardConfigurationParserTest extends TestBase {
VALID_PROGUARD_DIR + "skipnonpubliclibraryclasses.flags";
private static final String PARSE_AND_SKIP_SINGLE_ARGUMENT =
VALID_PROGUARD_DIR + "parse-and-skip-single-argument.flags";
+ private static final String PRINT_USAGE =
+ VALID_PROGUARD_DIR + "printusage.flags";
+ private static final String PRINT_USAGE_TO_FILE =
+ VALID_PROGUARD_DIR + "printusage-to-file.flags";
private static final String TARGET =
VALID_PROGUARD_DIR + "target.flags";
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
@Test
public void parse() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
@@ -327,6 +328,14 @@ public class ProguardConfigurationParserTest extends TestBase {
}
@Test
+ public void parseDontshrink() throws IOException, ProguardRuleParserException {
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
+ parser.parse(Paths.get(DONT_SHRINK));
+ ProguardConfiguration config = parser.getConfig();
+ assertFalse(config.isShrinking());
+ }
+
+ @Test
public void parseDontSkipNonPublicLibraryClasses()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
@@ -355,12 +364,14 @@ public class ProguardConfigurationParserTest extends TestBase {
}
@Test
- public void parseSkipNonPublicLibraryClasses()
- throws IOException, ProguardRuleParserException {
- thrown.expect(ProguardRuleParserException.class);
- thrown.expectMessage("Unsupported option: -skipnonpubliclibraryclasses");
- ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
- parser.parse(Paths.get(SKIP_NON_PUBLIC_LIBRARY_CLASSES));
+ public void parseSkipNonPublicLibraryClasses() throws IOException {
+ try {
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
+ parser.parse(Paths.get(SKIP_NON_PUBLIC_LIBRARY_CLASSES));
+ fail();
+ } catch (ProguardRuleParserException e) {
+ assertTrue(e.getMessage().contains("Unsupported option: -skipnonpubliclibraryclasses"));
+ }
}
@Test
@@ -370,6 +381,24 @@ public class ProguardConfigurationParserTest extends TestBase {
}
@Test
+ public void parsePrintUsage() throws IOException, ProguardRuleParserException {
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
+ parser.parse(Paths.get(PRINT_USAGE));
+ ProguardConfiguration config = parser.getConfig();
+ assertTrue(config.isPrintUsage());
+ assertNull(config.getPrintUsageFile());
+ }
+
+ @Test
+ public void parsePrintUsageToFile() throws IOException, ProguardRuleParserException {
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
+ parser.parse(Paths.get(PRINT_USAGE_TO_FILE));
+ ProguardConfiguration config = parser.getConfig();
+ assertTrue(config.isPrintUsage());
+ assertNotNull(config.getPrintUsageFile());
+ }
+
+ @Test
public void parseTarget()
throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
@@ -378,15 +407,18 @@ public class ProguardConfigurationParserTest extends TestBase {
@Test
public void parseInvalidKeepClassOption() throws IOException, ProguardRuleParserException {
- thrown.expect(ProguardRuleParserException.class);
- thrown.expectMessage("Unknown option at ");
- ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
- Path proguardConfig = writeTextToTempFile(
- "-keepclassx public class * { ",
- " native <methods>; ",
- "} "
- );
- parser.parse(proguardConfig);
+ try {
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
+ Path proguardConfig = writeTextToTempFile(
+ "-keepclassx public class * { ",
+ " native <methods>; ",
+ "} "
+ );
+ parser.parse(proguardConfig);
+ fail();
+ } catch (ProguardRuleParserException e) {
+ assertTrue(e.getMessage().contains("Unknown option at "));
+ }
}
@Test
diff --git a/src/test/java/com/android/tools/r8/utils/D8CommandTest.java b/src/test/java/com/android/tools/r8/utils/D8CommandTest.java
index 2844a22de..1db48c4fc 100644
--- a/src/test/java/com/android/tools/r8/utils/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/utils/D8CommandTest.java
@@ -163,6 +163,12 @@ public class D8CommandTest {
parse("--output", invalidType.toString());
}
+ @Test
+ public void nonExistingOutputJar() throws Throwable {
+ Path nonExistingJar = temp.getRoot().toPath().resolve("non-existing-archive.jar");
+ D8Command.builder().setOutputPath(nonExistingJar).build();
+ }
+
private D8Command parse(String... args) throws IOException, CompilationException {
return D8Command.parse(args).build();
}
diff --git a/src/test/java/com/android/tools/r8/utils/OutputModeTest.java b/src/test/java/com/android/tools/r8/utils/OutputModeTest.java
new file mode 100644
index 000000000..5929b6073
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/OutputModeTest.java
@@ -0,0 +1,34 @@
+// Copyright (c) 2017, 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.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.Resource;
+import java.util.Collections;
+import org.junit.Test;
+
+public class OutputModeTest {
+ @Test
+ public void testIndexedFileName() {
+ assertEquals("classes.dex", OutputMode.Indexed.getOutputPath(null, 0));
+ assertEquals("classes2.dex", OutputMode.Indexed.getOutputPath(null, 1));
+ }
+
+ @Test
+ public void testFilePerClass() {
+ Resource test =
+ Resource.fromBytes(Resource.Kind.CLASSFILE, new byte[]{}, Collections.singleton("LTest;"));
+ assertEquals("Test.dex", OutputMode.FilePerClass.getOutputPath(test, 0));
+ Resource comTest =
+ Resource.fromBytes(
+ Resource.Kind.CLASSFILE, new byte[]{}, Collections.singleton("Lcom/Test;"));
+ assertEquals("com/Test.dex", OutputMode.FilePerClass.getOutputPath(comTest, 0));
+ Resource comExampleTest =
+ Resource.fromBytes(
+ Resource.Kind.CLASSFILE, new byte[]{}, Collections.singleton("Lcom/example/Test;"));
+ assertEquals("com/example/Test.dex", OutputMode.FilePerClass.getOutputPath(comExampleTest, 0));
+ assertEquals("com/example/Test.dex", OutputMode.FilePerClass.getOutputPath(comExampleTest, 1));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/R8CommandTest.java b/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
index ed38b888a..2af79cbcf 100644
--- a/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
@@ -184,6 +184,12 @@ public class R8CommandTest {
assertEquals(1, ToolHelper.getApp(command).getDexProgramResources().size());
}
+ @Test
+ public void nonExistingOutputJar() throws Throwable {
+ Path nonExistingJar = temp.getRoot().toPath().resolve("non-existing-archive.jar");
+ R8Command.builder().setOutputPath(nonExistingJar).build();
+ }
+
private R8Command parse(String... args)
throws CompilationException, ProguardRuleParserException, IOException {
return R8Command.parse(args).build();
diff --git a/src/test/proguard/valid/dontshrink.flags b/src/test/proguard/valid/dontshrink.flags
new file mode 100644
index 000000000..3d7dbaa3c
--- /dev/null
+++ b/src/test/proguard/valid/dontshrink.flags
@@ -0,0 +1,5 @@
+# Copyright (c) 2017, 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.
+
+-dontshrink
diff --git a/src/test/proguard/valid/printusage-to-file.flags b/src/test/proguard/valid/printusage-to-file.flags
new file mode 100644
index 000000000..c3dcdc5b6
--- /dev/null
+++ b/src/test/proguard/valid/printusage-to-file.flags
@@ -0,0 +1,5 @@
+# Copyright (c) 2017, 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.
+
+-printusage ~/tmp/random_output_file.txt
diff --git a/src/test/proguard/valid/printusage.flags b/src/test/proguard/valid/printusage.flags
new file mode 100644
index 000000000..2606411da
--- /dev/null
+++ b/src/test/proguard/valid/printusage.flags
@@ -0,0 +1,5 @@
+# Copyright (c) 2017, 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.
+
+-printusage
diff --git a/third_party/gradle/gradle.tar.gz.sha1 b/third_party/gradle/gradle.tar.gz.sha1
index 60fe88df5..008d84c90 100644
--- a/third_party/gradle/gradle.tar.gz.sha1
+++ b/third_party/gradle/gradle.tar.gz.sha1
@@ -1 +1 @@
-6d7736db6f3f9c2dbe57e1ea6b36a1f694b9feef
+1d118f48ff995b7eca95f3655293ea959779a6c0 \ No newline at end of file
diff --git a/third_party/jctf.tar.gz.sha1 b/third_party/jctf.tar.gz.sha1
index 35ec1ba1e..41e1ea9dd 100644
--- a/third_party/jctf.tar.gz.sha1
+++ b/third_party/jctf.tar.gz.sha1
@@ -1 +1 @@
-93c13a164ca54db72273642d27308e325526fd38 \ No newline at end of file
+d824506dedb8cb186a13d2fd45aae349ce86bcad \ No newline at end of file
diff --git a/tools/proguard.py b/tools/proguard.py
index 58c049f9e..efcf560d2 100755
--- a/tools/proguard.py
+++ b/tools/proguard.py
@@ -15,10 +15,13 @@ import utils
PROGUARD_JAR = os.path.join(utils.REPO_ROOT, 'third_party', 'proguard',
'proguard_internal_159423826', 'ProGuard_deploy.jar')
-def run(args):
- cmd = ['java', '-jar', PROGUARD_JAR]
+def run(args, track_memory_file = None):
+ cmd = []
+ if track_memory_file:
+ cmd.extend(['tools/track_memory.sh', track_memory_file])
+ cmd.extend(['java', '-jar', PROGUARD_JAR])
cmd.extend(args)
- print('-- ' + ' '.join(cmd))
+ utils.PrintCmd(cmd)
subprocess.check_call(cmd)
def Main():
diff --git a/tools/run_on_app.py b/tools/run_on_app.py
index f3cc9b5ca..d7db7fb16 100755
--- a/tools/run_on_app.py
+++ b/tools/run_on_app.py
@@ -3,6 +3,7 @@
# 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.
+from __future__ import print_function
import optparse
import os
import sys
@@ -55,8 +56,11 @@ def ParseOptions():
'If passing several options use a quoted string.')
result.add_option('--r8-flags',
help='Additional option(s) for the compiler. ' +
- 'Same as --compiler-flags, keeping it for backward compatibility. ' +
+ 'Same as --compiler-flags, keeping it for backward'
+ ' compatibility. ' +
'If passing several options use a quoted string.')
+ # TODO(tamaskenez) remove track-memory-to-file as soon as we updated golem
+ # to use --print-memoryuse instead
result.add_option('--track-memory-to-file',
help='Track how much memory the jvm is using while ' +
' compiling. Output to the specified file.')
@@ -73,6 +77,11 @@ def ParseOptions():
help='Prints the line \'<BENCHMARKNAME>(RunTimeRaw):' +
' <elapsed> ms\' at the end where <elapsed> is' +
' the elapsed time in milliseconds.')
+ result.add_option('--print-memoryuse',
+ metavar='BENCHMARKNAME',
+ help='Prints the line \'<BENCHMARKNAME>(MemoryUse):' +
+ ' <mem>\' at the end where <mem> is the peak' +
+ ' peak resident set size (VmHWM) in bytes.')
return result.parse_args()
# Most apps have the -printmapping and -printseeds in the Proguard
@@ -81,10 +90,10 @@ def ParseOptions():
# placing these two output files together with the dex output.
def GenerateAdditionalProguardConfiguration(temp, outdir):
name = "output.config"
- with open(os.path.join(temp, name), 'w') as file:
- file.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n")
- file.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n")
- return os.path.abspath(file.name)
+ with open(os.path.join(temp, name), 'w') as f:
+ f.write('-printmapping ' + os.path.join(outdir, 'proguard.map') + "\n")
+ f.write('-printseeds ' + os.path.join(outdir, 'proguard.seeds') + "\n")
+ return os.path.abspath(f.name)
def main():
app_provided_pg_conf = False;
@@ -104,8 +113,9 @@ def main():
raise 'Unexpected'
if not options.version in data.VERSIONS.keys():
- print 'No version %s for application %s' % (options.version, options.app)
- print 'Valid versions are %s' % data.VERSIONS.keys()
+ print('No version {} for application {}'
+ .format(options.version, options.app))
+ print('Valid versions are {}'.format(data.VERSIONS.keys()))
return 1
version = data.VERSIONS[options.version]
@@ -115,13 +125,15 @@ def main():
else 'proguarded'
if options.type not in version:
- print 'No type %s for version %s' % (options.type, options.version)
- print 'Valid types are %s' % version.keys()
+ print('No type {} for version {}'.format(options.type, options.version))
+ print('Valid types are {}'.format(version.keys()))
return 1
values = version[options.type]
inputs = None
- # For R8 'deploy' the JAR is located using the Proguard configuration -injars option.
- if 'inputs' in values and (options.compiler != 'r8' or options.type != 'deploy'):
+ # For R8 'deploy' the JAR is located using the Proguard configuration
+ # -injars option.
+ if 'inputs' in values and (options.compiler != 'r8'
+ or options.type != 'deploy'):
inputs = values['inputs']
args.extend(['--output', outdir])
@@ -145,7 +157,8 @@ def main():
for lib in values['libraries']:
args.extend(['--lib', lib])
- if not outdir.endswith('.zip') and not outdir.endswith('.jar') and not os.path.exists(outdir):
+ if not outdir.endswith('.zip') and not outdir.endswith('.jar') \
+ and not os.path.exists(outdir):
os.makedirs(outdir)
if options.compiler == 'r8':
@@ -161,16 +174,18 @@ def main():
args.extend(inputs)
t0 = time.time()
-
if options.dump_args_file:
with open(options.dump_args_file, 'w') as args_file:
args_file.writelines([arg + os.linesep for arg in args])
else:
- if options.compiler == 'd8':
- d8.run(args, not options.no_build, not options.no_debug, options.profile,
- options.track_memory_to_file)
- else:
- with utils.TempDir() as temp:
+ with utils.TempDir() as temp:
+ if options.print_memoryuse and not options.track_memory_to_file:
+ options.track_memory_to_file = os.path.join(temp,
+ utils.MEMORY_USE_TMP_FILE)
+ if options.compiler == 'd8':
+ d8.run(args, not options.no_build, not options.no_debug,
+ options.profile, options.track_memory_to_file)
+ else:
if app_provided_pg_conf:
# Ensure that output of -printmapping and -printseeds go to the output
# location and not where the app Proguard configuration places them.
@@ -181,8 +196,12 @@ def main():
additional_pg_conf = GenerateAdditionalProguardConfiguration(
temp, os.path.abspath(pg_outdir))
args.extend(['--pg-conf', additional_pg_conf])
- r8.run(args, not options.no_build, not options.no_debug, options.profile,
- options.track_memory_to_file)
+ r8.run(args, not options.no_build, not options.no_debug,
+ options.profile, options.track_memory_to_file)
+ if options.print_memoryuse:
+ print('{}(MemoryUse): {}'
+ .format(options.print_memoryuse,
+ utils.grep_memoryuse(options.track_memory_to_file)))
if options.print_runtimeraw:
print('{}(RunTimeRaw): {} ms'
diff --git a/tools/run_proguard_dx_on_gmscore.py b/tools/run_proguard_dx_on_gmscore.py
index ca0b5e9e9..de716b082 100755
--- a/tools/run_proguard_dx_on_gmscore.py
+++ b/tools/run_proguard_dx_on_gmscore.py
@@ -40,6 +40,11 @@ def parse_arguments():
help = 'Prints the line \'<BENCHMARKNAME>(RunTimeRaw): <elapsed>' +
' ms\' at the end where <elapsed> is the elapsed time in' +
' milliseconds.')
+ parser.add_argument('--print-memoryuse',
+ metavar='BENCHMARKNAME',
+ help='Prints the line \'<BENCHMARKNAME>(MemoryUse):' +
+ ' <mem>\' at the end where <mem> is the peak' +
+ ' peak resident set size (VmHWM) in bytes.')
parser.add_argument('--compatdx',
help = 'Use CompatDx (D8) instead of DX.',
default = False,
@@ -72,7 +77,15 @@ def Main():
t0 = time.time()
- proguard.run(args)
+ proguard_memoryuse = None
+
+ with utils.TempDir() as temp:
+ track_memory_file = None
+ if options.print_memoryuse:
+ track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
+ proguard.run(args, track_memory_file = track_memory_file)
+ if options.print_memoryuse:
+ proguard_memoryuse = utils.grep_memoryuse(track_memory_file)
# run dex on the result
if options.compatdx:
@@ -80,10 +93,21 @@ def Main():
else:
jar = DX_JAR
- cmd = ['java', '-jar', jar, '--min-sdk-version=26', '--multi-dex',
- '--output=' + outdir, '--dex', PROGUARDED_OUTPUT];
- utils.PrintCmd(cmd);
- check_call(cmd)
+ with utils.TempDir() as temp:
+ track_memory_file = None
+ cmd = []
+ if options.print_memoryuse:
+ track_memory_file = join(temp, utils.MEMORY_USE_TMP_FILE)
+ cmd.extend(['tools/track_memory.sh', track_memory_file])
+ cmd.extend(['java', '-jar', jar, '--min-sdk-version=26', '--multi-dex',
+ '--output=' + outdir, '--dex', PROGUARDED_OUTPUT]);
+ utils.PrintCmd(cmd);
+ check_call(cmd)
+ if options.print_memoryuse:
+ dx_memoryuse = utils.grep_memoryuse(track_memory_file)
+ print('{}(MemoryUse): {}'
+ .format(options.print_memoryuse,
+ max(proguard_memoryuse, dx_memoryuse)))
if options.print_runtimeraw:
print('{}(RunTimeRaw): {} ms'
diff --git a/tools/test_framework.py b/tools/test_framework.py
index 810935d18..57279bfb4 100755
--- a/tools/test_framework.py
+++ b/tools/test_framework.py
@@ -53,6 +53,12 @@ def parse_arguments():
required = True,
help = 'Results will be printed using the specified benchmark name (e.g.'
' <NAME>-<segment>(CodeSize): <bytes>)')
+ parser.add_argument('--print-memoryuse',
+ help = 'Prints the line \'<NAME>(MemoryUse):' +
+ ' <mem>\' at the end where <mem> is the peak' +
+ ' peak resident set size (VmHWM) in bytes.',
+ default = False,
+ action = 'store_true')
return parser.parse_args()
# Return a dictionary: {segment_name -> segments_size}
@@ -96,10 +102,16 @@ def Main():
if args.tool == 'd8-release':
tool_args.append('--release')
+
+ cmd = []
+
+ track_memory_file = None
+ if args.print_memoryuse:
+ track_memory_file = os.path.join(temp_dir, utils.MEMORY_USE_TMP_FILE)
+ cmd.extend(['tools/track_memory.sh', track_memory_file])
+
if tool_file.endswith('.jar'):
- cmd = ['java', '-jar']
- else:
- cmd = []
+ cmd.extend(['java', '-jar'])
cmd.extend([tool_file] + tool_args + [FRAMEWORK_JAR])
@@ -109,6 +121,10 @@ def Main():
subprocess.check_call(cmd)
dt = time.time() - t0
+ if args.print_memoryuse:
+ print('{}(MemoryUse): {}'
+ .format(args.name, utils.grep_memoryuse(track_memory_file)))
+
dex_files = [f for f in glob(os.path.join(temp_dir, '*.dex'))]
code_size = 0
for dex_file in dex_files:
diff --git a/tools/utils.py b/tools/utils.py
index fd7212bd7..2564adc2e 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -14,6 +14,7 @@ import tempfile
TOOLS_DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..')))
REPO_ROOT = os.path.realpath(os.path.join(TOOLS_DIR, '..'))
+MEMORY_USE_TMP_FILE = 'memory_use.tmp'
def PrintCmd(s):
if type(s) is list:
@@ -118,3 +119,25 @@ def read_cts_test_result(file_xml):
outcome = m.groups()[0]
assert outcome in ['fail', 'pass']
yield CtsTest(m.groups()[1], outcome == 'pass')
+
+def grep_memoryuse(logfile):
+ re_vmhwm = re.compile('^VmHWM:[ \t]*([0-9]+)[ \t]*([a-zA-Z]*)')
+ result = None
+ with open(logfile) as f:
+ for line in f:
+ m = re_vmhwm.search(line)
+ if m:
+ groups = m.groups()
+ s = len(groups)
+ if s >= 1:
+ result = int(groups[0])
+ if s >= 2:
+ unit = groups[1]
+ if unit == 'kB':
+ result *= 1024
+ elif unit != '':
+ raise Exception('Unrecognized unit in memory usage log: {}'
+ .format(unit))
+ if result is None:
+ raise Exception('No memory usage found in log: {}'.format(logfile))
+ return result \ No newline at end of file