Add host Art 12.0.0-beta4
Test: tools/test.py --no-internal --runtimes=dex-12.0.0
Bug: 197077780
Change-Id: I963f8d3c44ed73969420afe6a7e28a64d3a753ba
diff --git a/.gitignore b/.gitignore
index 80c9662..07f90a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -262,6 +262,8 @@
tools/*/art-9.0.0.tar.gz
tools/*/art-10.0.0
tools/*/art-10.0.0.tar.gz
+tools/*/host/art-12.0.0-beta4
+tools/*/host/art-12.0.0-beta4.tar.gz
tools/*/art.tar.gz
tools/*/dalvik
tools/*/dalvik-4.0.4
diff --git a/build.gradle b/build.gradle
index 4a8dd81..8b0525f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -361,6 +361,7 @@
"linux/art-8.1.0",
"linux/art-9.0.0",
"linux/art-10.0.0",
+ "linux/host/art-12.0.0-beta4",
"linux/dalvik",
"linux/dalvik-4.0.4",
"${osString}/dx",
diff --git a/scripts/update-host-art.sh b/scripts/update-host-art.sh
index 76572e0..58165cd 100755
--- a/scripts/update-host-art.sh
+++ b/scripts/update-host-art.sh
@@ -109,11 +109,15 @@
# dalvikvm32 or dalvikvm64).
cp $ANDROID_HOST_BUILD/bin/dalvikvm $DEST/bin
cp $ANDROID_HOST_BUILD/bin/dex2oat $DEST/bin
+if [ -e $ANDROID_HOST_BUILD/bin/dex2oat64 ]
+ then cp $ANDROID_HOST_BUILD/bin/dex2oat64 $DEST/bin
+fi
if [ -e $ANDROID_HOST_BUILD/bin/patchoat ]
# File patchoat does not exist on Q anymore.
then cp $ANDROID_HOST_BUILD/bin/patchoat $DEST/bin
fi
+
# Required framework files.
mkdir -p $DEST/framework
cp -R $ANDROID_HOST_BUILD/framework/* $DEST/framework
@@ -127,15 +131,32 @@
# Image files required for dex2oat of actual android apps. We need an actual android product
# image containing framework classes to verify the code against.
mkdir -p $DEST/product/$ANDROID_PRODUCT/system/framework
-cp -r $ANDROID_TARGET_BUILD/product/$ANDROID_PRODUCT/system/framework/* $DEST/product/$ANDROID_PRODUCT/system/framework
+cp -rL $ANDROID_TARGET_BUILD/product/$ANDROID_PRODUCT/system/framework/* $DEST/product/$ANDROID_PRODUCT/system/framework
# Required auxillary files.
-if [ -e $ANDROID_HOST_BUILD/usr/icu ]; then
- mkdir -p $DEST/usr/icu
- cp -r $ANDROID_HOST_BUILD/usr/icu/* $DEST/usr/icu
+if [ -e $ANDROID_HOST_BUILD/apex ]; then
+ mkdir -p $DEST/apex
+ cp -rL $ANDROID_HOST_BUILD/apex/* $DEST/apex
+ if [ -e $ANDROID_HOST_BUILD/com.android.i18n ]; then
+ mkdir -p $DEST/com.android.i18n
+ cp -r $ANDROID_HOST_BUILD/com.android.i18n/* $DEST/com.android.i18n
+ fi
+ if [ -e $ANDROID_HOST_BUILD/com.android.tzdata ]; then
+ mkdir -p $DEST/com.android.tzdata
+ cp -r $ANDROID_HOST_BUILD/com.android.tzdata/* $DEST/com.android.tzdata
+ fi
+ if [ -e $ANDROID_HOST_BUILD/usr ]; then
+ mkdir -p $DEST/usr
+ cp -r $ANDROID_HOST_BUILD/usr/* $DEST/usr
+ fi
else
- mkdir -p $DEST/com.android.runtime/etc/icu/
- cp -r $ANDROID_HOST_BUILD/com.android.runtime/etc/icu/* $DEST/com.android.runtime/etc/icu/
+ if [ -e $ANDROID_HOST_BUILD/usr/icu ]; then
+ mkdir -p $DEST/usr/icu
+ cp -r $ANDROID_HOST_BUILD/usr/icu/* $DEST/usr/icu
+ else
+ mkdir -p $DEST/com.android.runtime/etc/icu/
+ cp -r $ANDROID_HOST_BUILD/com.android.runtime/etc/icu/* $DEST/com.android.runtime/etc/icu/
+ fi
fi
# Update links for vdex files for Android P and later.
@@ -166,3 +187,4 @@
echo "Now run"
echo "(cd $DEST_ROOT; upload_to_google_storage.py -a --bucket r8-deps $ART_DIR)"
+echo "NOTE; If $ART_DIR has several directory elements adjust accordingly."
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java b/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java
index d8e0196..848c566 100644
--- a/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java
+++ b/src/test/java/com/android/tools/r8/CompileWithJdkClassFileProviderTest.java
@@ -116,8 +116,12 @@
containsString(
"java.lang.NoClassDefFoundError: "
+ "Failed resolution of: Ljava/util/concurrent/Flow$Subscriber;"),
- // Art 10+.
- containsString("java.lang.ClassNotFoundException: MySubscriber")));
+ // Art 10.
+ containsString("java.lang.ClassNotFoundException: MySubscriber"),
+ // Art 11+.
+ containsString(
+ "java.lang.ClassNotFoundException: "
+ + "java.util.concurrent.SubmissionPublisher")));
} else {
if (parameters.getRuntime().asCf().getVm() == CfVm.JDK8) {
// java.util.concurrent.Flow$Subscriber not present in JDK8.
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index bcd4fea..f58f1fd 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -95,15 +95,17 @@
private static final String ART_TESTS_NATIVE_LIBRARY_DIR = "tests/2017-10-04/art/lib64";
private static final String ART_LEGACY_TESTS_NATIVE_LIBRARY_DIR = "tests/2016-12-19/art/lib64";
- private static final RuntimeSet LEGACY_RUNTIME = TestCondition.runtimes(
- DexVm.Version.V4_0_4,
- DexVm.Version.V4_4_4,
- DexVm.Version.V5_1_1,
- DexVm.Version.V6_0_1,
- DexVm.Version.V7_0_0,
- DexVm.Version.V8_1_0,
- DexVm.Version.V9_0_0,
- DexVm.Version.V10_0_0);
+ private static final RuntimeSet LEGACY_RUNTIME =
+ TestCondition.runtimes(
+ DexVm.Version.V4_0_4,
+ DexVm.Version.V4_4_4,
+ DexVm.Version.V5_1_1,
+ DexVm.Version.V6_0_1,
+ DexVm.Version.V7_0_0,
+ DexVm.Version.V8_1_0,
+ DexVm.Version.V9_0_0,
+ DexVm.Version.V10_0_0,
+ DexVm.Version.V12_0_0);
// Input jar for jctf tests.
private static final String JCTF_COMMON_JAR = "build/libs/jctfCommon.jar";
@@ -185,6 +187,18 @@
.put(
"134-reg-promotion",
TestCondition.match(TestCondition.runtimes(DexVm.Version.V10_0_0)))
+ // TODO(b/197078742): Triage - test OOMs.
+ .put(
+ "134-reg-promotion",
+ TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0)))
+ // TODO(b/197078746): Triage - fails with "java.lang.NoSuchMethodException:
+ // org.apache.harmony.dalvik.ddmc.DdmVmInternal.enableRecentAllocations [boolean]"
+ .put("098-ddmc", TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0)))
+ // TODO(b/197079442): Triage - fails with "java.lang.NoSuchMethodException:
+ // org.apache.harmony.dalvik.ddmc.DdmVmInternal.enableRecentAllocations [boolean]"
+ .put(
+ "145-alloc-tracking-stress",
+ TestCondition.match(TestCondition.runtimes(DexVm.Version.V12_0_0)))
.build();
// Tests that are flaky with the Art version we currently use.
@@ -488,115 +502,134 @@
static {
ImmutableMap.Builder<DexVm.Version, List<String>> builder = ImmutableMap.builder();
builder
- .put(DexVm.Version.V10_0_0, ImmutableList.of(
- // TODO(b/144975341): Triage, Verif error.
- "518-null-array-get",
- // TODO(b/144975341): Triage, Linking error.
- "457-regs",
- "543-env-long-ref",
- "454-get-vreg"
- ))
- .put(DexVm.Version.V9_0_0, ImmutableList.of(
- // TODO(120400625): Triage.
- "454-get-vreg",
- // TODO(120402198): Triage.
- "457-regs",
- // TODO(120401674): Triage.
- "543-env-long-ref",
- // TODO(120261858) Triage.
- "518-null-array-get"
- ))
- .put(DexVm.Version.V8_1_0, ImmutableList.of(
- // TODO(119938529): Triage.
- "709-checker-varhandles",
- "454-get-vreg",
- "457-regs"
- ))
- .put(DexVm.Version.V7_0_0, ImmutableList.of(
- // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
- "008-exceptions",
+ .put(
+ DexVm.Version.V12_0_0,
+ ImmutableList.of("454-get-vreg", "457-regs", "543-env-long-ref", "518-null-array-get"))
+ .put(
+ DexVm.Version.V10_0_0,
+ ImmutableList.of(
+ // TODO(b/144975341): Triage, Verif error.
+ "518-null-array-get",
+ // TODO(b/144975341): Triage, Linking error.
+ "457-regs",
+ "543-env-long-ref",
+ "454-get-vreg"))
+ .put(
+ DexVm.Version.V9_0_0,
+ ImmutableList.of(
+ // TODO(120400625): Triage.
+ "454-get-vreg",
+ // TODO(120402198): Triage.
+ "457-regs",
+ // TODO(120401674): Triage.
+ "543-env-long-ref",
+ // TODO(120261858) Triage.
+ "518-null-array-get"))
+ .put(
+ DexVm.Version.V8_1_0,
+ ImmutableList.of(
+ // TODO(119938529): Triage.
+ "709-checker-varhandles", "454-get-vreg", "457-regs"))
+ .put(
+ DexVm.Version.V7_0_0,
+ ImmutableList.of(
+ // Addition of checks for super-class-initialization cause this to abort on non-ToT
+ // art.
+ "008-exceptions",
- // Generally fails on non-R8/D8 running.
- "156-register-dex-file-multi-loader",
- "412-new-array",
- "610-arraycopy",
- "625-checker-licm-regressions"))
- .put(DexVm.Version.V6_0_1, ImmutableList.of(
- // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
- "008-exceptions",
+ // Generally fails on non-R8/D8 running.
+ "156-register-dex-file-multi-loader",
+ "412-new-array",
+ "610-arraycopy",
+ "625-checker-licm-regressions"))
+ .put(
+ DexVm.Version.V6_0_1,
+ ImmutableList.of(
+ // Addition of checks for super-class-initialization cause this to abort on non-ToT
+ // art.
+ "008-exceptions",
- // Generally fails on non-R8/D8 running.
- "004-checker-UnsafeTest18",
- "005-annotations",
- "008-exceptions",
- "082-inline-execute",
- "099-vmdebug",
- "156-register-dex-file-multi-loader",
- "412-new-array",
- "580-checker-round",
- "594-invoke-super",
- "625-checker-licm-regressions",
- "626-const-class-linking"))
- .put(DexVm.Version.V5_1_1, ImmutableList.of(
- // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
- "008-exceptions",
+ // Generally fails on non-R8/D8 running.
+ "004-checker-UnsafeTest18",
+ "005-annotations",
+ "008-exceptions",
+ "082-inline-execute",
+ "099-vmdebug",
+ "156-register-dex-file-multi-loader",
+ "412-new-array",
+ "580-checker-round",
+ "594-invoke-super",
+ "625-checker-licm-regressions",
+ "626-const-class-linking"))
+ .put(
+ DexVm.Version.V5_1_1,
+ ImmutableList.of(
+ // Addition of checks for super-class-initialization cause this to abort on non-ToT
+ // art.
+ "008-exceptions",
- // Generally fails on non R8/D8 running.
- "004-checker-UnsafeTest18",
- "004-NativeAllocations",
- "005-annotations",
- "008-exceptions",
- "082-inline-execute",
- "099-vmdebug",
- "143-string-value",
- "156-register-dex-file-multi-loader",
- "536-checker-intrinsic-optimization",
- "552-invoke-non-existent-super",
- "580-checker-round",
- "580-checker-string-fact-intrinsics",
- "594-invoke-super",
- "605-new-string-from-bytes",
- "626-const-class-linking"))
- .put(DexVm.Version.V4_4_4, ImmutableList.of(
- // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
- "008-exceptions",
+ // Generally fails on non R8/D8 running.
+ "004-checker-UnsafeTest18",
+ "004-NativeAllocations",
+ "005-annotations",
+ "008-exceptions",
+ "082-inline-execute",
+ "099-vmdebug",
+ "143-string-value",
+ "156-register-dex-file-multi-loader",
+ "536-checker-intrinsic-optimization",
+ "552-invoke-non-existent-super",
+ "580-checker-round",
+ "580-checker-string-fact-intrinsics",
+ "594-invoke-super",
+ "605-new-string-from-bytes",
+ "626-const-class-linking"))
+ .put(
+ DexVm.Version.V4_4_4,
+ ImmutableList.of(
+ // Addition of checks for super-class-initialization cause this to abort on non-ToT
+ // art.
+ "008-exceptions",
- // Generally fails on non R8/D8 running.
- "004-checker-UnsafeTest18",
- "004-NativeAllocations",
- "005-annotations",
- "008-exceptions",
- "082-inline-execute",
- "099-vmdebug",
- "143-string-value",
- "156-register-dex-file-multi-loader",
- "536-checker-intrinsic-optimization",
- "552-invoke-non-existent-super",
- "580-checker-round",
- "580-checker-string-fact-intrinsics",
- "594-invoke-super",
- "605-new-string-from-bytes",
- "626-const-class-linking"))
- .put(DexVm.Version.V4_0_4, ImmutableList.of(
- // Addition of checks for super-class-initialization cause this to abort on non-ToT art.
- "008-exceptions",
+ // Generally fails on non R8/D8 running.
+ "004-checker-UnsafeTest18",
+ "004-NativeAllocations",
+ "005-annotations",
+ "008-exceptions",
+ "082-inline-execute",
+ "099-vmdebug",
+ "143-string-value",
+ "156-register-dex-file-multi-loader",
+ "536-checker-intrinsic-optimization",
+ "552-invoke-non-existent-super",
+ "580-checker-round",
+ "580-checker-string-fact-intrinsics",
+ "594-invoke-super",
+ "605-new-string-from-bytes",
+ "626-const-class-linking"))
+ .put(
+ DexVm.Version.V4_0_4,
+ ImmutableList.of(
+ // Addition of checks for super-class-initialization cause this to abort on non-ToT
+ // art.
+ "008-exceptions",
- // Generally fails on non R8/D8 running.
- "004-checker-UnsafeTest18",
- "004-NativeAllocations",
- "005-annotations",
- "008-exceptions",
- "082-inline-execute",
- "099-vmdebug",
- "143-string-value",
- "156-register-dex-file-multi-loader",
- "536-checker-intrinsic-optimization",
- "552-invoke-non-existent-super",
- "580-checker-round",
- "580-checker-string-fact-intrinsics",
- "594-invoke-super",
- "605-new-string-from-bytes",
- "626-const-class-linking"));
+ // Generally fails on non R8/D8 running.
+ "004-checker-UnsafeTest18",
+ "004-NativeAllocations",
+ "005-annotations",
+ "008-exceptions",
+ "082-inline-execute",
+ "099-vmdebug",
+ "143-string-value",
+ "156-register-dex-file-multi-loader",
+ "536-checker-intrinsic-optimization",
+ "552-invoke-non-existent-super",
+ "580-checker-round",
+ "580-checker-string-fact-intrinsics",
+ "594-invoke-super",
+ "605-new-string-from-bytes",
+ "626-const-class-linking"));
expectedToFailRunWithArtVersion = builder.build();
}
@@ -2050,6 +2083,10 @@
System.out.println("Running on 10.0.0 is disabled, see b/144966342");
continue;
}
+ if (vm.getVersion() == DexVm.Version.V12_0_0) {
+ System.out.println("Running on 12.0.0 is disabled, see b/197078995");
+ continue;
+ }
vms.add(new DexRuntime(vm));
}
}
diff --git a/src/test/java/com/android/tools/r8/TestCondition.java b/src/test/java/com/android/tools/r8/TestCondition.java
index d72ba77..07fff0e 100644
--- a/src/test/java/com/android/tools/r8/TestCondition.java
+++ b/src/test/java/com/android/tools/r8/TestCondition.java
@@ -25,6 +25,7 @@
ART_V8_1_0,
ART_V9_0_0,
ART_V10_0_0,
+ ART_V12_0_0,
ART_DEFAULT,
JAVA;
@@ -49,6 +50,8 @@
return ART_V9_0_0;
case V10_0_0:
return ART_V10_0_0;
+ case V12_0_0:
+ return ART_V12_0_0;
case DEFAULT:
return ART_DEFAULT;
default:
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index a1bdeb8..a38852e 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -256,7 +256,9 @@
ART_9_0_0_TARGET(Version.V9_0_0, Kind.TARGET),
ART_9_0_0_HOST(Version.V9_0_0, Kind.HOST),
ART_10_0_0_TARGET(Version.V10_0_0, Kind.TARGET),
- ART_10_0_0_HOST(Version.V10_0_0, Kind.HOST);
+ ART_10_0_0_HOST(Version.V10_0_0, Kind.HOST),
+ ART_12_0_0_TARGET(Version.V12_0_0, Kind.TARGET),
+ ART_12_0_0_HOST(Version.V12_0_0, Kind.HOST);
private static final ImmutableMap<String, DexVm> SHORT_NAME_MAP =
Arrays.stream(DexVm.values()).collect(ImmutableMap.toImmutableMap(
@@ -271,7 +273,8 @@
V8_1_0("8.1.0"),
DEFAULT("default"),
V9_0_0("9.0.0"),
- V10_0_0("10.0.0");
+ V10_0_0("10.0.0"),
+ V12_0_0("12.0.0");
Version(String shortName) {
this.shortName = shortName;
@@ -289,6 +292,10 @@
return this == last();
}
+ public boolean isEqualTo(Version other) {
+ return compareTo(other) == 0;
+ }
+
public boolean isNewerThan(Version other) {
return compareTo(other) > 0;
}
@@ -321,7 +328,7 @@
}
public static Version last() {
- return V10_0_0;
+ return V12_0_0;
}
static {
@@ -358,10 +365,22 @@
return SHORT_NAME_MAP.get(version.shortName + "_" + Kind.HOST.toString());
}
+ public boolean isEqualTo(DexVm other) {
+ return version.isNewerThanOrEqual(other.version);
+ }
+
public boolean isNewerThan(DexVm other) {
return version.isNewerThan(other.version);
}
+ public boolean isNewerThanOrEqual(DexVm other) {
+ return version.isNewerThanOrEqual(other.version);
+ }
+
+ public boolean isOlderThan(DexVm other) {
+ return version.isOlderThan(other.version);
+ }
+
public boolean isOlderThanOrEqual(DexVm other) {
return version.isOlderThanOrEqual(other.version);
}
@@ -580,6 +599,7 @@
private static final Map<DexVm, String> ART_DIRS =
ImmutableMap.<DexVm, String>builder()
.put(DexVm.ART_DEFAULT, "art")
+ .put(DexVm.ART_12_0_0_HOST, "host/art-12.0.0-beta4")
.put(DexVm.ART_10_0_0_HOST, "art-10.0.0")
.put(DexVm.ART_9_0_0_HOST, "art-9.0.0")
.put(DexVm.ART_8_1_0_HOST, "art-8.1.0")
@@ -587,10 +607,12 @@
.put(DexVm.ART_6_0_1_HOST, "art-6.0.1")
.put(DexVm.ART_5_1_1_HOST, "art-5.1.1")
.put(DexVm.ART_4_4_4_HOST, "dalvik")
- .put(DexVm.ART_4_0_4_HOST, "dalvik-4.0.4").build();
+ .put(DexVm.ART_4_0_4_HOST, "dalvik-4.0.4")
+ .build();
private static final Map<DexVm, String> ART_BINARY_VERSIONS =
ImmutableMap.<DexVm, String>builder()
.put(DexVm.ART_DEFAULT, "bin/art")
+ .put(DexVm.ART_12_0_0_HOST, "bin/art")
.put(DexVm.ART_10_0_0_HOST, "bin/art")
.put(DexVm.ART_9_0_0_HOST, "bin/art")
.put(DexVm.ART_8_1_0_HOST, "bin/art")
@@ -598,16 +620,19 @@
.put(DexVm.ART_6_0_1_HOST, "bin/art")
.put(DexVm.ART_5_1_1_HOST, "bin/art")
.put(DexVm.ART_4_4_4_HOST, "bin/dalvik")
- .put(DexVm.ART_4_0_4_HOST, "bin/dalvik").build();
+ .put(DexVm.ART_4_0_4_HOST, "bin/dalvik")
+ .build();
private static final Map<DexVm, String> ART_BINARY_VERSIONS_X64 =
ImmutableMap.<DexVm, String>builder()
.put(DexVm.ART_DEFAULT, "bin/art")
+ .put(DexVm.ART_12_0_0_HOST, "bin/art")
.put(DexVm.ART_10_0_0_HOST, "bin/art")
.put(DexVm.ART_9_0_0_HOST, "bin/art")
.put(DexVm.ART_8_1_0_HOST, "bin/art")
.put(DexVm.ART_7_0_0_HOST, "bin/art")
- .put(DexVm.ART_6_0_1_HOST, "bin/art").build();
+ .put(DexVm.ART_6_0_1_HOST, "bin/art")
+ .build();
private static final List<String> DALVIK_BOOT_LIBS =
ImmutableList.of(
@@ -627,6 +652,7 @@
ImmutableMap.Builder<DexVm, List<String>> builder = ImmutableMap.builder();
builder
.put(DexVm.ART_DEFAULT, ART_BOOT_LIBS)
+ .put(DexVm.ART_12_0_0_HOST, ART_BOOT_LIBS)
.put(DexVm.ART_10_0_0_HOST, ART_BOOT_LIBS)
.put(DexVm.ART_9_0_0_HOST, ART_BOOT_LIBS)
.put(DexVm.ART_8_1_0_HOST, ART_BOOT_LIBS)
@@ -644,6 +670,7 @@
ImmutableMap.Builder<DexVm, String> builder = ImmutableMap.builder();
builder
.put(DexVm.ART_DEFAULT, "angler")
+ .put(DexVm.ART_12_0_0_HOST, "redfin")
.put(DexVm.ART_10_0_0_HOST, "coral")
.put(DexVm.ART_9_0_0_HOST, "marlin")
.put(DexVm.ART_8_1_0_HOST, "marlin")
@@ -1002,6 +1029,8 @@
switch (dexVm.version) {
case DEFAULT:
return AndroidApiLevel.O;
+ case V12_0_0:
+ return AndroidApiLevel.S;
case V10_0_0:
return AndroidApiLevel.Q;
case V9_0_0:
@@ -1898,7 +1927,8 @@
public static ProcessResult runDex2OatRaw(Path file, Path outFile, DexVm vm) throws IOException {
// TODO(jmhenaff): find a way to run this on windows (push dex and run on device/emulator?)
Assume.assumeTrue(ToolHelper.isDex2OatSupported());
- Assume.assumeFalse("b/144975341", vm.version == DexVm.Version.V10_0_0);
+ Assume.assumeFalse(
+ "b/144975341", vm.version == DexVm.Version.V10_0_0 || vm.version == DexVm.Version.V12_0_0);
if (vm.isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
// Run default dex2oat for tests on dalvik runtimes.
vm = DexVm.ART_DEFAULT;
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java
index 04337ec..c87f2cc 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelVirtualDispatchLinkInterfaceTest.java
@@ -7,7 +7,7 @@
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.addTracedApiReferenceLevelCallBack;
import static com.android.tools.r8.utils.AndroidApiLevel.LATEST;
import static com.android.tools.r8.utils.AndroidApiLevel.R;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -56,7 +56,7 @@
addTracedApiReferenceLevelCallBack(
(method, apiLevel) -> {
if (Reference.methodFromMethod(main).equals(method)) {
- assertEquals(R, apiLevel);
+ assertTrue(apiLevel.isGreaterThanOrEqualTo(R));
}
}))
.compile();
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
index 37aa606..81038d6 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ByteBackportJava9Test.java
@@ -4,17 +4,18 @@
package com.android.tools.r8.desugar.backports;
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
@RunWith(Parameterized.class)
public final class ByteBackportJava9Test extends AbstractBackportTest {
@Parameters(name = "{0}")
@@ -31,7 +32,8 @@
public ByteBackportJava9Test(TestParameters parameters) {
super(parameters, Byte.class, TEST_JAR, "backport.ByteBackportJava9Main");
- // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
- // an actual API level, migrate these tests to ByteBackportTest.
+
+ // Byte.compareUnsigned added in API 31.
+ registerTarget(AndroidApiLevel.S, 16);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java
index 309b319..7b80e96 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava10Test.java
@@ -4,9 +4,12 @@
package com.android.tools.r8.desugar.backports;
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
@@ -14,8 +17,6 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
@RunWith(Parameterized.class)
public class ListBackportJava10Test extends AbstractBackportTest {
@Parameters(name = "{0}")
@@ -40,5 +41,8 @@
ignoreInvokes("get");
ignoreInvokes("set");
ignoreInvokes("size");
+
+ // List.copyOf added in API 31.
+ registerTarget(AndroidApiLevel.S, 3);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
index 0d55065..ddf502b 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ListBackportJava9Test.java
@@ -44,13 +44,16 @@
ignoreInvokes("get");
ignoreInvokes("set");
ignoreInvokes("size");
+
+ // List.of added in API 30.
+ registerTarget(AndroidApiLevel.R, 18);
}
@Test
public void desugaringApiLevelR() throws Exception {
- // TODO(154759404): This test should start to fail when testing on an Android R VM.
- if (parameters.getRuntime().isDex()
- && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+ // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+ // This has now been checked with S, when R testing is added check and remove this.
+ if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.Q)) {
testForD8()
.setMinApi(AndroidApiLevel.R)
.addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java
index e54d7d8..11008cc 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava10Test.java
@@ -4,9 +4,12 @@
package com.android.tools.r8.desugar.backports;
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
@@ -14,8 +17,6 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
@RunWith(Parameterized.class)
public class MapBackportJava10Test extends AbstractBackportTest {
@Parameters(name = "{0}")
@@ -40,5 +41,8 @@
ignoreInvokes("get");
ignoreInvokes("put");
ignoreInvokes("size");
+
+ // Map.copyOf added in API 31.
+ registerTarget(AndroidApiLevel.S, 4);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
index 27cb824..73ffa29 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MapBackportJava9Test.java
@@ -44,13 +44,16 @@
ignoreInvokes("get");
ignoreInvokes("put");
ignoreInvokes("size");
+
+ // Map.entry, Map.of and Map.ofEntries added in API 30.
+ registerTarget(AndroidApiLevel.R, 29);
}
@Test
public void desugaringApiLevelR() throws Exception {
- // TODO(154759404): This test should start to fail when testing on an Android R VM.
- if (parameters.getRuntime().isDex()
- && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+ // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+ // This has now been checked with S, when R testing is added check and remove this.
+ if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
testForD8()
.setMinApi(AndroidApiLevel.R)
.addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
index 387697e..2f70fc2 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MathBackportJava9Test.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.runner.RunWith;
@@ -31,7 +32,9 @@
public MathBackportJava9Test(TestParameters parameters) {
super(parameters, Math.class, TEST_JAR, "backport.MathBackportJava9Main");
- // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
- // an actual API level, migrate these tests to MathBackportTest.
+
+ // Math.floorDiv, Math.floorMod, Math.multiplyExact, Math.multiplyFull and Math.multiplyHigh
+ // added in API 31.
+ registerTarget(AndroidApiLevel.S, 27);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
index 09aef1e..527d2c0 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ObjectsBackportJava9Test.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Objects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -34,16 +35,20 @@
private static final String TEST_CLASS = "backport.ObjectsBackportJava9Main";
public ObjectsBackportJava9Test(TestParameters parameters) {
- super(parameters, Short.class, TEST_JAR, TEST_CLASS);
+ super(parameters, Objects.class, TEST_JAR, TEST_CLASS);
// Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
// an actual API level, migrate these tests to ObjectsBackportTest.
+
+ // Objects.checkFromIndexSize, Objects.checkFromToIndex, Objects.checkIndex,
+ // Objects.requireNonNullElse and Objects.requireNonNullElseGet added in API 30.
+ registerTarget(AndroidApiLevel.R, 28);
}
@Test
public void desugaringApiLevelR() throws Exception {
- // TODO(154759404): This test should start to fail when testing on an Android R VM.
- if (parameters.getRuntime().isDex()
- && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+ // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+ // This has now been checked with S, when R testing is added chck and remove this.
+ if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
testForD8()
.setMinApi(AndroidApiLevel.R)
.addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java
index 5c08b8f..2a17cb2 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava10Test.java
@@ -4,9 +4,12 @@
package com.android.tools.r8.desugar.backports;
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
@@ -14,8 +17,6 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
@RunWith(Parameterized.class)
public class SetBackportJava10Test extends AbstractBackportTest {
@Parameters(name = "{0}")
@@ -39,5 +40,10 @@
ignoreInvokes("add");
ignoreInvokes("contains");
ignoreInvokes("size");
+
+ // Set.of added in API 30
+ registerTarget(AndroidApiLevel.R, 1);
+ // Set.copyOf added in API 31
+ registerTarget(AndroidApiLevel.S, 5);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
index 408b203..652cde0 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/SetBackportJava9Test.java
@@ -43,13 +43,16 @@
ignoreInvokes("add");
ignoreInvokes("contains");
ignoreInvokes("size");
+
+ // Set.of added in API 30.
+ registerTarget(AndroidApiLevel.R, 21);
}
@Test
public void desugaringApiLevelR() throws Exception {
- // TODO(154759404): This test should start to fail when testing on an Android R VM.
- if (parameters.getRuntime().isDex()
- && parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.Q)) {
+ // TODO(b/154759404): This test should start to fail when testing on an Android R VM.
+ // This has now been checked with S, when R testing is added check and remove this.
+ if (parameters.getRuntime().isDex() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.R)) {
testForD8()
.setMinApi(AndroidApiLevel.R)
.addProgramClasses(MiniAssert.class, IgnoreInvokes.class)
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java b/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
index beffd8a..d1d3c95 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/ShortBackportJava9Test.java
@@ -4,17 +4,18 @@
package com.android.tools.r8.desugar.backports;
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.AndroidApiLevel;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
-import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-
@RunWith(Parameterized.class)
public final class ShortBackportJava9Test extends AbstractBackportTest {
@Parameters(name = "{0}")
@@ -31,7 +32,8 @@
public ShortBackportJava9Test(TestParameters parameters) {
super(parameters, Short.class, TEST_JAR, "backport.ShortBackportJava9Main");
- // Note: None of the methods in this test exist in the latest android.jar. If/when they ship in
- // an actual API level, migrate these tests to ShortBackportTest.
+
+ // Short.compareUnsigned added in API 31.
+ registerTarget(AndroidApiLevel.S, 16);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java b/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java
index 61cf95d..1ebfe97 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/SparseArrayBackportTest.java
@@ -5,6 +5,8 @@
package com.android.tools.r8.desugar.backports;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import org.junit.runner.RunWith;
@@ -24,18 +26,29 @@
public SparseArrayBackportTest(TestParameters parameters) throws IOException {
super(
parameters,
- SparseArrayBackportTest.getSparseArray(),
+ SparseArrayBackportTest.getSparseArray(parameters),
ImmutableList.of(
- SparseArrayBackportTest.getTestRunner(), SparseArrayBackportTest.getSparseArray()));
+ SparseArrayBackportTest.getTestRunner(),
+ SparseArrayBackportTest.getSparseArray(parameters)));
// The constructor is used by the test and put has been available since API 1 and is the
// method set is rewritten to.
ignoreInvokes("<init>");
ignoreInvokes("put");
+
+ // android.util.SparseArray.set added in API 31.
+ registerTarget(AndroidApiLevel.S, 1);
}
- private static byte[] getSparseArray() throws IOException {
- return transformer(SparseArray.class).setClassDescriptor(SPARSE_ARRAY_DESCRIPTOR).transform();
+ private static byte[] getSparseArray(TestParameters parameters) throws IOException {
+ if (parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.S)) {
+ assert parameters.getRuntime().asDex().getVm().isNewerThanOrEqual(DexVm.ART_12_0_0_HOST);
+ return transformer(SparseArrayAndroid12.class)
+ .setClassDescriptor(SPARSE_ARRAY_DESCRIPTOR)
+ .transform();
+ } else {
+ return transformer(SparseArray.class).setClassDescriptor(SPARSE_ARRAY_DESCRIPTOR).transform();
+ }
}
private static byte[] getTestRunner() throws IOException {
@@ -56,6 +69,17 @@
}
}
+ public static class SparseArrayAndroid12 {
+ public void set(int index, Object value) {
+ TestRunner.doAssertEquals(42, index);
+ TestRunner.doAssertEquals("Forty two", value);
+ }
+
+ public void put(int index, Object value) {
+ TestRunner.doFail("put should not be called");
+ }
+ }
+
public static class TestRunner extends MiniAssert {
public static void main(String[] args) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java
index c8ddd5d..80828b1 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/jdktests/Jdk11TimeTests.java
@@ -11,7 +11,7 @@
import com.android.tools.r8.D8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
@@ -35,7 +35,6 @@
return buildParameters(
BooleanUtils.values(),
getTestParameters()
- .withDexRuntimesStartingFromIncluding(Version.V5_1_1)
.withAllApiLevels()
.withApiLevel(AndroidApiLevel.N)
.build());
@@ -134,6 +133,10 @@
@Test
public void testTime() throws Exception {
+ if (parameters.getRuntime().asDex().getVm().isEqualTo(DexVm.ART_12_0_0_HOST)) {
+ // TODO(b/197078988): Many additional tests fails with Android 12.
+ return;
+ }
KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
String verbosity = "2";
D8TestCompileResult compileResult =
diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java
index cd2b968..363e539 100644
--- a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPrivateStaticResolutionInvokeVirtualTest.java
@@ -111,13 +111,6 @@
result.assertSuccessWithOutput(EXPECTED);
return;
}
- if (!unexpectedArtFailure() && !parameters.canUseDefaultAndStaticInterfaceMethods()) {
- assert false : "Dead code until future ART behavior change. See b/152199517";
- // Desugaring will insert a forwarding bridge which will hide the "invalid invoke" case.
- // Thus, a future ART runtime that does not have the invalid IAE for the private override
- // will end up calling the forward method to I.m.
- result.assertSuccessWithOutput(EXPECTED);
- }
// The expected behavior is IAE since the resolved method is private.
result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
return;
@@ -142,7 +135,8 @@
private boolean unexpectedArtFailure() {
return parameters.isDexRuntime()
- && parameters.getRuntime().asDex().getVm().isNewerThan(DexVm.ART_6_0_1_HOST);
+ && parameters.getRuntime().asDex().getVm().isNewerThan(DexVm.ART_6_0_1_HOST)
+ && parameters.getRuntime().asDex().getVm().isOlderThan(DexVm.ART_12_0_0_HOST);
}
static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java
index 92f5365..12869e2 100644
--- a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithPublicStaticResolutionInvokeVirtualTest.java
@@ -116,7 +116,8 @@
if (isR8
&& parameters.isDexRuntime()
- && parameters.getDexRuntimeVersion().isNewerThan(Version.V6_0_1)) {
+ && parameters.getDexRuntimeVersion().isNewerThan(Version.V6_0_1)
+ && parameters.getDexRuntimeVersion().isOlderThan(Version.V12_0_0)) {
// TODO(b/182255398): This should be EXPECTED.
result.assertSuccessWithOutput(EXPECTED_R8);
return;
diff --git a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
index efa7b4e..e110f57 100644
--- a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
@@ -74,6 +74,7 @@
case V4_0_4:
case V4_4_4:
case V10_0_0:
+ case V12_0_0:
return StringUtils.joinLines("Hello!", "Goodbye!", "");
case V7_0_0:
diff --git a/tools/linux/README.art-versions b/tools/linux/README.art-versions
index 9cf0717..ff57695 100644
--- a/tools/linux/README.art-versions
+++ b/tools/linux/README.art-versions
@@ -41,6 +41,33 @@
repo init -u https://android.googlesource.com/platform/manifest -m aosp_master_manifest.xml
<continue with repo sync as above>
+
+art-12.0.0 (Android S)
+---------------------
+Build from branch sc-beta4-release.
+
+export BRANCH=sc-beta4-release
+mkdir ${BRANCH}
+cd ${BRANCH}
+repo init -u https://android.googlesource.com/platform/manifest -b ${BRANCH}
+repo sync -cq -j24
+source build/envsetup.sh
+lunch aosp_redfin-userdebug
+m -j48
+m -j48 build-art
+m -j48 test-art-host
+
+Collected into tools/linux/host/art-12.0.0-beta4. The "host" path element is checked
+by the script for running Art.
+
+ cd <r8 checkout>
+ scripts/update-host-art.sh \
+ --android-checkout /usr/local/ssd/android/${BRANCH} \
+ --art-dir host/art-12.0.0-beta4 \
+ --android-product redfin
+
+(cd tools/linux/host; upload_to_google_storage.py -a --bucket r8-deps art-12.0.0-beta4)
+
art-10.0.0 (Android Q)
---------------------
Build from branch android-10.0.0_r14.
diff --git a/tools/linux/host/art-12.0.0-beta4.tar.gz.sha1 b/tools/linux/host/art-12.0.0-beta4.tar.gz.sha1
new file mode 100644
index 0000000..b95d909
--- /dev/null
+++ b/tools/linux/host/art-12.0.0-beta4.tar.gz.sha1
@@ -0,0 +1 @@
+9b6d0b061669e0fb1b09ba92c3650d5c7bdc9e85
\ No newline at end of file
diff --git a/tools/test.py b/tools/test.py
index 9c35352..6553358 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -23,6 +23,7 @@
ALL_ART_VMS = [
"default",
+ "12.0.0",
"10.0.0",
"9.0.0",
"8.1.0",