diff options
Diffstat (limited to 'test')
42 files changed, 989 insertions, 312 deletions
diff --git a/test/631-checker-fp-abs/expected.txt b/test/631-checker-fp-abs/expected.txt new file mode 100644 index 0000000000..b0aad4deb5 --- /dev/null +++ b/test/631-checker-fp-abs/expected.txt @@ -0,0 +1 @@ +passed diff --git a/test/631-checker-fp-abs/info.txt b/test/631-checker-fp-abs/info.txt new file mode 100644 index 0000000000..0a1499e72c --- /dev/null +++ b/test/631-checker-fp-abs/info.txt @@ -0,0 +1 @@ +Tests on floating-point Math.abs. diff --git a/test/631-checker-fp-abs/src/Main.java b/test/631-checker-fp-abs/src/Main.java new file mode 100644 index 0000000000..0f85dc6865 --- /dev/null +++ b/test/631-checker-fp-abs/src/Main.java @@ -0,0 +1,176 @@ +/* + * 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. + */ + +/** + * A few tests of Math.abs for floating-point data. + * + * Note, as a "quality of implementation", rather than pure "spec compliance", + * we require that Math.abs() clears the sign bit (but changes nothing else) + * for all numbers, including NaN (signaling NaN may become quiet though). + */ +public class Main { + + private static final int SPQUIET = 1 << 22; + private static final long DPQUIET = 1L << 51; + + public static boolean doThrow = false; + + /// CHECK-START: float Main.$opt$noinline$absSP(float) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:f\d+>> InvokeStaticOrDirect intrinsic:MathAbsFloat + /// CHECK-DAG: Return [<<Result>>] + private static float $opt$noinline$absSP(float f) { + if (doThrow) { + throw new Error("Something to prevent inlining"); + } + return Math.abs(f); + } + + /// CHECK-START: double Main.$opt$noinline$absDP(double) intrinsics_recognition (after) + /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect intrinsic:MathAbsDouble + /// CHECK-DAG: Return [<<Result>>] + private static double $opt$noinline$absDP(double d) { + if (doThrow) { + throw new Error("Something to prevent inlining"); + } + return Math.abs(d); + } + + public static void main(String args[]) { + // A few obvious numbers. + for (float f = -100.0f; f < 0.0f; f += 0.5f) { + expectEqualsSP(-f, $opt$noinline$absSP(f)); + } + for (float f = 0.0f; f <= 100.0f; f += 0.5f) { + expectEqualsSP(f, $opt$noinline$absSP(f)); + } + for (float f = -1.5f; f <= -1.499f; f = Math.nextAfter(f, Float.POSITIVE_INFINITY)) { + expectEqualsSP(-f, $opt$noinline$absSP(f)); + } + for (float f = 1.499f; f <= 1.5f; f = Math.nextAfter(f, Float.POSITIVE_INFINITY)) { + expectEqualsSP(f, $opt$noinline$absSP(f)); + } + + // Zero + expectEquals32(0, Float.floatToRawIntBits($opt$noinline$absSP(+0.0f))); + expectEquals32(0, Float.floatToRawIntBits($opt$noinline$absSP(-0.0f))); + + // Inf. + expectEqualsSP(Float.POSITIVE_INFINITY, $opt$noinline$absSP(Float.NEGATIVE_INFINITY)); + expectEqualsSP(Float.POSITIVE_INFINITY, $opt$noinline$absSP(Float.POSITIVE_INFINITY)); + + // A few NaN numbers. + int[] spnans = { + 0x7f800001, + 0x7fa00000, + 0x7fc00000, + 0x7fffffff, + 0xff800001, + 0xffa00000, + 0xffc00000, + 0xffffffff + }; + for (int i = 0; i < spnans.length; i++) { + float f = Float.intBitsToFloat(spnans[i]); + expectEqualsNaN32( + spnans[i] & Integer.MAX_VALUE, + Float.floatToRawIntBits($opt$noinline$absSP(f))); + } + + // A few obvious numbers. + for (double d = -100.0; d < 0.0; d += 0.5) { + expectEqualsDP(-d, $opt$noinline$absDP(d)); + } + for (double d = 0.0; d <= 100.0; d += 0.5) { + expectEqualsDP(d, $opt$noinline$absDP(d)); + } + for (double d = -1.5d; d <= -1.49999999999d; d = Math.nextAfter(d, Double.POSITIVE_INFINITY)) { + expectEqualsDP(-d, $opt$noinline$absDP(d)); + } + for (double d = 1.49999999999d; d <= 1.5; d = Math.nextAfter(d, Double.POSITIVE_INFINITY)) { + expectEqualsDP(d, $opt$noinline$absDP(d)); + } + + // Zero + expectEquals64(0L, Double.doubleToRawLongBits($opt$noinline$absDP(+0.0f))); + expectEquals64(0L, Double.doubleToRawLongBits($opt$noinline$absDP(-0.0f))); + + // Inf. + expectEqualsDP(Double.POSITIVE_INFINITY, $opt$noinline$absDP(Double.NEGATIVE_INFINITY)); + expectEqualsDP(Double.POSITIVE_INFINITY, $opt$noinline$absDP(Double.POSITIVE_INFINITY)); + + // A few NaN numbers. + long[] dpnans = { + 0x7ff0000000000001L, + 0x7ff4000000000000L, + 0x7ff8000000000000L, + 0x7fffffffffffffffL, + 0xfff0000000000001L, + 0xfff4000000000000L, + 0xfff8000000000000L, + 0xffffffffffffffffL + }; + for (int i = 0; i < dpnans.length; i++) { + double d = Double.longBitsToDouble(dpnans[i]); + expectEqualsNaN64( + dpnans[i] & Long.MAX_VALUE, + Double.doubleToRawLongBits($opt$noinline$absDP(d))); + } + + System.out.println("passed"); + } + + private static void expectEquals32(int expected, int result) { + if (expected != result) { + throw new Error("Expected: 0x" + Integer.toHexString(expected) + + ", found: 0x" + Integer.toHexString(result)); + } + } + + // We allow that an expected NaN result has become quiet. + private static void expectEqualsNaN32(int expected, int result) { + if (expected != result && (expected | SPQUIET) != result) { + throw new Error("Expected: 0x" + Integer.toHexString(expected) + + ", found: 0x" + Integer.toHexString(result)); + } + } + + private static void expectEquals64(long expected, long result) { + if (expected != result) { + throw new Error("Expected: 0x" + Long.toHexString(expected) + + ", found: 0x" + Long.toHexString(result)); + } + } + + // We allow that an expected NaN result has become quiet. + private static void expectEqualsNaN64(long expected, long result) { + if (expected != result && (expected | DPQUIET) != result) { + throw new Error("Expected: 0x" + Long.toHexString(expected) + + ", found: 0x" + Long.toHexString(result)); + } + } + + private static void expectEqualsSP(float expected, float result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } + + private static void expectEqualsDP(double expected, double result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } +} diff --git a/test/901-hello-ti-agent/run b/test/901-hello-ti-agent/run index 8079a8c457..4379349cb2 100755 --- a/test/901-hello-ti-agent/run +++ b/test/901-hello-ti-agent/run @@ -14,14 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=901-hello-ti-agent \ - --android-runtime-option -Xplugin:${plugin} + --jvmti diff --git a/test/902-hello-transformation/run b/test/902-hello-transformation/run index 94a8b2d975..4379349cb2 100755 --- a/test/902-hello-transformation/run +++ b/test/902-hello-transformation/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" - if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " - else - other_args="" - fi -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=902-hello-transformation,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - --android-runtime-option -Xfully-deoptable \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/903-hello-tagging/run b/test/903-hello-tagging/run index 5e3c0bd32a..4379349cb2 100755 --- a/test/903-hello-tagging/run +++ b/test/903-hello-tagging/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=903-hello-tagging,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/904-object-allocation/run b/test/904-object-allocation/run index 2f7ad21886..4379349cb2 100755 --- a/test/904-object-allocation/run +++ b/test/904-object-allocation/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=904-object-allocation,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/905-object-free/run b/test/905-object-free/run index 753b742681..4379349cb2 100755 --- a/test/905-object-free/run +++ b/test/905-object-free/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=905-object-free,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/906-iterate-heap/run b/test/906-iterate-heap/run index 3e135a378d..4379349cb2 100755 --- a/test/906-iterate-heap/run +++ b/test/906-iterate-heap/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=906-iterate-heap,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/907-get-loaded-classes/run b/test/907-get-loaded-classes/run index 3f5a059fe2..4379349cb2 100755 --- a/test/907-get-loaded-classes/run +++ b/test/907-get-loaded-classes/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=907-get-loaded-classes,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/908-gc-start-finish/run b/test/908-gc-start-finish/run index 2fc35f0048..4379349cb2 100755 --- a/test/908-gc-start-finish/run +++ b/test/908-gc-start-finish/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=908-gc-start-finish,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/910-methods/run b/test/910-methods/run index 4dd2555f9e..4379349cb2 100755 --- a/test/910-methods/run +++ b/test/910-methods/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=910-methods,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/911-get-stack-trace/run b/test/911-get-stack-trace/run index 43fc325363..4379349cb2 100755 --- a/test/911-get-stack-trace/run +++ b/test/911-get-stack-trace/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=911-get-stack-trace,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/912-classes/run b/test/912-classes/run index 64bbb987a1..4379349cb2 100755 --- a/test/912-classes/run +++ b/test/912-classes/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=912-classes,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/913-heaps/run b/test/913-heaps/run index 7bd8cbd1dd..4379349cb2 100755 --- a/test/913-heaps/run +++ b/test/913-heaps/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" -fi - -if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " -else - other_args="" -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=913-heaps,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/914-hello-obsolescence/build b/test/914-hello-obsolescence/build new file mode 100755 index 0000000000..898e2e54a2 --- /dev/null +++ b/test/914-hello-obsolescence/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/914-hello-obsolescence/expected.txt b/test/914-hello-obsolescence/expected.txt new file mode 100644 index 0000000000..83efda144d --- /dev/null +++ b/test/914-hello-obsolescence/expected.txt @@ -0,0 +1,9 @@ +hello +Not doing anything here +goodbye +hello +transforming calling function +goodbye +Hello - Transformed +Not doing anything here +Goodbye - Transformed diff --git a/test/914-hello-obsolescence/info.txt b/test/914-hello-obsolescence/info.txt new file mode 100644 index 0000000000..c8b892cedd --- /dev/null +++ b/test/914-hello-obsolescence/info.txt @@ -0,0 +1 @@ +Tests basic obsolete method support diff --git a/test/914-hello-obsolescence/run b/test/914-hello-obsolescence/run new file mode 100755 index 0000000000..4379349cb2 --- /dev/null +++ b/test/914-hello-obsolescence/run @@ -0,0 +1,19 @@ +#!/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 "$@" --experimental agents \ + --experimental runtime-plugins \ + --jvmti diff --git a/test/914-hello-obsolescence/src/Main.java b/test/914-hello-obsolescence/src/Main.java new file mode 100644 index 0000000000..46266efb28 --- /dev/null +++ b/test/914-hello-obsolescence/src/Main.java @@ -0,0 +1,73 @@ +/* + * 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.Base64; + +public class Main { + // class Transform { + // public void sayHi(Runnable r) { + // System.out.println("Hello - Transformed"); + // r.run(); + // System.out.println("Goodbye - Transformed"); + // } + // } + private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAJAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" + + "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" + + "KVYBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkACgcAHAwAHQAeAQATSGVsbG8gLSBU" + + "cmFuc2Zvcm1lZAcAHwwAIAAhBwAiDAAjAAoBABVHb29kYnllIC0gVHJhbnNmb3JtZWQBAAlUcmFu" + + "c2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZh" + + "L2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZh" + + "L2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAABwAIAAAAAAACAAAA" + + "CQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAAAQABAA0ADgABAAsAAAA7AAIA" + + "AgAAABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAMACAAEAA4ABQAWAAYA" + + "AQAPAAAAAgAQ"); + private static final byte[] DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQAYeAMMXgYWxoeSHAS9EWKCCtVRSAGpqZVQAwAAcAAAAHhWNBIAAAAAAAAAALACAAAR" + + "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAMAgAARAEAAKIB" + + "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAAB3AgAAfAIA" + + "AIUCAACKAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" + + "lAEAAAsAAAAGAAAAnAEAAAUAAQANAAAAAAAAAAAAAAAAAAEAEAAAAAEAAgAOAAAAAgAAAAAAAAAD" + + "AAAADwAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAJ8CAAAAAAAAAQABAAEAAACRAgAABAAAAHAQ" + + "AwAAAA4ABAACAAIAAACWAgAAFAAAAGIAAAAbAQIAAABuIAIAEAByEAQAAwBiAAAAGwEBAAAAbiAC" + + "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" + + "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" + + "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" + + "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00" + + "LjEzAANvdXQAB3ByaW50bG4AA3J1bgAFc2F5SGkAAQAHDgADAQAHDoc8hwAAAAEBAICABMQCAQHc" + + "AgAAAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAACAAAABwAAALQAAAADAAAAAwAAANAAAAAE" + + "AAAAAQAAAPQAAAAFAAAABQAAAPwAAAAGAAAAAQAAACQBAAABIAAAAgAAAEQBAAABEAAAAgAAAJQB" + + "AAACIAAAEQAAAKIBAAADIAAAAgAAAJECAAAAIAAAAQAAAJ8CAAAAEAAAAQAAALACAAA="); + + public static void main(String[] args) { + System.loadLibrary(args[1]); + doTest(new Transform()); + } + + public static void doTest(Transform t) { + t.sayHi(() -> { System.out.println("Not doing anything here"); }); + t.sayHi(() -> { + System.out.println("transforming calling function"); + doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); + }); + t.sayHi(() -> { System.out.println("Not doing anything here"); }); + } + + // Transforms the class + private static native void doCommonClassRedefinition(Class<?> target, + byte[] classfile, + byte[] dexfile); +} diff --git a/test/914-hello-obsolescence/src/Transform.java b/test/914-hello-obsolescence/src/Transform.java new file mode 100644 index 0000000000..8cda6cdf53 --- /dev/null +++ b/test/914-hello-obsolescence/src/Transform.java @@ -0,0 +1,30 @@ +/* + * 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 Transform { + public void sayHi(Runnable r) { + // Use lower 'h' to make sure the string will have a different string id + // than the transformation (the transformation code is the same except + // the actual printed String, which was making the test inacurately passing + // in JIT mode when loading the string from the dex cache, as the string ids + // of the two different strings were the same). + // We know the string ids will be different because lexicographically: + // "Hello" < "LTransform;" < "hello". + System.out.println("hello"); + r.run(); + System.out.println("goodbye"); + } +} diff --git a/test/915-obsolete-2/build b/test/915-obsolete-2/build new file mode 100755 index 0000000000..898e2e54a2 --- /dev/null +++ b/test/915-obsolete-2/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/915-obsolete-2/expected.txt b/test/915-obsolete-2/expected.txt new file mode 100644 index 0000000000..04aff3a6dc --- /dev/null +++ b/test/915-obsolete-2/expected.txt @@ -0,0 +1,21 @@ +Pre Start private method call +hello - private +Post Start private method call +Not doing anything here +Pre Finish private method call +goodbye - private +Post Finish private method call +Pre Start private method call +hello - private +Post Start private method call +transforming calling function +Pre Finish private method call +Goodbye - private - Transformed +Post Finish private method call +Pre Start private method call - Transformed +Hello - private - Transformed +Post Start private method call - Transformed +Not doing anything here +Pre Finish private method call - Transformed +Goodbye - private - Transformed +Post Finish private method call - Transformed diff --git a/test/915-obsolete-2/info.txt b/test/915-obsolete-2/info.txt new file mode 100644 index 0000000000..c8b892cedd --- /dev/null +++ b/test/915-obsolete-2/info.txt @@ -0,0 +1 @@ +Tests basic obsolete method support diff --git a/test/915-obsolete-2/run b/test/915-obsolete-2/run new file mode 100755 index 0000000000..4379349cb2 --- /dev/null +++ b/test/915-obsolete-2/run @@ -0,0 +1,19 @@ +#!/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 "$@" --experimental agents \ + --experimental runtime-plugins \ + --jvmti diff --git a/test/915-obsolete-2/src/Main.java b/test/915-obsolete-2/src/Main.java new file mode 100644 index 0000000000..bbeb726858 --- /dev/null +++ b/test/915-obsolete-2/src/Main.java @@ -0,0 +1,99 @@ +/* + * 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.Base64; + +public class Main { + // class Transform { + // private void Start() { + // System.out.println("Hello - private - Transformed"); + // } + // + // private void Finish() { + // System.out.println("Goodbye - private - Transformed"); + // } + // + // public void sayHi(Runnable r) { + // System.out.println("Pre Start private method call - Transformed"); + // Start(); + // System.out.println("Post Start private method call - Transformed"); + // r.run(); + // System.out.println("Pre Finish private method call - Transformed"); + // Finish(); + // System.out.println("Post Finish private method call - Transformed"); + // } + // } + private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAMgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" + + "JwcAKAcAKQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" + + "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAO" + + "VHJhbnNmb3JtLmphdmEMAA8AEAcAKgwAKwAsAQAdSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3Jt" + + "ZWQHAC0MAC4ALwEAH0dvb2RieWUgLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQBACtQcmUgU3RhcnQg" + + "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAATABABACxQb3N0IFN0YXJ0IHByaXZh" + + "dGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAcAMAwAMQAQAQAsUHJlIEZpbmlzaCBwcml2YXRl" + + "IG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQMABQAEAEALVBvc3QgRmluaXNoIHByaXZhdGUgbWV0" + + "aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAEACVRyYW5zZm9ybQEAEGphdmEvbGFuZy9PYmplY3QBABBq" + + "YXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9Q" + + "cmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABJqYXZhL2xhbmcv" + + "UnVubmFibGUBAANydW4AIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAAB" + + "ABIAAAAGAAEAAAABAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAA" + + "AAMACAAEAAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAcACAAI" + + "AAEAFQAWAAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQq" + + "twALsgACEgy2AASxAAAAAQASAAAAIgAIAAAACwAIAAwADAANABQADgAaAA8AIgAQACYAEQAuABIA" + + "AQAXAAAAAgAY"); + private static final byte[] DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQCM0QYTJmX+NsZXkImojgSkJtXyuew3oaXcBAAAcAAAAHhWNBIAAAAAAAAAADwEAAAX" + + "AAAAcAAAAAcAAADMAAAAAwAAAOgAAAABAAAADAEAAAcAAAAUAQAAAQAAAEwBAABwAwAAbAEAAD4C" + + "AABGAgAATgIAAG8CAACOAgAAmwIAALICAADGAgAA3AIAAPACAAAEAwAAMwMAAGEDAACPAwAAvAMA" + + "AMMDAADTAwAA1gMAANoDAADuAwAA8wMAAPwDAAABBAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" + + "EAAAABAAAAAGAAAAAAAAABEAAAAGAAAAMAIAABEAAAAGAAAAOAIAAAUAAQATAAAAAAAAAAAAAAAA" + + "AAAAAQAAAAAAAAAOAAAAAAABABYAAAABAAIAFAAAAAIAAAAAAAAAAwAAABUAAAAAAAAAAAAAAAIA" + + "AAAAAAAADwAAAAAAAAAmBAAAAAAAAAEAAQABAAAACAQAAAQAAABwEAUAAAAOAAMAAQACAAAADQQA" + + "AAkAAABiAAAAGwECAAAAbiAEABAADgAAAAMAAQACAAAAEwQAAAkAAABiAAAAGwEDAAAAbiAEABAA" + + "DgAAAAQAAgACAAAAGQQAACoAAABiAAAAGwENAAAAbiAEABAAcBACAAIAYgAAABsBCwAAAG4gBAAQ" + + "AHIQBgADAGIAAAAbAQwAAABuIAQAEABwEAEAAgBiAAAAGwEKAAAAbiAEABAADgABAAAAAwAAAAEA" + + "AAAEAAY8aW5pdD4ABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVs" + + "bG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07ABVMamF2YS9pby9QcmludFN0" + + "cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xh" + + "bmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AC1Qb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhv" + + "ZCBjYWxsIC0gVHJhbnNmb3JtZWQALFBvc3QgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRy" + + "YW5zZm9ybWVkACxQcmUgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAr" + + "UHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAFU3RhcnQADlRyYW5z" + + "Zm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00LjEzAANvdXQAB3ByaW50bG4AA3J1bgAF" + + "c2F5SGkAAQAHDgAHAAcOhwADAAcOhwALAQAHDoc8hzyHPIcAAAADAQCAgATsAgEChAMBAqgDAwHM" + + "Aw0AAAAAAAAAAQAAAAAAAAABAAAAFwAAAHAAAAACAAAABwAAAMwAAAADAAAAAwAAAOgAAAAEAAAA" + + "AQAAAAwBAAAFAAAABwAAABQBAAAGAAAAAQAAAEwBAAABIAAABAAAAGwBAAABEAAAAgAAADACAAAC" + + "IAAAFwAAAD4CAAADIAAABAAAAAgEAAAAIAAAAQAAACYEAAAAEAAAAQAAADwEAAA="); + + public static void main(String[] args) { + System.loadLibrary(args[1]); + doTest(new Transform()); + } + + public static void doTest(Transform t) { + t.sayHi(() -> { System.out.println("Not doing anything here"); }); + t.sayHi(() -> { + System.out.println("transforming calling function"); + doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); + }); + t.sayHi(() -> { System.out.println("Not doing anything here"); }); + } + + // Transforms the class + private static native void doCommonClassRedefinition(Class<?> target, + byte[] classfile, + byte[] dexfile); +} diff --git a/test/915-obsolete-2/src/Transform.java b/test/915-obsolete-2/src/Transform.java new file mode 100644 index 0000000000..e914e29479 --- /dev/null +++ b/test/915-obsolete-2/src/Transform.java @@ -0,0 +1,35 @@ +/* + * 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 Transform { + private void Start() { + System.out.println("hello - private"); + } + + private void Finish() { + System.out.println("goodbye - private"); + } + + public void sayHi(Runnable r) { + System.out.println("Pre Start private method call"); + Start(); + System.out.println("Post Start private method call"); + r.run(); + System.out.println("Pre Finish private method call"); + Finish(); + System.out.println("Post Finish private method call"); + } +} diff --git a/test/916-obsolete-jit/build b/test/916-obsolete-jit/build new file mode 100755 index 0000000000..898e2e54a2 --- /dev/null +++ b/test/916-obsolete-jit/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/916-obsolete-jit/expected.txt b/test/916-obsolete-jit/expected.txt new file mode 100644 index 0000000000..4caefc6200 --- /dev/null +++ b/test/916-obsolete-jit/expected.txt @@ -0,0 +1,21 @@ +Pre Start private method call +hello - private +Post Start private method call +Not doing anything here +Pre Finish private method call +goodbye - private +Post Finish private method call +Pre Start private method call +hello - private +Post Start private method call +transforming calling function +Pre Finish private method call +Goodbye - private - Transformed +Post Finish private method call +pre Start private method call - Transformed +Hello - private - Transformed +post Start private method call - Transformed +Not doing anything here +pre Finish private method call - Transformed +Goodbye - private - Transformed +post Finish private method call - Transformed diff --git a/test/916-obsolete-jit/info.txt b/test/916-obsolete-jit/info.txt new file mode 100644 index 0000000000..c8b892cedd --- /dev/null +++ b/test/916-obsolete-jit/info.txt @@ -0,0 +1 @@ +Tests basic obsolete method support diff --git a/test/916-obsolete-jit/run b/test/916-obsolete-jit/run new file mode 100755 index 0000000000..9056211284 --- /dev/null +++ b/test/916-obsolete-jit/run @@ -0,0 +1,27 @@ +#!/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. + +# We are testing the redefinition of compiled code but with jvmti we only allow +# jitted compiled code so always add the --jit argument. +if [[ "$@" == *"--jit"* ]]; then + other_args="" +else + other_args="--jit" +fi +./default-run "$@" --experimental agents \ + --experimental runtime-plugins \ + ${other_args} \ + --jvmti diff --git a/test/916-obsolete-jit/src/Main.java b/test/916-obsolete-jit/src/Main.java new file mode 100644 index 0000000000..74eb003d5c --- /dev/null +++ b/test/916-obsolete-jit/src/Main.java @@ -0,0 +1,210 @@ +/* + * 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.function.Consumer; +import java.lang.reflect.Method; +import java.util.Base64; + +public class Main { + + // import java.util.function.Consumer; + // + // class Transform { + // private void Start(Consumer<String> reporter) { + // reporter.accept("Hello - private - Transformed"); + // } + // + // private void Finish(Consumer<String> reporter) { + // reporter.accept("Goodbye - private - Transformed"); + // } + // + // public void sayHi(Runnable r, Consumer<String> reporter) { + // reporter.accept("pre Start private method call - Transformed"); + // Start(reporter); + // reporter.accept("post Start private method call - Transformed"); + // r.run(); + // reporter.accept("pre Finish private method call - Transformed"); + // Finish(reporter); + // reporter.accept("post Finish private method call - Transformed"); + // } + // } + private static final byte[] CLASS_BYTES = Base64.getDecoder().decode( + "yv66vgAAADQAMAoADQAcCAAdCwAeAB8IACAIACEKAAwAIggAIwsAJAAlCAAmCgAMACcIACgHACkH" + + "ACoBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAFU3RhcnQBACAoTGph" + + "dmEvdXRpbC9mdW5jdGlvbi9Db25zdW1lcjspVgEACVNpZ25hdHVyZQEANChMamF2YS91dGlsL2Z1" + + "bmN0aW9uL0NvbnN1bWVyPExqYXZhL2xhbmcvU3RyaW5nOz47KVYBAAZGaW5pc2gBAAVzYXlIaQEA" + + "NChMamF2YS9sYW5nL1J1bm5hYmxlO0xqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXI7KVYBAEgo" + + "TGphdmEvbGFuZy9SdW5uYWJsZTtMamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyPExqYXZhL2xh" + + "bmcvU3RyaW5nOz47KVYBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAA4ADwEAHUhlbGxv" + + "IC0gcHJpdmF0ZSAtIFRyYW5zZm9ybWVkBwArDAAsAC0BAB9Hb29kYnllIC0gcHJpdmF0ZSAtIFRy" + + "YW5zZm9ybWVkAQArcHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAwA" + + "EgATAQAscG9zdCBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQHAC4MAC8A" + + "DwEALHByZSBGaW5pc2ggcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAAWABMBAC1w" + + "b3N0IEZpbmlzaCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQBAAlUcmFuc2Zvcm0B" + + "ABBqYXZhL2xhbmcvT2JqZWN0AQAbamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyAQAGYWNjZXB0" + + "AQAVKExqYXZhL2xhbmcvT2JqZWN0OylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAADAAN" + + "AAAAAAAEAAAADgAPAAEAEAAAAB0AAQABAAAABSq3AAGxAAAAAQARAAAABgABAAAAEwACABIAEwAC" + + "ABAAAAAlAAIAAgAAAAkrEgK5AAMCALEAAAABABEAAAAKAAIAAAAVAAgAFgAUAAAAAgAVAAIAFgAT" + + "AAIAEAAAACUAAgACAAAACSsSBLkAAwIAsQAAAAEAEQAAAAoAAgAAABkACAAaABQAAAACABUAAQAX" + + "ABgAAgAQAAAAZQACAAMAAAAxLBIFuQADAgAqLLcABiwSB7kAAwIAK7kACAEALBIJuQADAgAqLLcA" + + "CiwSC7kAAwIAsQAAAAEAEQAAACIACAAAAB0ACAAeAA0AHwAVACAAGwAhACMAIgAoACMAMAAkABQA" + + "AAACABkAAQAaAAAAAgAb"); + private static final byte[] DEX_BYTES = Base64.getDecoder().decode( + "ZGV4CjAzNQBc8wr9PcHqnOR61m+0kimXTSddVMToJPuYBQAAcAAAAHhWNBIAAAAAAAAAAOAEAAAc" + + "AAAAcAAAAAYAAADgAAAABAAAAPgAAAAAAAAAAAAAAAcAAAAoAQAAAQAAAGABAAAYBAAAgAEAAHoC" + + "AAB9AgAAgAIAAIgCAACOAgAAlgIAALcCAADWAgAA4wIAAAIDAAAWAwAALAMAAEADAABeAwAAfQMA" + + "AIQDAACUAwAAlwMAAJsDAACgAwAAqAMAALwDAADrAwAAGQQAAEcEAAB0BAAAeQQAAIAEAAAHAAAA" + + "CAAAAAkAAAAKAAAADQAAABAAAAAQAAAABQAAAAAAAAARAAAABQAAAGQCAAASAAAABQAAAGwCAAAR" + + "AAAABQAAAHQCAAAAAAAAAgAAAAAAAwAEAAAAAAADAA4AAAAAAAIAGgAAAAIAAAACAAAAAwAAABkA" + + "AAAEAAEAEwAAAAAAAAAAAAAAAgAAAAAAAAAPAAAAPAIAAMoEAAAAAAAAAQAAAKgEAAABAAAAuAQA" + + "AAEAAQABAAAAhwQAAAQAAABwEAQAAAAOAAMAAgACAAAAjAQAAAcAAAAbAAUAAAByIAYAAgAOAAAA" + + "AwACAAIAAACTBAAABwAAABsABgAAAHIgBgACAA4AAAAEAAMAAgAAAJoEAAAiAAAAGwAYAAAAciAG" + + "AAMAcCACADEAGwAWAAAAciAGAAMAchAFAAIAGwAXAAAAciAGAAMAcCABADEAGwAVAAAAciAGAAMA" + + "DgAAAAAAAAAAAAMAAAAAAAAAAQAAAIABAAACAAAAgAEAAAMAAACIAQAAAQAAAAIAAAACAAAAAwAE" + + "AAEAAAAEAAEoAAE8AAY8aW5pdD4ABD47KVYABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBU" + + "cmFuc2Zvcm1lZAAdSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07AB1M" + + "ZGFsdmlrL2Fubm90YXRpb24vU2lnbmF0dXJlOwASTGphdmEvbGFuZy9PYmplY3Q7ABRMamF2YS9s" + + "YW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABxMamF2YS91dGlsL2Z1bmN0aW9uL0Nv" + + "bnN1bWVyAB1MamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyOwAFU3RhcnQADlRyYW5zZm9ybS5q" + + "YXZhAAFWAAJWTAADVkxMAAZhY2NlcHQAEmVtaXR0ZXI6IGphY2stNC4xOQAtcG9zdCBGaW5pc2gg" + + "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkACxwb3N0IFN0YXJ0IHByaXZhdGUgbWV0" + + "aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAscHJlIEZpbmlzaCBwcml2YXRlIG1ldGhvZCBjYWxsIC0g" + + "VHJhbnNmb3JtZWQAK3ByZSBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQA" + + "A3J1bgAFc2F5SGkABXZhbHVlABMABw4AGQEABw5pABUBAAcOaQAdAgAABw5pPGk8aTxpAAIBARsc" + + "BRcAFwwXARcLFwMCAQEbHAYXABcKFwwXARcLFwMAAAMBAICABJADAQKoAwECyAMDAegDDwAAAAAA" + + "AAABAAAAAAAAAAEAAAAcAAAAcAAAAAIAAAAGAAAA4AAAAAMAAAAEAAAA+AAAAAUAAAAHAAAAKAEA" + + "AAYAAAABAAAAYAEAAAMQAAACAAAAgAEAAAEgAAAEAAAAkAEAAAYgAAABAAAAPAIAAAEQAAADAAAA" + + "ZAIAAAIgAAAcAAAAegIAAAMgAAAEAAAAhwQAAAQgAAACAAAAqAQAAAAgAAABAAAAygQAAAAQAAAB" + + "AAAA4AQAAA=="); + + // A class that we can use to keep track of the output of this test. + private static class TestWatcher implements Consumer<String> { + private StringBuilder sb; + public TestWatcher() { + sb = new StringBuilder(); + } + + @Override + public void accept(String s) { + sb.append(s); + sb.append('\n'); + } + + public String getOutput() { + return sb.toString(); + } + + public void clear() { + sb = new StringBuilder(); + } + } + + public static void main(String[] args) { + System.loadLibrary(args[1]); + doTest(new Transform(), new TestWatcher()); + } + + // TODO Workaround to (1) inability to ensure that current_method is not put into a register by + // the JIT and/or (2) inability to deoptimize frames near runtime functions. + // TODO Fix one/both of these issues. + public static void doCall(Runnable r) { + r.run(); + } + + private static boolean interpreting = true; + private static boolean retry = false; + + public static void doTest(Transform t, TestWatcher w) { + // Get the methods that need to be optimized. + Method say_hi_method; + Method do_call_method; + // Figure out if we can even JIT at all. + final boolean has_jit = hasJit(); + try { + say_hi_method = Transform.class.getDeclaredMethod( + "sayHi", Runnable.class, Consumer.class); + do_call_method = Main.class.getDeclaredMethod("doCall", Runnable.class); + } catch (Exception e) { + System.out.println("Unable to find methods!"); + e.printStackTrace(); + return; + } + // Makes sure the stack is the way we want it for the test and does the redefinition. It will + // set the retry boolean to true if we need to go around again due to a bad stack. + Runnable do_redefinition = () -> { + if (has_jit && + (Main.isInterpretedFunction(say_hi_method, true) || + Main.isInterpretedFunction(do_call_method, false))) { + // Try again. We are not running the right jitted methods/cannot redefine them now. + retry = true; + } else { + // Actually do the redefinition. The stack looks good. + retry = false; + w.accept("transforming calling function"); + doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES); + } + }; + // This does nothing. + Runnable noop = () -> {}; + // This just prints something out to show we are running the Runnable. + Runnable say_nothing = () -> { w.accept("Not doing anything here"); }; + // This checks to see if we have jitted the methods we are testing. + Runnable check_interpreting = () -> { + // TODO remove the second check when we remove the doCall function. We need to check that + // both of these functions aren't being interpreted because if sayHi is the test doesn't do + // anything and if doCall is then there will be a runtime call right above the sayHi + // function preventing sayHi from being deoptimized. + interpreting = has_jit && (Main.isInterpretedFunction(say_hi_method, true) || + Main.isInterpretedFunction(do_call_method, false)); + }; + do { + w.clear(); + // Wait for the methods to be jitted + long j = 0; + do { + for (int i = 0; i < 10000; i++) { + t.sayHi(noop, w); + j++; + // Clear so that we won't OOM if we go around a few times. + w.clear(); + } + t.sayHi(check_interpreting, w); + if (j >= 1000000) { + System.out.println("FAIL: Could not make sayHi be Jitted!"); + return; + } + j++; + } while(interpreting); + // Clear output. Now we try for real. + w.clear(); + // Try and redefine. + t.sayHi(say_nothing, w); + t.sayHi(do_redefinition, w); + t.sayHi(say_nothing, w); + } while (retry); + // Print output of last run. + System.out.print(w.getOutput()); + } + + private static native boolean hasJit(); + + private static native boolean isInterpretedFunction(Method m, boolean require_deoptimizable); + + // Transforms the class + private static native void doCommonClassRedefinition(Class<?> target, + byte[] classfile, + byte[] dexfile); +} diff --git a/test/916-obsolete-jit/src/Transform.java b/test/916-obsolete-jit/src/Transform.java new file mode 100644 index 0000000000..f4dcf09dc6 --- /dev/null +++ b/test/916-obsolete-jit/src/Transform.java @@ -0,0 +1,43 @@ +/* + * 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.function.Consumer; + +class Transform { + private void Start(Consumer<String> reporter) { + reporter.accept("hello - private"); + } + + private void Finish(Consumer<String> reporter) { + reporter.accept("goodbye - private"); + } + + public void sayHi(Runnable r, Consumer<String> reporter) { + reporter.accept("Pre Start private method call"); + Start(reporter); + reporter.accept("Post Start private method call"); + // TODO Revisit with b/33616143 + // TODO Uncomment this once either b/33630159 or b/33616143 are resolved. + // r.run(); + // TODO This doCall function is a very temporary fix until we get either deoptimization near + // runtime frames working, forcing current method to be always read from the stack or both + // working. + Main.doCall(r); + reporter.accept("Pre Finish private method call"); + Finish(reporter); + reporter.accept("Post Finish private method call"); + } +} diff --git a/test/917-fields-transformation/run b/test/917-fields-transformation/run index a434b63e42..4379349cb2 100755 --- a/test/917-fields-transformation/run +++ b/test/917-fields-transformation/run @@ -14,30 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -plugin=libopenjdkjvmtid.so -agent=libtiagentd.so -lib=tiagentd -if [[ "$@" == *"-O"* ]]; then - agent=libtiagent.so - plugin=libopenjdkjvmti.so - lib=tiagent -fi - -if [[ "$@" == *"--jvm"* ]]; then - arg="jvm" -else - arg="art" - if [[ "$@" != *"--debuggable"* ]]; then - other_args=" -Xcompiler-option --debuggable " - else - other_args="" - fi -fi - ./default-run "$@" --experimental agents \ --experimental runtime-plugins \ - --runtime-option -agentpath:${agent}=917-fields-transformation,${arg} \ - --android-runtime-option -Xplugin:${plugin} \ - --android-runtime-option -Xfully-deoptable \ - ${other_args} \ - --args ${lib} + --jvmti diff --git a/test/Android.bp b/test/Android.bp index 2625f56418..5a2c90230e 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -243,6 +243,9 @@ art_cc_defaults { name: "libtiagent-defaults", defaults: ["libartagent-defaults"], srcs: [ + // This is to get the IsInterpreted native method. + "common/stack_inspect.cc", + "common/runtime_state.cc", "ti-agent/common_load.cc", "ti-agent/common_helper.cc", "901-hello-ti-agent/basics.cc", diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index fdd5b6009c..ec1f6ba239 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -286,6 +286,9 @@ TEST_ART_BROKEN_TARGET_TESTS += \ 911-get-stack-trace \ 912-classes \ 913-heaps \ + 914-hello-obsolescence \ + 915-obsolete-2 \ + 916-obsolete-jit \ 917-fields-transformation \ ifneq (,$(filter target,$(TARGET_TYPES))) @@ -539,7 +542,6 @@ TEST_ART_BROKEN_INTERPRETER_RUN_TESTS := # Test 906 iterates the heap filtering with different options. No instances should be created # between those runs to be able to have precise checks. # Test 902 hits races with the JIT compiler. b/32821077 -# Test 626-const-class-linking can deadlock with JIT. b/33567581 # Test 629 requires compilation. # Test 914, 915, 917, & 918 are very sensitive to the exact state of the stack, # including the jit-inserted runtime frames. This causes them to be somewhat @@ -548,7 +550,6 @@ TEST_ART_BROKEN_INTERPRETER_RUN_TESTS := # feature for JIT use cases in a way that is resilient to the jit frames. TEST_ART_BROKEN_JIT_RUN_TESTS := \ 137-cfi \ - 626-const-class-linking \ 629-vdex-speed \ 902-hello-transformation \ 904-object-allocation \ diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc index f26e122580..7451cf97de 100644 --- a/test/common/runtime_state.cc +++ b/test/common/runtime_state.cc @@ -19,6 +19,7 @@ #include "base/enums.h" #include "base/logging.h" #include "dex_file-inl.h" +#include "instrumentation.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" #include "mirror/class-inl.h" @@ -30,6 +31,16 @@ namespace art { +// public static native boolean hasJit(); + +extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJit(JNIEnv*, jclass) { + Runtime* runtime = Runtime::Current(); + return runtime != nullptr + && runtime->GetJit() != nullptr + && runtime->GetInstrumentation()->GetCurrentInstrumentationLevel() != + instrumentation::Instrumentation::InstrumentationLevel::kInstrumentWithInterpreter; +} + // public static native boolean hasOatFile(); extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasOatFile(JNIEnv* env, jclass cls) { diff --git a/test/common/stack_inspect.cc b/test/common/stack_inspect.cc index 4df2d470ec..df7fa20226 100644 --- a/test/common/stack_inspect.cc +++ b/test/common/stack_inspect.cc @@ -18,6 +18,7 @@ #include "base/logging.h" #include "dex_file-inl.h" +#include "jni_internal.h" #include "mirror/class-inl.h" #include "nth_caller_visitor.h" #include "oat_file.h" @@ -52,6 +53,89 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpreted(JNIEnv* env, jclas return IsInterpreted(env, klass, 1); } +// public static native boolean isInterpreted(int depth); + +extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpretedAt(JNIEnv* env, + jclass klass, + jint depth) { + return IsInterpreted(env, klass, depth); +} + + +// public static native boolean isInterpretedFunction(String smali); + +// TODO Remove 'allow_runtime_frames' option once we have deoptimization through runtime frames. +struct MethodIsInterpretedVisitor : public StackVisitor { + public: + MethodIsInterpretedVisitor(Thread* thread, ArtMethod* goal, bool require_deoptable) + : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames), + goal_(goal), + method_is_interpreted_(true), + method_found_(false), + prev_was_runtime_(true), + require_deoptable_(require_deoptable) {} + + virtual bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) { + if (goal_ == GetMethod()) { + method_is_interpreted_ = (require_deoptable_ && prev_was_runtime_) || IsShadowFrame(); + method_found_ = true; + return false; + } + prev_was_runtime_ = GetMethod()->IsRuntimeMethod(); + return true; + } + + bool IsInterpreted() { + return method_is_interpreted_; + } + + bool IsFound() { + return method_found_; + } + + private: + const ArtMethod* goal_; + bool method_is_interpreted_; + bool method_found_; + bool prev_was_runtime_; + bool require_deoptable_; +}; + +// TODO Remove 'require_deoptimizable' option once we have deoptimization through runtime frames. +extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpretedFunction( + JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jobject method, jboolean require_deoptimizable) { + // Return false if this seems to not be an ART runtime. + if (Runtime::Current() == nullptr) { + return JNI_FALSE; + } + if (method == nullptr) { + env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "method is null!"); + return JNI_FALSE; + } + jmethodID id = env->FromReflectedMethod(method); + if (id == nullptr) { + env->ThrowNew(env->FindClass("java/lang/Error"), "Unable to interpret method argument!"); + return JNI_FALSE; + } + bool result; + bool found; + { + ScopedObjectAccess soa(env); + ArtMethod* goal = jni::DecodeArtMethod(id); + MethodIsInterpretedVisitor v(soa.Self(), goal, require_deoptimizable); + v.WalkStack(); + bool enters_interpreter = Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge( + goal->GetEntryPointFromQuickCompiledCode()); + result = (v.IsInterpreted() || enters_interpreter); + found = v.IsFound(); + } + if (!found) { + env->ThrowNew(env->FindClass("java/lang/Error"), "Unable to find given method in stack!"); + return JNI_FALSE; + } + return result; +} + // public static native void assertIsInterpreted(); extern "C" JNIEXPORT void JNICALL Java_Main_assertIsInterpreted(JNIEnv* env, jclass klass) { diff --git a/test/etc/default-build b/test/etc/default-build index a0408aaf79..e9e388646a 100755 --- a/test/etc/default-build +++ b/test/etc/default-build @@ -69,6 +69,7 @@ DEFAULT_EXPERIMENT="no-experiment" # Setup experimental flag mappings in a bash associative array. declare -A JACK_EXPERIMENTAL_ARGS +JACK_EXPERIMENTAL_ARGS["agents"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24" JACK_EXPERIMENTAL_ARGS["method-handles"]="-D jack.java.source.version=1.7 -D jack.android.min-api-level=o-b1" @@ -76,12 +77,14 @@ JACK_EXPERIMENTAL_ARGS["method-handles"]="-D jack.java.source.version=1.7 -D jac declare -A SMALI_EXPERIMENTAL_ARGS SMALI_EXPERIMENTAL_ARGS["default-methods"]="--api-level 24" SMALI_EXPERIMENTAL_ARGS["method-handles"]="--api-level 26" +SMALI_EXPERIMENTAL_ARGS["agents"]="--api-level 26" 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["method-handles"]="-source 1.8 -target 1.8" JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.7 -target 1.7" +JAVAC_EXPERIMENTAL_ARGS["agents"]="-source 1.8 -target 1.8" while true; do if [ "x$1" = "x--dx-option" ]; then diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 566f7ba522..8245947251 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -30,6 +30,7 @@ HOST="n" INTERPRETER="n" JIT="n" INVOKE_WITH="" +IS_JVMTI_TEST="n" ISA=x86 LIBRARY_DIRECTORY="lib" TEST_DIRECTORY="nativetest" @@ -59,14 +60,18 @@ ARGS="" EXTERNAL_LOG_TAGS="n" # if y respect externally set ANDROID_LOG_TAGS. DRY_RUN="n" # if y prepare to run the test but don't run it. TEST_VDEX="n" +TEST_IS_NDEBUG="n" APP_IMAGE="y" while true; do if [ "x$1" = "x--quiet" ]; then QUIET="y" shift + elif [ "x$1" = "x--jvmti" ]; then + IS_JVMTI_TEST="y" + shift elif [ "x$1" = "x-O" ]; then - # Ignore this option. + TEST_IS_NDEBUG="y" shift elif [ "x$1" = "x--lib" ]; then shift @@ -382,6 +387,28 @@ if [ "$JIT" = "y" ]; then fi fi +if [ "$IS_JVMTI_TEST" = "y" ]; then + plugin=libopenjdkjvmtid.so + agent=libtiagentd.so + lib=tiagentd + if [[ "$TEST_IS_NDEBUG" = "y" ]]; then + agent=libtiagent.so + plugin=libopenjdkjvmti.so + lib=tiagent + fi + + ARGS="${ARGS} ${lib}" + if [[ "$USE_JVM" = "y" ]]; then + FLAGS="${FLAGS} -agentpath:${agent}=${TEST_NAME},jvm" + else + FLAGS="${FLAGS} -agentpath:${agent}=${TEST_NAME},art" + FLAGS="${FLAGS} -Xplugin:${plugin}" + FLAGS="${FLAGS} -Xfully-deoptable" + # Always make the compilation be debuggable. + COMPILE_FLAGS="${COMPILE_FLAGS} --debuggable" + fi +fi + JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni" if [ "$RELOCATE" = "y" ]; then diff --git a/test/ti-agent/common_helper.cc b/test/ti-agent/common_helper.cc index 3e2b16802b..ebf1e4621c 100644 --- a/test/ti-agent/common_helper.cc +++ b/test/ti-agent/common_helper.cc @@ -18,8 +18,11 @@ #include <stdio.h> +#include "art_method.h" #include "jni.h" #include "openjdkjvmti/jvmti.h" +#include "scoped_thread_state_change-inl.h" +#include "stack.h" #include "ti-agent/common_load.h" #include "utils.h" diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc index 38861482d2..79c17d744f 100644 --- a/test/ti-agent/common_load.cc +++ b/test/ti-agent/common_load.cc @@ -66,6 +66,9 @@ AgentLib agents[] = { { "911-get-stack-trace", Test911GetStackTrace::OnLoad, nullptr }, { "912-classes", Test912Classes::OnLoad, nullptr }, { "913-heaps", Test913Heaps::OnLoad, nullptr }, + { "914-hello-obsolescence", common_redefine::OnLoad, nullptr }, + { "915-obsolete-2", common_redefine::OnLoad, nullptr }, + { "916-obsolete-jit", common_redefine::OnLoad, nullptr }, { "917-fields-transformation", common_redefine::OnLoad, nullptr }, }; |