diff options
Diffstat (limited to 'test')
35 files changed, 439 insertions, 128 deletions
diff --git a/test/496-checker-inlining-and-class-loader/src/Main.java b/test/496-checker-inlining-and-class-loader/src/Main.java index 91cf0a0704..15d4dc07bc 100644 --- a/test/496-checker-inlining-and-class-loader/src/Main.java +++ b/test/496-checker-inlining-and-class-loader/src/Main.java @@ -107,7 +107,8 @@ class LoadedByMyClassLoader { /* Load and initialize FirstSeenByMyClassLoader */ /// CHECK: LoadClass gen_clinit_check:true /* Load and initialize System */ - /// CHECK-NEXT: LoadClass gen_clinit_check:true + // There may be MipsComputeBaseMethodAddress here. + /// CHECK: LoadClass gen_clinit_check:true /// CHECK-NEXT: StaticFieldGet // There may be HArmDexCacheArraysBase or HX86ComputeBaseMethodAddress here. /// CHECK: LoadString diff --git a/test/497-inlining-and-class-loader/clear_dex_cache.cc b/test/497-inlining-and-class-loader/clear_dex_cache.cc index 50d1a6361d..1597c4a65d 100644 --- a/test/497-inlining-and-class-loader/clear_dex_cache.cc +++ b/test/497-inlining-and-class-loader/clear_dex_cache.cc @@ -15,6 +15,7 @@ */ #include "art_method-inl.h" +#include "base/enums.h" #include "jni.h" #include "scoped_thread_state_change.h" #include "stack.h" @@ -44,8 +45,8 @@ extern "C" JNIEXPORT jobject JNICALL Java_Main_cloneResolvedMethods(JNIEnv* env, CHECK(array != nullptr); mirror::PointerArray* pointer_array = soa.Decode<mirror::PointerArray*>(array); for (size_t i = 0; i != num_methods; ++i) { - ArtMethod* method = mirror::DexCache::GetElementPtrSize(methods, i, sizeof(void*)); - pointer_array->SetElementPtrSize(i, method, sizeof(void*)); + ArtMethod* method = mirror::DexCache::GetElementPtrSize(methods, i, kRuntimePointerSize); + pointer_array->SetElementPtrSize(i, method, kRuntimePointerSize); } return array; } @@ -61,8 +62,8 @@ extern "C" JNIEXPORT void JNICALL Java_Main_restoreResolvedMethods( CHECK_EQ(methods != nullptr, old != nullptr); CHECK_EQ(num_methods, static_cast<size_t>(old->GetLength())); for (size_t i = 0; i != num_methods; ++i) { - ArtMethod* method = old->GetElementPtrSize<ArtMethod*>(i, sizeof(void*)); - mirror::DexCache::SetElementPtrSize(methods, i, method, sizeof(void*)); + ArtMethod* method = old->GetElementPtrSize<ArtMethod*>(i, kRuntimePointerSize); + mirror::DexCache::SetElementPtrSize(methods, i, method, kRuntimePointerSize); } } diff --git a/test/552-checker-sharpening/src/Main.java b/test/552-checker-sharpening/src/Main.java index 09a77ed285..2232ff43d2 100644 --- a/test/552-checker-sharpening/src/Main.java +++ b/test/552-checker-sharpening/src/Main.java @@ -51,6 +51,10 @@ public class Main { /// CHECK-START-ARM64: int Main.testSimple(int) sharpening (after) /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-MIPS: int Main.testSimple(int) sharpening (after) + /// CHECK-NOT: MipsDexCacheArraysBase + /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-X86: int Main.testSimple(int) sharpening (after) /// CHECK-NOT: X86ComputeBaseMethodAddress /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative @@ -62,6 +66,10 @@ public class Main { /// CHECK: ArmDexCacheArraysBase /// CHECK-NOT: ArmDexCacheArraysBase + /// CHECK-START-MIPS: int Main.testSimple(int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NOT: MipsDexCacheArraysBase + /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress /// CHECK-NOT: X86ComputeBaseMethodAddress @@ -83,6 +91,11 @@ public class Main { /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) sharpening (after) + /// CHECK-NOT: MipsDexCacheArraysBase + /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-X86: int Main.testDiamond(boolean, int) sharpening (after) /// CHECK-NOT: X86ComputeBaseMethodAddress /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative @@ -100,6 +113,14 @@ public class Main { /// CHECK: ArmDexCacheArraysBase /// CHECK-NEXT: If + /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testDiamond(boolean, int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NEXT: If + /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after) /// CHECK: X86ComputeBaseMethodAddress /// CHECK-NOT: X86ComputeBaseMethodAddress @@ -110,7 +131,7 @@ public class Main { public static int testDiamond(boolean negate, int x) { // These calls should use PC-relative dex cache array loads to retrieve the target method. - // PC-relative bases used by X86 and ARM should be pulled before the If. + // PC-relative bases used by ARM, MIPS and X86 should be pulled before the If. if (negate) { return $noinline$foo(-x); } else { @@ -154,8 +175,26 @@ public class Main { /// CHECK: begin_block /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (before) + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) + /// CHECK: MipsDexCacheArraysBase + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) + /// CHECK: InvokeStaticOrDirect + /// CHECK-NOT: InvokeStaticOrDirect + + /// CHECK-START-MIPS: int Main.testLoop(int[], int) dex_cache_array_fixups_mips (after) + /// CHECK: ArrayLength + /// CHECK-NEXT: MipsDexCacheArraysBase + /// CHECK-NEXT: Goto + /// CHECK: begin_block + /// CHECK: InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative + public static int testLoop(int[] array, int x) { - // PC-relative bases used by X86 and ARM should be pulled before the loop. + // PC-relative bases used by ARM, MIPS and X86 should be pulled before the loop. for (int i : array) { x += $noinline$foo(i); } @@ -182,8 +221,18 @@ public class Main { /// CHECK-NEXT: ArmDexCacheArraysBase /// CHECK-NEXT: Goto + /// CHECK-START-MIPS: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_mips (before) + /// CHECK-NOT: MipsDexCacheArraysBase + + /// CHECK-START-MIPS: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_mips (after) + /// CHECK: If + /// CHECK: begin_block + /// CHECK: ArrayLength + /// CHECK-NEXT: MipsDexCacheArraysBase + /// CHECK-NEXT: Goto + public static int testLoopWithDiamond(int[] array, boolean negate, int x) { - // PC-relative bases used by X86 and ARM should be pulled before the loop + // PC-relative bases used by ARM, MIPS and X86 should be pulled before the loop // but not outside the if. if (array != null) { for (int i : array) { @@ -220,6 +269,11 @@ public class Main { // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} + /// CHECK-START-MIPS: java.lang.String Main.$noinline$getBootImageString() sharpening (after) + // Note: load kind depends on PIC/non-PIC + // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. + /// CHECK: LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} + public static String $noinline$getBootImageString() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } @@ -250,6 +304,13 @@ public class Main { /// CHECK-START-ARM64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) /// CHECK: LoadString load_kind:DexCachePcRelative + /// CHECK-START-MIPS: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after) + /// CHECK: LoadString load_kind:DexCachePcRelative + + /// CHECK-START-MIPS: java.lang.String Main.$noinline$getNonBootImageString() dex_cache_array_fixups_mips (after) + /// CHECK-DAG: MipsDexCacheArraysBase + /// CHECK-DAG: LoadString load_kind:DexCachePcRelative + public static String $noinline$getNonBootImageString() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } @@ -280,6 +341,11 @@ public class Main { // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String + /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getStringClass() sharpening (after) + // Note: load kind depends on PIC/non-PIC + // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress. + /// CHECK: LoadClass load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}} class_name:java.lang.String + public static Class<?> $noinline$getStringClass() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } @@ -310,6 +376,13 @@ public class Main { /// CHECK-START-ARM64: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getOtherClass() sharpening (after) + /// CHECK: LoadClass load_kind:DexCachePcRelative class_name:Other + + /// CHECK-START-MIPS: java.lang.Class Main.$noinline$getOtherClass() dex_cache_array_fixups_mips (after) + /// CHECK-DAG: MipsDexCacheArraysBase + /// CHECK-DAG: LoadClass load_kind:DexCachePcRelative class_name:Other + public static Class<?> $noinline$getOtherClass() { // Prevent inlining to avoid the string comparison being optimized away. if (doThrow) { throw new Error(); } diff --git a/test/566-polymorphic-inlining/polymorphic_inline.cc b/test/566-polymorphic-inlining/polymorphic_inline.cc index 9f4c6c91f8..89293cc38a 100644 --- a/test/566-polymorphic-inlining/polymorphic_inline.cc +++ b/test/566-polymorphic-inlining/polymorphic_inline.cc @@ -15,6 +15,7 @@ */ #include "art_method.h" +#include "base/enums.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" #include "jit/profiling_info.h" @@ -29,7 +30,7 @@ static void do_checks(jclass cls, const char* method_name) { mirror::Class* klass = soa.Decode<mirror::Class*>(cls); jit::Jit* jit = Runtime::Current()->GetJit(); jit::JitCodeCache* code_cache = jit->GetCodeCache(); - ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, sizeof(void*)); + ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, kRuntimePointerSize); OatQuickMethodHeader* header = nullptr; // Infinite loop... Test harness will have its own timeout. @@ -53,7 +54,7 @@ static void do_checks(jclass cls, const char* method_name) { static void allocate_profiling_info(jclass cls, const char* method_name) { ScopedObjectAccess soa(Thread::Current()); mirror::Class* klass = soa.Decode<mirror::Class*>(cls); - ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, sizeof(void*)); + ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, kRuntimePointerSize); ProfilingInfo::Create(soa.Self(), method, /* retry_allocation */ true); } diff --git a/test/580-checker-round/src/Main.java b/test/580-checker-round/src/Main.java index 9e248ef95a..83bc55c480 100644 --- a/test/580-checker-round/src/Main.java +++ b/test/580-checker-round/src/Main.java @@ -36,7 +36,8 @@ public class Main { expectEquals32(-2, round32(-1.51f)); expectEquals32(-1, round32(-1.2f)); expectEquals32(-1, round32(-1.0f)); - expectEquals32(-1, round32(-0.51f)); + expectEquals32(-1, round32(-0.5000001f)); + expectEquals32(0, round32(-0.5f)); expectEquals32(0, round32(-0.2f)); expectEquals32(0, round32(-0.0f)); expectEquals32(0, round32(+0.0f)); @@ -47,11 +48,23 @@ public class Main { expectEquals32(2, round32(+1.5f)); expectEquals32(2147483647, round32(Float.POSITIVE_INFINITY)); + // Near minint. + expectEquals32(-2147483648, round32(Math.nextAfter(-2147483648.0f, Float.NEGATIVE_INFINITY))); + expectEquals32(-2147483648, round32(-2147483648.0f)); + expectEquals32(-2147483520, round32(Math.nextAfter(-2147483648.0f, Float.POSITIVE_INFINITY))); + + // Near maxint. + expectEquals32(2147483520, round32(Math.nextAfter(2147483648.0f, Float.NEGATIVE_INFINITY))); + expectEquals32(2147483647, round32(2147483648.0f)); + expectEquals32(2147483647, round32(Math.nextAfter(2147483648.0f, Float.POSITIVE_INFINITY))); + // Some others. for (int i = -100; i <= 100; ++i) { expectEquals32(i - 1, round32((float) i - 0.51f)); + expectEquals32(i, round32((float) i - 0.5f)); expectEquals32(i, round32((float) i)); expectEquals32(i + 1, round32((float) i + 0.5f)); + expectEquals32(i + 1, round32((float) i + 0.51f)); } for (float f = -1.5f; f <= -1.499f; f = Math.nextAfter(f, Float.POSITIVE_INFINITY)) { expectEquals32(-1, round32(f)); @@ -61,8 +74,10 @@ public class Main { float[] fvals = { -16777215.5f, -16777215.0f, - -0.4999f, - 0.4999f, + -0.49999998f, + -0.4999999701976776123046875f, + 0.4999999701976776123046875f, + 0.49999998f, 16777215.0f, 16777215.5f }; @@ -71,6 +86,8 @@ public class Main { -16777215, 0, 0, + 0, + 0, 16777215, 16777216 }; @@ -98,7 +115,8 @@ public class Main { expectEquals64(-2L, round64(-1.51d)); expectEquals64(-1L, round64(-1.2d)); expectEquals64(-1L, round64(-1.0d)); - expectEquals64(-1L, round64(-0.51d)); + expectEquals64(-1L, round64(-0.5000001f)); + expectEquals64(0L, round64(-0.5d)); expectEquals64(0L, round64(-0.2d)); expectEquals64(0L, round64(-0.0d)); expectEquals64(0L, round64(+0.0d)); @@ -109,11 +127,27 @@ public class Main { expectEquals64(2L, round64(+1.5d)); expectEquals64(9223372036854775807L, round64(Double.POSITIVE_INFINITY)); + // Near minlong. + expectEquals64(-9223372036854775808L, + round64(Math.nextAfter(-9223372036854775808.0, Double.NEGATIVE_INFINITY))); + expectEquals64(-9223372036854775808L, round64(-9223372036854775808.0)); + expectEquals64(-9223372036854774784L, + round64(Math.nextAfter(-9223372036854775809.0, Double.POSITIVE_INFINITY))); + + // Near maxlong. + expectEquals64(9223372036854774784L, + round64(Math.nextAfter(9223372036854775808.0, Double.NEGATIVE_INFINITY))); + expectEquals64(9223372036854775807L, round64(9223372036854775808.0)); + expectEquals64(9223372036854775807L, + round64(Math.nextAfter(9223372036854775808.0, Double.POSITIVE_INFINITY))); + // Some others. for (long l = -100; l <= 100; ++l) { expectEquals64(l - 1, round64((double) l - 0.51d)); + expectEquals64(l, round64((double) l - 0.5d)); + expectEquals64(l, round64((double) l)); expectEquals64(l + 1, round64((double) l + 0.5d)); - expectEquals64(l + 1, round64((double) l + 0.5d)); + expectEquals64(l + 1, round64((double) l + 0.51d)); } for (double d = -1.5d; d <= -1.49999999999d; d = Math.nextAfter(d, Double.POSITIVE_INFINITY)) { expectEquals64(-1L, round64(d)); @@ -123,8 +157,10 @@ public class Main { double[] dvals = { -9007199254740991.5d, -9007199254740991.0d, + -0.49999999999999997d, -0.49999999999999994d, 0.49999999999999994d, + 0.49999999999999997d, 9007199254740991.0d, 9007199254740991.5d }; @@ -133,6 +169,8 @@ public class Main { -9007199254740991L, 0L, 0L, + 0L, + 0L, 9007199254740991L, 9007199254740992L }; diff --git a/test/600-verifier-fails/expected.txt b/test/600-verifier-fails/expected.txt index eaa0c933c4..974b995a6d 100644 --- a/test/600-verifier-fails/expected.txt +++ b/test/600-verifier-fails/expected.txt @@ -3,3 +3,4 @@ passed B passed C passed D passed E +passed F diff --git a/test/600-verifier-fails/info.txt b/test/600-verifier-fails/info.txt index df2396eef7..23f3ebcf24 100644 --- a/test/600-verifier-fails/info.txt +++ b/test/600-verifier-fails/info.txt @@ -17,4 +17,7 @@ dexfuzz on the DEX files of fuzzingly random generated Java test. later on (E) b/29068831: access validation on method should occur prior to null reference check +(F) b/29758098: + new-instance of java.lang.Class should throw an IllegalAccessError to + avoid interpreter crash on zero size object later diff --git a/test/601-verifier-fails/smali/iget.smali b/test/600-verifier-fails/smali/class.smali index 5c045e6b76..b2eb254843 100644 --- a/test/601-verifier-fails/smali/iget.smali +++ b/test/600-verifier-fails/smali/class.smali @@ -13,13 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -.class public LD; +.class public LF; .super Ljava/lang/Object; .method public constructor <init>()V - .registers 2 +.registers 2 invoke-direct {v1}, Ljava/lang/Object;-><init>()V - const v0, 2 - iget v1, v0, LMain;->privateField:I + new-instance v0, Ljava/lang/Class; return-void .end method diff --git a/test/600-verifier-fails/src/Main.java b/test/600-verifier-fails/src/Main.java index fa25d58e43..1726bc4411 100644 --- a/test/600-verifier-fails/src/Main.java +++ b/test/600-verifier-fails/src/Main.java @@ -39,5 +39,6 @@ public class Main { test("C"); test("D"); test("E"); + test("F"); } } diff --git a/test/601-verifier-fails/expected.txt b/test/601-verifier-fails/expected.txt deleted file mode 100644 index 8399969a2d..0000000000 --- a/test/601-verifier-fails/expected.txt +++ /dev/null @@ -1,4 +0,0 @@ -passed A -passed B -passed C -passed D diff --git a/test/601-verifier-fails/info.txt b/test/601-verifier-fails/info.txt deleted file mode 100644 index f77de05ac7..0000000000 --- a/test/601-verifier-fails/info.txt +++ /dev/null @@ -1,18 +0,0 @@ -The situations in these tests were discovered by running the mutating -dexfuzz on the DEX files of fuzzingly random generated Java test. - -(A) b/28908555: - soft verification failure (on the final field modification) should - not hide the hard verification failure (on the type mismatch) to - avoid compiler crash later on -(B) b/29070461: - hard verification failure (not calling super in constructor) should - bail immediately and not allow soft verification failures to pile up - behind it to avoid fatal message later on -(C) b/29068831: - access validation should occur prior to null reference check -(D) b/29126870: - soft verification failure (cannot access) should not hide the hard - verification failure (non-reference type) to avoid a compiler crash - later on - diff --git a/test/601-verifier-fails/smali/construct.smali b/test/601-verifier-fails/smali/construct.smali deleted file mode 100644 index 417ced94fa..0000000000 --- a/test/601-verifier-fails/smali/construct.smali +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -.class public LB; -.super Ljava/lang/Object; - -.method public constructor <init>()V - .registers 1 - if-eqz v0, :bail - invoke-direct {v0}, LB;->append(Ljava/lang/String;)V -:bail - return-void -.end method diff --git a/test/613-inlining-dex-cache/expected.txt b/test/613-inlining-dex-cache/expected.txt new file mode 100644 index 0000000000..6a5618ebc6 --- /dev/null +++ b/test/613-inlining-dex-cache/expected.txt @@ -0,0 +1 @@ +JNI_OnLoad called diff --git a/test/613-inlining-dex-cache/info.txt b/test/613-inlining-dex-cache/info.txt new file mode 100644 index 0000000000..e80f642f3e --- /dev/null +++ b/test/613-inlining-dex-cache/info.txt @@ -0,0 +1,2 @@ +Regression test for the JIT compiler which used to +wrongly update the dex cache of a class loader. diff --git a/test/601-verifier-fails/smali/sput.smali b/test/613-inlining-dex-cache/run index e8e56acf13..9c1e7aa95c 100644 --- a/test/601-verifier-fails/smali/sput.smali +++ b/test/613-inlining-dex-cache/run @@ -1,3 +1,4 @@ +#!/bin/bash # # Copyright (C) 2016 The Android Open Source Project # @@ -13,11 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -.class public LA; -.super Ljava/lang/Object; - -.method public foo(I)V -.registers 2 - sput v1, LMain;->staticFinalField:Ljava/lang/String; - return-void -.end method +flags="$@" +# We need the dex files pre-verified to avoid running the verifier +# at runtime which will update the dex cache. +exec ${RUN} ${flags/verify-at-runtime/interpret-only} diff --git a/test/613-inlining-dex-cache/src-ex/B.java b/test/613-inlining-dex-cache/src-ex/B.java new file mode 100644 index 0000000000..4da9a1da6b --- /dev/null +++ b/test/613-inlining-dex-cache/src-ex/B.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class B { +} diff --git a/test/601-verifier-fails/src/Main.java b/test/613-inlining-dex-cache/src-ex/LoadedByAppClassLoader.java index a6a07fda79..f4e0f1019a 100644 --- a/test/601-verifier-fails/src/Main.java +++ b/test/613-inlining-dex-cache/src-ex/LoadedByAppClassLoader.java @@ -14,27 +14,9 @@ * limitations under the License. */ -public class Main { - - public static final String staticFinalField = null; - - private static String staticPrivateField = null; - - private int privateField = 0; - - private static void test(String name) throws Exception { - try { - Class<?> a = Class.forName(name); - a.newInstance(); - } catch (java.lang.LinkageError e) { - System.out.println("passed " + name); - } - } - - public static void main(String[] args) throws Exception { - test("A"); - test("B"); - test("C"); - test("D"); +public class LoadedByAppClassLoader { + public static void letMeInlineYou() { + // We used to pass the wrong class loader when trying to inline 'Main.foo'. + Main.foo(null); } } diff --git a/test/613-inlining-dex-cache/src/B.java b/test/613-inlining-dex-cache/src/B.java new file mode 100644 index 0000000000..6e7e55d430 --- /dev/null +++ b/test/613-inlining-dex-cache/src/B.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class B { + public void foo() { + } +} diff --git a/test/613-inlining-dex-cache/src/Main.java b/test/613-inlining-dex-cache/src/Main.java new file mode 100644 index 0000000000..31ab1d2bfa --- /dev/null +++ b/test/613-inlining-dex-cache/src/Main.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +import dalvik.system.PathClassLoader; + +// ClassLoader not delegating for non java. packages. +class DelegateLastPathClassLoader extends PathClassLoader { + + public DelegateLastPathClassLoader(String dexPath, ClassLoader parent) { + super(dexPath, parent); + } + + @Override + protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + if (!name.startsWith("java.")) { + try { + return findClass(name); + } catch (ClassNotFoundException ignore) { + // Ignore and fall through to parent class loader. + } + } + return super.loadClass(name, resolve); + } +} + +public class Main { + + public static void main(String[] args) throws Exception { + System.loadLibrary(args[0]); + final String DEX_FILE = System.getenv("DEX_LOCATION") + "/613-inlining-dex-cache-ex.jar"; + ClassLoader loader = new DelegateLastPathClassLoader(DEX_FILE, Main.class.getClassLoader()); + Class cls = loader.loadClass("LoadedByAppClassLoader"); + Method m = cls.getDeclaredMethod("letMeInlineYou"); + // Invoke the method enough times to get JITted. + for (int i = 0; i < 10000; ++i) { + m.invoke(null); + } + ensureJitCompiled(cls, "letMeInlineYou"); + ClassLoader bLoader = areYouB(); + if (bLoader != Main.class.getClassLoader()) { + throw new Error("Wrong class loader"); + } + } + + public static void foo(Main o) { + // LoadedByAppClassLoader.letMeInlineYou will try to inline this + // method but used to pass the wrong class loader. As a result, + // the lookup of B.foo was updating the dex cache with the other + // class loader's B class. + if (o != null) { + o.myField.foo(); + } + } + + public B myField; + + public static ClassLoader areYouB() { + return OtherClass.getB().getClassLoader(); + } + + public static native void ensureJitCompiled(Class cls, String method_name); +} + +class OtherClass { + public static Class getB() { + // This used to return the B class of another class loader. + return B.class; + } +} diff --git a/test/614-checker-dump-constant-location/expected.txt b/test/614-checker-dump-constant-location/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/614-checker-dump-constant-location/expected.txt diff --git a/test/614-checker-dump-constant-location/info.txt b/test/614-checker-dump-constant-location/info.txt new file mode 100644 index 0000000000..4a94fface0 --- /dev/null +++ b/test/614-checker-dump-constant-location/info.txt @@ -0,0 +1,2 @@ +Test that the graph visualizer outputs useful information for constant +locations in parallel moves. diff --git a/test/614-checker-dump-constant-location/src/Main.java b/test/614-checker-dump-constant-location/src/Main.java new file mode 100644 index 0000000000..f6bc063d86 --- /dev/null +++ b/test/614-checker-dump-constant-location/src/Main.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + public static int array_int[] = { 0 }; + public static long array_long[] = { 0 }; + public static float array_float[] = { 0.0f }; + public static double array_double[] = { 0.0 }; + + // The code used to print constant locations in parallel moves is architecture + // independent. We only test for ARM and ARM64 as it is easy: 'store' + // instructions only take registers as a source. + + /// CHECK-START-ARM: void Main.store_to_arrays() register (after) + /// CHECK: ParallelMove {{.*#1->.*#2->.*#3\.3->.*#4\.4->.*}} + + /// CHECK-START-ARM64: void Main.store_to_arrays() register (after) + /// CHECK: ParallelMove {{.*#1->.*#2->.*#3\.3->.*#4\.4->.*}} + + public void store_to_arrays() { + array_int[0] = 1; + array_long[0] = 2; + array_float[0] = 3.3f; + array_double[0] = 4.4; + } + + public static void main(String args[]) {} +} diff --git a/test/615-checker-arm64-zr-parallel-move/expected.txt b/test/615-checker-arm64-zr-parallel-move/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/615-checker-arm64-zr-parallel-move/expected.txt diff --git a/test/615-checker-arm64-zr-parallel-move/info.txt b/test/615-checker-arm64-zr-parallel-move/info.txt new file mode 100644 index 0000000000..199755d38d --- /dev/null +++ b/test/615-checker-arm64-zr-parallel-move/info.txt @@ -0,0 +1 @@ +Checker test to verify we correctly use wzr and xzr to synthesize zero constants. diff --git a/test/615-checker-arm64-zr-parallel-move/src/Main.java b/test/615-checker-arm64-zr-parallel-move/src/Main.java new file mode 100644 index 0000000000..5024f2881c --- /dev/null +++ b/test/615-checker-arm64-zr-parallel-move/src/Main.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + public static boolean doThrow = false; + + public void $noinline$foo(int in_w1, + int in_w2, + int in_w3, + int in_w4, + int in_w5, + int in_w6, + int in_w7, + int on_stack_int, + long on_stack_long, + float in_s0, + float in_s1, + float in_s2, + float in_s3, + float in_s4, + float in_s5, + float in_s6, + float in_s7, + float on_stack_float, + double on_stack_double) { + if (doThrow) throw new Error(); + } + + // We expect a parallel move that moves four times the zero constant to stack locations. + /// CHECK-START-ARM64: void Main.bar() register (after) + /// CHECK: ParallelMove {{.*#0->[0-9x]+\(sp\).*#0->[0-9x]+\(sp\).*#0->[0-9x]+\(sp\).*#0->[0-9x]+\(sp\).*}} + + // Those four moves should generate four 'store' instructions using directly the zero register. + /// CHECK-START-ARM64: void Main.bar() disassembly (after) + /// CHECK-DAG: {{(str|stur)}} wzr, [sp, #{{[0-9]+}}] + /// CHECK-DAG: {{(str|stur)}} xzr, [sp, #{{[0-9]+}}] + /// CHECK-DAG: {{(str|stur)}} wzr, [sp, #{{[0-9]+}}] + /// CHECK-DAG: {{(str|stur)}} xzr, [sp, #{{[0-9]+}}] + + public void bar() { + $noinline$foo(1, 2, 3, 4, 5, 6, 7, // Integral values in registers. + 0, 0L, // Integral values on the stack. + 1, 2, 3, 4, 5, 6, 7, 8, // Floating-point values in registers. + 0.0f, 0.0); // Floating-point values on the stack. + } + + public static void main(String args[]) {} +} diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt index 8473e06cf8..3bb372529f 100644 --- a/test/800-smali/expected.txt +++ b/test/800-smali/expected.txt @@ -69,4 +69,5 @@ b/27799205 (6) b/28187158 b/29778499 (1) b/29778499 (2) +b/30458218 Done! diff --git a/test/601-verifier-fails/smali/iput.smali b/test/800-smali/smali/B30458218.smali index bd8b9280c0..67b882a879 100644 --- a/test/601-verifier-fails/smali/iput.smali +++ b/test/800-smali/smali/B30458218.smali @@ -1,11 +1,10 @@ -# # Copyright (C) 2016 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -13,13 +12,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -.class public LC; -.super Ljava/lang/Object; +.class public LB30458218; +.super Ljava/io/InterruptedIOException; -.method public constructor <init>()V +.method public static run()V .registers 2 - invoke-direct {v1}, Ljava/lang/Object;-><init>()V - const v0, 0 - iput-object v0, v0, LMain;->staticPrivateField:Ljava/lang/String; + new-instance v0, LB30458218; + invoke-direct {v0}, LB30458218;-><init>()V + + # IGET used to wrongly cache 'InterruptedIOException' class under the key 'LB30458218;' + iget v1, v0, LB30458218;->bytesTransferred:I + return-void .end method diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java index bf50879541..34f2580dde 100644 --- a/test/800-smali/src/Main.java +++ b/test/800-smali/src/Main.java @@ -180,6 +180,7 @@ public class Main { new IncompatibleClassChangeError(), null)); testCases.add(new TestCase("b/29778499 (2)", "B29778499_2", "run", null, new IncompatibleClassChangeError(), null)); + testCases.add(new TestCase("b/30458218", "B30458218", "run", null, null, null)); } public void runTests() { diff --git a/test/Android.libarttest.mk b/test/Android.libarttest.mk index 7813d16657..ec5b7d23c0 100644 --- a/test/Android.libarttest.mk +++ b/test/Android.libarttest.mk @@ -86,7 +86,7 @@ define build-libarttest LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.libarttest.mk ifeq ($$(art_target_or_host),target) - $(call set-target-local-clang-vars) + LOCAL_CLANG := $(ART_TARGET_CLANG) ifeq ($$(suffix),d) $(call set-target-local-cflags-vars,debug) else @@ -109,7 +109,7 @@ define build-libarttest LOCAL_CFLAGS += $(ART_HOST_NON_DEBUG_CFLAGS) LOCAL_ASFLAGS += $(ART_HOST_NON_DEBUG_ASFLAGS) endif - LOCAL_LDLIBS := $(ART_HOST_LDLIBS) -ldl -lpthread + LOCAL_LDLIBS := -ldl -lpthread LOCAL_IS_HOST_MODULE := true LOCAL_MULTILIB := both include $(BUILD_HOST_SHARED_LIBRARY) diff --git a/test/Android.libnativebridgetest.mk b/test/Android.libnativebridgetest.mk index 992332e922..5c97e4dabb 100644 --- a/test/Android.libnativebridgetest.mk +++ b/test/Android.libnativebridgetest.mk @@ -48,7 +48,7 @@ define build-libnativebridgetest LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.libnativebridgetest.mk ifeq ($$(art_target_or_host),target) - $(call set-target-local-clang-vars) + LOCAL_CLANG := $(ART_TARGET_CLANG) $(call set-target-local-cflags-vars,debug) LOCAL_SHARED_LIBRARIES += libdl LOCAL_STATIC_LIBRARIES := libgtest @@ -62,7 +62,7 @@ define build-libnativebridgetest LOCAL_CFLAGS := $(ART_HOST_CFLAGS) $(ART_HOST_DEBUG_CFLAGS) LOCAL_ASFLAGS := $(ART_HOST_ASFLAGS) $(ART_HOST_DEBUG_ASFLAGS) LOCAL_SHARED_LIBRARIES := libcutils - LOCAL_LDLIBS := $(ART_HOST_LDLIBS) -ldl -lpthread + LOCAL_LDLIBS := -ldl -lpthread ifeq ($(HOST_OS),linux) LOCAL_LDLIBS += -lrt endif diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 8f8b667429..8d7d70dcbe 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -26,7 +26,8 @@ TEST_ART_RUN_TESTS := $(subst $(LOCAL_PATH)/,, $(TEST_ART_RUN_TESTS)) # The path where build only targets will be output, e.g. # out/target/product/generic_x86_64/obj/PACKAGING/art-run-tests_intermediates/DATA -art_run_tests_dir := $(call intermediates-dir-for,PACKAGING,art-run-tests)/DATA +art_run_tests_build_dir := $(call intermediates-dir-for,JAVA_LIBRARIES,art-run-tests)/DATA +art_run_tests_install_dir := $(call intermediates-dir-for,PACKAGING,art-run-tests)/DATA # A generated list of prerequisites that call 'run-test --build-only', the actual prerequisite is # an empty file touched in the intermediate directory. @@ -49,7 +50,8 @@ endif # Helper to create individual build targets for tests. Must be called with $(eval). # $(1): the test number define define-build-art-run-test - dmart_target := $(art_run_tests_dir)/art-run-tests/$(1)/touch + dmart_target := $(art_run_tests_build_dir)/art-run-tests/$(1)/touch + dmart_install_target := $(art_run_tests_install_dir)/art-run-tests/$(1)/touch run_test_options = --build-only ifeq ($(ART_TEST_QUIET),true) run_test_options += --quiet @@ -67,8 +69,13 @@ $$(dmart_target): $(TEST_ART_RUN_TEST_DEPENDENCIES) $(TARGET_JACK_CLASSPATH_DEPE $(LOCAL_PATH)/run-test $$(PRIVATE_RUN_TEST_OPTIONS) --output-path $$(abspath $$(dir $$@)) $(1) $(hide) touch $$@ - TEST_ART_RUN_TEST_BUILD_RULES += $$(dmart_target) +$$(dmart_install_target): $$(dmart_target) + $(hide) rm -rf $$(dir $$@) && mkdir -p $$(dir $$@) + $(hide) cp $$(dir $$<)/* $$(dir $$@)/ + + TEST_ART_RUN_TEST_BUILD_RULES += $$(dmart_install_target) dmart_target := + dmart_install_target := run_test_options := endef $(foreach test, $(TEST_ART_RUN_TESTS), $(eval $(call define-build-art-run-test,$(test)))) @@ -78,12 +85,13 @@ LOCAL_MODULE_TAGS := tests LOCAL_MODULE := art-run-tests LOCAL_ADDITIONAL_DEPENDENCIES := $(TEST_ART_RUN_TEST_BUILD_RULES) # The build system use this flag to pick up files generated by declare-make-art-run-test. -LOCAL_PICKUP_FILES := $(art_run_tests_dir) +LOCAL_PICKUP_FILES := $(art_run_tests_install_dir) include $(BUILD_PHONY_PACKAGE) # Clear temp vars. -art_run_tests_dir := +art_run_tests_build_dir := +art_run_tests_install_dir := define-build-art-run-test := TEST_ART_RUN_TEST_BUILD_RULES := diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc index e70a95cbb5..ee2ee1a36a 100644 --- a/test/common/runtime_state.cc +++ b/test/common/runtime_state.cc @@ -16,6 +16,7 @@ #include "jni.h" +#include "base/enums.h" #include "base/logging.h" #include "dex_file-inl.h" #include "jit/jit.h" @@ -129,18 +130,18 @@ extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env, return; } - ScopedObjectAccess soa(Thread::Current()); + ArtMethod* method = nullptr; + { + ScopedObjectAccess soa(Thread::Current()); - ScopedUtfChars chars(env, method_name); - CHECK(chars.c_str() != nullptr); - - mirror::Class* klass = soa.Decode<mirror::Class*>(cls); - ArtMethod* method = klass->FindDeclaredDirectMethodByName(chars.c_str(), sizeof(void*)); + ScopedUtfChars chars(env, method_name); + CHECK(chars.c_str() != nullptr); + method = soa.Decode<mirror::Class*>(cls)->FindDeclaredDirectMethodByName( + chars.c_str(), kRuntimePointerSize); + } jit::JitCodeCache* code_cache = jit->GetCodeCache(); OatQuickMethodHeader* header = nullptr; - // Make sure there is a profiling info, required by the compiler. - ProfilingInfo::Create(soa.Self(), method, /* retry_allocation */ true); while (true) { header = OatQuickMethodHeader::FromEntryPoint(method->GetEntryPointFromQuickCompiledCode()); if (code_cache->ContainsPc(header->GetCode())) { @@ -148,6 +149,9 @@ extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env, } else { // Sleep to yield to the compiler thread. usleep(1000); + ScopedObjectAccess soa(Thread::Current()); + // Make sure there is a profiling info, required by the compiler. + ProfilingInfo::Create(soa.Self(), method, /* retry_allocation */ true); // Will either ensure it's compiled or do the compilation itself. jit->CompileMethod(method, soa.Self(), /* osr */ false); } diff --git a/test/etc/default-build b/test/etc/default-build index 962ae38041..37ce0f216d 100755 --- a/test/etc/default-build +++ b/test/etc/default-build @@ -64,6 +64,9 @@ DX_FLAGS="" SKIP_DX_MERGER="false" EXPERIMENTAL="" +# The key for default arguments if no experimental things are enabled. +DEFAULT_EXPERIMENT="no-experiment" + # Setup experimental flag mappings in a bash associative array. declare -A JACK_EXPERIMENTAL_ARGS JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" @@ -72,6 +75,11 @@ JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.andro declare -A SMALI_EXPERIMENTAL_ARGS SMALI_EXPERIMENTAL_ARGS["default-methods"]="--api-level 24" +declare -A JAVAC_EXPERIMENTAL_ARGS +JAVAC_EXPERIMENTAL_ARGS["default-methods"]="-source 1.8 -target 1.8" +JAVAC_EXPERIMENTAL_ARGS["lambdas"]="-source 1.8 -target 1.8" +JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.7 -target 1.7" + while true; do if [ "x$1" = "x--dx-option" ]; then shift @@ -100,6 +108,8 @@ while true; do shift elif [ "x$1" = "x--experimental" ]; then shift + # We have a specific experimental configuration so don't use the default. + DEFAULT_EXPERIMENT="" EXPERIMENTAL="${EXPERIMENTAL} $1" shift elif expr "x$1" : "x--" >/dev/null 2>&1; then @@ -110,10 +120,14 @@ while true; do fi done +# Be sure to get any default arguments if not doing any experiments. +EXPERIMENTAL="${EXPERIMENTAL} ${DEFAULT_EXPERIMENT}" + # Add args from the experimental mappings. for experiment in ${EXPERIMENTAL}; do JACK_ARGS="${JACK_ARGS} ${JACK_EXPERIMENTAL_ARGS[${experiment}]}" SMALI_ARGS="${SMALI_ARGS} ${SMALI_EXPERIMENTAL_ARGS[${experiment}]}" + JAVAC_ARGS="${JAVAC_ARGS} ${JAVAC_EXPERIMENTAL_ARGS[${experiment}]}" done if [ -e classes.dex ]; then diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 64bf4f3046..c6c9380412 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -553,12 +553,10 @@ else if [ "$TIME_OUT" = "timeout" ]; then # Add timeout command if time out is desired. # - # Note: We use nested timeouts. The inner timeout sends SIGRTMIN+2 (usually 36) to ART, which - # will induce a full thread dump before abort. However, dumping threads might deadlock, - # so the outer timeout sends the regular SIGTERM after an additional minute to ensure - # termination (without dumping all threads). - TIME_PLUS_ONE=$(($TIME_OUT_VALUE + 60)) - cmdline="timeout ${TIME_PLUS_ONE}s timeout -s SIGRTMIN+2 ${TIME_OUT_VALUE}s $cmdline" + # Note: We first send SIGRTMIN+2 (usually 36) to ART, which will induce a full thread dump + # before abort. However, dumping threads might deadlock, so we also use the "-k" + # option to definitely kill the child. + cmdline="timeout -k 120s -s SIGRTMIN+2 ${TIME_OUT_VALUE}s $cmdline" fi if [ "$DEV_MODE" = "y" ]; then diff --git a/test/run-test b/test/run-test index 1ef5428726..edee4ae31f 100755 --- a/test/run-test +++ b/test/run-test @@ -41,7 +41,7 @@ else fi checker="${progdir}/../tools/checker/checker.py" export JAVA="java" -export JAVAC="javac -g -source 1.7 -target 1.7 -Xlint:-options" +export JAVAC="javac -g -Xlint:-options" export RUN="${progdir}/etc/run-test-jar" export DEX_LOCATION=/data/run-test/${test_dir} export NEED_DEX="true" |