| // 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; |
| |
| import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest; |
| import com.android.tools.r8.R8RunArtTestsTest.DexTool; |
| import com.android.tools.r8.ToolHelper.DexVm; |
| import com.android.tools.r8.errors.Unreachable; |
| import com.google.common.collect.Sets; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.EnumSet; |
| import java.util.List; |
| import java.util.stream.Collectors; |
| |
| public class TestCondition { |
| |
| enum Runtime { |
| ART_V4_0_4, |
| ART_V4_4_4, |
| ART_V5_1_1, |
| ART_V6_0_1, |
| ART_V7_0_0, |
| ART_V8_1_0, |
| ART_V9_0_0, |
| ART_DEFAULT, |
| JAVA; |
| |
| static final Runtime LOWEST_ART_VERSION = ART_V4_0_4; |
| static final Runtime HIGHEST_ART_VERSION = ART_DEFAULT; |
| |
| static Runtime fromDexVmVersion(DexVm.Version version) { |
| switch (version) { |
| case V4_0_4: |
| return ART_V4_0_4; |
| case V4_4_4: |
| return ART_V4_4_4; |
| case V5_1_1: |
| return ART_V5_1_1; |
| case V6_0_1: |
| return ART_V6_0_1; |
| case V7_0_0: |
| return ART_V7_0_0; |
| case V8_1_0: |
| return ART_V8_1_0; |
| case V9_0_0: |
| return ART_V9_0_0; |
| case DEFAULT: |
| return ART_DEFAULT; |
| default: |
| throw new Unreachable(); |
| } |
| } |
| |
| static boolean isArt(Runtime runtime) { |
| return EnumSet.range(LOWEST_ART_VERSION, HIGHEST_ART_VERSION).contains(runtime); |
| } |
| } |
| |
| static class ToolSet { |
| |
| final EnumSet<DexTool> set; |
| |
| public ToolSet(EnumSet<DexTool> set) { |
| this.set = set; |
| } |
| } |
| |
| static class CompilerSet { |
| |
| final EnumSet<CompilerUnderTest> set; |
| |
| public CompilerSet(EnumSet<CompilerUnderTest> set) { |
| this.set = set; |
| } |
| } |
| |
| static class RuntimeSet { |
| |
| private EnumSet<Runtime> set; |
| |
| public RuntimeSet(EnumSet<Runtime> set) { |
| this.set = set; |
| } |
| |
| public static RuntimeSet fromDexVmVersionSet(EnumSet<DexVm.Version> dexVmSet) { |
| List<Runtime> list = new ArrayList<>(dexVmSet.size()); |
| for (DexVm.Version version : dexVmSet) { |
| list.add(Runtime.fromDexVmVersion(version)); |
| } |
| return new RuntimeSet(EnumSet.copyOf(list)); |
| } |
| |
| boolean contains(Runtime runtime) { |
| return set.contains(runtime); |
| } |
| } |
| |
| static class CompilationModeSet { |
| |
| final EnumSet<CompilationMode> set; |
| |
| public CompilationModeSet(EnumSet<CompilationMode> set) { |
| this.set = set; |
| } |
| } |
| |
| public static final CompilerSet D8_COMPILER = |
| compilers(CompilerUnderTest.D8, CompilerUnderTest.D8_AFTER_R8CF); |
| public static final CompilerSet D8_NOT_AFTER_R8CF_COMPILER = compilers(CompilerUnderTest.D8); |
| public static final CompilerSet D8_AFTER_R8CF_COMPILER = |
| compilers(CompilerUnderTest.D8_AFTER_R8CF); |
| // R8_COMPILER refers to R8 both in the standalone setting and after D8 |
| // R8_NOT_AFTER_D8_COMPILER and R8_AFTER_D8_COMPILER refers to the standalone and the combined |
| // settings, respectively |
| public static final CompilerSet R8_COMPILER = |
| compilers( |
| CompilerUnderTest.R8, |
| CompilerUnderTest.R8_AFTER_D8, |
| CompilerUnderTest.D8_AFTER_R8CF, |
| CompilerUnderTest.R8CF); |
| public static final CompilerSet R8DEX_COMPILER = |
| compilers(CompilerUnderTest.R8, CompilerUnderTest.R8_AFTER_D8); |
| public static final CompilerSet R8_NOT_AFTER_D8_COMPILER = |
| compilers(CompilerUnderTest.R8, CompilerUnderTest.D8_AFTER_R8CF, CompilerUnderTest.R8CF); |
| public static final CompilerSet R8CF = compilers(CompilerUnderTest.R8CF); |
| |
| public static final CompilationModeSet DEBUG_MODE = |
| new CompilationModeSet(EnumSet.of(CompilationMode.DEBUG)); |
| public static final CompilationModeSet RELEASE_MODE = |
| new CompilationModeSet(EnumSet.of(CompilationMode.RELEASE)); |
| |
| private static final ToolSet ANY_TOOL = new ToolSet(EnumSet.allOf(DexTool.class)); |
| private static final CompilerSet ANY_COMPILER = |
| new CompilerSet(EnumSet.allOf(CompilerUnderTest.class)); |
| private static final RuntimeSet ANY_RUNTIME = new RuntimeSet(EnumSet.allOf(Runtime.class)); |
| private static final RuntimeSet ANY_DEX_VM_RUNTIME = |
| RuntimeSet.fromDexVmVersionSet(EnumSet.allOf(ToolHelper.DexVm.Version.class)); |
| public static final RuntimeSet JAVA_RUNTIME = new RuntimeSet(EnumSet.of(Runtime.JAVA)); |
| private static final CompilationModeSet ANY_MODE = |
| new CompilationModeSet(EnumSet.allOf(CompilationMode.class)); |
| |
| private final EnumSet<DexTool> dexTools; |
| private final EnumSet<CompilerUnderTest> compilers; |
| private final EnumSet<Runtime> runtimes; |
| private final EnumSet<CompilationMode> compilationModes; |
| |
| public TestCondition( |
| EnumSet<DexTool> dexTools, |
| EnumSet<CompilerUnderTest> compilers, |
| EnumSet<Runtime> runtimes, |
| EnumSet<CompilationMode> compilationModes) { |
| this.dexTools = dexTools; |
| this.compilers = compilers; |
| this.runtimes = runtimes; |
| this.compilationModes = compilationModes; |
| } |
| |
| public static ToolSet tools(DexTool... tools) { |
| assert tools.length > 0; |
| return new ToolSet(EnumSet.copyOf(Arrays.asList(tools))); |
| } |
| |
| public static CompilerSet compilers(CompilerUnderTest... compilers) { |
| assert compilers.length > 0; |
| return new CompilerSet(EnumSet.copyOf(Arrays.asList(compilers))); |
| } |
| |
| public static RuntimeSet runtimes(DexVm.Version... runtimes) { |
| assert runtimes.length > 0; |
| return RuntimeSet.fromDexVmVersionSet(EnumSet.copyOf(Arrays.asList(runtimes))); |
| } |
| |
| public static RuntimeSet runtimes(Runtime... runtimes) { |
| assert runtimes.length > 0; |
| return new RuntimeSet(EnumSet.copyOf(Arrays.asList(runtimes))); |
| } |
| |
| public static RuntimeSet runtimesUpTo(DexVm.Version upto) { |
| return RuntimeSet.fromDexVmVersionSet(EnumSet.range(DexVm.Version.first(), upto)); |
| } |
| |
| public static RuntimeSet artRuntimesUpTo(Runtime upto) { |
| assert Runtime.isArt(upto); |
| return new RuntimeSet(EnumSet.range(Runtime.LOWEST_ART_VERSION, upto)); |
| } |
| |
| public static RuntimeSet artRuntimesUpToAndJava(Runtime upto) { |
| return runtimes( |
| Sets.union(artRuntimesUpTo(upto).set, runtimes(Runtime.JAVA).set).toArray(new Runtime[0])); |
| } |
| |
| public static RuntimeSet runtimesFrom(DexVm.Version start) { |
| return RuntimeSet.fromDexVmVersionSet(EnumSet.range(start, DexVm.Version.last())); |
| } |
| |
| public static RuntimeSet artRuntimesFrom(Runtime start) { |
| assert Runtime.isArt(start); |
| return new RuntimeSet(EnumSet.range(start, Runtime.HIGHEST_ART_VERSION)); |
| } |
| |
| public static RuntimeSet artRuntimesFromAndJava(Runtime start) { |
| return runtimes( |
| Sets.union(artRuntimesFrom(start).set, runtimes(Runtime.JAVA).set).toArray(new Runtime[0])); |
| } |
| |
| public static RuntimeSet and(RuntimeSet... sets) { |
| return new RuntimeSet( |
| EnumSet.copyOf( |
| Arrays.stream(sets) |
| .flatMap(runtimeSet -> runtimeSet.set.stream()) |
| .collect(Collectors.toSet()))); |
| } |
| |
| public static TestCondition or(TestCondition... conditions) { |
| return new OrTestCondition(conditions); |
| } |
| |
| public static TestCondition match( |
| ToolSet tools, |
| CompilerSet compilers, |
| RuntimeSet runtimes, |
| CompilationModeSet compilationModes) { |
| return new TestCondition(tools.set, compilers.set, runtimes.set, compilationModes.set); |
| } |
| |
| public static TestCondition match(ToolSet tools, CompilerSet compilers, RuntimeSet runtimes) { |
| return match(tools, compilers, runtimes, TestCondition.ANY_MODE); |
| } |
| |
| public static TestCondition any() { |
| return match(TestCondition.ANY_TOOL, TestCondition.ANY_COMPILER, TestCondition.ANY_RUNTIME); |
| } |
| |
| public static TestCondition anyDexVm() { |
| return match( |
| TestCondition.ANY_TOOL, TestCondition.ANY_COMPILER, TestCondition.ANY_DEX_VM_RUNTIME); |
| } |
| |
| public static TestCondition cf() { |
| return match(TestCondition.ANY_TOOL, R8CF, JAVA_RUNTIME); |
| } |
| |
| public static TestCondition match(ToolSet tools) { |
| return match(tools, TestCondition.ANY_COMPILER, TestCondition.ANY_RUNTIME); |
| } |
| |
| public static TestCondition match(ToolSet tools, CompilerSet compilers) { |
| return match(tools, compilers, TestCondition.ANY_RUNTIME); |
| } |
| |
| public static TestCondition match(ToolSet tools, RuntimeSet runtimes) { |
| return match(tools, TestCondition.ANY_COMPILER, runtimes); |
| } |
| |
| public static TestCondition match(CompilerSet compilers) { |
| return match(TestCondition.ANY_TOOL, compilers, TestCondition.ANY_RUNTIME); |
| } |
| |
| public static TestCondition match(CompilerSet compilers, CompilationModeSet compilationModes) { |
| return match(TestCondition.ANY_TOOL, compilers, TestCondition.ANY_RUNTIME, compilationModes); |
| } |
| |
| public static TestCondition match(CompilerSet compilers, RuntimeSet runtimes) { |
| return match(TestCondition.ANY_TOOL, compilers, runtimes); |
| } |
| |
| public static TestCondition match(RuntimeSet runtimes) { |
| return match(TestCondition.ANY_TOOL, TestCondition.ANY_COMPILER, runtimes); |
| } |
| |
| public boolean test( |
| DexTool dexTool, |
| CompilerUnderTest compilerUnderTest, |
| Runtime runtime, |
| CompilationMode compilationMode) { |
| return dexTools.contains(dexTool) |
| && compilers.contains(compilerUnderTest) |
| && runtimes.contains(runtime) |
| && compilationModes.contains(compilationMode); |
| } |
| |
| public boolean test( |
| DexTool dexTool, |
| CompilerUnderTest compilerUnderTest, |
| DexVm.Version version, |
| CompilationMode compilationMode) { |
| return test(dexTool, compilerUnderTest, Runtime.fromDexVmVersion(version), compilationMode); |
| } |
| |
| public static class OrTestCondition extends TestCondition { |
| |
| private final TestCondition[] conditions; |
| |
| public OrTestCondition(TestCondition[] conditions) { |
| super(null, null, null, null); |
| this.conditions = conditions; |
| } |
| |
| @Override |
| public boolean test( |
| DexTool dexTool, |
| CompilerUnderTest compilerUnderTest, |
| Runtime runtime, |
| CompilationMode compilationMode) { |
| for (TestCondition condition : conditions) { |
| if (condition.test(dexTool, compilerUnderTest, runtime, compilationMode)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean test( |
| DexTool dexTool, |
| CompilerUnderTest compilerUnderTest, |
| DexVm.Version version, |
| CompilationMode compilationMode) { |
| for (TestCondition condition : conditions) { |
| if (condition.test(dexTool, compilerUnderTest, version, compilationMode)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |
| } |