diff options
Diffstat (limited to 'test')
39 files changed, 1258 insertions, 297 deletions
diff --git a/test/021-string2/src/Main.java b/test/021-string2/src/Main.java index 5a43a4f23f..0dd82abf6f 100644 --- a/test/021-string2/src/Main.java +++ b/test/021-string2/src/Main.java @@ -16,6 +16,7 @@ import junit.framework.Assert; import java.lang.reflect.Method; +import java.util.Locale; /** * more string tests @@ -120,6 +121,12 @@ public class Main { testEqualsConstString(); testConstStringEquals(); + + // Regression tests for String.setCharAt() breaking string compression invariants. + Locale en_US = new Locale("en", "US"); + Assert.assertEquals("I", /* Small latin dotless i */ "\u0131".toUpperCase()); + Assert.assertEquals("abc", "a\u0131c".replace('\u0131', 'b')); + Assert.assertEquals("a\u0131c", "abc".replace('b', '\u0131')); } public static void testCompareToAndEquals() { diff --git a/test/155-java-set-resolved-type/src/Main.java b/test/155-java-set-resolved-type/src/Main.java index f92363e915..56b8c3ece9 100644 --- a/test/155-java-set-resolved-type/src/Main.java +++ b/test/155-java-set-resolved-type/src/Main.java @@ -55,11 +55,7 @@ public class Main { Class<?> timpl = Class.forName("TestImplementation", false, mainLoader); // Clear the dex cache resolved types to force a proper lookup the next time // we need to find TestInterface. - // TODO: Enable clearing the dex cache when we switch to the hash-based type array - // and do a proper lookup. Currently, ClassLinker fully relies on the DexCache. - if (false) { - clearResolvedTypes(timpl); - } + clearResolvedTypes(timpl); // Force intialization of TestClass2. This expects the interface type to be // resolved and found through simple lookup. diff --git a/test/551-checker-shifter-operand/src/Main.java b/test/551-checker-shifter-operand/src/Main.java index a4561b83da..e9673987da 100644 --- a/test/551-checker-shifter-operand/src/Main.java +++ b/test/551-checker-shifter-operand/src/Main.java @@ -76,6 +76,25 @@ public class Main { * the shifter operand. */ + /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (before) + /// CHECK-DAG: <<l:j\d+>> ParameterValue + /// CHECK-DAG: <<b:b\d+>> ParameterValue + /// CHECK: <<tmp:j\d+>> TypeConversion [<<b>>] + /// CHECK: Sub [<<l>>,<<tmp>>] + + /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (after) + /// CHECK-DAG: <<l:j\d+>> ParameterValue + /// CHECK-DAG: <<b:b\d+>> ParameterValue + /// CHECK: DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB + + /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (after) + /// CHECK-NOT: TypeConversion + /// CHECK-NOT: Sub + + /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) disassembly (after) + /// CHECK: subs r{{\d+}}, r{{\d+}}, r{{\d+}} + /// CHECK: sbc r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 + /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (before) /// CHECK-DAG: <<l:j\d+>> ParameterValue /// CHECK-DAG: <<b:b\d+>> ParameterValue @@ -85,7 +104,7 @@ public class Main { /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after) /// CHECK-DAG: <<l:j\d+>> ParameterValue /// CHECK-DAG: <<b:b\d+>> ParameterValue - /// CHECK: Arm64DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB + /// CHECK: DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after) /// CHECK-NOT: TypeConversion @@ -106,6 +125,21 @@ public class Main { * inputs are the the IR. */ + /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (before) + /// CHECK: <<a:i\d+>> ParameterValue + /// CHECK: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<tmp:i\d+>> Shl [<<a>>,<<Const2>>] + /// CHECK: Add [<<tmp>>,<<tmp>>] + + /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (after) + /// CHECK-DAG: <<a:i\d+>> ParameterValue + /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 + /// CHECK: <<Shl:i\d+>> Shl [<<a>>,<<Const2>>] + /// CHECK: Add [<<Shl>>,<<Shl>>] + + /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (before) /// CHECK: <<a:i\d+>> ParameterValue /// CHECK: <<Const2:i\d+>> IntConstant 2 @@ -119,7 +153,7 @@ public class Main { /// CHECK: Add [<<Shl>>,<<Shl>>] /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (after) - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp public static int $opt$noinline$sameInput(int a) { if (doThrow) throw new Error(); @@ -131,6 +165,28 @@ public class Main { * Check that we perform the merge for multiple uses. */ + /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (before) + /// CHECK: <<arg:i\d+>> ParameterValue + /// CHECK: <<Const23:i\d+>> IntConstant 23 + /// CHECK: <<tmp:i\d+>> Shl [<<arg>>,<<Const23>>] + /// CHECK: Add [<<tmp>>,{{i\d+}}] + /// CHECK: Add [<<tmp>>,{{i\d+}}] + /// CHECK: Add [<<tmp>>,{{i\d+}}] + /// CHECK: Add [<<tmp>>,{{i\d+}}] + /// CHECK: Add [<<tmp>>,{{i\d+}}] + + /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (after) + /// CHECK: <<arg:i\d+>> ParameterValue + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + + /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (after) + /// CHECK-NOT: Shl + /// CHECK-NOT: Add + /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (before) /// CHECK: <<arg:i\d+>> ParameterValue /// CHECK: <<Const23:i\d+>> IntConstant 23 @@ -143,11 +199,11 @@ public class Main { /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after) /// CHECK: <<arg:i\d+>> ParameterValue - /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 - /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 - /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 - /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 - /// CHECK: Arm64DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 + /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after) /// CHECK-NOT: Shl @@ -171,9 +227,19 @@ public class Main { * operand, so test that only the shifts are merged. */ + /// CHECK-START-ARM: void Main.$opt$noinline$testAnd(long, long) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$noinline$testAnd(long, long) disassembly (after) + /// CHECK: and lsl + /// CHECK: sbfx + /// CHECK: asr + /// CHECK: and + /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) disassembly (after) /// CHECK: and lsl @@ -186,9 +252,18 @@ public class Main { (a & (b << 5)) | (a & (byte)b)); } + /// CHECK-START-ARM: void Main.$opt$noinline$testOr(int, int) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$noinline$testOr(int, int) disassembly (after) + /// CHECK: orr asr + /// CHECK: ubfx + /// CHECK: orr + /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) disassembly (after) /// CHECK: orr asr @@ -201,9 +276,19 @@ public class Main { (a | (b >> 6)) | (a | (char)b)); } + /// CHECK-START-ARM: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$noinline$testXor(long, long) disassembly (after) + /// CHECK: eor lsr + /// CHECK: mov + /// CHECK: asr + /// CHECK: eor + /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) disassembly (after) /// CHECK: eor lsr @@ -216,9 +301,12 @@ public class Main { (a ^ (b >>> 7)) | (a ^ (int)b)); } + /// CHECK-START-ARM: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) disassembly (after) /// CHECK: neg lsl @@ -239,9 +327,12 @@ public class Main { * does occur on the right-hand. */ + /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after) /// CHECK-NOT: TypeConversion @@ -252,9 +343,11 @@ public class Main { assertIntEquals(a + $noinline$byteToShort(b), a + (short)b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm64 (after) - /// CHECK-NOT: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp public static void $opt$validateExtendByteInt2(int a, byte b) { // The conversion to `int` has been optimized away, so there is nothing to merge. @@ -263,13 +356,25 @@ public class Main { assertLongEquals(a + $noinline$byteToLong(b), a + (long)b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm (after) + /// CHECK: TypeConversion + /// CHECK-NOT: TypeConversion + /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after) /// CHECK: TypeConversion @@ -294,9 +399,12 @@ public class Main { $opt$validateExtendByteLong(a, b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after) /// CHECK-NOT: TypeConversion @@ -306,22 +414,41 @@ public class Main { assertIntEquals(a + $noinline$charToShort(b), a + (short)b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm64 (after) - /// CHECK-NOT: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp public static void $opt$validateExtendCharInt2(int a, char b) { // The conversion to `int` has been optimized away, so there is nothing to merge. assertIntEquals (a + $noinline$charToInt (b), a + (int)b); - // There is an environment use for `(long)b`, preventing the merge. + // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge. assertLongEquals(a + $noinline$charToLong(b), a + (long)b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after) + /// CHECK: TypeConversion + /// CHECK: TypeConversion + /// CHECK-NOT: TypeConversion + /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after) /// CHECK: TypeConversion @@ -332,7 +459,7 @@ public class Main { // The first two tests have a type conversion. assertLongEquals(a + $noinline$charToByte (b), a + (byte)b); assertLongEquals(a + $noinline$charToShort(b), a + (short)b); - // This test does not because the conversion to `int` is optimized away. + // On ARM64 this test does not because the conversion to `int` is optimized away. assertLongEquals(a + $noinline$charToInt (b), a + (int)b); } @@ -342,9 +469,12 @@ public class Main { $opt$validateExtendCharLong(a, b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after) /// CHECK-NOT: TypeConversion @@ -354,21 +484,41 @@ public class Main { assertIntEquals(a + $noinline$shortToChar (b), a + (char)b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm (after) + /// CHECK-NOT: DataProcWithShifterOp + /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm64 (after) - /// CHECK-NOT: Arm64DataProcWithShifterOp - /// CHECK-NOT: Arm64DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp public static void $opt$validateExtendShortInt2(int a, short b) { // The conversion to `int` has been optimized away, so there is nothing to merge. assertIntEquals (a + $noinline$shortToInt (b), a + (int)b); - // There is an environment use for `(long)b`, preventing the merge. + // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge. assertLongEquals(a + $noinline$shortToLong (b), a + (long)b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after) + /// CHECK: TypeConversion + /// CHECK: TypeConversion + /// CHECK-NOT: TypeConversion + /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after) /// CHECK: TypeConversion @@ -379,7 +529,7 @@ public class Main { // The first two tests have a type conversion. assertLongEquals(a + $noinline$shortToByte(b), a + (byte)b); assertLongEquals(a + $noinline$shortToChar(b), a + (char)b); - // This test does not because the conversion to `int` is optimized away. + // On ARM64 this test does not because the conversion to `int` is optimized away. assertLongEquals(a + $noinline$shortToInt (b), a + (int)b); } @@ -389,11 +539,31 @@ public class Main { $opt$validateExtendShortLong(a, b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after) + /// CHECK: TypeConversion + /// CHECK: TypeConversion + /// CHECK: TypeConversion + /// CHECK-NOT: TypeConversion + /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after) /// CHECK: TypeConversion @@ -411,11 +581,34 @@ public class Main { assertLongEquals(a + $noinline$intToLong (b), a + (long)b); } + /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after) + /// CHECK: TypeConversion + /// CHECK: TypeConversion + /// CHECK: TypeConversion + /// CHECK: TypeConversion + /// CHECK-NOT: TypeConversion + /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after) /// CHECK: TypeConversion @@ -449,40 +642,83 @@ public class Main { // Each test line below should see one merge. + /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier. + + /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after) + /// CHECK-NOT: Shl + /// CHECK-NOT: Shr + /// CHECK-NOT: UShr + /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier. /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after) @@ -552,43 +788,89 @@ public class Main { } // Each test line below should see one merge. + /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after) + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp + + // On ARM shifts by 1 are not merged. + /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after) + /// CHECK: Shl + /// CHECK-NOT: Shl + /// CHECK: Shr + /// CHECK-NOT: Shr + /// CHECK: UShr + /// CHECK-NOT: UShr + /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after) - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp - /// CHECK: Arm64DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK: DataProcWithShifterOp + /// CHECK-NOT: DataProcWithShifterOp /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after) /// CHECK-NOT: Shl diff --git a/test/593-checker-shift-and-simplifier/src/Main.java b/test/593-checker-shift-and-simplifier/src/Main.java index 65e809a30e..c9826bc546 100644 --- a/test/593-checker-shift-and-simplifier/src/Main.java +++ b/test/593-checker-shift-and-simplifier/src/Main.java @@ -21,6 +21,17 @@ public class Main { // A very particular set of operations that caused a double removal by the // ARM64 simplifier doing "forward" removals (b/27851582). + /// CHECK-START-ARM: int Main.operations() instruction_simplifier_arm (before) + /// CHECK-DAG: <<Get:i\d+>> ArrayGet + /// CHECK-DAG: <<Not:i\d+>> Not [<<Get>>] + /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Get>>,i{{\d+}}] + /// CHECK-DAG: And [<<Not>>,<<Shl>>] + // + /// CHECK-START-ARM: int Main.operations() instruction_simplifier_arm (after) + /// CHECK-DAG: <<Get:i\d+>> ArrayGet + /// CHECK-DAG: <<Not:i\d+>> Not [<<Get>>] + /// CHECK-DAG: DataProcWithShifterOp [<<Not>>,<<Get>>] kind:And+LSL shift:2 + /// CHECK-START-ARM64: int Main.operations() instruction_simplifier_arm64 (before) /// CHECK-DAG: <<Get:i\d+>> ArrayGet /// CHECK-DAG: <<Not:i\d+>> Not [<<Get>>] @@ -30,7 +41,7 @@ public class Main { /// CHECK-START-ARM64: int Main.operations() instruction_simplifier_arm64 (after) /// CHECK-DAG: <<Get:i\d+>> ArrayGet /// CHECK-DAG: <<Not:i\d+>> Not [<<Get>>] - /// CHECK-DAG: Arm64DataProcWithShifterOp [<<Not>>,<<Get>>] kind:And+LSL shift:2 + /// CHECK-DAG: DataProcWithShifterOp [<<Not>>,<<Get>>] kind:And+LSL shift:2 private static int operations() { int r = a[0]; int n = ~r; diff --git a/test/624-checker-stringops/src/Main.java b/test/624-checker-stringops/src/Main.java index 75b782e8c0..63da4f5560 100644 --- a/test/624-checker-stringops/src/Main.java +++ b/test/624-checker-stringops/src/Main.java @@ -232,8 +232,9 @@ public class Main { /// CHECK-NOT: InvokeVirtual intrinsic:StringStringIndexOfAfter static int bufferDeadLoop() { StringBuffer b = new StringBuffer(); + String x = "x"; for (int i = 0; i < 10; i++) { - int d = b.toString().indexOf("x", 1); + int d = b.toString().indexOf(x, 1); } return b.length(); } @@ -252,8 +253,9 @@ public class Main { /// CHECK-NOT: InvokeVirtual intrinsic:StringStringIndexOfAfter static int builderDeadLoop() { StringBuilder b = new StringBuilder(); + String x = "x"; for (int i = 0; i < 10; i++) { - int d = b.toString().indexOf("x", 1); + int d = b.toString().indexOf(x, 1); } return b.length(); } diff --git a/test/626-const-class-linking/clear_dex_cache_types.cc b/test/626-const-class-linking/clear_dex_cache_types.cc index b35dff48ee..e1af02edfd 100644 --- a/test/626-const-class-linking/clear_dex_cache_types.cc +++ b/test/626-const-class-linking/clear_dex_cache_types.cc @@ -27,7 +27,8 @@ extern "C" JNIEXPORT void JNICALL Java_Main_nativeClearResolvedTypes(JNIEnv*, jc ScopedObjectAccess soa(Thread::Current()); mirror::DexCache* dex_cache = soa.Decode<mirror::Class>(cls)->GetDexCache(); for (size_t i = 0, num_types = dex_cache->NumResolvedTypes(); i != num_types; ++i) { - dex_cache->SetResolvedType(dex::TypeIndex(i), ObjPtr<mirror::Class>(nullptr)); + mirror::TypeDexCachePair cleared(nullptr, mirror::TypeDexCachePair::InvalidIndexForSlot(i)); + dex_cache->GetResolvedTypes()[i].store(cleared, std::memory_order_relaxed); } } diff --git a/test/638-no-line-number/build b/test/638-no-line-number/build new file mode 100644 index 0000000000..7eaf50e938 --- /dev/null +++ b/test/638-no-line-number/build @@ -0,0 +1,25 @@ +#!/bin/bash +# +# Copyright (C) 2017 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. + +# Stop if something fails. +set -e + +mkdir classes +# Only keep the source name, to make sure we do remove it in the stack trace +# when there is no line number mapping. +${JAVAC} -g:source -source 7 -target 7 -d classes `find src -name '*.java'` +${DX} --dex --output=classes.dex classes +zip $TEST_NAME.jar classes.dex diff --git a/test/638-no-line-number/expected.txt b/test/638-no-line-number/expected.txt new file mode 100644 index 0000000000..ffde15312b --- /dev/null +++ b/test/638-no-line-number/expected.txt @@ -0,0 +1,5 @@ +java.lang.Error + at Main.main(Unknown Source:2) +java.lang.NullPointerException: throw with null exception + at Main.doThrow(Unknown Source:0) + at Main.main(Unknown Source:9) diff --git a/test/638-no-line-number/info.txt b/test/638-no-line-number/info.txt new file mode 100644 index 0000000000..89e6432e66 --- /dev/null +++ b/test/638-no-line-number/info.txt @@ -0,0 +1 @@ +Test for b/30183883, that we emit the dex pc when the line number is missing. diff --git a/test/638-no-line-number/src/Main.java b/test/638-no-line-number/src/Main.java new file mode 100644 index 0000000000..7fe0404204 --- /dev/null +++ b/test/638-no-line-number/src/Main.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 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 void main(String[] args) { + try { + doThrow(new Error()); + } catch (Error e) { + e.printStackTrace(); + } + try { + doThrow(null); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static void doThrow(Error e) { + throw e; + } +} diff --git a/test/909-attach-agent/attach.cc b/test/909-attach-agent/attach.cc index 2b50eb83b4..adae844ef0 100644 --- a/test/909-attach-agent/attach.cc +++ b/test/909-attach-agent/attach.cc @@ -28,7 +28,7 @@ namespace Test909AttachAgent { jint OnAttach(JavaVM* vm, char* options ATTRIBUTE_UNUSED, void* reserved ATTRIBUTE_UNUSED) { - printf("Attached Agent for test 909-attach-agent\n"); + fprintf(stderr, "Attached Agent for test 909-attach-agent\n"); fsync(1); jvmtiEnv* env = nullptr; jvmtiEnv* env2 = nullptr; @@ -36,7 +36,7 @@ jint OnAttach(JavaVM* vm, #define CHECK_CALL_SUCCESS(c) \ do { \ if ((c) != JNI_OK) { \ - printf("call " #c " did not succeed\n"); \ + fprintf(stderr, "call " #c " did not succeed\n"); \ return -1; \ } \ } while (false) @@ -44,7 +44,7 @@ jint OnAttach(JavaVM* vm, CHECK_CALL_SUCCESS(vm->GetEnv(reinterpret_cast<void**>(&env), JVMTI_VERSION_1_0)); CHECK_CALL_SUCCESS(vm->GetEnv(reinterpret_cast<void**>(&env2), JVMTI_VERSION_1_0)); if (env == env2) { - printf("GetEnv returned same environment twice!\n"); + fprintf(stderr, "GetEnv returned same environment twice!\n"); return -1; } unsigned char* local_data = nullptr; @@ -54,19 +54,19 @@ jint OnAttach(JavaVM* vm, unsigned char* get_data = nullptr; CHECK_CALL_SUCCESS(env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&get_data))); if (get_data != local_data) { - printf("Got different data from local storage then what was set!\n"); + fprintf(stderr, "Got different data from local storage then what was set!\n"); return -1; } CHECK_CALL_SUCCESS(env2->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&get_data))); if (get_data != nullptr) { - printf("env2 did not have nullptr local storage.\n"); + fprintf(stderr, "env2 did not have nullptr local storage.\n"); return -1; } CHECK_CALL_SUCCESS(env->Deallocate(local_data)); jint version = 0; CHECK_CALL_SUCCESS(env->GetVersionNumber(&version)); if ((version & JVMTI_VERSION_1) != JVMTI_VERSION_1) { - printf("Unexpected version number!\n"); + fprintf(stderr, "Unexpected version number!\n"); return -1; } CHECK_CALL_SUCCESS(env->DisposeEnvironment()); diff --git a/test/910-methods/expected.txt b/test/910-methods/expected.txt index c913b3ffe5..e87929f00c 100644 --- a/test/910-methods/expected.txt +++ b/test/910-methods/expected.txt @@ -28,7 +28,7 @@ Location end: JVMTI_ERROR_NATIVE_METHOD Is native: true Is obsolete: false Is synthetic: false -[add, (Ljava/lang/Object;)Z, null] +[add, (Ljava/lang/Object;)Z, (TE;)Z] interface java.util.List 1025 Max locals: 0 diff --git a/test/912-classes/expected.txt b/test/912-classes/expected.txt index 328216b324..e932b206c0 100644 --- a/test/912-classes/expected.txt +++ b/test/912-classes/expected.txt @@ -1,10 +1,10 @@ [Ljava/lang/Object;, null] 1 -[Ljava/lang/String;, null] +[Ljava/lang/String;, Ljava/lang/Object;Ljava/io/Serializable;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/lang/CharSequence;] 11 [Ljava/lang/Math;, null] 11 -[Ljava/util/List;, null] +[Ljava/util/List;, <E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;] 601 [L$Proxy0;, null] 11 diff --git a/test/918-fields/expected.txt b/test/918-fields/expected.txt index 39d3e70550..1a1209c34c 100644 --- a/test/918-fields/expected.txt +++ b/test/918-fields/expected.txt @@ -14,3 +14,7 @@ true interface Main$Bar 25 false +[generics, Ljava/lang/Object;, TT;] +class Main$Generics +0 +false diff --git a/test/918-fields/src/Main.java b/test/918-fields/src/Main.java index 3ba535b31b..ad0d0c5dc2 100644 --- a/test/918-fields/src/Main.java +++ b/test/918-fields/src/Main.java @@ -27,6 +27,7 @@ public class Main { testField(Integer.class, "value"); testField(Foo.class, "this$0"); testField(Bar.class, "VAL"); + testField(Generics.class, "generics"); } private static void testField(Class<?> base, String fieldName) @@ -65,4 +66,8 @@ public class Main { private static interface Bar { public static int VAL = 1; } + + private static class Generics<T> { + T generics; + } } diff --git a/test/948-change-annotations/build b/test/948-change-annotations/build new file mode 100755 index 0000000000..898e2e54a2 --- /dev/null +++ b/test/948-change-annotations/build @@ -0,0 +1,17 @@ +#!/bin/bash +# +# Copyright 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. + +./default-build "$@" --experimental agents diff --git a/test/948-change-annotations/expected.txt b/test/948-change-annotations/expected.txt new file mode 100644 index 0000000000..7974c7a694 --- /dev/null +++ b/test/948-change-annotations/expected.txt @@ -0,0 +1,21 @@ +Running test class RemoveAnnotationsTest +Type annotations: [@TestClassAnnotation1(value=hello)] +method public void Transform.sayHi() -> [@TestMethodAnnotation1(value=hi hi)] +hello +Goodbye +Type annotations: [] +method public void Transform.sayHi() -> [] +Running test class AddAnnotationsTest +Type annotations: [@TestClassAnnotation1(value=hello)] +method public void Transform.sayHi() -> [@TestMethodAnnotation1(value=hi hi)] +hello +Goodbye +Type annotations: [@TestClassAnnotation1(value=hello), @TestClassAnnotation2(value=hello2)] +method public void Transform.sayHi() -> [@TestMethodAnnotation1(value=hi hi), @TestMethodAnnotation2(value=hi hi2)] +Running test class ChangeAnnotationValues +Type annotations: [@TestClassAnnotation1(value=hello)] +method public void Transform.sayHi() -> [@TestMethodAnnotation1(value=hi hi)] +hello +Goodbye +Type annotations: [@TestClassAnnotation1(value=Goodbye)] +method public void Transform.sayHi() -> [@TestMethodAnnotation1(value=Bye Bye)] diff --git a/test/948-change-annotations/info.txt b/test/948-change-annotations/info.txt new file mode 100644 index 0000000000..875a5f6ec1 --- /dev/null +++ b/test/948-change-annotations/info.txt @@ -0,0 +1 @@ +Tests basic functions in the jvmti plugin. diff --git a/test/948-change-annotations/run b/test/948-change-annotations/run new file mode 100755 index 0000000000..c6e62ae6cd --- /dev/null +++ b/test/948-change-annotations/run @@ -0,0 +1,17 @@ +#!/bin/bash +# +# Copyright 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. + +./default-run "$@" --jvmti diff --git a/test/948-change-annotations/src/AddAnnotationsTest.java b/test/948-change-annotations/src/AddAnnotationsTest.java new file mode 100644 index 0000000000..6876e8736e --- /dev/null +++ b/test/948-change-annotations/src/AddAnnotationsTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 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.util.Base64; +public class AddAnnotationsTest implements TestCase { + /** + * base64 encoded class/dex file for + * @TestClassAnnotation1("hello") + * @TestClassAnnotation2("hello2") + * class Transform { + * @TestMethodAnnotation1("hi hi") + * @TestMethodAnnotation2("hi hi2") + * public void sayHi() { + * System.out.println("Goodbye"); + * } + * } + */ + private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAKQoABgAbCQAcAB0IAB4KAB8AIAcAIQcAIgEABjxpbml0PgEAAygpVgEABENvZGUB" + + "AA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQALTFRyYW5zZm9y" + + "bTsBAAVzYXlIaQEAGVJ1bnRpbWVWaXNpYmxlQW5ub3RhdGlvbnMBABdMVGVzdE1ldGhvZEFubm90" + + "YXRpb24xOwEABXZhbHVlAQAFaGkgaGkBABdMVGVzdE1ldGhvZEFubm90YXRpb24yOwEABmhpIGhp" + + "MgEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQEAFkxUZXN0Q2xhc3NBbm5vdGF0aW9uMTsB" + + "AAVoZWxsbwEAFkxUZXN0Q2xhc3NBbm5vdGF0aW9uMjsBAAZoZWxsbzIMAAcACAcAIwwAJAAlAQAH" + + "R29vZGJ5ZQcAJgwAJwAoAQAJVHJhbnNmb3JtAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFu" + + "Zy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3Ry" + + "ZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgAgAAUABgAAAAAAAgAAAAcACAAB" + + "AAkAAAAvAAEAAQAAAAUqtwABsQAAAAIACgAAAAYAAQAAABMACwAAAAwAAQAAAAUADAANAAAAAQAO" + + "AAgAAgAJAAAANwACAAEAAAAJsgACEgO2AASxAAAAAgAKAAAACgACAAAAFwAIABgACwAAAAwAAQAA" + + "AAkADAANAAAADwAAABQAAgAQAAEAEXMAEgATAAEAEXMAFAACABUAAAACABYADwAAABQAAgAXAAEA" + + "EXMAGAAZAAEAEXMAGg=="); + private static final byte[] DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQA7mPKPjUKe43s+OLHHgFVRVCAPn/rRz9z0AwAAcAAAAHhWNBIAAAAAAAAAADADAAAX" + + "AAAAcAAAAAoAAADMAAAAAgAAAPQAAAABAAAADAEAAAQAAAAUAQAAAQAAADQBAACgAgAAVAEAAMYB" + + "AADOAQAA1wEAAO8BAAAHAgAAIAIAADkCAABGAgAAXQIAAHECAACFAgAAmQIAAKkCAACsAgAAsAIA" + + "AMQCAADLAgAA0wIAANoCAADiAgAA5wIAAPACAAD3AgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAA" + + "CAAAAAkAAAAKAAAADAAAAAwAAAAJAAAAAAAAAA0AAAAJAAAAwAEAAAgABQATAAAABAAAAAAAAAAE" + + "AAAAFQAAAAUAAQAUAAAABgAAAAAAAAAEAAAAAAAAAAYAAAAAAAAACwAAAKgBAAAhAwAAAAAAAAIA" + + "AAAJAwAADwMAAAIAAAAVAwAAGwMAAAEAAQABAAAA/gIAAAQAAABwEAMAAAAOAAMAAQACAAAAAwMA" + + "AAkAAABiAAAAGwEBAAAAbiACABAADgAAAFQBAAAAAAAAAQAAAAAAAAABAAAAYAEAAAEAAAAHAAY8" + + "aW5pdD4AB0dvb2RieWUAFkxUZXN0Q2xhc3NBbm5vdGF0aW9uMTsAFkxUZXN0Q2xhc3NBbm5vdGF0" + + "aW9uMjsAF0xUZXN0TWV0aG9kQW5ub3RhdGlvbjE7ABdMVGVzdE1ldGhvZEFubm90YXRpb24yOwAL" + + "TFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJM" + + "amF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYA" + + "AlZMABJlbWl0dGVyOiBqYWNrLTQuMjUABWhlbGxvAAZoZWxsbzIABWhpIGhpAAZoaSBoaTIAA291" + + "dAAHcHJpbnRsbgAFc2F5SGkABXZhbHVlABMABw4AFwAHDocAAQABFhcPAQEBFhcQAQIBFhcRAQMB" + + "FhcSAAABAQCAgATsAgEBhAMAEAAAAAAAAAABAAAAAAAAAAEAAAAXAAAAcAAAAAIAAAAKAAAAzAAA" + + "AAMAAAACAAAA9AAAAAQAAAABAAAADAEAAAUAAAAEAAAAFAEAAAYAAAABAAAANAEAAAMQAAACAAAA" + + "VAEAAAEgAAACAAAAbAEAAAYgAAABAAAAqAEAAAEQAAABAAAAwAEAAAIgAAAXAAAAxgEAAAMgAAAC" + + "AAAA/gIAAAQgAAAEAAAACQMAAAAgAAABAAAAIQMAAAAQAAABAAAAMAMAAA=="); + + public void runTest(Transform t) { + t.sayHi(); + Main.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); + t.sayHi(); + } +} diff --git a/test/948-change-annotations/src/ChangeAnnotationValues.java b/test/948-change-annotations/src/ChangeAnnotationValues.java new file mode 100644 index 0000000000..89a766cdeb --- /dev/null +++ b/test/948-change-annotations/src/ChangeAnnotationValues.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 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.util.Base64; +public class ChangeAnnotationValues implements TestCase { + /** + * base64 encoded class/dex file for + * @TestClassAnnotation1("Goodbye") + * class Transform { + * @TestMethodAnnotation1("Bye Bye") + * public void sayHi() { + * System.out.println("Goodbye"); + * } + * } + */ + private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAJAoABgAXCQAYABkIABYKABoAGwcAHAcAHQEABjxpbml0PgEAAygpVgEABENvZGUB" + + "AA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQALTFRyYW5zZm9y" + + "bTsBAAVzYXlIaQEAGVJ1bnRpbWVWaXNpYmxlQW5ub3RhdGlvbnMBABdMVGVzdE1ldGhvZEFubm90" + + "YXRpb24xOwEABXZhbHVlAQAHQnllIEJ5ZQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQEA" + + "FkxUZXN0Q2xhc3NBbm5vdGF0aW9uMTsBAAdHb29kYnllDAAHAAgHAB4MAB8AIAcAIQwAIgAjAQAJ" + + "VHJhbnNmb3JtAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVM" + + "amF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShM" + + "amF2YS9sYW5nL1N0cmluZzspVgAgAAUABgAAAAAAAgAAAAcACAABAAkAAAAvAAEAAQAAAAUqtwAB" + + "sQAAAAIACgAAAAYAAQAAAAIACwAAAAwAAQAAAAUADAANAAAAAQAOAAgAAgAJAAAANwACAAEAAAAJ" + + "sgACEgO2AASxAAAAAgAKAAAACgACAAAABQAIAAYACwAAAAwAAQAAAAkADAANAAAADwAAAAsAAQAQ" + + "AAEAEXMAEgACABMAAAACABQADwAAAAsAAQAVAAEAEXMAFg=="); + private static final byte[] DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQAXfYs9FUE830lxfnB+X66S7iZiP5A7uDSAAwAAcAAAAHhWNBIAAAAAAAAAALwCAAAS" + + "AAAAcAAAAAgAAAC4AAAAAgAAANgAAAABAAAA8AAAAAQAAAD4AAAAAQAAABgBAABIAgAAOAEAAKIB" + + "AACqAQAAswEAALwBAADUAQAA7QEAAPoBAAARAgAAJQIAADkCAABNAgAAXQIAAGACAABkAgAAeAIA" + + "AH0CAACGAgAAjQIAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAALAAAACwAAAAcAAAAAAAAA" + + "DAAAAAcAAACcAQAABgADAA4AAAACAAAAAAAAAAIAAAAQAAAAAwABAA8AAAAEAAAAAAAAAAIAAAAA" + + "AAAABAAAAAAAAAAKAAAAhAEAAKsCAAAAAAAAAQAAAJ8CAAABAAAApQIAAAEAAQABAAAAlAIAAAQA" + + "AABwEAMAAAAOAAMAAQACAAAAmQIAAAkAAABiAAAAGwECAAAAbiACABAADgAAADgBAAAAAAAAAQAA" + + "AAAAAAABAAAAQAEAAAEAAAAFAAY8aW5pdD4AB0J5ZSBCeWUAB0dvb2RieWUAFkxUZXN0Q2xhc3NB" + + "bm5vdGF0aW9uMTsAF0xUZXN0TWV0aG9kQW5ub3RhdGlvbjE7AAtMVHJhbnNmb3JtOwAVTGphdmEv" + + "aW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAS" + + "TGphdmEvbGFuZy9TeXN0ZW07AA5UcmFuc2Zvcm0uamF2YQABVgACVkwAEmVtaXR0ZXI6IGphY2st" + + "NC4yNQADb3V0AAdwcmludGxuAAVzYXlIaQAFdmFsdWUAAgAHDgAFAAcOhwABAAERFwIBAQERFwEA" + + "AAEBAICABMgCAQHgAgAAABAAAAAAAAAAAQAAAAAAAAABAAAAEgAAAHAAAAACAAAACAAAALgAAAAD" + + "AAAAAgAAANgAAAAEAAAAAQAAAPAAAAAFAAAABAAAAPgAAAAGAAAAAQAAABgBAAADEAAAAgAAADgB" + + "AAABIAAAAgAAAEgBAAAGIAAAAQAAAIQBAAABEAAAAQAAAJwBAAACIAAAEgAAAKIBAAADIAAAAgAA" + + "AJQCAAAEIAAAAgAAAJ8CAAAAIAAAAQAAAKsCAAAAEAAAAQAAALwCAAA="); + + public void runTest(Transform t) { + t.sayHi(); + Main.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); + t.sayHi(); + } +} diff --git a/test/948-change-annotations/src/Main.java b/test/948-change-annotations/src/Main.java new file mode 100644 index 0000000000..30bfbf9fc6 --- /dev/null +++ b/test/948-change-annotations/src/Main.java @@ -0,0 +1,90 @@ +/* + * 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.util.Arrays; +import java.util.Base64; +import java.util.Comparator; +import java.lang.reflect.*; +import java.lang.annotation.*; +public class Main { + + /** + * base64 encoded class/dex file for for initial Transform.java + */ + private static final byte[] INITIAL_CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAJAoABgAXCQAYABkIABYKABoAGwcAHAcAHQEABjxpbml0PgEAAygpVgEABENvZGUB" + + "AA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQALTFRyYW5zZm9y" + + "bTsBAAVzYXlIaQEAGVJ1bnRpbWVWaXNpYmxlQW5ub3RhdGlvbnMBABdMVGVzdE1ldGhvZEFubm90" + + "YXRpb24xOwEABXZhbHVlAQAFaGkgaGkBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEBABZM" + + "VGVzdENsYXNzQW5ub3RhdGlvbjE7AQAFaGVsbG8MAAcACAcAHgwAHwAgBwAhDAAiACMBAAlUcmFu" + + "c2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZh" + + "L2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZh" + + "L2xhbmcvU3RyaW5nOylWACAABQAGAAAAAAACAAAABwAIAAEACQAAAC8AAQABAAAABSq3AAGxAAAA" + + "AgAKAAAABgABAAAAEgALAAAADAABAAAABQAMAA0AAAABAA4ACAACAAkAAAA3AAIAAQAAAAmyAAIS" + + "A7YABLEAAAACAAoAAAAKAAIAAAAVAAgAFgALAAAADAABAAAACQAMAA0AAAAPAAAACwABABAAAQAR" + + "cwASAAIAEwAAAAIAFAAPAAAACwABABUAAQARcwAW"); + private static final byte[] INITIAL_DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQCufKz9atC18kWgSsEfRq699UEcX4cHonN8AwAAcAAAAHhWNBIAAAAAAAAAALgCAAAS" + + "AAAAcAAAAAgAAAC4AAAAAgAAANgAAAABAAAA8AAAAAQAAAD4AAAAAQAAABgBAABEAgAAOAEAAKIB" + + "AACqAQAAwgEAANsBAADoAQAA/wEAABMCAAAnAgAAOwIAAEsCAABOAgAAUgIAAGYCAABtAgAAdAIA" + + "AHkCAACCAgAAiQIAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAJAAAACQAAAAcAAAAAAAAA" + + "CgAAAAcAAACcAQAABgADAA4AAAACAAAAAAAAAAIAAAAQAAAAAwABAA8AAAAEAAAAAAAAAAIAAAAA" + + "AAAABAAAAAAAAAAIAAAAhAEAAKcCAAAAAAAAAQAAAJsCAAABAAAAoQIAAAEAAQABAAAAkAIAAAQA" + + "AABwEAMAAAAOAAMAAQACAAAAlQIAAAkAAABiAAAAGwEMAAAAbiACABAADgAAADgBAAAAAAAAAQAA" + + "AAAAAAABAAAAQAEAAAEAAAAFAAY8aW5pdD4AFkxUZXN0Q2xhc3NBbm5vdGF0aW9uMTsAF0xUZXN0" + + "TWV0aG9kQW5ub3RhdGlvbjE7AAtMVHJhbnNmb3JtOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJM" + + "amF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07" + + "AA5UcmFuc2Zvcm0uamF2YQABVgACVkwAEmVtaXR0ZXI6IGphY2stNC4yNQAFaGVsbG8ABWhpIGhp" + + "AANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQASAAcOABUABw6HAAEAAREXDAEBAREXDQAAAQEA" + + "gIAEyAIBAeACAAAAEAAAAAAAAAABAAAAAAAAAAEAAAASAAAAcAAAAAIAAAAIAAAAuAAAAAMAAAAC" + + "AAAA2AAAAAQAAAABAAAA8AAAAAUAAAAEAAAA+AAAAAYAAAABAAAAGAEAAAMQAAACAAAAOAEAAAEg" + + "AAACAAAASAEAAAYgAAABAAAAhAEAAAEQAAABAAAAnAEAAAIgAAASAAAAogEAAAMgAAACAAAAkAIA" + + "AAQgAAACAAAAmwIAAAAgAAABAAAApwIAAAAQAAABAAAAuAIAAA=="); + + public static void main(String[] args) { + doTest(new RemoveAnnotationsTest()); + doTest(new AddAnnotationsTest()); + doTest(new ChangeAnnotationValues()); + } + + private static Annotation[] sortedAnno(Annotation[] annos) { + Arrays.sort(annos, Comparator.comparing((v) -> v.toString())); + return annos; + } + + public static void doTest(TestCase t) { + // Get back to normal first. + doCommonClassRedefinition(Transform.class, INITIAL_CLASS_BYTES, INITIAL_DEX_BYTES); + System.out.println("Running test " + t.getClass()); + printAnnotations(Transform.class); + t.runTest(new Transform()); + printAnnotations(Transform.class); + } + + private static void printAnnotations(Class<?> transform) { + System.out.println("Type annotations: " + + Arrays.toString(sortedAnno(transform.getAnnotations()))); + for (Method m : transform.getDeclaredMethods()) { + System.out.println("method " + m + " -> " + + Arrays.toString(sortedAnno(m.getDeclaredAnnotations()))); + } + } + + // Transforms the class + public static native void doCommonClassRedefinition(Class<?> target, + byte[] class_file, + byte[] dex_file); +} diff --git a/test/948-change-annotations/src/RemoveAnnotationsTest.java b/test/948-change-annotations/src/RemoveAnnotationsTest.java new file mode 100644 index 0000000000..3b1725a67e --- /dev/null +++ b/test/948-change-annotations/src/RemoveAnnotationsTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017 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.util.Base64; +public class RemoveAnnotationsTest implements TestCase { + /** + * base64 encoded class/dex file for + * class Transform { + * public void sayHi() { + * System.out.println("Goodbye"); + * } + * } + */ + private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" + + "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" + + "BwAIBwAWDAAXABgBAAdHb29kYnllBwAZDAAaABsBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2Jq" + + "ZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2ph" + + "dmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABQAG" + + "AAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAEQABAAsACAAB" + + "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAATAAgAFAABAAwAAAACAA0="); + private static final byte[] DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" + + "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" + + "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" + + "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" + + "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" + + "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" + + "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" + + "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" + + "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" + + "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" + + "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" + + "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" + + "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA="); + + public void runTest(Transform t) { + t.sayHi(); + Main.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); + t.sayHi(); + } +} diff --git a/test/948-change-annotations/src/TestCase.java b/test/948-change-annotations/src/TestCase.java new file mode 100644 index 0000000000..9edc01e4f9 --- /dev/null +++ b/test/948-change-annotations/src/TestCase.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 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 interface TestCase { + public void runTest(Transform t); +} diff --git a/test/948-change-annotations/src/TestClassAnnotation1.java b/test/948-change-annotations/src/TestClassAnnotation1.java new file mode 100644 index 0000000000..adef98f5d4 --- /dev/null +++ b/test/948-change-annotations/src/TestClassAnnotation1.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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.annotation.*; +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @ interface TestClassAnnotation1 { + public String value(); +} diff --git a/test/948-change-annotations/src/TestClassAnnotation2.java b/test/948-change-annotations/src/TestClassAnnotation2.java new file mode 100644 index 0000000000..67e6260459 --- /dev/null +++ b/test/948-change-annotations/src/TestClassAnnotation2.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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.annotation.*; +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @ interface TestClassAnnotation2 { + public String value(); +} diff --git a/test/948-change-annotations/src/TestMethodAnnotation1.java b/test/948-change-annotations/src/TestMethodAnnotation1.java new file mode 100644 index 0000000000..d3920f3976 --- /dev/null +++ b/test/948-change-annotations/src/TestMethodAnnotation1.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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.annotation.*; +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @ interface TestMethodAnnotation1 { + public String value(); +} diff --git a/test/948-change-annotations/src/TestMethodAnnotation2.java b/test/948-change-annotations/src/TestMethodAnnotation2.java new file mode 100644 index 0000000000..2d5bb728a4 --- /dev/null +++ b/test/948-change-annotations/src/TestMethodAnnotation2.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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.annotation.*; +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @ interface TestMethodAnnotation2 { + public String value(); +} diff --git a/test/948-change-annotations/src/Transform.java b/test/948-change-annotations/src/Transform.java new file mode 100644 index 0000000000..1c6a145da4 --- /dev/null +++ b/test/948-change-annotations/src/Transform.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +@TestClassAnnotation1("hello") +class Transform { + @TestMethodAnnotation1("hi hi") + public void sayHi() { + System.out.println("hello"); + } +} diff --git a/test/949-in-memory-transform/expected.txt b/test/949-in-memory-transform/expected.txt new file mode 100644 index 0000000000..4774b81b49 --- /dev/null +++ b/test/949-in-memory-transform/expected.txt @@ -0,0 +1,2 @@ +hello +Goodbye diff --git a/test/949-in-memory-transform/info.txt b/test/949-in-memory-transform/info.txt new file mode 100644 index 0000000000..7753729dc7 --- /dev/null +++ b/test/949-in-memory-transform/info.txt @@ -0,0 +1,4 @@ +Tests basic functions in the jvmti plugin. + +Tests that transformation works even when the class being transformed comes from +an in-memory dex file (i.e. loaded from an InMemoryDexClassLoader). diff --git a/test/949-in-memory-transform/run b/test/949-in-memory-transform/run new file mode 100755 index 0000000000..e92b873956 --- /dev/null +++ b/test/949-in-memory-transform/run @@ -0,0 +1,17 @@ +#!/bin/bash +# +# Copyright 2017 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. + +./default-run "$@" --jvmti diff --git a/test/949-in-memory-transform/src/Main.java b/test/949-in-memory-transform/src/Main.java new file mode 100644 index 0000000000..2ffabf5424 --- /dev/null +++ b/test/949-in-memory-transform/src/Main.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2017 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.util.Base64; +import java.lang.reflect.*; +import java.nio.ByteBuffer; + +public class Main { + /** + * base64 encoded class/dex file for + * public class Transform { + * public void sayHi() { + * System.out.println("hello"); + * } + * } + */ + private static final byte[] INITIAL_CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" + + "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" + + "BwAIBwAWDAAXABgBAAVoZWxsbwcAGQwAGgAbAQAJVHJhbnNmb3JtAQAQamF2YS9sYW5nL09iamVj" + + "dAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZh" + + "L2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgAhAAUABgAA" + + "AAAAAgABAAcACAABAAkAAAAdAAEAAQAAAAUqtwABsQAAAAEACgAAAAYAAQAAABEAAQALAAgAAQAJ" + + "AAAAJQACAAEAAAAJsgACEgO2AASxAAAAAQAKAAAACgACAAAAGgAIABsAAQAMAAAAAgAN"); + private static final byte[] INITIAL_DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQAJX3mZphwHJCT1qdTz/GS+jXOR+O/9e3fMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" + + "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" + + "AABqAQAAdwEAAI4BAACiAQAAtgEAAMoBAADaAQAA3QEAAOEBAAD1AQAA/AEAAAECAAAKAgAAAQAA" + + "AAIAAAADAAAABAAAAAUAAAAHAAAABwAAAAUAAAAAAAAACAAAAAUAAABcAQAABAABAAsAAAAAAAAA" + + "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAABAAAAAgAAAAAAAAAGAAAAAAAAABwCAAAA" + + "AAAAAQABAAEAAAARAgAABAAAAHAQAwAAAA4AAwABAAIAAAAWAgAACQAAAGIAAAAbAQoAAABuIAIA" + + "EAAOAAAAAQAAAAMABjxpbml0PgALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwAS" + + "TGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVt" + + "OwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTQuMjUABWhlbGxvAANvdXQA" + + "B3ByaW50bG4ABXNheUhpABEABw4AGgAHDocAAAABAQCBgASgAgEBuAIAAA0AAAAAAAAAAQAAAAAA" + + "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" + + "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" + + "AgAAABECAAAAIAAAAQAAABwCAAAAEAAAAQAAACwCAAA="); + + + /** + * base64 encoded class/dex file for + * public class Transform { + * public void sayHi() { + * System.out.println("Goodbye"); + * } + * } + */ + private static final byte[] TRANSFORMED_CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" + + "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" + + "BwAIBwAWDAAXABgBAAdHb29kYnllBwAZDAAaABsBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2Jq" + + "ZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2ph" + + "dmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACEABQAG" + + "AAAAAAACAAEABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAEQABAAsACAAB" + + "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAaAAgAGwABAAwAAAACAA0="); + private static final byte[] TRANSFORMED_DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQAPXh6T3l1FObhHsKf1U2vi+0GmAvElxBLMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" + + "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" + + "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" + + "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" + + "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAABAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" + + "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" + + "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" + + "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" + + "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTQuMjUAA291" + + "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgAaAAcOhwAAAAEBAIGABKACAQG4Ag0AAAAAAAAAAQAAAAAA" + + "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" + + "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" + + "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA="); + + public static void main(String[] args) throws Exception { + ClassLoader loader; + try { + // Art uses this classloader to do in-memory dex files. There is no support for defineClass + loader = (ClassLoader)Class.forName("dalvik.system.InMemoryDexClassLoader") + .getConstructor(ByteBuffer.class, ClassLoader.class) + .newInstance(ByteBuffer.wrap(INITIAL_DEX_BYTES), + ClassLoader.getSystemClassLoader()); + } catch (ClassNotFoundException e) { + // Seem to be on RI. Just make a new ClassLoader that calls defineClass. + loader = new ClassLoader() { + public Class<?> findClass(String name) throws ClassNotFoundException { + if (name.equals("Transform")) { + return defineClass(name, INITIAL_CLASS_BYTES, 0, INITIAL_CLASS_BYTES.length); + } else { + throw new ClassNotFoundException("Couldn't find class: " + name); + } + } + }; + } + doTest(loader); + } + + public static void doTest(ClassLoader loader) throws Exception { + // Get the class + Class<?> transform_class = loader.loadClass("Transform"); + Method say_hi_method = transform_class.getMethod("sayHi"); + Object t = transform_class.newInstance(); + + // Run the actual test. + say_hi_method.invoke(t); + doCommonClassRedefinition(transform_class, TRANSFORMED_CLASS_BYTES, TRANSFORMED_DEX_BYTES); + say_hi_method.invoke(t); + } + + // Transforms the class + private static native void doCommonClassRedefinition(Class<?> target, + byte[] class_file, + byte[] dex_file); +} diff --git a/test/956-methodhandles/src/Main.java b/test/956-methodhandles/src/Main.java index fc9f030559..cb06e4263e 100644 --- a/test/956-methodhandles/src/Main.java +++ b/test/956-methodhandles/src/Main.java @@ -183,15 +183,23 @@ public class Main { public String bar(); } - public static class BarSuper { + public static abstract class BarAbstractSuper { + public abstract String abstractSuperPublicMethod(); + } + + public static class BarSuper extends BarAbstractSuper { public String superPublicMethod() { return "superPublicMethod"; } - public String superProtectedMethod() { + protected String superProtectedMethod() { return "superProtectedMethod"; } + public String abstractSuperPublicMethod() { + return "abstractSuperPublicMethod"; + } + String superPackageMethod() { return "superPackageMethod"; } @@ -288,15 +296,19 @@ public class Main { System.out.println("Unexpected return value for BarImpl#bar: " + str); } - // TODO(narayan): Fix this case, we're using the wrong ArtMethod for the - // invoke resulting in a failing check in the interpreter. - // - // mh = MethodHandles.lookup().findVirtual(Bar.class, "bar", - // MethodType.methodType(String.class)); - // str = (String) mh.invoke(new BarImpl()); - // if (!"bar".equals(str)) { - // System.out.println("Unexpected return value for BarImpl#bar: " + str); - // } + mh = MethodHandles.lookup().findVirtual(Bar.class, "bar", + MethodType.methodType(String.class)); + str = (String) mh.invoke(new BarImpl()); + if (!"bar".equals(str)) { + System.out.println("Unexpected return value for BarImpl#bar: " + str); + } + + mh = MethodHandles.lookup().findVirtual(BarAbstractSuper.class, "abstractSuperPublicMethod", + MethodType.methodType(String.class)); + str = (String) mh.invoke(new BarImpl()); + if (!"abstractSuperPublicMethod".equals(str)) { + System.out.println("Unexpected return value for BarImpl#abstractSuperPublicMethod: " + str); + } // We should also be able to lookup public / protected / package methods in // the super class, given sufficient access privileges. diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 1938b92db8..95967b527c 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -170,12 +170,6 @@ endif ifeq ($(ART_TEST_RUN_TEST_MULTI_IMAGE),true) IMAGE_TYPES := multipicimage endif -ifeq ($(ART_TEST_NPIC_IMAGE),true) - IMAGE_TYPES += npicimage - ifeq ($(ART_TEST_RUN_TEST_MULTI_IMAGE),true) - IMAGE_TYPES := multinpicimage - endif -endif PICTEST_TYPES := npictest ifeq ($(ART_TEST_PIC_TEST),true) PICTEST_TYPES += pictest @@ -878,32 +872,36 @@ define core-image-dependencies endif endif ifeq ($(2),no-image) - $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_pic_$(4)) + $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_$(4)) else - ifeq ($(2),npicimage) - $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_no-pic_$(4)) + ifeq ($(2),picimage) + $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_$(4)) else - ifeq ($(2),picimage) - $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_pic_$(4)) - else - ifeq ($(2),multinpicimage) - $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_no-pic_multi_$(4)) - else - ifeq ($(2),multipicimage) - $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_pic_multi_$(4)) - endif - endif + ifeq ($(2),multipicimage) + $(1)_prereq_rules += $$($(call name-to-var,$(1))_CORE_IMAGE_$$(image_suffix)_multi_$(4)) endif endif endif endef +COMPILER_TYPES_2 := optimizing +COMPILER_TYPES_2 += interpreter +COMPILER_TYPES_2 += jit +COMPILER_TYPES_2 += regalloc_gc +COMPILER_TYPES_2 += interp-ac +ALL_ADDRESS_SIZES_2 := 32 64 +IMAGE_TYPES_2 := picimage +IMAGE_TYPES_2 += no-image +IMAGE_TYPES_2 += npicimage +IMAGE_TYPES_2 += multinpicimage +IMAGE_TYPES_2 += multipicimage + # Add core image dependencies required for given target - HOST or TARGET, # IMAGE_TYPE, COMPILER_TYPE and ADDRESS_SIZE to the prereq_rules. $(foreach target, $(TARGET_TYPES), \ - $(foreach image, $(IMAGE_TYPES), \ - $(foreach compiler, $(COMPILER_TYPES), \ - $(foreach address_size, $(ALL_ADDRESS_SIZES), $(eval \ + $(foreach image, $(IMAGE_TYPES_2), \ + $(foreach compiler, $(COMPILER_TYPES_2), \ + $(foreach address_size, $(ALL_ADDRESS_SIZES_2), $(eval \ $(call core-image-dependencies,$(target),$(image),$(compiler),$(address_size))))))) test-art-host-run-test-dependencies : $(host_prereq_rules) @@ -1081,50 +1079,29 @@ define define-test-art-run-test # Add the core dependency. This is required for pre-building. # Use the PIC image, as it is the default in run-test, to match dependencies. ifeq ($(1),host) - prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_pic_$(13)) + prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_$(13)) else - prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_pic_$(13)) + prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_$(13)) endif else - ifeq ($(9),npicimage) - test_groups += ART_RUN_TEST_$$(uc_host_or_target)_IMAGE_RULES - run_test_options += --npic-image - # Add the core dependency. + ifeq ($(9),picimage) + test_groups += ART_RUN_TEST_$$(uc_host_or_target)_PICIMAGE_RULES ifeq ($(1),host) - prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_no-pic_$(13)) + prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_$(13)) else - prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_no-pic_$(13)) + prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_$(13)) endif else - ifeq ($(9),picimage) + ifeq ($(9),multipicimage) test_groups += ART_RUN_TEST_$$(uc_host_or_target)_PICIMAGE_RULES + run_test_options += --multi-image ifeq ($(1),host) - prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_pic_$(13)) + prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_multi_$(13)) else - prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_pic_$(13)) + prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_multi_$(13)) endif else - ifeq ($(9),multinpicimage) - test_groups += ART_RUN_TEST_$$(uc_host_or_target)_IMAGE_RULES - run_test_options += --npic-image --multi-image - ifeq ($(1),host) - prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_no-pic_multi_$(13)) - else - prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_no-pic_multi_$(13)) - endif - else - ifeq ($(9),multipicimage) - test_groups += ART_RUN_TEST_$$(uc_host_or_target)_PICIMAGE_RULES - run_test_options += --multi-image - ifeq ($(1),host) - prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_pic_multi_$(13)) - else - prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_pic_multi_$(13)) - endif - else - $$(error found $(9) expected $(IMAGE_TYPES)) - endif - endif + $$(error found $(9) expected $(IMAGE_TYPES)) endif endif endif diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 7d218f1d61..f3d4332009 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -19,7 +19,7 @@ DEBUGGER="n" DEV_MODE="n" DEX2OAT="" EXPERIMENTAL="" -FALSE_BIN="/system/bin/false" +FALSE_BIN="false" FLAGS="" ANDROID_FLAGS="" GDB="" diff --git a/test/run-test b/test/run-test index c926c115e2..e808deef52 100755 --- a/test/run-test +++ b/test/run-test @@ -143,7 +143,6 @@ never_clean="no" have_dex2oat="yes" have_patchoat="yes" have_image="yes" -pic_image_suffix="" multi_image_suffix="" android_root="/system" bisection_search="no" @@ -199,9 +198,6 @@ while true; do elif [ "x$1" = "x--no-image" ]; then have_image="no" shift - elif [ "x$1" = "x--npic-image" ]; then - pic_image_suffix="-npic" - shift elif [ "x$1" = "x--multi-image" ]; then multi_image_suffix="-multi" shift @@ -507,12 +503,12 @@ if [ "$runtime" = "dalvik" ]; then elif [ "$runtime" = "art" ]; then if [ "$target_mode" = "no" ]; then guess_host_arch_name - run_args="${run_args} --boot ${ANDROID_HOST_OUT}/framework/core${image_suffix}${pic_image_suffix}${multi_image_suffix}.art" + run_args="${run_args} --boot ${ANDROID_HOST_OUT}/framework/core${image_suffix}${multi_image_suffix}.art" run_args="${run_args} --runtime-option -Djava.library.path=${ANDROID_HOST_OUT}/lib${suffix64}:${ANDROID_HOST_OUT}/nativetest${suffix64}" else guess_target_arch_name run_args="${run_args} --runtime-option -Djava.library.path=/data/nativetest${suffix64}/art/${target_arch_name}" - run_args="${run_args} --boot /data/art-test/core${image_suffix}${pic_image_suffix}${multi_image_suffix}.art" + run_args="${run_args} --boot /data/art-test/core${image_suffix}${multi_image_suffix}.art" fi if [ "$relocate" = "yes" ]; then run_args="${run_args} --relocate" @@ -668,8 +664,6 @@ if [ "$usage" = "yes" ]; then echo " --dex2oat-swap Use a dex2oat swap file." echo " --instruction-set-features [string]" echo " Set instruction-set-features for compilation." - echo " --npic-image Use an image compiled with non-position independent code " - echo " for the boot class path." echo " --multi-image Use a set of images compiled with dex2oat multi-image for" echo " the boot class path." echo " --pic-test Compile the test code position independent." diff --git a/test/testrunner/env.py b/test/testrunner/env.py index 0b69718f93..f327974dae 100644 --- a/test/testrunner/env.py +++ b/test/testrunner/env.py @@ -105,9 +105,6 @@ ART_TEST_OPTIMIZING = getEnvBoolean('ART_TEST_OPTIMIZING', ART_TEST_FULL) # Do you want to test the optimizing compiler with graph coloring register allocation? ART_TEST_OPTIMIZING_GRAPH_COLOR = getEnvBoolean('ART_TEST_OPTIMIZING_GRAPH_COLOR', ART_TEST_FULL) -# Do we want to test a non-PIC-compiled core image? -ART_TEST_NPIC_IMAGE = getEnvBoolean('ART_TEST_NPIC_IMAGE', ART_TEST_FULL) - # Do we want to test PIC-compiled tests ("apps")? ART_TEST_PIC_TEST = getEnvBoolean('ART_TEST_PIC_TEST', ART_TEST_FULL) # Do you want tracing tests run? diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py index a5bfcffae1..748ec31ae4 100755 --- a/test/testrunner/testrunner.py +++ b/test/testrunner/testrunner.py @@ -133,8 +133,7 @@ def gather_test_info(): VARIANT_TYPE_DICT['run'] = {'ndebug', 'debug'} VARIANT_TYPE_DICT['target'] = {'target', 'host'} VARIANT_TYPE_DICT['trace'] = {'trace', 'ntrace', 'stream'} - VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image', 'npicimage', - 'multinpicimage', 'multipicimage'} + VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image', 'multipicimage'} VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'} VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'} VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'no-dex2oat', 'prebuild'} @@ -218,10 +217,6 @@ def setup_test_env(): IMAGE_TYPES.add('no-image') if env.ART_TEST_RUN_TEST_MULTI_IMAGE: IMAGE_TYPES.add('multipicimage') - if env.ART_TEST_NPIC_IMAGE: - IMAGE_TYPES.add('npicimage') - if env.ART_TEST_RUN_TEST_MULTI_IMAGE: - IMAGE_TYPES.add('multinpicimage') if env.ART_TEST_RUN_TEST_IMAGE or not IMAGE_TYPES: # Default IMAGE_TYPES.add('picimage') @@ -388,10 +383,6 @@ def run_tests(tests): if image == 'no-image': options_test += ' --no-image' - elif image == 'npicimage': - options_test += ' --npic-image' - elif image == 'multinpicimage': - options_test += ' --npic-image --multi-image' elif image == 'multipicimage': options_test += ' --multi-image' @@ -446,29 +437,34 @@ def run_test(command, test, test_variant, test_name): test_name: The name of the test along with the variants. """ global stop_testrunner - if is_test_disabled(test, test_variant): - test_skipped = True - else: - test_skipped = False - proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, stdout=subprocess.PIPE) - script_output = proc.stdout.read().strip() - test_passed = not proc.wait() - - if not test_skipped: - if test_passed: - print_test_info(test_name, 'PASS') + try: + if is_test_disabled(test, test_variant): + test_skipped = True else: - failed_tests.append(test_name) - if not env.ART_TEST_KEEP_GOING: - stop_testrunner = True - print_test_info(test_name, 'FAIL', ('%s\n%s') % ( - command, script_output)) - elif not dry_run: - print_test_info(test_name, 'SKIP') - skipped_tests.append(test_name) - else: - print_test_info(test_name, '') - semaphore.release() + test_skipped = False + proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, stdout=subprocess.PIPE) + script_output = proc.stdout.read().strip() + test_passed = not proc.wait() + + if not test_skipped: + if test_passed: + print_test_info(test_name, 'PASS') + else: + failed_tests.append(test_name) + if not env.ART_TEST_KEEP_GOING: + stop_testrunner = True + print_test_info(test_name, 'FAIL', ('%s\n%s') % ( + command, script_output)) + elif not dry_run: + print_test_info(test_name, 'SKIP') + skipped_tests.append(test_name) + else: + print_test_info(test_name, '') + except Exception, e: + failed_tests.append(test_name) + print_text(('%s\n%s\n') % (command, str(e))) + finally: + semaphore.release() def print_test_info(test_name, result, failed_test_info=""): @@ -485,6 +481,7 @@ def print_test_info(test_name, result, failed_test_info=""): command used to invoke the script. It doesn't override the failing test information in either of the cases. """ + global test_count info = '' if not verbose: @@ -493,48 +490,53 @@ def print_test_info(test_name, result, failed_test_info=""): # the console width. console_width = int(os.popen('stty size', 'r').read().split()[1]) info = '\r' + ' ' * console_width + '\r' - print_mutex.acquire() - test_count += 1 - percent = (test_count * 100) / total_test_count - progress_info = ('[ %d%% %d/%d ]') % ( - percent, - test_count, - total_test_count) - - if result == "FAIL": - info += ('%s %s %s\n%s\n') % ( - progress_info, - test_name, - COLOR_ERROR + 'FAIL' + COLOR_NORMAL, - failed_test_info) - else: - result_text = '' - if result == 'PASS': - result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL - elif result == 'SKIP': - result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL - - if verbose: - info += ('%s %s %s\n') % ( - progress_info, - test_name, - result_text) - else: - total_output_length = 2 # Two spaces - total_output_length += len(progress_info) - total_output_length += len(result) - allowed_test_length = console_width - total_output_length - test_name_len = len(test_name) - if allowed_test_length < test_name_len: - test_name = ('%s...%s') % ( - test_name[:(allowed_test_length - 3)/2], - test_name[-(allowed_test_length - 3)/2:]) - info += ('%s %s %s') % ( + try: + print_mutex.acquire() + test_count += 1 + percent = (test_count * 100) / total_test_count + progress_info = ('[ %d%% %d/%d ]') % ( + percent, + test_count, + total_test_count) + + if result == "FAIL": + info += ('%s %s %s\n%s\n') % ( progress_info, test_name, - result_text) - print_text(info) - print_mutex.release() + COLOR_ERROR + 'FAIL' + COLOR_NORMAL, + failed_test_info) + else: + result_text = '' + if result == 'PASS': + result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL + elif result == 'SKIP': + result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL + + if verbose: + info += ('%s %s %s\n') % ( + progress_info, + test_name, + result_text) + else: + total_output_length = 2 # Two spaces + total_output_length += len(progress_info) + total_output_length += len(result) + allowed_test_length = console_width - total_output_length + test_name_len = len(test_name) + if allowed_test_length < test_name_len: + test_name = ('%s...%s') % ( + test_name[:(allowed_test_length - 3)/2], + test_name[-(allowed_test_length - 3)/2:]) + info += ('%s %s %s') % ( + progress_info, + test_name, + result_text) + print_text(info) + except Exception, e: + print_text(('%s\n%s\n') % (test_name, str(e))) + failed_tests.append(test_name) + finally: + print_mutex.release() def get_disabled_test_info(): """Generate set of known failures. @@ -788,10 +790,6 @@ def parse_option(): TRACE_TYPES.add('ntrace') if options.cms: GC_TYPES.add('cms') - if options.npicimage: - IMAGE_TYPES.add('npicimage') - if options.multinpicimage: - IMAGE_TYPES.add('multinpicimage') if options.multipicimage: IMAGE_TYPES.add('multipicimage') if options.verbose: @@ -837,15 +835,13 @@ def main(): while threading.active_count() > 1: time.sleep(0.1) print_analysis() - if failed_tests: - sys.exit(1) - sys.exit(0) - except SystemExit: - pass except Exception, e: print_analysis() print_text(str(e)) sys.exit(1) + if failed_tests: + sys.exit(1) + sys.exit(0) if __name__ == '__main__': main() |