summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/051-thread/expected.txt2
-rw-r--r--test/051-thread/src/Main.java48
-rw-r--r--test/160-read-barrier-stress/expected.txt0
-rw-r--r--test/160-read-barrier-stress/info.txt1
-rw-r--r--test/160-read-barrier-stress/run18
-rw-r--r--test/160-read-barrier-stress/src/Main.java1111
-rw-r--r--test/160-read-barrier-stress/src/ManyFieldsBase0.java1018
-rw-r--r--test/160-read-barrier-stress/src/ManyFieldsBase1.java1018
-rw-r--r--test/160-read-barrier-stress/src/ManyFieldsBase2.java1018
-rw-r--r--test/160-read-barrier-stress/src/ManyFieldsBase3.java1018
-rw-r--r--test/623-checker-loop-regressions/src/Main.java24
-rw-r--r--test/646-checker-arraycopy-large-cst-pos/expected.txt1
-rw-r--r--test/646-checker-arraycopy-large-cst-pos/info.txt4
-rw-r--r--test/646-checker-arraycopy-large-cst-pos/src/Main.java37
-rw-r--r--test/646-checker-hadd-alt-byte/expected.txt1
-rw-r--r--test/646-checker-hadd-alt-byte/info.txt1
-rw-r--r--test/646-checker-hadd-alt-byte/src/Main.java241
-rw-r--r--test/646-checker-hadd-alt-char/expected.txt1
-rw-r--r--test/646-checker-hadd-alt-char/info.txt1
-rw-r--r--test/646-checker-hadd-alt-char/src/Main.java251
-rw-r--r--test/646-checker-hadd-alt-short/expected.txt1
-rw-r--r--test/646-checker-hadd-alt-short/info.txt1
-rw-r--r--test/646-checker-hadd-alt-short/src/Main.java242
-rw-r--r--test/646-checker-hadd-byte/expected.txt1
-rw-r--r--test/646-checker-hadd-byte/info.txt1
-rw-r--r--test/646-checker-hadd-byte/src/Main.java236
-rw-r--r--test/646-checker-hadd-char/expected.txt1
-rw-r--r--test/646-checker-hadd-char/info.txt1
-rw-r--r--test/646-checker-hadd-char/src/Main.java246
-rw-r--r--test/646-checker-hadd-short/expected.txt1
-rw-r--r--test/646-checker-hadd-short/info.txt1
-rw-r--r--test/646-checker-hadd-short/src/Main.java237
-rw-r--r--test/646-checker-long-const-to-int/expected.txt1
-rw-r--r--test/646-checker-long-const-to-int/info.txt1
-rw-r--r--test/646-checker-long-const-to-int/src/Main.java56
-rw-r--r--test/902-hello-transformation/src/Main.java51
-rw-r--r--test/902-hello-transformation/src/Transform.java28
-rw-r--r--test/902-hello-transformation/src/art/Redefinition.java96
-rw-r--r--test/902-hello-transformation/src/art/Test902.java82
-rw-r--r--test/904-object-allocation/expected.txt10
-rw-r--r--test/904-object-allocation/src/art/Test904.java10
-rw-r--r--test/904-object-allocation/tracking.cc27
-rw-r--r--test/910-methods/expected.txt14
-rw-r--r--test/910-methods/src/art/Test910.java69
-rw-r--r--test/912-classes/classes.cc219
-rw-r--r--test/912-classes/classes_art.cc146
-rw-r--r--test/912-classes/expected.txt75
-rw-r--r--test/912-classes/src/B.java18
-rw-r--r--test/912-classes/src/Main.java447
-rw-r--r--test/912-classes/src/art/DexData.java100
-rw-r--r--test/912-classes/src/art/Test912.java454
-rw-r--r--test/912-classes/src/art/Test912Art.java78
-rw-r--r--test/913-heaps/expected.txt169
-rw-r--r--test/913-heaps/heaps.cc111
-rw-r--r--test/913-heaps/src/art/Test913.java34
-rw-r--r--test/914-hello-obsolescence/src/Main.java58
-rw-r--r--test/914-hello-obsolescence/src/Transform.java30
-rw-r--r--test/914-hello-obsolescence/src/art/Redefinition.java96
-rw-r--r--test/914-hello-obsolescence/src/art/Test914.java86
-rw-r--r--test/915-obsolete-2/src/Main.java84
-rw-r--r--test/915-obsolete-2/src/art/Redefinition.java96
-rw-r--r--test/915-obsolete-2/src/art/Test915.java123
-rw-r--r--test/916-obsolete-jit/src/Main.java10
-rw-r--r--test/916-obsolete-jit/src/art/Redefinition.java96
-rw-r--r--test/917-fields-transformation/src/Main.java65
-rw-r--r--test/917-fields-transformation/src/Transform.java29
-rw-r--r--test/917-fields-transformation/src/art/Redefinition.java96
-rw-r--r--test/917-fields-transformation/src/art/Test917.java97
-rw-r--r--test/919-obsolete-fields/src/Main.java133
-rw-r--r--test/919-obsolete-fields/src/Transform.java42
-rw-r--r--test/919-obsolete-fields/src/art/Redefinition.java96
-rw-r--r--test/919-obsolete-fields/src/art/Test919.java173
-rw-r--r--test/921-hello-failure/src/Main.java68
-rw-r--r--test/921-hello-failure/src/art/Redefinition.java96
-rw-r--r--test/924-threads/expected.txt11
-rw-r--r--test/924-threads/src/art/Test924.java72
-rw-r--r--test/924-threads/threads.cc37
-rw-r--r--test/926-multi-obsolescence/src/Main.java113
-rw-r--r--test/926-multi-obsolescence/src/Transform.java30
-rw-r--r--test/926-multi-obsolescence/src/Transform2.java23
-rw-r--r--test/926-multi-obsolescence/src/art/Redefinition.java96
-rw-r--r--test/926-multi-obsolescence/src/art/Test926.java140
-rw-r--r--test/930-hello-retransform/src/Main.java55
-rw-r--r--test/930-hello-retransform/src/Transform.java28
-rw-r--r--test/930-hello-retransform/src/art/Redefinition.java96
-rw-r--r--test/930-hello-retransform/src/art/Test930.java78
-rw-r--r--test/932-transform-saves/src/Main.java101
-rw-r--r--test/932-transform-saves/src/Transform.java28
-rw-r--r--test/932-transform-saves/src/art/Redefinition.java96
-rw-r--r--test/932-transform-saves/src/art/Test932.java129
-rw-r--r--test/934-load-transform/src/Main.java11
-rw-r--r--test/934-load-transform/src/art/Redefinition.java96
-rw-r--r--test/935-non-retransformable/src/Main.java24
-rw-r--r--test/935-non-retransformable/src/art/Redefinition.java96
-rw-r--r--test/937-hello-retransform-package/src/Main.java16
-rw-r--r--test/937-hello-retransform-package/src/art/Redefinition.java96
-rw-r--r--test/938-load-transform-bcp/src/Main.java8
-rw-r--r--test/938-load-transform-bcp/src/art/Redefinition.java96
-rw-r--r--test/939-hello-transformation-bcp/src/Main.java7
-rw-r--r--test/939-hello-transformation-bcp/src/art/Redefinition.java96
-rw-r--r--test/940-recursive-obsolete/src/Main.java75
-rw-r--r--test/940-recursive-obsolete/src/Transform.java28
-rw-r--r--test/940-recursive-obsolete/src/art/Redefinition.java96
-rw-r--r--test/940-recursive-obsolete/src/art/Test940.java106
-rw-r--r--test/941-recurive-obsolete-jit/src/Main.java7
-rw-r--r--test/941-recurive-obsolete-jit/src/art/Redefinition.java96
-rw-r--r--test/942-private-recursive/src/Main.java80
-rw-r--r--test/942-private-recursive/src/art/Redefinition.java96
-rw-r--r--test/942-private-recursive/src/art/Test942.java115
-rw-r--r--test/943-private-recursive-jit/src/Main.java7
-rw-r--r--test/943-private-recursive-jit/src/art/Redefinition.java96
-rw-r--r--test/944-transform-classloaders/classloader.cc43
-rw-r--r--test/944-transform-classloaders/src/Main.java248
-rw-r--r--test/944-transform-classloaders/src/Transform.java28
-rw-r--r--test/944-transform-classloaders/src/Transform2.java21
-rw-r--r--test/944-transform-classloaders/src/art/Redefinition.java96
-rw-r--r--test/944-transform-classloaders/src/art/Test944.java297
-rw-r--r--test/945-obsolete-native/obsolete_native.cc17
-rw-r--r--test/945-obsolete-native/src/Main.java63
-rw-r--r--test/945-obsolete-native/src/Transform.java25
-rw-r--r--test/945-obsolete-native/src/art/Redefinition.java96
-rw-r--r--test/945-obsolete-native/src/art/Test945.java96
-rw-r--r--test/946-obsolete-throw/expected.txt9
-rw-r--r--test/946-obsolete-throw/src/Main.java67
-rw-r--r--test/946-obsolete-throw/src/Transform.java30
-rw-r--r--test/946-obsolete-throw/src/art/Redefinition.java96
-rw-r--r--test/946-obsolete-throw/src/art/Test946.java95
-rw-r--r--test/947-reflect-method/src/Main.java56
-rw-r--r--test/947-reflect-method/src/Transform.java28
-rw-r--r--test/947-reflect-method/src/art/Redefinition.java96
-rw-r--r--test/947-reflect-method/src/art/Test947.java82
-rw-r--r--test/948-change-annotations/src/Main.java9
-rw-r--r--test/948-change-annotations/src/art/Redefinition.java96
-rw-r--r--test/949-in-memory-transform/src/Main.java106
-rw-r--r--test/949-in-memory-transform/src/art/Redefinition.java96
-rw-r--r--test/949-in-memory-transform/src/art/Test949.java123
-rw-r--r--test/950-redefine-intrinsic/src/Main.java6
-rw-r--r--test/950-redefine-intrinsic/src/art/Redefinition.java96
-rw-r--r--test/951-threaded-obsolete/src/Main.java82
-rw-r--r--test/951-threaded-obsolete/src/Transform.java30
-rw-r--r--test/951-threaded-obsolete/src/art/Redefinition.java96
-rw-r--r--test/951-threaded-obsolete/src/art/Test951.java108
-rw-r--r--test/959-invoke-polymorphic-accessors/src/Main.java12
-rwxr-xr-xtest/980-redefine-object/check2
-rw-r--r--test/980-redefine-object/expected.txt56
-rw-r--r--test/980-redefine-object/redefine_object.cc58
-rw-r--r--test/980-redefine-object/src-ex/TestWatcher.java60
-rw-r--r--test/980-redefine-object/src/Main.java45
-rw-r--r--test/980-redefine-object/src/art/Redefinition.java96
-rw-r--r--test/981-dedup-original-dex/src/Main.java188
-rw-r--r--test/981-dedup-original-dex/src/Transform.java21
-rw-r--r--test/981-dedup-original-dex/src/Transform2.java21
-rw-r--r--test/981-dedup-original-dex/src/art/Redefinition.java96
-rw-r--r--test/981-dedup-original-dex/src/art/Test981.java210
-rw-r--r--test/982-ok-no-retransform/src/Main.java20
-rw-r--r--test/982-ok-no-retransform/src/Transform.java28
-rw-r--r--test/982-ok-no-retransform/src/art/Redefinition.java96
-rw-r--r--test/982-ok-no-retransform/src/art/Test982.java (renamed from test/942-private-recursive/src/Transform.java)29
-rw-r--r--test/983-source-transform-verify/expected.txt2
-rw-r--r--test/983-source-transform-verify/src/Main.java21
-rw-r--r--test/983-source-transform-verify/src/Transform.java28
-rw-r--r--test/983-source-transform-verify/src/art/Redefinition.java96
-rw-r--r--test/983-source-transform-verify/src/art/Test983.java (renamed from test/915-obsolete-2/src/Transform.java)29
-rw-r--r--test/984-obsolete-invoke/obsolete_invoke.cc6
-rw-r--r--test/984-obsolete-invoke/src/Main.java94
-rw-r--r--test/984-obsolete-invoke/src/Transform.java25
-rw-r--r--test/984-obsolete-invoke/src/art/Redefinition.java96
-rw-r--r--test/984-obsolete-invoke/src/art/Test984.java122
-rw-r--r--test/985-re-obsolete/expected.txt35
-rw-r--r--test/985-re-obsolete/info.txt4
-rwxr-xr-xtest/985-re-obsolete/run17
-rw-r--r--test/985-re-obsolete/src/Main.java (renamed from test/912-classes/src-ex/A.java)5
-rw-r--r--test/985-re-obsolete/src/art/Main.java (renamed from test/926-multi-obsolescence/src/CommonClassDefinition.java)19
-rw-r--r--test/985-re-obsolete/src/art/Redefinition.java96
-rw-r--r--test/985-re-obsolete/src/art/Test985.java197
-rw-r--r--test/986-native-method-bind/expected.txt8
-rw-r--r--test/986-native-method-bind/info.txt1
-rw-r--r--test/986-native-method-bind/native_bind.cc110
-rwxr-xr-xtest/986-native-method-bind/run17
-rw-r--r--test/986-native-method-bind/src/Main.java (renamed from test/912-classes/src-ex/C.java)5
-rw-r--r--test/986-native-method-bind/src/art/Main.java (renamed from test/944-transform-classloaders/src/CommonClassDefinition.java)19
-rw-r--r--test/986-native-method-bind/src/art/Redefinition.java96
-rw-r--r--test/986-native-method-bind/src/art/Test986.java82
-rw-r--r--test/Android.bp43
-rw-r--r--test/Android.run-test-jvmti-java-library.mk46
-rw-r--r--test/Android.run-test.mk12
-rw-r--r--test/common/stack_inspect.cc13
-rwxr-xr-xtest/etc/default-build2
-rwxr-xr-xtest/etc/run-test-jar28
-rw-r--r--test/knownfailures.json254
-rwxr-xr-xtest/run-test8
-rw-r--r--test/testrunner/env.py3
-rw-r--r--test/testrunner/target_config.py26
-rwxr-xr-xtest/testrunner/testrunner.py27
-rw-r--r--test/ti-agent/common_helper.cc129
-rw-r--r--test/ti-agent/common_load.cc14
-rw-r--r--test/ti-agent/scoped_local_ref.h2
-rw-r--r--test/ti-stress/stress.cc210
198 files changed, 15159 insertions, 3497 deletions
diff --git a/test/051-thread/expected.txt b/test/051-thread/expected.txt
index 3fc34929eb..c8af963723 100644
--- a/test/051-thread/expected.txt
+++ b/test/051-thread/expected.txt
@@ -12,4 +12,6 @@ testSetName running
testSetName finished
testThreadPriorities starting
testThreadPriorities finished
+Found current Thread in ThreadGroup
+Found expected stack in getAllStackTraces()
thread test done
diff --git a/test/051-thread/src/Main.java b/test/051-thread/src/Main.java
index 82fc0d471b..08cb5deeac 100644
--- a/test/051-thread/src/Main.java
+++ b/test/051-thread/src/Main.java
@@ -15,6 +15,9 @@
*/
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
/**
* Test some basic thread stuff.
@@ -28,6 +31,8 @@ public class Main {
testSleepZero();
testSetName();
testThreadPriorities();
+ testMainThreadGroup();
+ testMainThreadAllStackTraces();
System.out.println("thread test done");
}
@@ -159,6 +164,49 @@ public class Main {
System.out.print("testThreadPriorities finished\n");
}
+ private static void testMainThreadGroup() {
+ Thread threads[] = new Thread[10];
+ Thread current = Thread.currentThread();
+ current.getThreadGroup().enumerate(threads);
+
+ for (Thread t : threads) {
+ if (t == current) {
+ System.out.println("Found current Thread in ThreadGroup");
+ return;
+ }
+ }
+ throw new RuntimeException("Did not find main thread: " + Arrays.toString(threads));
+ }
+
+ private static void testMainThreadAllStackTraces() {
+ StackTraceElement[] trace = Thread.getAllStackTraces().get(Thread.currentThread());
+ if (trace == null) {
+ throw new RuntimeException("Did not find main thread: " + Thread.getAllStackTraces());
+ }
+ List<StackTraceElement> list = Arrays.asList(trace);
+ Iterator<StackTraceElement> it = list.iterator();
+ while (it.hasNext()) {
+ StackTraceElement ste = it.next();
+ if (ste.getClassName().equals("Main")) {
+ if (!ste.getMethodName().equals("testMainThreadAllStackTraces")) {
+ throw new RuntimeException(list.toString());
+ }
+
+ StackTraceElement ste2 = it.next();
+ if (!ste2.getClassName().equals("Main")) {
+ throw new RuntimeException(list.toString());
+ }
+ if (!ste2.getMethodName().equals("main")) {
+ throw new RuntimeException(list.toString());
+ }
+
+ System.out.println("Found expected stack in getAllStackTraces()");
+ return;
+ }
+ }
+ throw new RuntimeException(list.toString());
+ }
+
private static native int getNativePriority();
private static native boolean supportsThreadPriorities();
diff --git a/test/160-read-barrier-stress/expected.txt b/test/160-read-barrier-stress/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/160-read-barrier-stress/expected.txt
diff --git a/test/160-read-barrier-stress/info.txt b/test/160-read-barrier-stress/info.txt
new file mode 100644
index 0000000000..505fe33338
--- /dev/null
+++ b/test/160-read-barrier-stress/info.txt
@@ -0,0 +1 @@
+Test stressing read barriers for CC GC.
diff --git a/test/160-read-barrier-stress/run b/test/160-read-barrier-stress/run
new file mode 100644
index 0000000000..ab82229e4e
--- /dev/null
+++ b/test/160-read-barrier-stress/run
@@ -0,0 +1,18 @@
+#!/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.
+
+# Limit the Java heap to 16MiB to force more GCs.
+exec ${RUN} $@ --runtime-option -Xmx16m
diff --git a/test/160-read-barrier-stress/src/Main.java b/test/160-read-barrier-stress/src/Main.java
new file mode 100644
index 0000000000..7e130cef94
--- /dev/null
+++ b/test/160-read-barrier-stress/src/Main.java
@@ -0,0 +1,1111 @@
+/*
+ * 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) {
+ // Initialize local variables for comparison.
+ Object f0000 = manyFields.testField0000;
+ Object f1024 = manyFields.testField1024;
+ Object f4444 = manyFields.testField4444;
+ Object f4999 = manyFields.testField4999;
+ // Initialize largeArray for comparison.
+ largeArray[0] = f0000;
+ largeArray[1024] = f1024;
+ largeArray[4444] = f4444;
+ largeArray[4999] = f4999;
+ // Read indexes, they cannot be considered constant because the variables are volatile.
+ int i0 = index0;
+ int i1024 = index1024;
+ int i4444 = index4444;
+ int i4999 = index4999;
+ // Initialize strings, hide this under a condition based on a volatile field.
+ String testString0 = null;
+ String testString1 = null;
+ String testString2 = null;
+ String testString3 = null;
+ if (index0 != 12345678) {
+ // By having this in the const-string instructions in an if-block, we avoid
+ // GVN eliminating identical const-string instructions in the loop below.
+ testString0 = "testString0";
+ testString1 = "testString1";
+ testString2 = "testString2";
+ testString3 = "testString3";
+ }
+
+ // Continually check reads from `manyFields` and `largeArray` while allocating
+ // over 64MiB memory (with heap size limited to 16MiB), ensuring we run GC and
+ // stress the read barrier implementation if concurrent collector is enabled.
+ for (int i = 0; i != 64 * 1024; ++i) {
+ allocateAtLeast1KiB();
+ ManyFields mf = manyFields; // Load the volatile `manyFields` once on each iteration.
+ Object[] la = largeArray; // Load the volatile `largeArray` once on each iteration.
+ // Test reference field access.
+ assertSameObject(f0000, mf.testField0000);
+ assertSameObject(f1024, mf.testField1024);
+ assertSameObject(f4444, mf.testField4444);
+ assertSameObject(f4999, mf.testField4999);
+ // Test array access with constant index.
+ assertSameObject(f0000, la[0]);
+ assertSameObject(f1024, la[1024]);
+ assertSameObject(f4444, la[4444]);
+ assertSameObject(f4999, la[4999]);
+ // Test array access with non-constant index.
+ assertSameObject(f0000, la[i0]);
+ assertSameObject(f1024, la[i1024]);
+ assertSameObject(f4444, la[i4444]);
+ assertSameObject(f4999, la[i4999]);
+ // Test GC roots.
+ if (index0 != 12345678) {
+ assertSameObject(testString0, "testString0");
+ assertSameObject(testString1, "testString1");
+ assertSameObject(testString2, "testString2");
+ assertSameObject(testString3, "testString3");
+ }
+ // TODO: Stress GC roots (const-string/const-class, kBssEntry/kReferrersClass).
+ }
+ }
+
+ public static void assertSameObject(Object lhs, Object rhs) {
+ if (lhs != rhs) {
+ throw new Error("Different objects: " + lhs + " and " + rhs);
+ }
+ }
+
+ public static void allocateAtLeast1KiB() {
+ // Give GC more work by allocating Object arrays.
+ memory[allocationIndex] = new Object[1024 / 4];
+ ++allocationIndex;
+ if (allocationIndex == memory.length) {
+ allocationIndex = 0;
+ }
+ }
+
+ // Make these volatile to avoid load elimination.
+ public static volatile ManyFields manyFields = new ManyFields();
+ public static volatile Object[] largeArray = new Object[5000];
+ public static volatile int index0 = 0;
+ public static volatile int index1024 = 1024;
+ public static volatile int index4444 = 4444;
+ public static volatile int index4999 = 4999;
+
+ // We shall retain some allocated memory and release old allocations
+ // so that the GC has something to do.
+ public static Object[] memory = new Object[1024];
+ public static int allocationIndex = 0;
+}
+
+class ManyFields extends ManyFieldsBase3 {
+ public Object testField4000 = new Integer(4000);
+ public Object testField4001 = new Integer(4001);
+ public Object testField4002 = new Integer(4002);
+ public Object testField4003 = new Integer(4003);
+ public Object testField4004 = new Integer(4004);
+ public Object testField4005 = new Integer(4005);
+ public Object testField4006 = new Integer(4006);
+ public Object testField4007 = new Integer(4007);
+ public Object testField4008 = new Integer(4008);
+ public Object testField4009 = new Integer(4009);
+ public Object testField4010 = new Integer(4010);
+ public Object testField4011 = new Integer(4011);
+ public Object testField4012 = new Integer(4012);
+ public Object testField4013 = new Integer(4013);
+ public Object testField4014 = new Integer(4014);
+ public Object testField4015 = new Integer(4015);
+ public Object testField4016 = new Integer(4016);
+ public Object testField4017 = new Integer(4017);
+ public Object testField4018 = new Integer(4018);
+ public Object testField4019 = new Integer(4019);
+ public Object testField4020 = new Integer(4020);
+ public Object testField4021 = new Integer(4021);
+ public Object testField4022 = new Integer(4022);
+ public Object testField4023 = new Integer(4023);
+ public Object testField4024 = new Integer(4024);
+ public Object testField4025 = new Integer(4025);
+ public Object testField4026 = new Integer(4026);
+ public Object testField4027 = new Integer(4027);
+ public Object testField4028 = new Integer(4028);
+ public Object testField4029 = new Integer(4029);
+ public Object testField4030 = new Integer(4030);
+ public Object testField4031 = new Integer(4031);
+ public Object testField4032 = new Integer(4032);
+ public Object testField4033 = new Integer(4033);
+ public Object testField4034 = new Integer(4034);
+ public Object testField4035 = new Integer(4035);
+ public Object testField4036 = new Integer(4036);
+ public Object testField4037 = new Integer(4037);
+ public Object testField4038 = new Integer(4038);
+ public Object testField4039 = new Integer(4039);
+ public Object testField4040 = new Integer(4040);
+ public Object testField4041 = new Integer(4041);
+ public Object testField4042 = new Integer(4042);
+ public Object testField4043 = new Integer(4043);
+ public Object testField4044 = new Integer(4044);
+ public Object testField4045 = new Integer(4045);
+ public Object testField4046 = new Integer(4046);
+ public Object testField4047 = new Integer(4047);
+ public Object testField4048 = new Integer(4048);
+ public Object testField4049 = new Integer(4049);
+ public Object testField4050 = new Integer(4050);
+ public Object testField4051 = new Integer(4051);
+ public Object testField4052 = new Integer(4052);
+ public Object testField4053 = new Integer(4053);
+ public Object testField4054 = new Integer(4054);
+ public Object testField4055 = new Integer(4055);
+ public Object testField4056 = new Integer(4056);
+ public Object testField4057 = new Integer(4057);
+ public Object testField4058 = new Integer(4058);
+ public Object testField4059 = new Integer(4059);
+ public Object testField4060 = new Integer(4060);
+ public Object testField4061 = new Integer(4061);
+ public Object testField4062 = new Integer(4062);
+ public Object testField4063 = new Integer(4063);
+ public Object testField4064 = new Integer(4064);
+ public Object testField4065 = new Integer(4065);
+ public Object testField4066 = new Integer(4066);
+ public Object testField4067 = new Integer(4067);
+ public Object testField4068 = new Integer(4068);
+ public Object testField4069 = new Integer(4069);
+ public Object testField4070 = new Integer(4070);
+ public Object testField4071 = new Integer(4071);
+ public Object testField4072 = new Integer(4072);
+ public Object testField4073 = new Integer(4073);
+ public Object testField4074 = new Integer(4074);
+ public Object testField4075 = new Integer(4075);
+ public Object testField4076 = new Integer(4076);
+ public Object testField4077 = new Integer(4077);
+ public Object testField4078 = new Integer(4078);
+ public Object testField4079 = new Integer(4079);
+ public Object testField4080 = new Integer(4080);
+ public Object testField4081 = new Integer(4081);
+ public Object testField4082 = new Integer(4082);
+ public Object testField4083 = new Integer(4083);
+ public Object testField4084 = new Integer(4084);
+ public Object testField4085 = new Integer(4085);
+ public Object testField4086 = new Integer(4086);
+ public Object testField4087 = new Integer(4087);
+ public Object testField4088 = new Integer(4088);
+ public Object testField4089 = new Integer(4089);
+ public Object testField4090 = new Integer(4090);
+ public Object testField4091 = new Integer(4091);
+ public Object testField4092 = new Integer(4092);
+ public Object testField4093 = new Integer(4093);
+ public Object testField4094 = new Integer(4094);
+ public Object testField4095 = new Integer(4095);
+ public Object testField4096 = new Integer(4096);
+ public Object testField4097 = new Integer(4097);
+ public Object testField4098 = new Integer(4098);
+ public Object testField4099 = new Integer(4099);
+ public Object testField4100 = new Integer(4100);
+ public Object testField4101 = new Integer(4101);
+ public Object testField4102 = new Integer(4102);
+ public Object testField4103 = new Integer(4103);
+ public Object testField4104 = new Integer(4104);
+ public Object testField4105 = new Integer(4105);
+ public Object testField4106 = new Integer(4106);
+ public Object testField4107 = new Integer(4107);
+ public Object testField4108 = new Integer(4108);
+ public Object testField4109 = new Integer(4109);
+ public Object testField4110 = new Integer(4110);
+ public Object testField4111 = new Integer(4111);
+ public Object testField4112 = new Integer(4112);
+ public Object testField4113 = new Integer(4113);
+ public Object testField4114 = new Integer(4114);
+ public Object testField4115 = new Integer(4115);
+ public Object testField4116 = new Integer(4116);
+ public Object testField4117 = new Integer(4117);
+ public Object testField4118 = new Integer(4118);
+ public Object testField4119 = new Integer(4119);
+ public Object testField4120 = new Integer(4120);
+ public Object testField4121 = new Integer(4121);
+ public Object testField4122 = new Integer(4122);
+ public Object testField4123 = new Integer(4123);
+ public Object testField4124 = new Integer(4124);
+ public Object testField4125 = new Integer(4125);
+ public Object testField4126 = new Integer(4126);
+ public Object testField4127 = new Integer(4127);
+ public Object testField4128 = new Integer(4128);
+ public Object testField4129 = new Integer(4129);
+ public Object testField4130 = new Integer(4130);
+ public Object testField4131 = new Integer(4131);
+ public Object testField4132 = new Integer(4132);
+ public Object testField4133 = new Integer(4133);
+ public Object testField4134 = new Integer(4134);
+ public Object testField4135 = new Integer(4135);
+ public Object testField4136 = new Integer(4136);
+ public Object testField4137 = new Integer(4137);
+ public Object testField4138 = new Integer(4138);
+ public Object testField4139 = new Integer(4139);
+ public Object testField4140 = new Integer(4140);
+ public Object testField4141 = new Integer(4141);
+ public Object testField4142 = new Integer(4142);
+ public Object testField4143 = new Integer(4143);
+ public Object testField4144 = new Integer(4144);
+ public Object testField4145 = new Integer(4145);
+ public Object testField4146 = new Integer(4146);
+ public Object testField4147 = new Integer(4147);
+ public Object testField4148 = new Integer(4148);
+ public Object testField4149 = new Integer(4149);
+ public Object testField4150 = new Integer(4150);
+ public Object testField4151 = new Integer(4151);
+ public Object testField4152 = new Integer(4152);
+ public Object testField4153 = new Integer(4153);
+ public Object testField4154 = new Integer(4154);
+ public Object testField4155 = new Integer(4155);
+ public Object testField4156 = new Integer(4156);
+ public Object testField4157 = new Integer(4157);
+ public Object testField4158 = new Integer(4158);
+ public Object testField4159 = new Integer(4159);
+ public Object testField4160 = new Integer(4160);
+ public Object testField4161 = new Integer(4161);
+ public Object testField4162 = new Integer(4162);
+ public Object testField4163 = new Integer(4163);
+ public Object testField4164 = new Integer(4164);
+ public Object testField4165 = new Integer(4165);
+ public Object testField4166 = new Integer(4166);
+ public Object testField4167 = new Integer(4167);
+ public Object testField4168 = new Integer(4168);
+ public Object testField4169 = new Integer(4169);
+ public Object testField4170 = new Integer(4170);
+ public Object testField4171 = new Integer(4171);
+ public Object testField4172 = new Integer(4172);
+ public Object testField4173 = new Integer(4173);
+ public Object testField4174 = new Integer(4174);
+ public Object testField4175 = new Integer(4175);
+ public Object testField4176 = new Integer(4176);
+ public Object testField4177 = new Integer(4177);
+ public Object testField4178 = new Integer(4178);
+ public Object testField4179 = new Integer(4179);
+ public Object testField4180 = new Integer(4180);
+ public Object testField4181 = new Integer(4181);
+ public Object testField4182 = new Integer(4182);
+ public Object testField4183 = new Integer(4183);
+ public Object testField4184 = new Integer(4184);
+ public Object testField4185 = new Integer(4185);
+ public Object testField4186 = new Integer(4186);
+ public Object testField4187 = new Integer(4187);
+ public Object testField4188 = new Integer(4188);
+ public Object testField4189 = new Integer(4189);
+ public Object testField4190 = new Integer(4190);
+ public Object testField4191 = new Integer(4191);
+ public Object testField4192 = new Integer(4192);
+ public Object testField4193 = new Integer(4193);
+ public Object testField4194 = new Integer(4194);
+ public Object testField4195 = new Integer(4195);
+ public Object testField4196 = new Integer(4196);
+ public Object testField4197 = new Integer(4197);
+ public Object testField4198 = new Integer(4198);
+ public Object testField4199 = new Integer(4199);
+ public Object testField4200 = new Integer(4200);
+ public Object testField4201 = new Integer(4201);
+ public Object testField4202 = new Integer(4202);
+ public Object testField4203 = new Integer(4203);
+ public Object testField4204 = new Integer(4204);
+ public Object testField4205 = new Integer(4205);
+ public Object testField4206 = new Integer(4206);
+ public Object testField4207 = new Integer(4207);
+ public Object testField4208 = new Integer(4208);
+ public Object testField4209 = new Integer(4209);
+ public Object testField4210 = new Integer(4210);
+ public Object testField4211 = new Integer(4211);
+ public Object testField4212 = new Integer(4212);
+ public Object testField4213 = new Integer(4213);
+ public Object testField4214 = new Integer(4214);
+ public Object testField4215 = new Integer(4215);
+ public Object testField4216 = new Integer(4216);
+ public Object testField4217 = new Integer(4217);
+ public Object testField4218 = new Integer(4218);
+ public Object testField4219 = new Integer(4219);
+ public Object testField4220 = new Integer(4220);
+ public Object testField4221 = new Integer(4221);
+ public Object testField4222 = new Integer(4222);
+ public Object testField4223 = new Integer(4223);
+ public Object testField4224 = new Integer(4224);
+ public Object testField4225 = new Integer(4225);
+ public Object testField4226 = new Integer(4226);
+ public Object testField4227 = new Integer(4227);
+ public Object testField4228 = new Integer(4228);
+ public Object testField4229 = new Integer(4229);
+ public Object testField4230 = new Integer(4230);
+ public Object testField4231 = new Integer(4231);
+ public Object testField4232 = new Integer(4232);
+ public Object testField4233 = new Integer(4233);
+ public Object testField4234 = new Integer(4234);
+ public Object testField4235 = new Integer(4235);
+ public Object testField4236 = new Integer(4236);
+ public Object testField4237 = new Integer(4237);
+ public Object testField4238 = new Integer(4238);
+ public Object testField4239 = new Integer(4239);
+ public Object testField4240 = new Integer(4240);
+ public Object testField4241 = new Integer(4241);
+ public Object testField4242 = new Integer(4242);
+ public Object testField4243 = new Integer(4243);
+ public Object testField4244 = new Integer(4244);
+ public Object testField4245 = new Integer(4245);
+ public Object testField4246 = new Integer(4246);
+ public Object testField4247 = new Integer(4247);
+ public Object testField4248 = new Integer(4248);
+ public Object testField4249 = new Integer(4249);
+ public Object testField4250 = new Integer(4250);
+ public Object testField4251 = new Integer(4251);
+ public Object testField4252 = new Integer(4252);
+ public Object testField4253 = new Integer(4253);
+ public Object testField4254 = new Integer(4254);
+ public Object testField4255 = new Integer(4255);
+ public Object testField4256 = new Integer(4256);
+ public Object testField4257 = new Integer(4257);
+ public Object testField4258 = new Integer(4258);
+ public Object testField4259 = new Integer(4259);
+ public Object testField4260 = new Integer(4260);
+ public Object testField4261 = new Integer(4261);
+ public Object testField4262 = new Integer(4262);
+ public Object testField4263 = new Integer(4263);
+ public Object testField4264 = new Integer(4264);
+ public Object testField4265 = new Integer(4265);
+ public Object testField4266 = new Integer(4266);
+ public Object testField4267 = new Integer(4267);
+ public Object testField4268 = new Integer(4268);
+ public Object testField4269 = new Integer(4269);
+ public Object testField4270 = new Integer(4270);
+ public Object testField4271 = new Integer(4271);
+ public Object testField4272 = new Integer(4272);
+ public Object testField4273 = new Integer(4273);
+ public Object testField4274 = new Integer(4274);
+ public Object testField4275 = new Integer(4275);
+ public Object testField4276 = new Integer(4276);
+ public Object testField4277 = new Integer(4277);
+ public Object testField4278 = new Integer(4278);
+ public Object testField4279 = new Integer(4279);
+ public Object testField4280 = new Integer(4280);
+ public Object testField4281 = new Integer(4281);
+ public Object testField4282 = new Integer(4282);
+ public Object testField4283 = new Integer(4283);
+ public Object testField4284 = new Integer(4284);
+ public Object testField4285 = new Integer(4285);
+ public Object testField4286 = new Integer(4286);
+ public Object testField4287 = new Integer(4287);
+ public Object testField4288 = new Integer(4288);
+ public Object testField4289 = new Integer(4289);
+ public Object testField4290 = new Integer(4290);
+ public Object testField4291 = new Integer(4291);
+ public Object testField4292 = new Integer(4292);
+ public Object testField4293 = new Integer(4293);
+ public Object testField4294 = new Integer(4294);
+ public Object testField4295 = new Integer(4295);
+ public Object testField4296 = new Integer(4296);
+ public Object testField4297 = new Integer(4297);
+ public Object testField4298 = new Integer(4298);
+ public Object testField4299 = new Integer(4299);
+ public Object testField4300 = new Integer(4300);
+ public Object testField4301 = new Integer(4301);
+ public Object testField4302 = new Integer(4302);
+ public Object testField4303 = new Integer(4303);
+ public Object testField4304 = new Integer(4304);
+ public Object testField4305 = new Integer(4305);
+ public Object testField4306 = new Integer(4306);
+ public Object testField4307 = new Integer(4307);
+ public Object testField4308 = new Integer(4308);
+ public Object testField4309 = new Integer(4309);
+ public Object testField4310 = new Integer(4310);
+ public Object testField4311 = new Integer(4311);
+ public Object testField4312 = new Integer(4312);
+ public Object testField4313 = new Integer(4313);
+ public Object testField4314 = new Integer(4314);
+ public Object testField4315 = new Integer(4315);
+ public Object testField4316 = new Integer(4316);
+ public Object testField4317 = new Integer(4317);
+ public Object testField4318 = new Integer(4318);
+ public Object testField4319 = new Integer(4319);
+ public Object testField4320 = new Integer(4320);
+ public Object testField4321 = new Integer(4321);
+ public Object testField4322 = new Integer(4322);
+ public Object testField4323 = new Integer(4323);
+ public Object testField4324 = new Integer(4324);
+ public Object testField4325 = new Integer(4325);
+ public Object testField4326 = new Integer(4326);
+ public Object testField4327 = new Integer(4327);
+ public Object testField4328 = new Integer(4328);
+ public Object testField4329 = new Integer(4329);
+ public Object testField4330 = new Integer(4330);
+ public Object testField4331 = new Integer(4331);
+ public Object testField4332 = new Integer(4332);
+ public Object testField4333 = new Integer(4333);
+ public Object testField4334 = new Integer(4334);
+ public Object testField4335 = new Integer(4335);
+ public Object testField4336 = new Integer(4336);
+ public Object testField4337 = new Integer(4337);
+ public Object testField4338 = new Integer(4338);
+ public Object testField4339 = new Integer(4339);
+ public Object testField4340 = new Integer(4340);
+ public Object testField4341 = new Integer(4341);
+ public Object testField4342 = new Integer(4342);
+ public Object testField4343 = new Integer(4343);
+ public Object testField4344 = new Integer(4344);
+ public Object testField4345 = new Integer(4345);
+ public Object testField4346 = new Integer(4346);
+ public Object testField4347 = new Integer(4347);
+ public Object testField4348 = new Integer(4348);
+ public Object testField4349 = new Integer(4349);
+ public Object testField4350 = new Integer(4350);
+ public Object testField4351 = new Integer(4351);
+ public Object testField4352 = new Integer(4352);
+ public Object testField4353 = new Integer(4353);
+ public Object testField4354 = new Integer(4354);
+ public Object testField4355 = new Integer(4355);
+ public Object testField4356 = new Integer(4356);
+ public Object testField4357 = new Integer(4357);
+ public Object testField4358 = new Integer(4358);
+ public Object testField4359 = new Integer(4359);
+ public Object testField4360 = new Integer(4360);
+ public Object testField4361 = new Integer(4361);
+ public Object testField4362 = new Integer(4362);
+ public Object testField4363 = new Integer(4363);
+ public Object testField4364 = new Integer(4364);
+ public Object testField4365 = new Integer(4365);
+ public Object testField4366 = new Integer(4366);
+ public Object testField4367 = new Integer(4367);
+ public Object testField4368 = new Integer(4368);
+ public Object testField4369 = new Integer(4369);
+ public Object testField4370 = new Integer(4370);
+ public Object testField4371 = new Integer(4371);
+ public Object testField4372 = new Integer(4372);
+ public Object testField4373 = new Integer(4373);
+ public Object testField4374 = new Integer(4374);
+ public Object testField4375 = new Integer(4375);
+ public Object testField4376 = new Integer(4376);
+ public Object testField4377 = new Integer(4377);
+ public Object testField4378 = new Integer(4378);
+ public Object testField4379 = new Integer(4379);
+ public Object testField4380 = new Integer(4380);
+ public Object testField4381 = new Integer(4381);
+ public Object testField4382 = new Integer(4382);
+ public Object testField4383 = new Integer(4383);
+ public Object testField4384 = new Integer(4384);
+ public Object testField4385 = new Integer(4385);
+ public Object testField4386 = new Integer(4386);
+ public Object testField4387 = new Integer(4387);
+ public Object testField4388 = new Integer(4388);
+ public Object testField4389 = new Integer(4389);
+ public Object testField4390 = new Integer(4390);
+ public Object testField4391 = new Integer(4391);
+ public Object testField4392 = new Integer(4392);
+ public Object testField4393 = new Integer(4393);
+ public Object testField4394 = new Integer(4394);
+ public Object testField4395 = new Integer(4395);
+ public Object testField4396 = new Integer(4396);
+ public Object testField4397 = new Integer(4397);
+ public Object testField4398 = new Integer(4398);
+ public Object testField4399 = new Integer(4399);
+ public Object testField4400 = new Integer(4400);
+ public Object testField4401 = new Integer(4401);
+ public Object testField4402 = new Integer(4402);
+ public Object testField4403 = new Integer(4403);
+ public Object testField4404 = new Integer(4404);
+ public Object testField4405 = new Integer(4405);
+ public Object testField4406 = new Integer(4406);
+ public Object testField4407 = new Integer(4407);
+ public Object testField4408 = new Integer(4408);
+ public Object testField4409 = new Integer(4409);
+ public Object testField4410 = new Integer(4410);
+ public Object testField4411 = new Integer(4411);
+ public Object testField4412 = new Integer(4412);
+ public Object testField4413 = new Integer(4413);
+ public Object testField4414 = new Integer(4414);
+ public Object testField4415 = new Integer(4415);
+ public Object testField4416 = new Integer(4416);
+ public Object testField4417 = new Integer(4417);
+ public Object testField4418 = new Integer(4418);
+ public Object testField4419 = new Integer(4419);
+ public Object testField4420 = new Integer(4420);
+ public Object testField4421 = new Integer(4421);
+ public Object testField4422 = new Integer(4422);
+ public Object testField4423 = new Integer(4423);
+ public Object testField4424 = new Integer(4424);
+ public Object testField4425 = new Integer(4425);
+ public Object testField4426 = new Integer(4426);
+ public Object testField4427 = new Integer(4427);
+ public Object testField4428 = new Integer(4428);
+ public Object testField4429 = new Integer(4429);
+ public Object testField4430 = new Integer(4430);
+ public Object testField4431 = new Integer(4431);
+ public Object testField4432 = new Integer(4432);
+ public Object testField4433 = new Integer(4433);
+ public Object testField4434 = new Integer(4434);
+ public Object testField4435 = new Integer(4435);
+ public Object testField4436 = new Integer(4436);
+ public Object testField4437 = new Integer(4437);
+ public Object testField4438 = new Integer(4438);
+ public Object testField4439 = new Integer(4439);
+ public Object testField4440 = new Integer(4440);
+ public Object testField4441 = new Integer(4441);
+ public Object testField4442 = new Integer(4442);
+ public Object testField4443 = new Integer(4443);
+ public Object testField4444 = new Integer(4444);
+ public Object testField4445 = new Integer(4445);
+ public Object testField4446 = new Integer(4446);
+ public Object testField4447 = new Integer(4447);
+ public Object testField4448 = new Integer(4448);
+ public Object testField4449 = new Integer(4449);
+ public Object testField4450 = new Integer(4450);
+ public Object testField4451 = new Integer(4451);
+ public Object testField4452 = new Integer(4452);
+ public Object testField4453 = new Integer(4453);
+ public Object testField4454 = new Integer(4454);
+ public Object testField4455 = new Integer(4455);
+ public Object testField4456 = new Integer(4456);
+ public Object testField4457 = new Integer(4457);
+ public Object testField4458 = new Integer(4458);
+ public Object testField4459 = new Integer(4459);
+ public Object testField4460 = new Integer(4460);
+ public Object testField4461 = new Integer(4461);
+ public Object testField4462 = new Integer(4462);
+ public Object testField4463 = new Integer(4463);
+ public Object testField4464 = new Integer(4464);
+ public Object testField4465 = new Integer(4465);
+ public Object testField4466 = new Integer(4466);
+ public Object testField4467 = new Integer(4467);
+ public Object testField4468 = new Integer(4468);
+ public Object testField4469 = new Integer(4469);
+ public Object testField4470 = new Integer(4470);
+ public Object testField4471 = new Integer(4471);
+ public Object testField4472 = new Integer(4472);
+ public Object testField4473 = new Integer(4473);
+ public Object testField4474 = new Integer(4474);
+ public Object testField4475 = new Integer(4475);
+ public Object testField4476 = new Integer(4476);
+ public Object testField4477 = new Integer(4477);
+ public Object testField4478 = new Integer(4478);
+ public Object testField4479 = new Integer(4479);
+ public Object testField4480 = new Integer(4480);
+ public Object testField4481 = new Integer(4481);
+ public Object testField4482 = new Integer(4482);
+ public Object testField4483 = new Integer(4483);
+ public Object testField4484 = new Integer(4484);
+ public Object testField4485 = new Integer(4485);
+ public Object testField4486 = new Integer(4486);
+ public Object testField4487 = new Integer(4487);
+ public Object testField4488 = new Integer(4488);
+ public Object testField4489 = new Integer(4489);
+ public Object testField4490 = new Integer(4490);
+ public Object testField4491 = new Integer(4491);
+ public Object testField4492 = new Integer(4492);
+ public Object testField4493 = new Integer(4493);
+ public Object testField4494 = new Integer(4494);
+ public Object testField4495 = new Integer(4495);
+ public Object testField4496 = new Integer(4496);
+ public Object testField4497 = new Integer(4497);
+ public Object testField4498 = new Integer(4498);
+ public Object testField4499 = new Integer(4499);
+ public Object testField4500 = new Integer(4500);
+ public Object testField4501 = new Integer(4501);
+ public Object testField4502 = new Integer(4502);
+ public Object testField4503 = new Integer(4503);
+ public Object testField4504 = new Integer(4504);
+ public Object testField4505 = new Integer(4505);
+ public Object testField4506 = new Integer(4506);
+ public Object testField4507 = new Integer(4507);
+ public Object testField4508 = new Integer(4508);
+ public Object testField4509 = new Integer(4509);
+ public Object testField4510 = new Integer(4510);
+ public Object testField4511 = new Integer(4511);
+ public Object testField4512 = new Integer(4512);
+ public Object testField4513 = new Integer(4513);
+ public Object testField4514 = new Integer(4514);
+ public Object testField4515 = new Integer(4515);
+ public Object testField4516 = new Integer(4516);
+ public Object testField4517 = new Integer(4517);
+ public Object testField4518 = new Integer(4518);
+ public Object testField4519 = new Integer(4519);
+ public Object testField4520 = new Integer(4520);
+ public Object testField4521 = new Integer(4521);
+ public Object testField4522 = new Integer(4522);
+ public Object testField4523 = new Integer(4523);
+ public Object testField4524 = new Integer(4524);
+ public Object testField4525 = new Integer(4525);
+ public Object testField4526 = new Integer(4526);
+ public Object testField4527 = new Integer(4527);
+ public Object testField4528 = new Integer(4528);
+ public Object testField4529 = new Integer(4529);
+ public Object testField4530 = new Integer(4530);
+ public Object testField4531 = new Integer(4531);
+ public Object testField4532 = new Integer(4532);
+ public Object testField4533 = new Integer(4533);
+ public Object testField4534 = new Integer(4534);
+ public Object testField4535 = new Integer(4535);
+ public Object testField4536 = new Integer(4536);
+ public Object testField4537 = new Integer(4537);
+ public Object testField4538 = new Integer(4538);
+ public Object testField4539 = new Integer(4539);
+ public Object testField4540 = new Integer(4540);
+ public Object testField4541 = new Integer(4541);
+ public Object testField4542 = new Integer(4542);
+ public Object testField4543 = new Integer(4543);
+ public Object testField4544 = new Integer(4544);
+ public Object testField4545 = new Integer(4545);
+ public Object testField4546 = new Integer(4546);
+ public Object testField4547 = new Integer(4547);
+ public Object testField4548 = new Integer(4548);
+ public Object testField4549 = new Integer(4549);
+ public Object testField4550 = new Integer(4550);
+ public Object testField4551 = new Integer(4551);
+ public Object testField4552 = new Integer(4552);
+ public Object testField4553 = new Integer(4553);
+ public Object testField4554 = new Integer(4554);
+ public Object testField4555 = new Integer(4555);
+ public Object testField4556 = new Integer(4556);
+ public Object testField4557 = new Integer(4557);
+ public Object testField4558 = new Integer(4558);
+ public Object testField4559 = new Integer(4559);
+ public Object testField4560 = new Integer(4560);
+ public Object testField4561 = new Integer(4561);
+ public Object testField4562 = new Integer(4562);
+ public Object testField4563 = new Integer(4563);
+ public Object testField4564 = new Integer(4564);
+ public Object testField4565 = new Integer(4565);
+ public Object testField4566 = new Integer(4566);
+ public Object testField4567 = new Integer(4567);
+ public Object testField4568 = new Integer(4568);
+ public Object testField4569 = new Integer(4569);
+ public Object testField4570 = new Integer(4570);
+ public Object testField4571 = new Integer(4571);
+ public Object testField4572 = new Integer(4572);
+ public Object testField4573 = new Integer(4573);
+ public Object testField4574 = new Integer(4574);
+ public Object testField4575 = new Integer(4575);
+ public Object testField4576 = new Integer(4576);
+ public Object testField4577 = new Integer(4577);
+ public Object testField4578 = new Integer(4578);
+ public Object testField4579 = new Integer(4579);
+ public Object testField4580 = new Integer(4580);
+ public Object testField4581 = new Integer(4581);
+ public Object testField4582 = new Integer(4582);
+ public Object testField4583 = new Integer(4583);
+ public Object testField4584 = new Integer(4584);
+ public Object testField4585 = new Integer(4585);
+ public Object testField4586 = new Integer(4586);
+ public Object testField4587 = new Integer(4587);
+ public Object testField4588 = new Integer(4588);
+ public Object testField4589 = new Integer(4589);
+ public Object testField4590 = new Integer(4590);
+ public Object testField4591 = new Integer(4591);
+ public Object testField4592 = new Integer(4592);
+ public Object testField4593 = new Integer(4593);
+ public Object testField4594 = new Integer(4594);
+ public Object testField4595 = new Integer(4595);
+ public Object testField4596 = new Integer(4596);
+ public Object testField4597 = new Integer(4597);
+ public Object testField4598 = new Integer(4598);
+ public Object testField4599 = new Integer(4599);
+ public Object testField4600 = new Integer(4600);
+ public Object testField4601 = new Integer(4601);
+ public Object testField4602 = new Integer(4602);
+ public Object testField4603 = new Integer(4603);
+ public Object testField4604 = new Integer(4604);
+ public Object testField4605 = new Integer(4605);
+ public Object testField4606 = new Integer(4606);
+ public Object testField4607 = new Integer(4607);
+ public Object testField4608 = new Integer(4608);
+ public Object testField4609 = new Integer(4609);
+ public Object testField4610 = new Integer(4610);
+ public Object testField4611 = new Integer(4611);
+ public Object testField4612 = new Integer(4612);
+ public Object testField4613 = new Integer(4613);
+ public Object testField4614 = new Integer(4614);
+ public Object testField4615 = new Integer(4615);
+ public Object testField4616 = new Integer(4616);
+ public Object testField4617 = new Integer(4617);
+ public Object testField4618 = new Integer(4618);
+ public Object testField4619 = new Integer(4619);
+ public Object testField4620 = new Integer(4620);
+ public Object testField4621 = new Integer(4621);
+ public Object testField4622 = new Integer(4622);
+ public Object testField4623 = new Integer(4623);
+ public Object testField4624 = new Integer(4624);
+ public Object testField4625 = new Integer(4625);
+ public Object testField4626 = new Integer(4626);
+ public Object testField4627 = new Integer(4627);
+ public Object testField4628 = new Integer(4628);
+ public Object testField4629 = new Integer(4629);
+ public Object testField4630 = new Integer(4630);
+ public Object testField4631 = new Integer(4631);
+ public Object testField4632 = new Integer(4632);
+ public Object testField4633 = new Integer(4633);
+ public Object testField4634 = new Integer(4634);
+ public Object testField4635 = new Integer(4635);
+ public Object testField4636 = new Integer(4636);
+ public Object testField4637 = new Integer(4637);
+ public Object testField4638 = new Integer(4638);
+ public Object testField4639 = new Integer(4639);
+ public Object testField4640 = new Integer(4640);
+ public Object testField4641 = new Integer(4641);
+ public Object testField4642 = new Integer(4642);
+ public Object testField4643 = new Integer(4643);
+ public Object testField4644 = new Integer(4644);
+ public Object testField4645 = new Integer(4645);
+ public Object testField4646 = new Integer(4646);
+ public Object testField4647 = new Integer(4647);
+ public Object testField4648 = new Integer(4648);
+ public Object testField4649 = new Integer(4649);
+ public Object testField4650 = new Integer(4650);
+ public Object testField4651 = new Integer(4651);
+ public Object testField4652 = new Integer(4652);
+ public Object testField4653 = new Integer(4653);
+ public Object testField4654 = new Integer(4654);
+ public Object testField4655 = new Integer(4655);
+ public Object testField4656 = new Integer(4656);
+ public Object testField4657 = new Integer(4657);
+ public Object testField4658 = new Integer(4658);
+ public Object testField4659 = new Integer(4659);
+ public Object testField4660 = new Integer(4660);
+ public Object testField4661 = new Integer(4661);
+ public Object testField4662 = new Integer(4662);
+ public Object testField4663 = new Integer(4663);
+ public Object testField4664 = new Integer(4664);
+ public Object testField4665 = new Integer(4665);
+ public Object testField4666 = new Integer(4666);
+ public Object testField4667 = new Integer(4667);
+ public Object testField4668 = new Integer(4668);
+ public Object testField4669 = new Integer(4669);
+ public Object testField4670 = new Integer(4670);
+ public Object testField4671 = new Integer(4671);
+ public Object testField4672 = new Integer(4672);
+ public Object testField4673 = new Integer(4673);
+ public Object testField4674 = new Integer(4674);
+ public Object testField4675 = new Integer(4675);
+ public Object testField4676 = new Integer(4676);
+ public Object testField4677 = new Integer(4677);
+ public Object testField4678 = new Integer(4678);
+ public Object testField4679 = new Integer(4679);
+ public Object testField4680 = new Integer(4680);
+ public Object testField4681 = new Integer(4681);
+ public Object testField4682 = new Integer(4682);
+ public Object testField4683 = new Integer(4683);
+ public Object testField4684 = new Integer(4684);
+ public Object testField4685 = new Integer(4685);
+ public Object testField4686 = new Integer(4686);
+ public Object testField4687 = new Integer(4687);
+ public Object testField4688 = new Integer(4688);
+ public Object testField4689 = new Integer(4689);
+ public Object testField4690 = new Integer(4690);
+ public Object testField4691 = new Integer(4691);
+ public Object testField4692 = new Integer(4692);
+ public Object testField4693 = new Integer(4693);
+ public Object testField4694 = new Integer(4694);
+ public Object testField4695 = new Integer(4695);
+ public Object testField4696 = new Integer(4696);
+ public Object testField4697 = new Integer(4697);
+ public Object testField4698 = new Integer(4698);
+ public Object testField4699 = new Integer(4699);
+ public Object testField4700 = new Integer(4700);
+ public Object testField4701 = new Integer(4701);
+ public Object testField4702 = new Integer(4702);
+ public Object testField4703 = new Integer(4703);
+ public Object testField4704 = new Integer(4704);
+ public Object testField4705 = new Integer(4705);
+ public Object testField4706 = new Integer(4706);
+ public Object testField4707 = new Integer(4707);
+ public Object testField4708 = new Integer(4708);
+ public Object testField4709 = new Integer(4709);
+ public Object testField4710 = new Integer(4710);
+ public Object testField4711 = new Integer(4711);
+ public Object testField4712 = new Integer(4712);
+ public Object testField4713 = new Integer(4713);
+ public Object testField4714 = new Integer(4714);
+ public Object testField4715 = new Integer(4715);
+ public Object testField4716 = new Integer(4716);
+ public Object testField4717 = new Integer(4717);
+ public Object testField4718 = new Integer(4718);
+ public Object testField4719 = new Integer(4719);
+ public Object testField4720 = new Integer(4720);
+ public Object testField4721 = new Integer(4721);
+ public Object testField4722 = new Integer(4722);
+ public Object testField4723 = new Integer(4723);
+ public Object testField4724 = new Integer(4724);
+ public Object testField4725 = new Integer(4725);
+ public Object testField4726 = new Integer(4726);
+ public Object testField4727 = new Integer(4727);
+ public Object testField4728 = new Integer(4728);
+ public Object testField4729 = new Integer(4729);
+ public Object testField4730 = new Integer(4730);
+ public Object testField4731 = new Integer(4731);
+ public Object testField4732 = new Integer(4732);
+ public Object testField4733 = new Integer(4733);
+ public Object testField4734 = new Integer(4734);
+ public Object testField4735 = new Integer(4735);
+ public Object testField4736 = new Integer(4736);
+ public Object testField4737 = new Integer(4737);
+ public Object testField4738 = new Integer(4738);
+ public Object testField4739 = new Integer(4739);
+ public Object testField4740 = new Integer(4740);
+ public Object testField4741 = new Integer(4741);
+ public Object testField4742 = new Integer(4742);
+ public Object testField4743 = new Integer(4743);
+ public Object testField4744 = new Integer(4744);
+ public Object testField4745 = new Integer(4745);
+ public Object testField4746 = new Integer(4746);
+ public Object testField4747 = new Integer(4747);
+ public Object testField4748 = new Integer(4748);
+ public Object testField4749 = new Integer(4749);
+ public Object testField4750 = new Integer(4750);
+ public Object testField4751 = new Integer(4751);
+ public Object testField4752 = new Integer(4752);
+ public Object testField4753 = new Integer(4753);
+ public Object testField4754 = new Integer(4754);
+ public Object testField4755 = new Integer(4755);
+ public Object testField4756 = new Integer(4756);
+ public Object testField4757 = new Integer(4757);
+ public Object testField4758 = new Integer(4758);
+ public Object testField4759 = new Integer(4759);
+ public Object testField4760 = new Integer(4760);
+ public Object testField4761 = new Integer(4761);
+ public Object testField4762 = new Integer(4762);
+ public Object testField4763 = new Integer(4763);
+ public Object testField4764 = new Integer(4764);
+ public Object testField4765 = new Integer(4765);
+ public Object testField4766 = new Integer(4766);
+ public Object testField4767 = new Integer(4767);
+ public Object testField4768 = new Integer(4768);
+ public Object testField4769 = new Integer(4769);
+ public Object testField4770 = new Integer(4770);
+ public Object testField4771 = new Integer(4771);
+ public Object testField4772 = new Integer(4772);
+ public Object testField4773 = new Integer(4773);
+ public Object testField4774 = new Integer(4774);
+ public Object testField4775 = new Integer(4775);
+ public Object testField4776 = new Integer(4776);
+ public Object testField4777 = new Integer(4777);
+ public Object testField4778 = new Integer(4778);
+ public Object testField4779 = new Integer(4779);
+ public Object testField4780 = new Integer(4780);
+ public Object testField4781 = new Integer(4781);
+ public Object testField4782 = new Integer(4782);
+ public Object testField4783 = new Integer(4783);
+ public Object testField4784 = new Integer(4784);
+ public Object testField4785 = new Integer(4785);
+ public Object testField4786 = new Integer(4786);
+ public Object testField4787 = new Integer(4787);
+ public Object testField4788 = new Integer(4788);
+ public Object testField4789 = new Integer(4789);
+ public Object testField4790 = new Integer(4790);
+ public Object testField4791 = new Integer(4791);
+ public Object testField4792 = new Integer(4792);
+ public Object testField4793 = new Integer(4793);
+ public Object testField4794 = new Integer(4794);
+ public Object testField4795 = new Integer(4795);
+ public Object testField4796 = new Integer(4796);
+ public Object testField4797 = new Integer(4797);
+ public Object testField4798 = new Integer(4798);
+ public Object testField4799 = new Integer(4799);
+ public Object testField4800 = new Integer(4800);
+ public Object testField4801 = new Integer(4801);
+ public Object testField4802 = new Integer(4802);
+ public Object testField4803 = new Integer(4803);
+ public Object testField4804 = new Integer(4804);
+ public Object testField4805 = new Integer(4805);
+ public Object testField4806 = new Integer(4806);
+ public Object testField4807 = new Integer(4807);
+ public Object testField4808 = new Integer(4808);
+ public Object testField4809 = new Integer(4809);
+ public Object testField4810 = new Integer(4810);
+ public Object testField4811 = new Integer(4811);
+ public Object testField4812 = new Integer(4812);
+ public Object testField4813 = new Integer(4813);
+ public Object testField4814 = new Integer(4814);
+ public Object testField4815 = new Integer(4815);
+ public Object testField4816 = new Integer(4816);
+ public Object testField4817 = new Integer(4817);
+ public Object testField4818 = new Integer(4818);
+ public Object testField4819 = new Integer(4819);
+ public Object testField4820 = new Integer(4820);
+ public Object testField4821 = new Integer(4821);
+ public Object testField4822 = new Integer(4822);
+ public Object testField4823 = new Integer(4823);
+ public Object testField4824 = new Integer(4824);
+ public Object testField4825 = new Integer(4825);
+ public Object testField4826 = new Integer(4826);
+ public Object testField4827 = new Integer(4827);
+ public Object testField4828 = new Integer(4828);
+ public Object testField4829 = new Integer(4829);
+ public Object testField4830 = new Integer(4830);
+ public Object testField4831 = new Integer(4831);
+ public Object testField4832 = new Integer(4832);
+ public Object testField4833 = new Integer(4833);
+ public Object testField4834 = new Integer(4834);
+ public Object testField4835 = new Integer(4835);
+ public Object testField4836 = new Integer(4836);
+ public Object testField4837 = new Integer(4837);
+ public Object testField4838 = new Integer(4838);
+ public Object testField4839 = new Integer(4839);
+ public Object testField4840 = new Integer(4840);
+ public Object testField4841 = new Integer(4841);
+ public Object testField4842 = new Integer(4842);
+ public Object testField4843 = new Integer(4843);
+ public Object testField4844 = new Integer(4844);
+ public Object testField4845 = new Integer(4845);
+ public Object testField4846 = new Integer(4846);
+ public Object testField4847 = new Integer(4847);
+ public Object testField4848 = new Integer(4848);
+ public Object testField4849 = new Integer(4849);
+ public Object testField4850 = new Integer(4850);
+ public Object testField4851 = new Integer(4851);
+ public Object testField4852 = new Integer(4852);
+ public Object testField4853 = new Integer(4853);
+ public Object testField4854 = new Integer(4854);
+ public Object testField4855 = new Integer(4855);
+ public Object testField4856 = new Integer(4856);
+ public Object testField4857 = new Integer(4857);
+ public Object testField4858 = new Integer(4858);
+ public Object testField4859 = new Integer(4859);
+ public Object testField4860 = new Integer(4860);
+ public Object testField4861 = new Integer(4861);
+ public Object testField4862 = new Integer(4862);
+ public Object testField4863 = new Integer(4863);
+ public Object testField4864 = new Integer(4864);
+ public Object testField4865 = new Integer(4865);
+ public Object testField4866 = new Integer(4866);
+ public Object testField4867 = new Integer(4867);
+ public Object testField4868 = new Integer(4868);
+ public Object testField4869 = new Integer(4869);
+ public Object testField4870 = new Integer(4870);
+ public Object testField4871 = new Integer(4871);
+ public Object testField4872 = new Integer(4872);
+ public Object testField4873 = new Integer(4873);
+ public Object testField4874 = new Integer(4874);
+ public Object testField4875 = new Integer(4875);
+ public Object testField4876 = new Integer(4876);
+ public Object testField4877 = new Integer(4877);
+ public Object testField4878 = new Integer(4878);
+ public Object testField4879 = new Integer(4879);
+ public Object testField4880 = new Integer(4880);
+ public Object testField4881 = new Integer(4881);
+ public Object testField4882 = new Integer(4882);
+ public Object testField4883 = new Integer(4883);
+ public Object testField4884 = new Integer(4884);
+ public Object testField4885 = new Integer(4885);
+ public Object testField4886 = new Integer(4886);
+ public Object testField4887 = new Integer(4887);
+ public Object testField4888 = new Integer(4888);
+ public Object testField4889 = new Integer(4889);
+ public Object testField4890 = new Integer(4890);
+ public Object testField4891 = new Integer(4891);
+ public Object testField4892 = new Integer(4892);
+ public Object testField4893 = new Integer(4893);
+ public Object testField4894 = new Integer(4894);
+ public Object testField4895 = new Integer(4895);
+ public Object testField4896 = new Integer(4896);
+ public Object testField4897 = new Integer(4897);
+ public Object testField4898 = new Integer(4898);
+ public Object testField4899 = new Integer(4899);
+ public Object testField4900 = new Integer(4900);
+ public Object testField4901 = new Integer(4901);
+ public Object testField4902 = new Integer(4902);
+ public Object testField4903 = new Integer(4903);
+ public Object testField4904 = new Integer(4904);
+ public Object testField4905 = new Integer(4905);
+ public Object testField4906 = new Integer(4906);
+ public Object testField4907 = new Integer(4907);
+ public Object testField4908 = new Integer(4908);
+ public Object testField4909 = new Integer(4909);
+ public Object testField4910 = new Integer(4910);
+ public Object testField4911 = new Integer(4911);
+ public Object testField4912 = new Integer(4912);
+ public Object testField4913 = new Integer(4913);
+ public Object testField4914 = new Integer(4914);
+ public Object testField4915 = new Integer(4915);
+ public Object testField4916 = new Integer(4916);
+ public Object testField4917 = new Integer(4917);
+ public Object testField4918 = new Integer(4918);
+ public Object testField4919 = new Integer(4919);
+ public Object testField4920 = new Integer(4920);
+ public Object testField4921 = new Integer(4921);
+ public Object testField4922 = new Integer(4922);
+ public Object testField4923 = new Integer(4923);
+ public Object testField4924 = new Integer(4924);
+ public Object testField4925 = new Integer(4925);
+ public Object testField4926 = new Integer(4926);
+ public Object testField4927 = new Integer(4927);
+ public Object testField4928 = new Integer(4928);
+ public Object testField4929 = new Integer(4929);
+ public Object testField4930 = new Integer(4930);
+ public Object testField4931 = new Integer(4931);
+ public Object testField4932 = new Integer(4932);
+ public Object testField4933 = new Integer(4933);
+ public Object testField4934 = new Integer(4934);
+ public Object testField4935 = new Integer(4935);
+ public Object testField4936 = new Integer(4936);
+ public Object testField4937 = new Integer(4937);
+ public Object testField4938 = new Integer(4938);
+ public Object testField4939 = new Integer(4939);
+ public Object testField4940 = new Integer(4940);
+ public Object testField4941 = new Integer(4941);
+ public Object testField4942 = new Integer(4942);
+ public Object testField4943 = new Integer(4943);
+ public Object testField4944 = new Integer(4944);
+ public Object testField4945 = new Integer(4945);
+ public Object testField4946 = new Integer(4946);
+ public Object testField4947 = new Integer(4947);
+ public Object testField4948 = new Integer(4948);
+ public Object testField4949 = new Integer(4949);
+ public Object testField4950 = new Integer(4950);
+ public Object testField4951 = new Integer(4951);
+ public Object testField4952 = new Integer(4952);
+ public Object testField4953 = new Integer(4953);
+ public Object testField4954 = new Integer(4954);
+ public Object testField4955 = new Integer(4955);
+ public Object testField4956 = new Integer(4956);
+ public Object testField4957 = new Integer(4957);
+ public Object testField4958 = new Integer(4958);
+ public Object testField4959 = new Integer(4959);
+ public Object testField4960 = new Integer(4960);
+ public Object testField4961 = new Integer(4961);
+ public Object testField4962 = new Integer(4962);
+ public Object testField4963 = new Integer(4963);
+ public Object testField4964 = new Integer(4964);
+ public Object testField4965 = new Integer(4965);
+ public Object testField4966 = new Integer(4966);
+ public Object testField4967 = new Integer(4967);
+ public Object testField4968 = new Integer(4968);
+ public Object testField4969 = new Integer(4969);
+ public Object testField4970 = new Integer(4970);
+ public Object testField4971 = new Integer(4971);
+ public Object testField4972 = new Integer(4972);
+ public Object testField4973 = new Integer(4973);
+ public Object testField4974 = new Integer(4974);
+ public Object testField4975 = new Integer(4975);
+ public Object testField4976 = new Integer(4976);
+ public Object testField4977 = new Integer(4977);
+ public Object testField4978 = new Integer(4978);
+ public Object testField4979 = new Integer(4979);
+ public Object testField4980 = new Integer(4980);
+ public Object testField4981 = new Integer(4981);
+ public Object testField4982 = new Integer(4982);
+ public Object testField4983 = new Integer(4983);
+ public Object testField4984 = new Integer(4984);
+ public Object testField4985 = new Integer(4985);
+ public Object testField4986 = new Integer(4986);
+ public Object testField4987 = new Integer(4987);
+ public Object testField4988 = new Integer(4988);
+ public Object testField4989 = new Integer(4989);
+ public Object testField4990 = new Integer(4990);
+ public Object testField4991 = new Integer(4991);
+ public Object testField4992 = new Integer(4992);
+ public Object testField4993 = new Integer(4993);
+ public Object testField4994 = new Integer(4994);
+ public Object testField4995 = new Integer(4995);
+ public Object testField4996 = new Integer(4996);
+ public Object testField4997 = new Integer(4997);
+ public Object testField4998 = new Integer(4998);
+ public Object testField4999 = new Integer(4999);
+}
diff --git a/test/160-read-barrier-stress/src/ManyFieldsBase0.java b/test/160-read-barrier-stress/src/ManyFieldsBase0.java
new file mode 100644
index 0000000000..1b6c2a608b
--- /dev/null
+++ b/test/160-read-barrier-stress/src/ManyFieldsBase0.java
@@ -0,0 +1,1018 @@
+/*
+ * 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.
+ */
+
+class ManyFieldsBase0 {
+ public Object testField0000 = new Integer(0);
+ public Object testField0001 = new Integer(1);
+ public Object testField0002 = new Integer(2);
+ public Object testField0003 = new Integer(3);
+ public Object testField0004 = new Integer(4);
+ public Object testField0005 = new Integer(5);
+ public Object testField0006 = new Integer(6);
+ public Object testField0007 = new Integer(7);
+ public Object testField0008 = new Integer(8);
+ public Object testField0009 = new Integer(9);
+ public Object testField0010 = new Integer(10);
+ public Object testField0011 = new Integer(11);
+ public Object testField0012 = new Integer(12);
+ public Object testField0013 = new Integer(13);
+ public Object testField0014 = new Integer(14);
+ public Object testField0015 = new Integer(15);
+ public Object testField0016 = new Integer(16);
+ public Object testField0017 = new Integer(17);
+ public Object testField0018 = new Integer(18);
+ public Object testField0019 = new Integer(19);
+ public Object testField0020 = new Integer(20);
+ public Object testField0021 = new Integer(21);
+ public Object testField0022 = new Integer(22);
+ public Object testField0023 = new Integer(23);
+ public Object testField0024 = new Integer(24);
+ public Object testField0025 = new Integer(25);
+ public Object testField0026 = new Integer(26);
+ public Object testField0027 = new Integer(27);
+ public Object testField0028 = new Integer(28);
+ public Object testField0029 = new Integer(29);
+ public Object testField0030 = new Integer(30);
+ public Object testField0031 = new Integer(31);
+ public Object testField0032 = new Integer(32);
+ public Object testField0033 = new Integer(33);
+ public Object testField0034 = new Integer(34);
+ public Object testField0035 = new Integer(35);
+ public Object testField0036 = new Integer(36);
+ public Object testField0037 = new Integer(37);
+ public Object testField0038 = new Integer(38);
+ public Object testField0039 = new Integer(39);
+ public Object testField0040 = new Integer(40);
+ public Object testField0041 = new Integer(41);
+ public Object testField0042 = new Integer(42);
+ public Object testField0043 = new Integer(43);
+ public Object testField0044 = new Integer(44);
+ public Object testField0045 = new Integer(45);
+ public Object testField0046 = new Integer(46);
+ public Object testField0047 = new Integer(47);
+ public Object testField0048 = new Integer(48);
+ public Object testField0049 = new Integer(49);
+ public Object testField0050 = new Integer(50);
+ public Object testField0051 = new Integer(51);
+ public Object testField0052 = new Integer(52);
+ public Object testField0053 = new Integer(53);
+ public Object testField0054 = new Integer(54);
+ public Object testField0055 = new Integer(55);
+ public Object testField0056 = new Integer(56);
+ public Object testField0057 = new Integer(57);
+ public Object testField0058 = new Integer(58);
+ public Object testField0059 = new Integer(59);
+ public Object testField0060 = new Integer(60);
+ public Object testField0061 = new Integer(61);
+ public Object testField0062 = new Integer(62);
+ public Object testField0063 = new Integer(63);
+ public Object testField0064 = new Integer(64);
+ public Object testField0065 = new Integer(65);
+ public Object testField0066 = new Integer(66);
+ public Object testField0067 = new Integer(67);
+ public Object testField0068 = new Integer(68);
+ public Object testField0069 = new Integer(69);
+ public Object testField0070 = new Integer(70);
+ public Object testField0071 = new Integer(71);
+ public Object testField0072 = new Integer(72);
+ public Object testField0073 = new Integer(73);
+ public Object testField0074 = new Integer(74);
+ public Object testField0075 = new Integer(75);
+ public Object testField0076 = new Integer(76);
+ public Object testField0077 = new Integer(77);
+ public Object testField0078 = new Integer(78);
+ public Object testField0079 = new Integer(79);
+ public Object testField0080 = new Integer(80);
+ public Object testField0081 = new Integer(81);
+ public Object testField0082 = new Integer(82);
+ public Object testField0083 = new Integer(83);
+ public Object testField0084 = new Integer(84);
+ public Object testField0085 = new Integer(85);
+ public Object testField0086 = new Integer(86);
+ public Object testField0087 = new Integer(87);
+ public Object testField0088 = new Integer(88);
+ public Object testField0089 = new Integer(89);
+ public Object testField0090 = new Integer(90);
+ public Object testField0091 = new Integer(91);
+ public Object testField0092 = new Integer(92);
+ public Object testField0093 = new Integer(93);
+ public Object testField0094 = new Integer(94);
+ public Object testField0095 = new Integer(95);
+ public Object testField0096 = new Integer(96);
+ public Object testField0097 = new Integer(97);
+ public Object testField0098 = new Integer(98);
+ public Object testField0099 = new Integer(99);
+ public Object testField0100 = new Integer(100);
+ public Object testField0101 = new Integer(101);
+ public Object testField0102 = new Integer(102);
+ public Object testField0103 = new Integer(103);
+ public Object testField0104 = new Integer(104);
+ public Object testField0105 = new Integer(105);
+ public Object testField0106 = new Integer(106);
+ public Object testField0107 = new Integer(107);
+ public Object testField0108 = new Integer(108);
+ public Object testField0109 = new Integer(109);
+ public Object testField0110 = new Integer(110);
+ public Object testField0111 = new Integer(111);
+ public Object testField0112 = new Integer(112);
+ public Object testField0113 = new Integer(113);
+ public Object testField0114 = new Integer(114);
+ public Object testField0115 = new Integer(115);
+ public Object testField0116 = new Integer(116);
+ public Object testField0117 = new Integer(117);
+ public Object testField0118 = new Integer(118);
+ public Object testField0119 = new Integer(119);
+ public Object testField0120 = new Integer(120);
+ public Object testField0121 = new Integer(121);
+ public Object testField0122 = new Integer(122);
+ public Object testField0123 = new Integer(123);
+ public Object testField0124 = new Integer(124);
+ public Object testField0125 = new Integer(125);
+ public Object testField0126 = new Integer(126);
+ public Object testField0127 = new Integer(127);
+ public Object testField0128 = new Integer(128);
+ public Object testField0129 = new Integer(129);
+ public Object testField0130 = new Integer(130);
+ public Object testField0131 = new Integer(131);
+ public Object testField0132 = new Integer(132);
+ public Object testField0133 = new Integer(133);
+ public Object testField0134 = new Integer(134);
+ public Object testField0135 = new Integer(135);
+ public Object testField0136 = new Integer(136);
+ public Object testField0137 = new Integer(137);
+ public Object testField0138 = new Integer(138);
+ public Object testField0139 = new Integer(139);
+ public Object testField0140 = new Integer(140);
+ public Object testField0141 = new Integer(141);
+ public Object testField0142 = new Integer(142);
+ public Object testField0143 = new Integer(143);
+ public Object testField0144 = new Integer(144);
+ public Object testField0145 = new Integer(145);
+ public Object testField0146 = new Integer(146);
+ public Object testField0147 = new Integer(147);
+ public Object testField0148 = new Integer(148);
+ public Object testField0149 = new Integer(149);
+ public Object testField0150 = new Integer(150);
+ public Object testField0151 = new Integer(151);
+ public Object testField0152 = new Integer(152);
+ public Object testField0153 = new Integer(153);
+ public Object testField0154 = new Integer(154);
+ public Object testField0155 = new Integer(155);
+ public Object testField0156 = new Integer(156);
+ public Object testField0157 = new Integer(157);
+ public Object testField0158 = new Integer(158);
+ public Object testField0159 = new Integer(159);
+ public Object testField0160 = new Integer(160);
+ public Object testField0161 = new Integer(161);
+ public Object testField0162 = new Integer(162);
+ public Object testField0163 = new Integer(163);
+ public Object testField0164 = new Integer(164);
+ public Object testField0165 = new Integer(165);
+ public Object testField0166 = new Integer(166);
+ public Object testField0167 = new Integer(167);
+ public Object testField0168 = new Integer(168);
+ public Object testField0169 = new Integer(169);
+ public Object testField0170 = new Integer(170);
+ public Object testField0171 = new Integer(171);
+ public Object testField0172 = new Integer(172);
+ public Object testField0173 = new Integer(173);
+ public Object testField0174 = new Integer(174);
+ public Object testField0175 = new Integer(175);
+ public Object testField0176 = new Integer(176);
+ public Object testField0177 = new Integer(177);
+ public Object testField0178 = new Integer(178);
+ public Object testField0179 = new Integer(179);
+ public Object testField0180 = new Integer(180);
+ public Object testField0181 = new Integer(181);
+ public Object testField0182 = new Integer(182);
+ public Object testField0183 = new Integer(183);
+ public Object testField0184 = new Integer(184);
+ public Object testField0185 = new Integer(185);
+ public Object testField0186 = new Integer(186);
+ public Object testField0187 = new Integer(187);
+ public Object testField0188 = new Integer(188);
+ public Object testField0189 = new Integer(189);
+ public Object testField0190 = new Integer(190);
+ public Object testField0191 = new Integer(191);
+ public Object testField0192 = new Integer(192);
+ public Object testField0193 = new Integer(193);
+ public Object testField0194 = new Integer(194);
+ public Object testField0195 = new Integer(195);
+ public Object testField0196 = new Integer(196);
+ public Object testField0197 = new Integer(197);
+ public Object testField0198 = new Integer(198);
+ public Object testField0199 = new Integer(199);
+ public Object testField0200 = new Integer(200);
+ public Object testField0201 = new Integer(201);
+ public Object testField0202 = new Integer(202);
+ public Object testField0203 = new Integer(203);
+ public Object testField0204 = new Integer(204);
+ public Object testField0205 = new Integer(205);
+ public Object testField0206 = new Integer(206);
+ public Object testField0207 = new Integer(207);
+ public Object testField0208 = new Integer(208);
+ public Object testField0209 = new Integer(209);
+ public Object testField0210 = new Integer(210);
+ public Object testField0211 = new Integer(211);
+ public Object testField0212 = new Integer(212);
+ public Object testField0213 = new Integer(213);
+ public Object testField0214 = new Integer(214);
+ public Object testField0215 = new Integer(215);
+ public Object testField0216 = new Integer(216);
+ public Object testField0217 = new Integer(217);
+ public Object testField0218 = new Integer(218);
+ public Object testField0219 = new Integer(219);
+ public Object testField0220 = new Integer(220);
+ public Object testField0221 = new Integer(221);
+ public Object testField0222 = new Integer(222);
+ public Object testField0223 = new Integer(223);
+ public Object testField0224 = new Integer(224);
+ public Object testField0225 = new Integer(225);
+ public Object testField0226 = new Integer(226);
+ public Object testField0227 = new Integer(227);
+ public Object testField0228 = new Integer(228);
+ public Object testField0229 = new Integer(229);
+ public Object testField0230 = new Integer(230);
+ public Object testField0231 = new Integer(231);
+ public Object testField0232 = new Integer(232);
+ public Object testField0233 = new Integer(233);
+ public Object testField0234 = new Integer(234);
+ public Object testField0235 = new Integer(235);
+ public Object testField0236 = new Integer(236);
+ public Object testField0237 = new Integer(237);
+ public Object testField0238 = new Integer(238);
+ public Object testField0239 = new Integer(239);
+ public Object testField0240 = new Integer(240);
+ public Object testField0241 = new Integer(241);
+ public Object testField0242 = new Integer(242);
+ public Object testField0243 = new Integer(243);
+ public Object testField0244 = new Integer(244);
+ public Object testField0245 = new Integer(245);
+ public Object testField0246 = new Integer(246);
+ public Object testField0247 = new Integer(247);
+ public Object testField0248 = new Integer(248);
+ public Object testField0249 = new Integer(249);
+ public Object testField0250 = new Integer(250);
+ public Object testField0251 = new Integer(251);
+ public Object testField0252 = new Integer(252);
+ public Object testField0253 = new Integer(253);
+ public Object testField0254 = new Integer(254);
+ public Object testField0255 = new Integer(255);
+ public Object testField0256 = new Integer(256);
+ public Object testField0257 = new Integer(257);
+ public Object testField0258 = new Integer(258);
+ public Object testField0259 = new Integer(259);
+ public Object testField0260 = new Integer(260);
+ public Object testField0261 = new Integer(261);
+ public Object testField0262 = new Integer(262);
+ public Object testField0263 = new Integer(263);
+ public Object testField0264 = new Integer(264);
+ public Object testField0265 = new Integer(265);
+ public Object testField0266 = new Integer(266);
+ public Object testField0267 = new Integer(267);
+ public Object testField0268 = new Integer(268);
+ public Object testField0269 = new Integer(269);
+ public Object testField0270 = new Integer(270);
+ public Object testField0271 = new Integer(271);
+ public Object testField0272 = new Integer(272);
+ public Object testField0273 = new Integer(273);
+ public Object testField0274 = new Integer(274);
+ public Object testField0275 = new Integer(275);
+ public Object testField0276 = new Integer(276);
+ public Object testField0277 = new Integer(277);
+ public Object testField0278 = new Integer(278);
+ public Object testField0279 = new Integer(279);
+ public Object testField0280 = new Integer(280);
+ public Object testField0281 = new Integer(281);
+ public Object testField0282 = new Integer(282);
+ public Object testField0283 = new Integer(283);
+ public Object testField0284 = new Integer(284);
+ public Object testField0285 = new Integer(285);
+ public Object testField0286 = new Integer(286);
+ public Object testField0287 = new Integer(287);
+ public Object testField0288 = new Integer(288);
+ public Object testField0289 = new Integer(289);
+ public Object testField0290 = new Integer(290);
+ public Object testField0291 = new Integer(291);
+ public Object testField0292 = new Integer(292);
+ public Object testField0293 = new Integer(293);
+ public Object testField0294 = new Integer(294);
+ public Object testField0295 = new Integer(295);
+ public Object testField0296 = new Integer(296);
+ public Object testField0297 = new Integer(297);
+ public Object testField0298 = new Integer(298);
+ public Object testField0299 = new Integer(299);
+ public Object testField0300 = new Integer(300);
+ public Object testField0301 = new Integer(301);
+ public Object testField0302 = new Integer(302);
+ public Object testField0303 = new Integer(303);
+ public Object testField0304 = new Integer(304);
+ public Object testField0305 = new Integer(305);
+ public Object testField0306 = new Integer(306);
+ public Object testField0307 = new Integer(307);
+ public Object testField0308 = new Integer(308);
+ public Object testField0309 = new Integer(309);
+ public Object testField0310 = new Integer(310);
+ public Object testField0311 = new Integer(311);
+ public Object testField0312 = new Integer(312);
+ public Object testField0313 = new Integer(313);
+ public Object testField0314 = new Integer(314);
+ public Object testField0315 = new Integer(315);
+ public Object testField0316 = new Integer(316);
+ public Object testField0317 = new Integer(317);
+ public Object testField0318 = new Integer(318);
+ public Object testField0319 = new Integer(319);
+ public Object testField0320 = new Integer(320);
+ public Object testField0321 = new Integer(321);
+ public Object testField0322 = new Integer(322);
+ public Object testField0323 = new Integer(323);
+ public Object testField0324 = new Integer(324);
+ public Object testField0325 = new Integer(325);
+ public Object testField0326 = new Integer(326);
+ public Object testField0327 = new Integer(327);
+ public Object testField0328 = new Integer(328);
+ public Object testField0329 = new Integer(329);
+ public Object testField0330 = new Integer(330);
+ public Object testField0331 = new Integer(331);
+ public Object testField0332 = new Integer(332);
+ public Object testField0333 = new Integer(333);
+ public Object testField0334 = new Integer(334);
+ public Object testField0335 = new Integer(335);
+ public Object testField0336 = new Integer(336);
+ public Object testField0337 = new Integer(337);
+ public Object testField0338 = new Integer(338);
+ public Object testField0339 = new Integer(339);
+ public Object testField0340 = new Integer(340);
+ public Object testField0341 = new Integer(341);
+ public Object testField0342 = new Integer(342);
+ public Object testField0343 = new Integer(343);
+ public Object testField0344 = new Integer(344);
+ public Object testField0345 = new Integer(345);
+ public Object testField0346 = new Integer(346);
+ public Object testField0347 = new Integer(347);
+ public Object testField0348 = new Integer(348);
+ public Object testField0349 = new Integer(349);
+ public Object testField0350 = new Integer(350);
+ public Object testField0351 = new Integer(351);
+ public Object testField0352 = new Integer(352);
+ public Object testField0353 = new Integer(353);
+ public Object testField0354 = new Integer(354);
+ public Object testField0355 = new Integer(355);
+ public Object testField0356 = new Integer(356);
+ public Object testField0357 = new Integer(357);
+ public Object testField0358 = new Integer(358);
+ public Object testField0359 = new Integer(359);
+ public Object testField0360 = new Integer(360);
+ public Object testField0361 = new Integer(361);
+ public Object testField0362 = new Integer(362);
+ public Object testField0363 = new Integer(363);
+ public Object testField0364 = new Integer(364);
+ public Object testField0365 = new Integer(365);
+ public Object testField0366 = new Integer(366);
+ public Object testField0367 = new Integer(367);
+ public Object testField0368 = new Integer(368);
+ public Object testField0369 = new Integer(369);
+ public Object testField0370 = new Integer(370);
+ public Object testField0371 = new Integer(371);
+ public Object testField0372 = new Integer(372);
+ public Object testField0373 = new Integer(373);
+ public Object testField0374 = new Integer(374);
+ public Object testField0375 = new Integer(375);
+ public Object testField0376 = new Integer(376);
+ public Object testField0377 = new Integer(377);
+ public Object testField0378 = new Integer(378);
+ public Object testField0379 = new Integer(379);
+ public Object testField0380 = new Integer(380);
+ public Object testField0381 = new Integer(381);
+ public Object testField0382 = new Integer(382);
+ public Object testField0383 = new Integer(383);
+ public Object testField0384 = new Integer(384);
+ public Object testField0385 = new Integer(385);
+ public Object testField0386 = new Integer(386);
+ public Object testField0387 = new Integer(387);
+ public Object testField0388 = new Integer(388);
+ public Object testField0389 = new Integer(389);
+ public Object testField0390 = new Integer(390);
+ public Object testField0391 = new Integer(391);
+ public Object testField0392 = new Integer(392);
+ public Object testField0393 = new Integer(393);
+ public Object testField0394 = new Integer(394);
+ public Object testField0395 = new Integer(395);
+ public Object testField0396 = new Integer(396);
+ public Object testField0397 = new Integer(397);
+ public Object testField0398 = new Integer(398);
+ public Object testField0399 = new Integer(399);
+ public Object testField0400 = new Integer(400);
+ public Object testField0401 = new Integer(401);
+ public Object testField0402 = new Integer(402);
+ public Object testField0403 = new Integer(403);
+ public Object testField0404 = new Integer(404);
+ public Object testField0405 = new Integer(405);
+ public Object testField0406 = new Integer(406);
+ public Object testField0407 = new Integer(407);
+ public Object testField0408 = new Integer(408);
+ public Object testField0409 = new Integer(409);
+ public Object testField0410 = new Integer(410);
+ public Object testField0411 = new Integer(411);
+ public Object testField0412 = new Integer(412);
+ public Object testField0413 = new Integer(413);
+ public Object testField0414 = new Integer(414);
+ public Object testField0415 = new Integer(415);
+ public Object testField0416 = new Integer(416);
+ public Object testField0417 = new Integer(417);
+ public Object testField0418 = new Integer(418);
+ public Object testField0419 = new Integer(419);
+ public Object testField0420 = new Integer(420);
+ public Object testField0421 = new Integer(421);
+ public Object testField0422 = new Integer(422);
+ public Object testField0423 = new Integer(423);
+ public Object testField0424 = new Integer(424);
+ public Object testField0425 = new Integer(425);
+ public Object testField0426 = new Integer(426);
+ public Object testField0427 = new Integer(427);
+ public Object testField0428 = new Integer(428);
+ public Object testField0429 = new Integer(429);
+ public Object testField0430 = new Integer(430);
+ public Object testField0431 = new Integer(431);
+ public Object testField0432 = new Integer(432);
+ public Object testField0433 = new Integer(433);
+ public Object testField0434 = new Integer(434);
+ public Object testField0435 = new Integer(435);
+ public Object testField0436 = new Integer(436);
+ public Object testField0437 = new Integer(437);
+ public Object testField0438 = new Integer(438);
+ public Object testField0439 = new Integer(439);
+ public Object testField0440 = new Integer(440);
+ public Object testField0441 = new Integer(441);
+ public Object testField0442 = new Integer(442);
+ public Object testField0443 = new Integer(443);
+ public Object testField0444 = new Integer(444);
+ public Object testField0445 = new Integer(445);
+ public Object testField0446 = new Integer(446);
+ public Object testField0447 = new Integer(447);
+ public Object testField0448 = new Integer(448);
+ public Object testField0449 = new Integer(449);
+ public Object testField0450 = new Integer(450);
+ public Object testField0451 = new Integer(451);
+ public Object testField0452 = new Integer(452);
+ public Object testField0453 = new Integer(453);
+ public Object testField0454 = new Integer(454);
+ public Object testField0455 = new Integer(455);
+ public Object testField0456 = new Integer(456);
+ public Object testField0457 = new Integer(457);
+ public Object testField0458 = new Integer(458);
+ public Object testField0459 = new Integer(459);
+ public Object testField0460 = new Integer(460);
+ public Object testField0461 = new Integer(461);
+ public Object testField0462 = new Integer(462);
+ public Object testField0463 = new Integer(463);
+ public Object testField0464 = new Integer(464);
+ public Object testField0465 = new Integer(465);
+ public Object testField0466 = new Integer(466);
+ public Object testField0467 = new Integer(467);
+ public Object testField0468 = new Integer(468);
+ public Object testField0469 = new Integer(469);
+ public Object testField0470 = new Integer(470);
+ public Object testField0471 = new Integer(471);
+ public Object testField0472 = new Integer(472);
+ public Object testField0473 = new Integer(473);
+ public Object testField0474 = new Integer(474);
+ public Object testField0475 = new Integer(475);
+ public Object testField0476 = new Integer(476);
+ public Object testField0477 = new Integer(477);
+ public Object testField0478 = new Integer(478);
+ public Object testField0479 = new Integer(479);
+ public Object testField0480 = new Integer(480);
+ public Object testField0481 = new Integer(481);
+ public Object testField0482 = new Integer(482);
+ public Object testField0483 = new Integer(483);
+ public Object testField0484 = new Integer(484);
+ public Object testField0485 = new Integer(485);
+ public Object testField0486 = new Integer(486);
+ public Object testField0487 = new Integer(487);
+ public Object testField0488 = new Integer(488);
+ public Object testField0489 = new Integer(489);
+ public Object testField0490 = new Integer(490);
+ public Object testField0491 = new Integer(491);
+ public Object testField0492 = new Integer(492);
+ public Object testField0493 = new Integer(493);
+ public Object testField0494 = new Integer(494);
+ public Object testField0495 = new Integer(495);
+ public Object testField0496 = new Integer(496);
+ public Object testField0497 = new Integer(497);
+ public Object testField0498 = new Integer(498);
+ public Object testField0499 = new Integer(499);
+ public Object testField0500 = new Integer(500);
+ public Object testField0501 = new Integer(501);
+ public Object testField0502 = new Integer(502);
+ public Object testField0503 = new Integer(503);
+ public Object testField0504 = new Integer(504);
+ public Object testField0505 = new Integer(505);
+ public Object testField0506 = new Integer(506);
+ public Object testField0507 = new Integer(507);
+ public Object testField0508 = new Integer(508);
+ public Object testField0509 = new Integer(509);
+ public Object testField0510 = new Integer(510);
+ public Object testField0511 = new Integer(511);
+ public Object testField0512 = new Integer(512);
+ public Object testField0513 = new Integer(513);
+ public Object testField0514 = new Integer(514);
+ public Object testField0515 = new Integer(515);
+ public Object testField0516 = new Integer(516);
+ public Object testField0517 = new Integer(517);
+ public Object testField0518 = new Integer(518);
+ public Object testField0519 = new Integer(519);
+ public Object testField0520 = new Integer(520);
+ public Object testField0521 = new Integer(521);
+ public Object testField0522 = new Integer(522);
+ public Object testField0523 = new Integer(523);
+ public Object testField0524 = new Integer(524);
+ public Object testField0525 = new Integer(525);
+ public Object testField0526 = new Integer(526);
+ public Object testField0527 = new Integer(527);
+ public Object testField0528 = new Integer(528);
+ public Object testField0529 = new Integer(529);
+ public Object testField0530 = new Integer(530);
+ public Object testField0531 = new Integer(531);
+ public Object testField0532 = new Integer(532);
+ public Object testField0533 = new Integer(533);
+ public Object testField0534 = new Integer(534);
+ public Object testField0535 = new Integer(535);
+ public Object testField0536 = new Integer(536);
+ public Object testField0537 = new Integer(537);
+ public Object testField0538 = new Integer(538);
+ public Object testField0539 = new Integer(539);
+ public Object testField0540 = new Integer(540);
+ public Object testField0541 = new Integer(541);
+ public Object testField0542 = new Integer(542);
+ public Object testField0543 = new Integer(543);
+ public Object testField0544 = new Integer(544);
+ public Object testField0545 = new Integer(545);
+ public Object testField0546 = new Integer(546);
+ public Object testField0547 = new Integer(547);
+ public Object testField0548 = new Integer(548);
+ public Object testField0549 = new Integer(549);
+ public Object testField0550 = new Integer(550);
+ public Object testField0551 = new Integer(551);
+ public Object testField0552 = new Integer(552);
+ public Object testField0553 = new Integer(553);
+ public Object testField0554 = new Integer(554);
+ public Object testField0555 = new Integer(555);
+ public Object testField0556 = new Integer(556);
+ public Object testField0557 = new Integer(557);
+ public Object testField0558 = new Integer(558);
+ public Object testField0559 = new Integer(559);
+ public Object testField0560 = new Integer(560);
+ public Object testField0561 = new Integer(561);
+ public Object testField0562 = new Integer(562);
+ public Object testField0563 = new Integer(563);
+ public Object testField0564 = new Integer(564);
+ public Object testField0565 = new Integer(565);
+ public Object testField0566 = new Integer(566);
+ public Object testField0567 = new Integer(567);
+ public Object testField0568 = new Integer(568);
+ public Object testField0569 = new Integer(569);
+ public Object testField0570 = new Integer(570);
+ public Object testField0571 = new Integer(571);
+ public Object testField0572 = new Integer(572);
+ public Object testField0573 = new Integer(573);
+ public Object testField0574 = new Integer(574);
+ public Object testField0575 = new Integer(575);
+ public Object testField0576 = new Integer(576);
+ public Object testField0577 = new Integer(577);
+ public Object testField0578 = new Integer(578);
+ public Object testField0579 = new Integer(579);
+ public Object testField0580 = new Integer(580);
+ public Object testField0581 = new Integer(581);
+ public Object testField0582 = new Integer(582);
+ public Object testField0583 = new Integer(583);
+ public Object testField0584 = new Integer(584);
+ public Object testField0585 = new Integer(585);
+ public Object testField0586 = new Integer(586);
+ public Object testField0587 = new Integer(587);
+ public Object testField0588 = new Integer(588);
+ public Object testField0589 = new Integer(589);
+ public Object testField0590 = new Integer(590);
+ public Object testField0591 = new Integer(591);
+ public Object testField0592 = new Integer(592);
+ public Object testField0593 = new Integer(593);
+ public Object testField0594 = new Integer(594);
+ public Object testField0595 = new Integer(595);
+ public Object testField0596 = new Integer(596);
+ public Object testField0597 = new Integer(597);
+ public Object testField0598 = new Integer(598);
+ public Object testField0599 = new Integer(599);
+ public Object testField0600 = new Integer(600);
+ public Object testField0601 = new Integer(601);
+ public Object testField0602 = new Integer(602);
+ public Object testField0603 = new Integer(603);
+ public Object testField0604 = new Integer(604);
+ public Object testField0605 = new Integer(605);
+ public Object testField0606 = new Integer(606);
+ public Object testField0607 = new Integer(607);
+ public Object testField0608 = new Integer(608);
+ public Object testField0609 = new Integer(609);
+ public Object testField0610 = new Integer(610);
+ public Object testField0611 = new Integer(611);
+ public Object testField0612 = new Integer(612);
+ public Object testField0613 = new Integer(613);
+ public Object testField0614 = new Integer(614);
+ public Object testField0615 = new Integer(615);
+ public Object testField0616 = new Integer(616);
+ public Object testField0617 = new Integer(617);
+ public Object testField0618 = new Integer(618);
+ public Object testField0619 = new Integer(619);
+ public Object testField0620 = new Integer(620);
+ public Object testField0621 = new Integer(621);
+ public Object testField0622 = new Integer(622);
+ public Object testField0623 = new Integer(623);
+ public Object testField0624 = new Integer(624);
+ public Object testField0625 = new Integer(625);
+ public Object testField0626 = new Integer(626);
+ public Object testField0627 = new Integer(627);
+ public Object testField0628 = new Integer(628);
+ public Object testField0629 = new Integer(629);
+ public Object testField0630 = new Integer(630);
+ public Object testField0631 = new Integer(631);
+ public Object testField0632 = new Integer(632);
+ public Object testField0633 = new Integer(633);
+ public Object testField0634 = new Integer(634);
+ public Object testField0635 = new Integer(635);
+ public Object testField0636 = new Integer(636);
+ public Object testField0637 = new Integer(637);
+ public Object testField0638 = new Integer(638);
+ public Object testField0639 = new Integer(639);
+ public Object testField0640 = new Integer(640);
+ public Object testField0641 = new Integer(641);
+ public Object testField0642 = new Integer(642);
+ public Object testField0643 = new Integer(643);
+ public Object testField0644 = new Integer(644);
+ public Object testField0645 = new Integer(645);
+ public Object testField0646 = new Integer(646);
+ public Object testField0647 = new Integer(647);
+ public Object testField0648 = new Integer(648);
+ public Object testField0649 = new Integer(649);
+ public Object testField0650 = new Integer(650);
+ public Object testField0651 = new Integer(651);
+ public Object testField0652 = new Integer(652);
+ public Object testField0653 = new Integer(653);
+ public Object testField0654 = new Integer(654);
+ public Object testField0655 = new Integer(655);
+ public Object testField0656 = new Integer(656);
+ public Object testField0657 = new Integer(657);
+ public Object testField0658 = new Integer(658);
+ public Object testField0659 = new Integer(659);
+ public Object testField0660 = new Integer(660);
+ public Object testField0661 = new Integer(661);
+ public Object testField0662 = new Integer(662);
+ public Object testField0663 = new Integer(663);
+ public Object testField0664 = new Integer(664);
+ public Object testField0665 = new Integer(665);
+ public Object testField0666 = new Integer(666);
+ public Object testField0667 = new Integer(667);
+ public Object testField0668 = new Integer(668);
+ public Object testField0669 = new Integer(669);
+ public Object testField0670 = new Integer(670);
+ public Object testField0671 = new Integer(671);
+ public Object testField0672 = new Integer(672);
+ public Object testField0673 = new Integer(673);
+ public Object testField0674 = new Integer(674);
+ public Object testField0675 = new Integer(675);
+ public Object testField0676 = new Integer(676);
+ public Object testField0677 = new Integer(677);
+ public Object testField0678 = new Integer(678);
+ public Object testField0679 = new Integer(679);
+ public Object testField0680 = new Integer(680);
+ public Object testField0681 = new Integer(681);
+ public Object testField0682 = new Integer(682);
+ public Object testField0683 = new Integer(683);
+ public Object testField0684 = new Integer(684);
+ public Object testField0685 = new Integer(685);
+ public Object testField0686 = new Integer(686);
+ public Object testField0687 = new Integer(687);
+ public Object testField0688 = new Integer(688);
+ public Object testField0689 = new Integer(689);
+ public Object testField0690 = new Integer(690);
+ public Object testField0691 = new Integer(691);
+ public Object testField0692 = new Integer(692);
+ public Object testField0693 = new Integer(693);
+ public Object testField0694 = new Integer(694);
+ public Object testField0695 = new Integer(695);
+ public Object testField0696 = new Integer(696);
+ public Object testField0697 = new Integer(697);
+ public Object testField0698 = new Integer(698);
+ public Object testField0699 = new Integer(699);
+ public Object testField0700 = new Integer(700);
+ public Object testField0701 = new Integer(701);
+ public Object testField0702 = new Integer(702);
+ public Object testField0703 = new Integer(703);
+ public Object testField0704 = new Integer(704);
+ public Object testField0705 = new Integer(705);
+ public Object testField0706 = new Integer(706);
+ public Object testField0707 = new Integer(707);
+ public Object testField0708 = new Integer(708);
+ public Object testField0709 = new Integer(709);
+ public Object testField0710 = new Integer(710);
+ public Object testField0711 = new Integer(711);
+ public Object testField0712 = new Integer(712);
+ public Object testField0713 = new Integer(713);
+ public Object testField0714 = new Integer(714);
+ public Object testField0715 = new Integer(715);
+ public Object testField0716 = new Integer(716);
+ public Object testField0717 = new Integer(717);
+ public Object testField0718 = new Integer(718);
+ public Object testField0719 = new Integer(719);
+ public Object testField0720 = new Integer(720);
+ public Object testField0721 = new Integer(721);
+ public Object testField0722 = new Integer(722);
+ public Object testField0723 = new Integer(723);
+ public Object testField0724 = new Integer(724);
+ public Object testField0725 = new Integer(725);
+ public Object testField0726 = new Integer(726);
+ public Object testField0727 = new Integer(727);
+ public Object testField0728 = new Integer(728);
+ public Object testField0729 = new Integer(729);
+ public Object testField0730 = new Integer(730);
+ public Object testField0731 = new Integer(731);
+ public Object testField0732 = new Integer(732);
+ public Object testField0733 = new Integer(733);
+ public Object testField0734 = new Integer(734);
+ public Object testField0735 = new Integer(735);
+ public Object testField0736 = new Integer(736);
+ public Object testField0737 = new Integer(737);
+ public Object testField0738 = new Integer(738);
+ public Object testField0739 = new Integer(739);
+ public Object testField0740 = new Integer(740);
+ public Object testField0741 = new Integer(741);
+ public Object testField0742 = new Integer(742);
+ public Object testField0743 = new Integer(743);
+ public Object testField0744 = new Integer(744);
+ public Object testField0745 = new Integer(745);
+ public Object testField0746 = new Integer(746);
+ public Object testField0747 = new Integer(747);
+ public Object testField0748 = new Integer(748);
+ public Object testField0749 = new Integer(749);
+ public Object testField0750 = new Integer(750);
+ public Object testField0751 = new Integer(751);
+ public Object testField0752 = new Integer(752);
+ public Object testField0753 = new Integer(753);
+ public Object testField0754 = new Integer(754);
+ public Object testField0755 = new Integer(755);
+ public Object testField0756 = new Integer(756);
+ public Object testField0757 = new Integer(757);
+ public Object testField0758 = new Integer(758);
+ public Object testField0759 = new Integer(759);
+ public Object testField0760 = new Integer(760);
+ public Object testField0761 = new Integer(761);
+ public Object testField0762 = new Integer(762);
+ public Object testField0763 = new Integer(763);
+ public Object testField0764 = new Integer(764);
+ public Object testField0765 = new Integer(765);
+ public Object testField0766 = new Integer(766);
+ public Object testField0767 = new Integer(767);
+ public Object testField0768 = new Integer(768);
+ public Object testField0769 = new Integer(769);
+ public Object testField0770 = new Integer(770);
+ public Object testField0771 = new Integer(771);
+ public Object testField0772 = new Integer(772);
+ public Object testField0773 = new Integer(773);
+ public Object testField0774 = new Integer(774);
+ public Object testField0775 = new Integer(775);
+ public Object testField0776 = new Integer(776);
+ public Object testField0777 = new Integer(777);
+ public Object testField0778 = new Integer(778);
+ public Object testField0779 = new Integer(779);
+ public Object testField0780 = new Integer(780);
+ public Object testField0781 = new Integer(781);
+ public Object testField0782 = new Integer(782);
+ public Object testField0783 = new Integer(783);
+ public Object testField0784 = new Integer(784);
+ public Object testField0785 = new Integer(785);
+ public Object testField0786 = new Integer(786);
+ public Object testField0787 = new Integer(787);
+ public Object testField0788 = new Integer(788);
+ public Object testField0789 = new Integer(789);
+ public Object testField0790 = new Integer(790);
+ public Object testField0791 = new Integer(791);
+ public Object testField0792 = new Integer(792);
+ public Object testField0793 = new Integer(793);
+ public Object testField0794 = new Integer(794);
+ public Object testField0795 = new Integer(795);
+ public Object testField0796 = new Integer(796);
+ public Object testField0797 = new Integer(797);
+ public Object testField0798 = new Integer(798);
+ public Object testField0799 = new Integer(799);
+ public Object testField0800 = new Integer(800);
+ public Object testField0801 = new Integer(801);
+ public Object testField0802 = new Integer(802);
+ public Object testField0803 = new Integer(803);
+ public Object testField0804 = new Integer(804);
+ public Object testField0805 = new Integer(805);
+ public Object testField0806 = new Integer(806);
+ public Object testField0807 = new Integer(807);
+ public Object testField0808 = new Integer(808);
+ public Object testField0809 = new Integer(809);
+ public Object testField0810 = new Integer(810);
+ public Object testField0811 = new Integer(811);
+ public Object testField0812 = new Integer(812);
+ public Object testField0813 = new Integer(813);
+ public Object testField0814 = new Integer(814);
+ public Object testField0815 = new Integer(815);
+ public Object testField0816 = new Integer(816);
+ public Object testField0817 = new Integer(817);
+ public Object testField0818 = new Integer(818);
+ public Object testField0819 = new Integer(819);
+ public Object testField0820 = new Integer(820);
+ public Object testField0821 = new Integer(821);
+ public Object testField0822 = new Integer(822);
+ public Object testField0823 = new Integer(823);
+ public Object testField0824 = new Integer(824);
+ public Object testField0825 = new Integer(825);
+ public Object testField0826 = new Integer(826);
+ public Object testField0827 = new Integer(827);
+ public Object testField0828 = new Integer(828);
+ public Object testField0829 = new Integer(829);
+ public Object testField0830 = new Integer(830);
+ public Object testField0831 = new Integer(831);
+ public Object testField0832 = new Integer(832);
+ public Object testField0833 = new Integer(833);
+ public Object testField0834 = new Integer(834);
+ public Object testField0835 = new Integer(835);
+ public Object testField0836 = new Integer(836);
+ public Object testField0837 = new Integer(837);
+ public Object testField0838 = new Integer(838);
+ public Object testField0839 = new Integer(839);
+ public Object testField0840 = new Integer(840);
+ public Object testField0841 = new Integer(841);
+ public Object testField0842 = new Integer(842);
+ public Object testField0843 = new Integer(843);
+ public Object testField0844 = new Integer(844);
+ public Object testField0845 = new Integer(845);
+ public Object testField0846 = new Integer(846);
+ public Object testField0847 = new Integer(847);
+ public Object testField0848 = new Integer(848);
+ public Object testField0849 = new Integer(849);
+ public Object testField0850 = new Integer(850);
+ public Object testField0851 = new Integer(851);
+ public Object testField0852 = new Integer(852);
+ public Object testField0853 = new Integer(853);
+ public Object testField0854 = new Integer(854);
+ public Object testField0855 = new Integer(855);
+ public Object testField0856 = new Integer(856);
+ public Object testField0857 = new Integer(857);
+ public Object testField0858 = new Integer(858);
+ public Object testField0859 = new Integer(859);
+ public Object testField0860 = new Integer(860);
+ public Object testField0861 = new Integer(861);
+ public Object testField0862 = new Integer(862);
+ public Object testField0863 = new Integer(863);
+ public Object testField0864 = new Integer(864);
+ public Object testField0865 = new Integer(865);
+ public Object testField0866 = new Integer(866);
+ public Object testField0867 = new Integer(867);
+ public Object testField0868 = new Integer(868);
+ public Object testField0869 = new Integer(869);
+ public Object testField0870 = new Integer(870);
+ public Object testField0871 = new Integer(871);
+ public Object testField0872 = new Integer(872);
+ public Object testField0873 = new Integer(873);
+ public Object testField0874 = new Integer(874);
+ public Object testField0875 = new Integer(875);
+ public Object testField0876 = new Integer(876);
+ public Object testField0877 = new Integer(877);
+ public Object testField0878 = new Integer(878);
+ public Object testField0879 = new Integer(879);
+ public Object testField0880 = new Integer(880);
+ public Object testField0881 = new Integer(881);
+ public Object testField0882 = new Integer(882);
+ public Object testField0883 = new Integer(883);
+ public Object testField0884 = new Integer(884);
+ public Object testField0885 = new Integer(885);
+ public Object testField0886 = new Integer(886);
+ public Object testField0887 = new Integer(887);
+ public Object testField0888 = new Integer(888);
+ public Object testField0889 = new Integer(889);
+ public Object testField0890 = new Integer(890);
+ public Object testField0891 = new Integer(891);
+ public Object testField0892 = new Integer(892);
+ public Object testField0893 = new Integer(893);
+ public Object testField0894 = new Integer(894);
+ public Object testField0895 = new Integer(895);
+ public Object testField0896 = new Integer(896);
+ public Object testField0897 = new Integer(897);
+ public Object testField0898 = new Integer(898);
+ public Object testField0899 = new Integer(899);
+ public Object testField0900 = new Integer(900);
+ public Object testField0901 = new Integer(901);
+ public Object testField0902 = new Integer(902);
+ public Object testField0903 = new Integer(903);
+ public Object testField0904 = new Integer(904);
+ public Object testField0905 = new Integer(905);
+ public Object testField0906 = new Integer(906);
+ public Object testField0907 = new Integer(907);
+ public Object testField0908 = new Integer(908);
+ public Object testField0909 = new Integer(909);
+ public Object testField0910 = new Integer(910);
+ public Object testField0911 = new Integer(911);
+ public Object testField0912 = new Integer(912);
+ public Object testField0913 = new Integer(913);
+ public Object testField0914 = new Integer(914);
+ public Object testField0915 = new Integer(915);
+ public Object testField0916 = new Integer(916);
+ public Object testField0917 = new Integer(917);
+ public Object testField0918 = new Integer(918);
+ public Object testField0919 = new Integer(919);
+ public Object testField0920 = new Integer(920);
+ public Object testField0921 = new Integer(921);
+ public Object testField0922 = new Integer(922);
+ public Object testField0923 = new Integer(923);
+ public Object testField0924 = new Integer(924);
+ public Object testField0925 = new Integer(925);
+ public Object testField0926 = new Integer(926);
+ public Object testField0927 = new Integer(927);
+ public Object testField0928 = new Integer(928);
+ public Object testField0929 = new Integer(929);
+ public Object testField0930 = new Integer(930);
+ public Object testField0931 = new Integer(931);
+ public Object testField0932 = new Integer(932);
+ public Object testField0933 = new Integer(933);
+ public Object testField0934 = new Integer(934);
+ public Object testField0935 = new Integer(935);
+ public Object testField0936 = new Integer(936);
+ public Object testField0937 = new Integer(937);
+ public Object testField0938 = new Integer(938);
+ public Object testField0939 = new Integer(939);
+ public Object testField0940 = new Integer(940);
+ public Object testField0941 = new Integer(941);
+ public Object testField0942 = new Integer(942);
+ public Object testField0943 = new Integer(943);
+ public Object testField0944 = new Integer(944);
+ public Object testField0945 = new Integer(945);
+ public Object testField0946 = new Integer(946);
+ public Object testField0947 = new Integer(947);
+ public Object testField0948 = new Integer(948);
+ public Object testField0949 = new Integer(949);
+ public Object testField0950 = new Integer(950);
+ public Object testField0951 = new Integer(951);
+ public Object testField0952 = new Integer(952);
+ public Object testField0953 = new Integer(953);
+ public Object testField0954 = new Integer(954);
+ public Object testField0955 = new Integer(955);
+ public Object testField0956 = new Integer(956);
+ public Object testField0957 = new Integer(957);
+ public Object testField0958 = new Integer(958);
+ public Object testField0959 = new Integer(959);
+ public Object testField0960 = new Integer(960);
+ public Object testField0961 = new Integer(961);
+ public Object testField0962 = new Integer(962);
+ public Object testField0963 = new Integer(963);
+ public Object testField0964 = new Integer(964);
+ public Object testField0965 = new Integer(965);
+ public Object testField0966 = new Integer(966);
+ public Object testField0967 = new Integer(967);
+ public Object testField0968 = new Integer(968);
+ public Object testField0969 = new Integer(969);
+ public Object testField0970 = new Integer(970);
+ public Object testField0971 = new Integer(971);
+ public Object testField0972 = new Integer(972);
+ public Object testField0973 = new Integer(973);
+ public Object testField0974 = new Integer(974);
+ public Object testField0975 = new Integer(975);
+ public Object testField0976 = new Integer(976);
+ public Object testField0977 = new Integer(977);
+ public Object testField0978 = new Integer(978);
+ public Object testField0979 = new Integer(979);
+ public Object testField0980 = new Integer(980);
+ public Object testField0981 = new Integer(981);
+ public Object testField0982 = new Integer(982);
+ public Object testField0983 = new Integer(983);
+ public Object testField0984 = new Integer(984);
+ public Object testField0985 = new Integer(985);
+ public Object testField0986 = new Integer(986);
+ public Object testField0987 = new Integer(987);
+ public Object testField0988 = new Integer(988);
+ public Object testField0989 = new Integer(989);
+ public Object testField0990 = new Integer(990);
+ public Object testField0991 = new Integer(991);
+ public Object testField0992 = new Integer(992);
+ public Object testField0993 = new Integer(993);
+ public Object testField0994 = new Integer(994);
+ public Object testField0995 = new Integer(995);
+ public Object testField0996 = new Integer(996);
+ public Object testField0997 = new Integer(997);
+ public Object testField0998 = new Integer(998);
+ public Object testField0999 = new Integer(999);
+}
diff --git a/test/160-read-barrier-stress/src/ManyFieldsBase1.java b/test/160-read-barrier-stress/src/ManyFieldsBase1.java
new file mode 100644
index 0000000000..8680c6bb03
--- /dev/null
+++ b/test/160-read-barrier-stress/src/ManyFieldsBase1.java
@@ -0,0 +1,1018 @@
+/*
+ * 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.
+ */
+
+class ManyFieldsBase1 extends ManyFieldsBase0 {
+ public Object testField1000 = new Integer(1000);
+ public Object testField1001 = new Integer(1001);
+ public Object testField1002 = new Integer(1002);
+ public Object testField1003 = new Integer(1003);
+ public Object testField1004 = new Integer(1004);
+ public Object testField1005 = new Integer(1005);
+ public Object testField1006 = new Integer(1006);
+ public Object testField1007 = new Integer(1007);
+ public Object testField1008 = new Integer(1008);
+ public Object testField1009 = new Integer(1009);
+ public Object testField1010 = new Integer(1010);
+ public Object testField1011 = new Integer(1011);
+ public Object testField1012 = new Integer(1012);
+ public Object testField1013 = new Integer(1013);
+ public Object testField1014 = new Integer(1014);
+ public Object testField1015 = new Integer(1015);
+ public Object testField1016 = new Integer(1016);
+ public Object testField1017 = new Integer(1017);
+ public Object testField1018 = new Integer(1018);
+ public Object testField1019 = new Integer(1019);
+ public Object testField1020 = new Integer(1020);
+ public Object testField1021 = new Integer(1021);
+ public Object testField1022 = new Integer(1022);
+ public Object testField1023 = new Integer(1023);
+ public Object testField1024 = new Integer(1024);
+ public Object testField1025 = new Integer(1025);
+ public Object testField1026 = new Integer(1026);
+ public Object testField1027 = new Integer(1027);
+ public Object testField1028 = new Integer(1028);
+ public Object testField1029 = new Integer(1029);
+ public Object testField1030 = new Integer(1030);
+ public Object testField1031 = new Integer(1031);
+ public Object testField1032 = new Integer(1032);
+ public Object testField1033 = new Integer(1033);
+ public Object testField1034 = new Integer(1034);
+ public Object testField1035 = new Integer(1035);
+ public Object testField1036 = new Integer(1036);
+ public Object testField1037 = new Integer(1037);
+ public Object testField1038 = new Integer(1038);
+ public Object testField1039 = new Integer(1039);
+ public Object testField1040 = new Integer(1040);
+ public Object testField1041 = new Integer(1041);
+ public Object testField1042 = new Integer(1042);
+ public Object testField1043 = new Integer(1043);
+ public Object testField1044 = new Integer(1044);
+ public Object testField1045 = new Integer(1045);
+ public Object testField1046 = new Integer(1046);
+ public Object testField1047 = new Integer(1047);
+ public Object testField1048 = new Integer(1048);
+ public Object testField1049 = new Integer(1049);
+ public Object testField1050 = new Integer(1050);
+ public Object testField1051 = new Integer(1051);
+ public Object testField1052 = new Integer(1052);
+ public Object testField1053 = new Integer(1053);
+ public Object testField1054 = new Integer(1054);
+ public Object testField1055 = new Integer(1055);
+ public Object testField1056 = new Integer(1056);
+ public Object testField1057 = new Integer(1057);
+ public Object testField1058 = new Integer(1058);
+ public Object testField1059 = new Integer(1059);
+ public Object testField1060 = new Integer(1060);
+ public Object testField1061 = new Integer(1061);
+ public Object testField1062 = new Integer(1062);
+ public Object testField1063 = new Integer(1063);
+ public Object testField1064 = new Integer(1064);
+ public Object testField1065 = new Integer(1065);
+ public Object testField1066 = new Integer(1066);
+ public Object testField1067 = new Integer(1067);
+ public Object testField1068 = new Integer(1068);
+ public Object testField1069 = new Integer(1069);
+ public Object testField1070 = new Integer(1070);
+ public Object testField1071 = new Integer(1071);
+ public Object testField1072 = new Integer(1072);
+ public Object testField1073 = new Integer(1073);
+ public Object testField1074 = new Integer(1074);
+ public Object testField1075 = new Integer(1075);
+ public Object testField1076 = new Integer(1076);
+ public Object testField1077 = new Integer(1077);
+ public Object testField1078 = new Integer(1078);
+ public Object testField1079 = new Integer(1079);
+ public Object testField1080 = new Integer(1080);
+ public Object testField1081 = new Integer(1081);
+ public Object testField1082 = new Integer(1082);
+ public Object testField1083 = new Integer(1083);
+ public Object testField1084 = new Integer(1084);
+ public Object testField1085 = new Integer(1085);
+ public Object testField1086 = new Integer(1086);
+ public Object testField1087 = new Integer(1087);
+ public Object testField1088 = new Integer(1088);
+ public Object testField1089 = new Integer(1089);
+ public Object testField1090 = new Integer(1090);
+ public Object testField1091 = new Integer(1091);
+ public Object testField1092 = new Integer(1092);
+ public Object testField1093 = new Integer(1093);
+ public Object testField1094 = new Integer(1094);
+ public Object testField1095 = new Integer(1095);
+ public Object testField1096 = new Integer(1096);
+ public Object testField1097 = new Integer(1097);
+ public Object testField1098 = new Integer(1098);
+ public Object testField1099 = new Integer(1099);
+ public Object testField1100 = new Integer(1100);
+ public Object testField1101 = new Integer(1101);
+ public Object testField1102 = new Integer(1102);
+ public Object testField1103 = new Integer(1103);
+ public Object testField1104 = new Integer(1104);
+ public Object testField1105 = new Integer(1105);
+ public Object testField1106 = new Integer(1106);
+ public Object testField1107 = new Integer(1107);
+ public Object testField1108 = new Integer(1108);
+ public Object testField1109 = new Integer(1109);
+ public Object testField1110 = new Integer(1110);
+ public Object testField1111 = new Integer(1111);
+ public Object testField1112 = new Integer(1112);
+ public Object testField1113 = new Integer(1113);
+ public Object testField1114 = new Integer(1114);
+ public Object testField1115 = new Integer(1115);
+ public Object testField1116 = new Integer(1116);
+ public Object testField1117 = new Integer(1117);
+ public Object testField1118 = new Integer(1118);
+ public Object testField1119 = new Integer(1119);
+ public Object testField1120 = new Integer(1120);
+ public Object testField1121 = new Integer(1121);
+ public Object testField1122 = new Integer(1122);
+ public Object testField1123 = new Integer(1123);
+ public Object testField1124 = new Integer(1124);
+ public Object testField1125 = new Integer(1125);
+ public Object testField1126 = new Integer(1126);
+ public Object testField1127 = new Integer(1127);
+ public Object testField1128 = new Integer(1128);
+ public Object testField1129 = new Integer(1129);
+ public Object testField1130 = new Integer(1130);
+ public Object testField1131 = new Integer(1131);
+ public Object testField1132 = new Integer(1132);
+ public Object testField1133 = new Integer(1133);
+ public Object testField1134 = new Integer(1134);
+ public Object testField1135 = new Integer(1135);
+ public Object testField1136 = new Integer(1136);
+ public Object testField1137 = new Integer(1137);
+ public Object testField1138 = new Integer(1138);
+ public Object testField1139 = new Integer(1139);
+ public Object testField1140 = new Integer(1140);
+ public Object testField1141 = new Integer(1141);
+ public Object testField1142 = new Integer(1142);
+ public Object testField1143 = new Integer(1143);
+ public Object testField1144 = new Integer(1144);
+ public Object testField1145 = new Integer(1145);
+ public Object testField1146 = new Integer(1146);
+ public Object testField1147 = new Integer(1147);
+ public Object testField1148 = new Integer(1148);
+ public Object testField1149 = new Integer(1149);
+ public Object testField1150 = new Integer(1150);
+ public Object testField1151 = new Integer(1151);
+ public Object testField1152 = new Integer(1152);
+ public Object testField1153 = new Integer(1153);
+ public Object testField1154 = new Integer(1154);
+ public Object testField1155 = new Integer(1155);
+ public Object testField1156 = new Integer(1156);
+ public Object testField1157 = new Integer(1157);
+ public Object testField1158 = new Integer(1158);
+ public Object testField1159 = new Integer(1159);
+ public Object testField1160 = new Integer(1160);
+ public Object testField1161 = new Integer(1161);
+ public Object testField1162 = new Integer(1162);
+ public Object testField1163 = new Integer(1163);
+ public Object testField1164 = new Integer(1164);
+ public Object testField1165 = new Integer(1165);
+ public Object testField1166 = new Integer(1166);
+ public Object testField1167 = new Integer(1167);
+ public Object testField1168 = new Integer(1168);
+ public Object testField1169 = new Integer(1169);
+ public Object testField1170 = new Integer(1170);
+ public Object testField1171 = new Integer(1171);
+ public Object testField1172 = new Integer(1172);
+ public Object testField1173 = new Integer(1173);
+ public Object testField1174 = new Integer(1174);
+ public Object testField1175 = new Integer(1175);
+ public Object testField1176 = new Integer(1176);
+ public Object testField1177 = new Integer(1177);
+ public Object testField1178 = new Integer(1178);
+ public Object testField1179 = new Integer(1179);
+ public Object testField1180 = new Integer(1180);
+ public Object testField1181 = new Integer(1181);
+ public Object testField1182 = new Integer(1182);
+ public Object testField1183 = new Integer(1183);
+ public Object testField1184 = new Integer(1184);
+ public Object testField1185 = new Integer(1185);
+ public Object testField1186 = new Integer(1186);
+ public Object testField1187 = new Integer(1187);
+ public Object testField1188 = new Integer(1188);
+ public Object testField1189 = new Integer(1189);
+ public Object testField1190 = new Integer(1190);
+ public Object testField1191 = new Integer(1191);
+ public Object testField1192 = new Integer(1192);
+ public Object testField1193 = new Integer(1193);
+ public Object testField1194 = new Integer(1194);
+ public Object testField1195 = new Integer(1195);
+ public Object testField1196 = new Integer(1196);
+ public Object testField1197 = new Integer(1197);
+ public Object testField1198 = new Integer(1198);
+ public Object testField1199 = new Integer(1199);
+ public Object testField1200 = new Integer(1200);
+ public Object testField1201 = new Integer(1201);
+ public Object testField1202 = new Integer(1202);
+ public Object testField1203 = new Integer(1203);
+ public Object testField1204 = new Integer(1204);
+ public Object testField1205 = new Integer(1205);
+ public Object testField1206 = new Integer(1206);
+ public Object testField1207 = new Integer(1207);
+ public Object testField1208 = new Integer(1208);
+ public Object testField1209 = new Integer(1209);
+ public Object testField1210 = new Integer(1210);
+ public Object testField1211 = new Integer(1211);
+ public Object testField1212 = new Integer(1212);
+ public Object testField1213 = new Integer(1213);
+ public Object testField1214 = new Integer(1214);
+ public Object testField1215 = new Integer(1215);
+ public Object testField1216 = new Integer(1216);
+ public Object testField1217 = new Integer(1217);
+ public Object testField1218 = new Integer(1218);
+ public Object testField1219 = new Integer(1219);
+ public Object testField1220 = new Integer(1220);
+ public Object testField1221 = new Integer(1221);
+ public Object testField1222 = new Integer(1222);
+ public Object testField1223 = new Integer(1223);
+ public Object testField1224 = new Integer(1224);
+ public Object testField1225 = new Integer(1225);
+ public Object testField1226 = new Integer(1226);
+ public Object testField1227 = new Integer(1227);
+ public Object testField1228 = new Integer(1228);
+ public Object testField1229 = new Integer(1229);
+ public Object testField1230 = new Integer(1230);
+ public Object testField1231 = new Integer(1231);
+ public Object testField1232 = new Integer(1232);
+ public Object testField1233 = new Integer(1233);
+ public Object testField1234 = new Integer(1234);
+ public Object testField1235 = new Integer(1235);
+ public Object testField1236 = new Integer(1236);
+ public Object testField1237 = new Integer(1237);
+ public Object testField1238 = new Integer(1238);
+ public Object testField1239 = new Integer(1239);
+ public Object testField1240 = new Integer(1240);
+ public Object testField1241 = new Integer(1241);
+ public Object testField1242 = new Integer(1242);
+ public Object testField1243 = new Integer(1243);
+ public Object testField1244 = new Integer(1244);
+ public Object testField1245 = new Integer(1245);
+ public Object testField1246 = new Integer(1246);
+ public Object testField1247 = new Integer(1247);
+ public Object testField1248 = new Integer(1248);
+ public Object testField1249 = new Integer(1249);
+ public Object testField1250 = new Integer(1250);
+ public Object testField1251 = new Integer(1251);
+ public Object testField1252 = new Integer(1252);
+ public Object testField1253 = new Integer(1253);
+ public Object testField1254 = new Integer(1254);
+ public Object testField1255 = new Integer(1255);
+ public Object testField1256 = new Integer(1256);
+ public Object testField1257 = new Integer(1257);
+ public Object testField1258 = new Integer(1258);
+ public Object testField1259 = new Integer(1259);
+ public Object testField1260 = new Integer(1260);
+ public Object testField1261 = new Integer(1261);
+ public Object testField1262 = new Integer(1262);
+ public Object testField1263 = new Integer(1263);
+ public Object testField1264 = new Integer(1264);
+ public Object testField1265 = new Integer(1265);
+ public Object testField1266 = new Integer(1266);
+ public Object testField1267 = new Integer(1267);
+ public Object testField1268 = new Integer(1268);
+ public Object testField1269 = new Integer(1269);
+ public Object testField1270 = new Integer(1270);
+ public Object testField1271 = new Integer(1271);
+ public Object testField1272 = new Integer(1272);
+ public Object testField1273 = new Integer(1273);
+ public Object testField1274 = new Integer(1274);
+ public Object testField1275 = new Integer(1275);
+ public Object testField1276 = new Integer(1276);
+ public Object testField1277 = new Integer(1277);
+ public Object testField1278 = new Integer(1278);
+ public Object testField1279 = new Integer(1279);
+ public Object testField1280 = new Integer(1280);
+ public Object testField1281 = new Integer(1281);
+ public Object testField1282 = new Integer(1282);
+ public Object testField1283 = new Integer(1283);
+ public Object testField1284 = new Integer(1284);
+ public Object testField1285 = new Integer(1285);
+ public Object testField1286 = new Integer(1286);
+ public Object testField1287 = new Integer(1287);
+ public Object testField1288 = new Integer(1288);
+ public Object testField1289 = new Integer(1289);
+ public Object testField1290 = new Integer(1290);
+ public Object testField1291 = new Integer(1291);
+ public Object testField1292 = new Integer(1292);
+ public Object testField1293 = new Integer(1293);
+ public Object testField1294 = new Integer(1294);
+ public Object testField1295 = new Integer(1295);
+ public Object testField1296 = new Integer(1296);
+ public Object testField1297 = new Integer(1297);
+ public Object testField1298 = new Integer(1298);
+ public Object testField1299 = new Integer(1299);
+ public Object testField1300 = new Integer(1300);
+ public Object testField1301 = new Integer(1301);
+ public Object testField1302 = new Integer(1302);
+ public Object testField1303 = new Integer(1303);
+ public Object testField1304 = new Integer(1304);
+ public Object testField1305 = new Integer(1305);
+ public Object testField1306 = new Integer(1306);
+ public Object testField1307 = new Integer(1307);
+ public Object testField1308 = new Integer(1308);
+ public Object testField1309 = new Integer(1309);
+ public Object testField1310 = new Integer(1310);
+ public Object testField1311 = new Integer(1311);
+ public Object testField1312 = new Integer(1312);
+ public Object testField1313 = new Integer(1313);
+ public Object testField1314 = new Integer(1314);
+ public Object testField1315 = new Integer(1315);
+ public Object testField1316 = new Integer(1316);
+ public Object testField1317 = new Integer(1317);
+ public Object testField1318 = new Integer(1318);
+ public Object testField1319 = new Integer(1319);
+ public Object testField1320 = new Integer(1320);
+ public Object testField1321 = new Integer(1321);
+ public Object testField1322 = new Integer(1322);
+ public Object testField1323 = new Integer(1323);
+ public Object testField1324 = new Integer(1324);
+ public Object testField1325 = new Integer(1325);
+ public Object testField1326 = new Integer(1326);
+ public Object testField1327 = new Integer(1327);
+ public Object testField1328 = new Integer(1328);
+ public Object testField1329 = new Integer(1329);
+ public Object testField1330 = new Integer(1330);
+ public Object testField1331 = new Integer(1331);
+ public Object testField1332 = new Integer(1332);
+ public Object testField1333 = new Integer(1333);
+ public Object testField1334 = new Integer(1334);
+ public Object testField1335 = new Integer(1335);
+ public Object testField1336 = new Integer(1336);
+ public Object testField1337 = new Integer(1337);
+ public Object testField1338 = new Integer(1338);
+ public Object testField1339 = new Integer(1339);
+ public Object testField1340 = new Integer(1340);
+ public Object testField1341 = new Integer(1341);
+ public Object testField1342 = new Integer(1342);
+ public Object testField1343 = new Integer(1343);
+ public Object testField1344 = new Integer(1344);
+ public Object testField1345 = new Integer(1345);
+ public Object testField1346 = new Integer(1346);
+ public Object testField1347 = new Integer(1347);
+ public Object testField1348 = new Integer(1348);
+ public Object testField1349 = new Integer(1349);
+ public Object testField1350 = new Integer(1350);
+ public Object testField1351 = new Integer(1351);
+ public Object testField1352 = new Integer(1352);
+ public Object testField1353 = new Integer(1353);
+ public Object testField1354 = new Integer(1354);
+ public Object testField1355 = new Integer(1355);
+ public Object testField1356 = new Integer(1356);
+ public Object testField1357 = new Integer(1357);
+ public Object testField1358 = new Integer(1358);
+ public Object testField1359 = new Integer(1359);
+ public Object testField1360 = new Integer(1360);
+ public Object testField1361 = new Integer(1361);
+ public Object testField1362 = new Integer(1362);
+ public Object testField1363 = new Integer(1363);
+ public Object testField1364 = new Integer(1364);
+ public Object testField1365 = new Integer(1365);
+ public Object testField1366 = new Integer(1366);
+ public Object testField1367 = new Integer(1367);
+ public Object testField1368 = new Integer(1368);
+ public Object testField1369 = new Integer(1369);
+ public Object testField1370 = new Integer(1370);
+ public Object testField1371 = new Integer(1371);
+ public Object testField1372 = new Integer(1372);
+ public Object testField1373 = new Integer(1373);
+ public Object testField1374 = new Integer(1374);
+ public Object testField1375 = new Integer(1375);
+ public Object testField1376 = new Integer(1376);
+ public Object testField1377 = new Integer(1377);
+ public Object testField1378 = new Integer(1378);
+ public Object testField1379 = new Integer(1379);
+ public Object testField1380 = new Integer(1380);
+ public Object testField1381 = new Integer(1381);
+ public Object testField1382 = new Integer(1382);
+ public Object testField1383 = new Integer(1383);
+ public Object testField1384 = new Integer(1384);
+ public Object testField1385 = new Integer(1385);
+ public Object testField1386 = new Integer(1386);
+ public Object testField1387 = new Integer(1387);
+ public Object testField1388 = new Integer(1388);
+ public Object testField1389 = new Integer(1389);
+ public Object testField1390 = new Integer(1390);
+ public Object testField1391 = new Integer(1391);
+ public Object testField1392 = new Integer(1392);
+ public Object testField1393 = new Integer(1393);
+ public Object testField1394 = new Integer(1394);
+ public Object testField1395 = new Integer(1395);
+ public Object testField1396 = new Integer(1396);
+ public Object testField1397 = new Integer(1397);
+ public Object testField1398 = new Integer(1398);
+ public Object testField1399 = new Integer(1399);
+ public Object testField1400 = new Integer(1400);
+ public Object testField1401 = new Integer(1401);
+ public Object testField1402 = new Integer(1402);
+ public Object testField1403 = new Integer(1403);
+ public Object testField1404 = new Integer(1404);
+ public Object testField1405 = new Integer(1405);
+ public Object testField1406 = new Integer(1406);
+ public Object testField1407 = new Integer(1407);
+ public Object testField1408 = new Integer(1408);
+ public Object testField1409 = new Integer(1409);
+ public Object testField1410 = new Integer(1410);
+ public Object testField1411 = new Integer(1411);
+ public Object testField1412 = new Integer(1412);
+ public Object testField1413 = new Integer(1413);
+ public Object testField1414 = new Integer(1414);
+ public Object testField1415 = new Integer(1415);
+ public Object testField1416 = new Integer(1416);
+ public Object testField1417 = new Integer(1417);
+ public Object testField1418 = new Integer(1418);
+ public Object testField1419 = new Integer(1419);
+ public Object testField1420 = new Integer(1420);
+ public Object testField1421 = new Integer(1421);
+ public Object testField1422 = new Integer(1422);
+ public Object testField1423 = new Integer(1423);
+ public Object testField1424 = new Integer(1424);
+ public Object testField1425 = new Integer(1425);
+ public Object testField1426 = new Integer(1426);
+ public Object testField1427 = new Integer(1427);
+ public Object testField1428 = new Integer(1428);
+ public Object testField1429 = new Integer(1429);
+ public Object testField1430 = new Integer(1430);
+ public Object testField1431 = new Integer(1431);
+ public Object testField1432 = new Integer(1432);
+ public Object testField1433 = new Integer(1433);
+ public Object testField1434 = new Integer(1434);
+ public Object testField1435 = new Integer(1435);
+ public Object testField1436 = new Integer(1436);
+ public Object testField1437 = new Integer(1437);
+ public Object testField1438 = new Integer(1438);
+ public Object testField1439 = new Integer(1439);
+ public Object testField1440 = new Integer(1440);
+ public Object testField1441 = new Integer(1441);
+ public Object testField1442 = new Integer(1442);
+ public Object testField1443 = new Integer(1443);
+ public Object testField1444 = new Integer(1444);
+ public Object testField1445 = new Integer(1445);
+ public Object testField1446 = new Integer(1446);
+ public Object testField1447 = new Integer(1447);
+ public Object testField1448 = new Integer(1448);
+ public Object testField1449 = new Integer(1449);
+ public Object testField1450 = new Integer(1450);
+ public Object testField1451 = new Integer(1451);
+ public Object testField1452 = new Integer(1452);
+ public Object testField1453 = new Integer(1453);
+ public Object testField1454 = new Integer(1454);
+ public Object testField1455 = new Integer(1455);
+ public Object testField1456 = new Integer(1456);
+ public Object testField1457 = new Integer(1457);
+ public Object testField1458 = new Integer(1458);
+ public Object testField1459 = new Integer(1459);
+ public Object testField1460 = new Integer(1460);
+ public Object testField1461 = new Integer(1461);
+ public Object testField1462 = new Integer(1462);
+ public Object testField1463 = new Integer(1463);
+ public Object testField1464 = new Integer(1464);
+ public Object testField1465 = new Integer(1465);
+ public Object testField1466 = new Integer(1466);
+ public Object testField1467 = new Integer(1467);
+ public Object testField1468 = new Integer(1468);
+ public Object testField1469 = new Integer(1469);
+ public Object testField1470 = new Integer(1470);
+ public Object testField1471 = new Integer(1471);
+ public Object testField1472 = new Integer(1472);
+ public Object testField1473 = new Integer(1473);
+ public Object testField1474 = new Integer(1474);
+ public Object testField1475 = new Integer(1475);
+ public Object testField1476 = new Integer(1476);
+ public Object testField1477 = new Integer(1477);
+ public Object testField1478 = new Integer(1478);
+ public Object testField1479 = new Integer(1479);
+ public Object testField1480 = new Integer(1480);
+ public Object testField1481 = new Integer(1481);
+ public Object testField1482 = new Integer(1482);
+ public Object testField1483 = new Integer(1483);
+ public Object testField1484 = new Integer(1484);
+ public Object testField1485 = new Integer(1485);
+ public Object testField1486 = new Integer(1486);
+ public Object testField1487 = new Integer(1487);
+ public Object testField1488 = new Integer(1488);
+ public Object testField1489 = new Integer(1489);
+ public Object testField1490 = new Integer(1490);
+ public Object testField1491 = new Integer(1491);
+ public Object testField1492 = new Integer(1492);
+ public Object testField1493 = new Integer(1493);
+ public Object testField1494 = new Integer(1494);
+ public Object testField1495 = new Integer(1495);
+ public Object testField1496 = new Integer(1496);
+ public Object testField1497 = new Integer(1497);
+ public Object testField1498 = new Integer(1498);
+ public Object testField1499 = new Integer(1499);
+ public Object testField1500 = new Integer(1500);
+ public Object testField1501 = new Integer(1501);
+ public Object testField1502 = new Integer(1502);
+ public Object testField1503 = new Integer(1503);
+ public Object testField1504 = new Integer(1504);
+ public Object testField1505 = new Integer(1505);
+ public Object testField1506 = new Integer(1506);
+ public Object testField1507 = new Integer(1507);
+ public Object testField1508 = new Integer(1508);
+ public Object testField1509 = new Integer(1509);
+ public Object testField1510 = new Integer(1510);
+ public Object testField1511 = new Integer(1511);
+ public Object testField1512 = new Integer(1512);
+ public Object testField1513 = new Integer(1513);
+ public Object testField1514 = new Integer(1514);
+ public Object testField1515 = new Integer(1515);
+ public Object testField1516 = new Integer(1516);
+ public Object testField1517 = new Integer(1517);
+ public Object testField1518 = new Integer(1518);
+ public Object testField1519 = new Integer(1519);
+ public Object testField1520 = new Integer(1520);
+ public Object testField1521 = new Integer(1521);
+ public Object testField1522 = new Integer(1522);
+ public Object testField1523 = new Integer(1523);
+ public Object testField1524 = new Integer(1524);
+ public Object testField1525 = new Integer(1525);
+ public Object testField1526 = new Integer(1526);
+ public Object testField1527 = new Integer(1527);
+ public Object testField1528 = new Integer(1528);
+ public Object testField1529 = new Integer(1529);
+ public Object testField1530 = new Integer(1530);
+ public Object testField1531 = new Integer(1531);
+ public Object testField1532 = new Integer(1532);
+ public Object testField1533 = new Integer(1533);
+ public Object testField1534 = new Integer(1534);
+ public Object testField1535 = new Integer(1535);
+ public Object testField1536 = new Integer(1536);
+ public Object testField1537 = new Integer(1537);
+ public Object testField1538 = new Integer(1538);
+ public Object testField1539 = new Integer(1539);
+ public Object testField1540 = new Integer(1540);
+ public Object testField1541 = new Integer(1541);
+ public Object testField1542 = new Integer(1542);
+ public Object testField1543 = new Integer(1543);
+ public Object testField1544 = new Integer(1544);
+ public Object testField1545 = new Integer(1545);
+ public Object testField1546 = new Integer(1546);
+ public Object testField1547 = new Integer(1547);
+ public Object testField1548 = new Integer(1548);
+ public Object testField1549 = new Integer(1549);
+ public Object testField1550 = new Integer(1550);
+ public Object testField1551 = new Integer(1551);
+ public Object testField1552 = new Integer(1552);
+ public Object testField1553 = new Integer(1553);
+ public Object testField1554 = new Integer(1554);
+ public Object testField1555 = new Integer(1555);
+ public Object testField1556 = new Integer(1556);
+ public Object testField1557 = new Integer(1557);
+ public Object testField1558 = new Integer(1558);
+ public Object testField1559 = new Integer(1559);
+ public Object testField1560 = new Integer(1560);
+ public Object testField1561 = new Integer(1561);
+ public Object testField1562 = new Integer(1562);
+ public Object testField1563 = new Integer(1563);
+ public Object testField1564 = new Integer(1564);
+ public Object testField1565 = new Integer(1565);
+ public Object testField1566 = new Integer(1566);
+ public Object testField1567 = new Integer(1567);
+ public Object testField1568 = new Integer(1568);
+ public Object testField1569 = new Integer(1569);
+ public Object testField1570 = new Integer(1570);
+ public Object testField1571 = new Integer(1571);
+ public Object testField1572 = new Integer(1572);
+ public Object testField1573 = new Integer(1573);
+ public Object testField1574 = new Integer(1574);
+ public Object testField1575 = new Integer(1575);
+ public Object testField1576 = new Integer(1576);
+ public Object testField1577 = new Integer(1577);
+ public Object testField1578 = new Integer(1578);
+ public Object testField1579 = new Integer(1579);
+ public Object testField1580 = new Integer(1580);
+ public Object testField1581 = new Integer(1581);
+ public Object testField1582 = new Integer(1582);
+ public Object testField1583 = new Integer(1583);
+ public Object testField1584 = new Integer(1584);
+ public Object testField1585 = new Integer(1585);
+ public Object testField1586 = new Integer(1586);
+ public Object testField1587 = new Integer(1587);
+ public Object testField1588 = new Integer(1588);
+ public Object testField1589 = new Integer(1589);
+ public Object testField1590 = new Integer(1590);
+ public Object testField1591 = new Integer(1591);
+ public Object testField1592 = new Integer(1592);
+ public Object testField1593 = new Integer(1593);
+ public Object testField1594 = new Integer(1594);
+ public Object testField1595 = new Integer(1595);
+ public Object testField1596 = new Integer(1596);
+ public Object testField1597 = new Integer(1597);
+ public Object testField1598 = new Integer(1598);
+ public Object testField1599 = new Integer(1599);
+ public Object testField1600 = new Integer(1600);
+ public Object testField1601 = new Integer(1601);
+ public Object testField1602 = new Integer(1602);
+ public Object testField1603 = new Integer(1603);
+ public Object testField1604 = new Integer(1604);
+ public Object testField1605 = new Integer(1605);
+ public Object testField1606 = new Integer(1606);
+ public Object testField1607 = new Integer(1607);
+ public Object testField1608 = new Integer(1608);
+ public Object testField1609 = new Integer(1609);
+ public Object testField1610 = new Integer(1610);
+ public Object testField1611 = new Integer(1611);
+ public Object testField1612 = new Integer(1612);
+ public Object testField1613 = new Integer(1613);
+ public Object testField1614 = new Integer(1614);
+ public Object testField1615 = new Integer(1615);
+ public Object testField1616 = new Integer(1616);
+ public Object testField1617 = new Integer(1617);
+ public Object testField1618 = new Integer(1618);
+ public Object testField1619 = new Integer(1619);
+ public Object testField1620 = new Integer(1620);
+ public Object testField1621 = new Integer(1621);
+ public Object testField1622 = new Integer(1622);
+ public Object testField1623 = new Integer(1623);
+ public Object testField1624 = new Integer(1624);
+ public Object testField1625 = new Integer(1625);
+ public Object testField1626 = new Integer(1626);
+ public Object testField1627 = new Integer(1627);
+ public Object testField1628 = new Integer(1628);
+ public Object testField1629 = new Integer(1629);
+ public Object testField1630 = new Integer(1630);
+ public Object testField1631 = new Integer(1631);
+ public Object testField1632 = new Integer(1632);
+ public Object testField1633 = new Integer(1633);
+ public Object testField1634 = new Integer(1634);
+ public Object testField1635 = new Integer(1635);
+ public Object testField1636 = new Integer(1636);
+ public Object testField1637 = new Integer(1637);
+ public Object testField1638 = new Integer(1638);
+ public Object testField1639 = new Integer(1639);
+ public Object testField1640 = new Integer(1640);
+ public Object testField1641 = new Integer(1641);
+ public Object testField1642 = new Integer(1642);
+ public Object testField1643 = new Integer(1643);
+ public Object testField1644 = new Integer(1644);
+ public Object testField1645 = new Integer(1645);
+ public Object testField1646 = new Integer(1646);
+ public Object testField1647 = new Integer(1647);
+ public Object testField1648 = new Integer(1648);
+ public Object testField1649 = new Integer(1649);
+ public Object testField1650 = new Integer(1650);
+ public Object testField1651 = new Integer(1651);
+ public Object testField1652 = new Integer(1652);
+ public Object testField1653 = new Integer(1653);
+ public Object testField1654 = new Integer(1654);
+ public Object testField1655 = new Integer(1655);
+ public Object testField1656 = new Integer(1656);
+ public Object testField1657 = new Integer(1657);
+ public Object testField1658 = new Integer(1658);
+ public Object testField1659 = new Integer(1659);
+ public Object testField1660 = new Integer(1660);
+ public Object testField1661 = new Integer(1661);
+ public Object testField1662 = new Integer(1662);
+ public Object testField1663 = new Integer(1663);
+ public Object testField1664 = new Integer(1664);
+ public Object testField1665 = new Integer(1665);
+ public Object testField1666 = new Integer(1666);
+ public Object testField1667 = new Integer(1667);
+ public Object testField1668 = new Integer(1668);
+ public Object testField1669 = new Integer(1669);
+ public Object testField1670 = new Integer(1670);
+ public Object testField1671 = new Integer(1671);
+ public Object testField1672 = new Integer(1672);
+ public Object testField1673 = new Integer(1673);
+ public Object testField1674 = new Integer(1674);
+ public Object testField1675 = new Integer(1675);
+ public Object testField1676 = new Integer(1676);
+ public Object testField1677 = new Integer(1677);
+ public Object testField1678 = new Integer(1678);
+ public Object testField1679 = new Integer(1679);
+ public Object testField1680 = new Integer(1680);
+ public Object testField1681 = new Integer(1681);
+ public Object testField1682 = new Integer(1682);
+ public Object testField1683 = new Integer(1683);
+ public Object testField1684 = new Integer(1684);
+ public Object testField1685 = new Integer(1685);
+ public Object testField1686 = new Integer(1686);
+ public Object testField1687 = new Integer(1687);
+ public Object testField1688 = new Integer(1688);
+ public Object testField1689 = new Integer(1689);
+ public Object testField1690 = new Integer(1690);
+ public Object testField1691 = new Integer(1691);
+ public Object testField1692 = new Integer(1692);
+ public Object testField1693 = new Integer(1693);
+ public Object testField1694 = new Integer(1694);
+ public Object testField1695 = new Integer(1695);
+ public Object testField1696 = new Integer(1696);
+ public Object testField1697 = new Integer(1697);
+ public Object testField1698 = new Integer(1698);
+ public Object testField1699 = new Integer(1699);
+ public Object testField1700 = new Integer(1700);
+ public Object testField1701 = new Integer(1701);
+ public Object testField1702 = new Integer(1702);
+ public Object testField1703 = new Integer(1703);
+ public Object testField1704 = new Integer(1704);
+ public Object testField1705 = new Integer(1705);
+ public Object testField1706 = new Integer(1706);
+ public Object testField1707 = new Integer(1707);
+ public Object testField1708 = new Integer(1708);
+ public Object testField1709 = new Integer(1709);
+ public Object testField1710 = new Integer(1710);
+ public Object testField1711 = new Integer(1711);
+ public Object testField1712 = new Integer(1712);
+ public Object testField1713 = new Integer(1713);
+ public Object testField1714 = new Integer(1714);
+ public Object testField1715 = new Integer(1715);
+ public Object testField1716 = new Integer(1716);
+ public Object testField1717 = new Integer(1717);
+ public Object testField1718 = new Integer(1718);
+ public Object testField1719 = new Integer(1719);
+ public Object testField1720 = new Integer(1720);
+ public Object testField1721 = new Integer(1721);
+ public Object testField1722 = new Integer(1722);
+ public Object testField1723 = new Integer(1723);
+ public Object testField1724 = new Integer(1724);
+ public Object testField1725 = new Integer(1725);
+ public Object testField1726 = new Integer(1726);
+ public Object testField1727 = new Integer(1727);
+ public Object testField1728 = new Integer(1728);
+ public Object testField1729 = new Integer(1729);
+ public Object testField1730 = new Integer(1730);
+ public Object testField1731 = new Integer(1731);
+ public Object testField1732 = new Integer(1732);
+ public Object testField1733 = new Integer(1733);
+ public Object testField1734 = new Integer(1734);
+ public Object testField1735 = new Integer(1735);
+ public Object testField1736 = new Integer(1736);
+ public Object testField1737 = new Integer(1737);
+ public Object testField1738 = new Integer(1738);
+ public Object testField1739 = new Integer(1739);
+ public Object testField1740 = new Integer(1740);
+ public Object testField1741 = new Integer(1741);
+ public Object testField1742 = new Integer(1742);
+ public Object testField1743 = new Integer(1743);
+ public Object testField1744 = new Integer(1744);
+ public Object testField1745 = new Integer(1745);
+ public Object testField1746 = new Integer(1746);
+ public Object testField1747 = new Integer(1747);
+ public Object testField1748 = new Integer(1748);
+ public Object testField1749 = new Integer(1749);
+ public Object testField1750 = new Integer(1750);
+ public Object testField1751 = new Integer(1751);
+ public Object testField1752 = new Integer(1752);
+ public Object testField1753 = new Integer(1753);
+ public Object testField1754 = new Integer(1754);
+ public Object testField1755 = new Integer(1755);
+ public Object testField1756 = new Integer(1756);
+ public Object testField1757 = new Integer(1757);
+ public Object testField1758 = new Integer(1758);
+ public Object testField1759 = new Integer(1759);
+ public Object testField1760 = new Integer(1760);
+ public Object testField1761 = new Integer(1761);
+ public Object testField1762 = new Integer(1762);
+ public Object testField1763 = new Integer(1763);
+ public Object testField1764 = new Integer(1764);
+ public Object testField1765 = new Integer(1765);
+ public Object testField1766 = new Integer(1766);
+ public Object testField1767 = new Integer(1767);
+ public Object testField1768 = new Integer(1768);
+ public Object testField1769 = new Integer(1769);
+ public Object testField1770 = new Integer(1770);
+ public Object testField1771 = new Integer(1771);
+ public Object testField1772 = new Integer(1772);
+ public Object testField1773 = new Integer(1773);
+ public Object testField1774 = new Integer(1774);
+ public Object testField1775 = new Integer(1775);
+ public Object testField1776 = new Integer(1776);
+ public Object testField1777 = new Integer(1777);
+ public Object testField1778 = new Integer(1778);
+ public Object testField1779 = new Integer(1779);
+ public Object testField1780 = new Integer(1780);
+ public Object testField1781 = new Integer(1781);
+ public Object testField1782 = new Integer(1782);
+ public Object testField1783 = new Integer(1783);
+ public Object testField1784 = new Integer(1784);
+ public Object testField1785 = new Integer(1785);
+ public Object testField1786 = new Integer(1786);
+ public Object testField1787 = new Integer(1787);
+ public Object testField1788 = new Integer(1788);
+ public Object testField1789 = new Integer(1789);
+ public Object testField1790 = new Integer(1790);
+ public Object testField1791 = new Integer(1791);
+ public Object testField1792 = new Integer(1792);
+ public Object testField1793 = new Integer(1793);
+ public Object testField1794 = new Integer(1794);
+ public Object testField1795 = new Integer(1795);
+ public Object testField1796 = new Integer(1796);
+ public Object testField1797 = new Integer(1797);
+ public Object testField1798 = new Integer(1798);
+ public Object testField1799 = new Integer(1799);
+ public Object testField1800 = new Integer(1800);
+ public Object testField1801 = new Integer(1801);
+ public Object testField1802 = new Integer(1802);
+ public Object testField1803 = new Integer(1803);
+ public Object testField1804 = new Integer(1804);
+ public Object testField1805 = new Integer(1805);
+ public Object testField1806 = new Integer(1806);
+ public Object testField1807 = new Integer(1807);
+ public Object testField1808 = new Integer(1808);
+ public Object testField1809 = new Integer(1809);
+ public Object testField1810 = new Integer(1810);
+ public Object testField1811 = new Integer(1811);
+ public Object testField1812 = new Integer(1812);
+ public Object testField1813 = new Integer(1813);
+ public Object testField1814 = new Integer(1814);
+ public Object testField1815 = new Integer(1815);
+ public Object testField1816 = new Integer(1816);
+ public Object testField1817 = new Integer(1817);
+ public Object testField1818 = new Integer(1818);
+ public Object testField1819 = new Integer(1819);
+ public Object testField1820 = new Integer(1820);
+ public Object testField1821 = new Integer(1821);
+ public Object testField1822 = new Integer(1822);
+ public Object testField1823 = new Integer(1823);
+ public Object testField1824 = new Integer(1824);
+ public Object testField1825 = new Integer(1825);
+ public Object testField1826 = new Integer(1826);
+ public Object testField1827 = new Integer(1827);
+ public Object testField1828 = new Integer(1828);
+ public Object testField1829 = new Integer(1829);
+ public Object testField1830 = new Integer(1830);
+ public Object testField1831 = new Integer(1831);
+ public Object testField1832 = new Integer(1832);
+ public Object testField1833 = new Integer(1833);
+ public Object testField1834 = new Integer(1834);
+ public Object testField1835 = new Integer(1835);
+ public Object testField1836 = new Integer(1836);
+ public Object testField1837 = new Integer(1837);
+ public Object testField1838 = new Integer(1838);
+ public Object testField1839 = new Integer(1839);
+ public Object testField1840 = new Integer(1840);
+ public Object testField1841 = new Integer(1841);
+ public Object testField1842 = new Integer(1842);
+ public Object testField1843 = new Integer(1843);
+ public Object testField1844 = new Integer(1844);
+ public Object testField1845 = new Integer(1845);
+ public Object testField1846 = new Integer(1846);
+ public Object testField1847 = new Integer(1847);
+ public Object testField1848 = new Integer(1848);
+ public Object testField1849 = new Integer(1849);
+ public Object testField1850 = new Integer(1850);
+ public Object testField1851 = new Integer(1851);
+ public Object testField1852 = new Integer(1852);
+ public Object testField1853 = new Integer(1853);
+ public Object testField1854 = new Integer(1854);
+ public Object testField1855 = new Integer(1855);
+ public Object testField1856 = new Integer(1856);
+ public Object testField1857 = new Integer(1857);
+ public Object testField1858 = new Integer(1858);
+ public Object testField1859 = new Integer(1859);
+ public Object testField1860 = new Integer(1860);
+ public Object testField1861 = new Integer(1861);
+ public Object testField1862 = new Integer(1862);
+ public Object testField1863 = new Integer(1863);
+ public Object testField1864 = new Integer(1864);
+ public Object testField1865 = new Integer(1865);
+ public Object testField1866 = new Integer(1866);
+ public Object testField1867 = new Integer(1867);
+ public Object testField1868 = new Integer(1868);
+ public Object testField1869 = new Integer(1869);
+ public Object testField1870 = new Integer(1870);
+ public Object testField1871 = new Integer(1871);
+ public Object testField1872 = new Integer(1872);
+ public Object testField1873 = new Integer(1873);
+ public Object testField1874 = new Integer(1874);
+ public Object testField1875 = new Integer(1875);
+ public Object testField1876 = new Integer(1876);
+ public Object testField1877 = new Integer(1877);
+ public Object testField1878 = new Integer(1878);
+ public Object testField1879 = new Integer(1879);
+ public Object testField1880 = new Integer(1880);
+ public Object testField1881 = new Integer(1881);
+ public Object testField1882 = new Integer(1882);
+ public Object testField1883 = new Integer(1883);
+ public Object testField1884 = new Integer(1884);
+ public Object testField1885 = new Integer(1885);
+ public Object testField1886 = new Integer(1886);
+ public Object testField1887 = new Integer(1887);
+ public Object testField1888 = new Integer(1888);
+ public Object testField1889 = new Integer(1889);
+ public Object testField1890 = new Integer(1890);
+ public Object testField1891 = new Integer(1891);
+ public Object testField1892 = new Integer(1892);
+ public Object testField1893 = new Integer(1893);
+ public Object testField1894 = new Integer(1894);
+ public Object testField1895 = new Integer(1895);
+ public Object testField1896 = new Integer(1896);
+ public Object testField1897 = new Integer(1897);
+ public Object testField1898 = new Integer(1898);
+ public Object testField1899 = new Integer(1899);
+ public Object testField1900 = new Integer(1900);
+ public Object testField1901 = new Integer(1901);
+ public Object testField1902 = new Integer(1902);
+ public Object testField1903 = new Integer(1903);
+ public Object testField1904 = new Integer(1904);
+ public Object testField1905 = new Integer(1905);
+ public Object testField1906 = new Integer(1906);
+ public Object testField1907 = new Integer(1907);
+ public Object testField1908 = new Integer(1908);
+ public Object testField1909 = new Integer(1909);
+ public Object testField1910 = new Integer(1910);
+ public Object testField1911 = new Integer(1911);
+ public Object testField1912 = new Integer(1912);
+ public Object testField1913 = new Integer(1913);
+ public Object testField1914 = new Integer(1914);
+ public Object testField1915 = new Integer(1915);
+ public Object testField1916 = new Integer(1916);
+ public Object testField1917 = new Integer(1917);
+ public Object testField1918 = new Integer(1918);
+ public Object testField1919 = new Integer(1919);
+ public Object testField1920 = new Integer(1920);
+ public Object testField1921 = new Integer(1921);
+ public Object testField1922 = new Integer(1922);
+ public Object testField1923 = new Integer(1923);
+ public Object testField1924 = new Integer(1924);
+ public Object testField1925 = new Integer(1925);
+ public Object testField1926 = new Integer(1926);
+ public Object testField1927 = new Integer(1927);
+ public Object testField1928 = new Integer(1928);
+ public Object testField1929 = new Integer(1929);
+ public Object testField1930 = new Integer(1930);
+ public Object testField1931 = new Integer(1931);
+ public Object testField1932 = new Integer(1932);
+ public Object testField1933 = new Integer(1933);
+ public Object testField1934 = new Integer(1934);
+ public Object testField1935 = new Integer(1935);
+ public Object testField1936 = new Integer(1936);
+ public Object testField1937 = new Integer(1937);
+ public Object testField1938 = new Integer(1938);
+ public Object testField1939 = new Integer(1939);
+ public Object testField1940 = new Integer(1940);
+ public Object testField1941 = new Integer(1941);
+ public Object testField1942 = new Integer(1942);
+ public Object testField1943 = new Integer(1943);
+ public Object testField1944 = new Integer(1944);
+ public Object testField1945 = new Integer(1945);
+ public Object testField1946 = new Integer(1946);
+ public Object testField1947 = new Integer(1947);
+ public Object testField1948 = new Integer(1948);
+ public Object testField1949 = new Integer(1949);
+ public Object testField1950 = new Integer(1950);
+ public Object testField1951 = new Integer(1951);
+ public Object testField1952 = new Integer(1952);
+ public Object testField1953 = new Integer(1953);
+ public Object testField1954 = new Integer(1954);
+ public Object testField1955 = new Integer(1955);
+ public Object testField1956 = new Integer(1956);
+ public Object testField1957 = new Integer(1957);
+ public Object testField1958 = new Integer(1958);
+ public Object testField1959 = new Integer(1959);
+ public Object testField1960 = new Integer(1960);
+ public Object testField1961 = new Integer(1961);
+ public Object testField1962 = new Integer(1962);
+ public Object testField1963 = new Integer(1963);
+ public Object testField1964 = new Integer(1964);
+ public Object testField1965 = new Integer(1965);
+ public Object testField1966 = new Integer(1966);
+ public Object testField1967 = new Integer(1967);
+ public Object testField1968 = new Integer(1968);
+ public Object testField1969 = new Integer(1969);
+ public Object testField1970 = new Integer(1970);
+ public Object testField1971 = new Integer(1971);
+ public Object testField1972 = new Integer(1972);
+ public Object testField1973 = new Integer(1973);
+ public Object testField1974 = new Integer(1974);
+ public Object testField1975 = new Integer(1975);
+ public Object testField1976 = new Integer(1976);
+ public Object testField1977 = new Integer(1977);
+ public Object testField1978 = new Integer(1978);
+ public Object testField1979 = new Integer(1979);
+ public Object testField1980 = new Integer(1980);
+ public Object testField1981 = new Integer(1981);
+ public Object testField1982 = new Integer(1982);
+ public Object testField1983 = new Integer(1983);
+ public Object testField1984 = new Integer(1984);
+ public Object testField1985 = new Integer(1985);
+ public Object testField1986 = new Integer(1986);
+ public Object testField1987 = new Integer(1987);
+ public Object testField1988 = new Integer(1988);
+ public Object testField1989 = new Integer(1989);
+ public Object testField1990 = new Integer(1990);
+ public Object testField1991 = new Integer(1991);
+ public Object testField1992 = new Integer(1992);
+ public Object testField1993 = new Integer(1993);
+ public Object testField1994 = new Integer(1994);
+ public Object testField1995 = new Integer(1995);
+ public Object testField1996 = new Integer(1996);
+ public Object testField1997 = new Integer(1997);
+ public Object testField1998 = new Integer(1998);
+ public Object testField1999 = new Integer(1999);
+}
diff --git a/test/160-read-barrier-stress/src/ManyFieldsBase2.java b/test/160-read-barrier-stress/src/ManyFieldsBase2.java
new file mode 100644
index 0000000000..54bbe99f73
--- /dev/null
+++ b/test/160-read-barrier-stress/src/ManyFieldsBase2.java
@@ -0,0 +1,1018 @@
+/*
+ * 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.
+ */
+
+class ManyFieldsBase2 extends ManyFieldsBase1 {
+ public Object testField2000 = new Integer(2000);
+ public Object testField2001 = new Integer(2001);
+ public Object testField2002 = new Integer(2002);
+ public Object testField2003 = new Integer(2003);
+ public Object testField2004 = new Integer(2004);
+ public Object testField2005 = new Integer(2005);
+ public Object testField2006 = new Integer(2006);
+ public Object testField2007 = new Integer(2007);
+ public Object testField2008 = new Integer(2008);
+ public Object testField2009 = new Integer(2009);
+ public Object testField2010 = new Integer(2010);
+ public Object testField2011 = new Integer(2011);
+ public Object testField2012 = new Integer(2012);
+ public Object testField2013 = new Integer(2013);
+ public Object testField2014 = new Integer(2014);
+ public Object testField2015 = new Integer(2015);
+ public Object testField2016 = new Integer(2016);
+ public Object testField2017 = new Integer(2017);
+ public Object testField2018 = new Integer(2018);
+ public Object testField2019 = new Integer(2019);
+ public Object testField2020 = new Integer(2020);
+ public Object testField2021 = new Integer(2021);
+ public Object testField2022 = new Integer(2022);
+ public Object testField2023 = new Integer(2023);
+ public Object testField2024 = new Integer(2024);
+ public Object testField2025 = new Integer(2025);
+ public Object testField2026 = new Integer(2026);
+ public Object testField2027 = new Integer(2027);
+ public Object testField2028 = new Integer(2028);
+ public Object testField2029 = new Integer(2029);
+ public Object testField2030 = new Integer(2030);
+ public Object testField2031 = new Integer(2031);
+ public Object testField2032 = new Integer(2032);
+ public Object testField2033 = new Integer(2033);
+ public Object testField2034 = new Integer(2034);
+ public Object testField2035 = new Integer(2035);
+ public Object testField2036 = new Integer(2036);
+ public Object testField2037 = new Integer(2037);
+ public Object testField2038 = new Integer(2038);
+ public Object testField2039 = new Integer(2039);
+ public Object testField2040 = new Integer(2040);
+ public Object testField2041 = new Integer(2041);
+ public Object testField2042 = new Integer(2042);
+ public Object testField2043 = new Integer(2043);
+ public Object testField2044 = new Integer(2044);
+ public Object testField2045 = new Integer(2045);
+ public Object testField2046 = new Integer(2046);
+ public Object testField2047 = new Integer(2047);
+ public Object testField2048 = new Integer(2048);
+ public Object testField2049 = new Integer(2049);
+ public Object testField2050 = new Integer(2050);
+ public Object testField2051 = new Integer(2051);
+ public Object testField2052 = new Integer(2052);
+ public Object testField2053 = new Integer(2053);
+ public Object testField2054 = new Integer(2054);
+ public Object testField2055 = new Integer(2055);
+ public Object testField2056 = new Integer(2056);
+ public Object testField2057 = new Integer(2057);
+ public Object testField2058 = new Integer(2058);
+ public Object testField2059 = new Integer(2059);
+ public Object testField2060 = new Integer(2060);
+ public Object testField2061 = new Integer(2061);
+ public Object testField2062 = new Integer(2062);
+ public Object testField2063 = new Integer(2063);
+ public Object testField2064 = new Integer(2064);
+ public Object testField2065 = new Integer(2065);
+ public Object testField2066 = new Integer(2066);
+ public Object testField2067 = new Integer(2067);
+ public Object testField2068 = new Integer(2068);
+ public Object testField2069 = new Integer(2069);
+ public Object testField2070 = new Integer(2070);
+ public Object testField2071 = new Integer(2071);
+ public Object testField2072 = new Integer(2072);
+ public Object testField2073 = new Integer(2073);
+ public Object testField2074 = new Integer(2074);
+ public Object testField2075 = new Integer(2075);
+ public Object testField2076 = new Integer(2076);
+ public Object testField2077 = new Integer(2077);
+ public Object testField2078 = new Integer(2078);
+ public Object testField2079 = new Integer(2079);
+ public Object testField2080 = new Integer(2080);
+ public Object testField2081 = new Integer(2081);
+ public Object testField2082 = new Integer(2082);
+ public Object testField2083 = new Integer(2083);
+ public Object testField2084 = new Integer(2084);
+ public Object testField2085 = new Integer(2085);
+ public Object testField2086 = new Integer(2086);
+ public Object testField2087 = new Integer(2087);
+ public Object testField2088 = new Integer(2088);
+ public Object testField2089 = new Integer(2089);
+ public Object testField2090 = new Integer(2090);
+ public Object testField2091 = new Integer(2091);
+ public Object testField2092 = new Integer(2092);
+ public Object testField2093 = new Integer(2093);
+ public Object testField2094 = new Integer(2094);
+ public Object testField2095 = new Integer(2095);
+ public Object testField2096 = new Integer(2096);
+ public Object testField2097 = new Integer(2097);
+ public Object testField2098 = new Integer(2098);
+ public Object testField2099 = new Integer(2099);
+ public Object testField2100 = new Integer(2100);
+ public Object testField2101 = new Integer(2101);
+ public Object testField2102 = new Integer(2102);
+ public Object testField2103 = new Integer(2103);
+ public Object testField2104 = new Integer(2104);
+ public Object testField2105 = new Integer(2105);
+ public Object testField2106 = new Integer(2106);
+ public Object testField2107 = new Integer(2107);
+ public Object testField2108 = new Integer(2108);
+ public Object testField2109 = new Integer(2109);
+ public Object testField2110 = new Integer(2110);
+ public Object testField2111 = new Integer(2111);
+ public Object testField2112 = new Integer(2112);
+ public Object testField2113 = new Integer(2113);
+ public Object testField2114 = new Integer(2114);
+ public Object testField2115 = new Integer(2115);
+ public Object testField2116 = new Integer(2116);
+ public Object testField2117 = new Integer(2117);
+ public Object testField2118 = new Integer(2118);
+ public Object testField2119 = new Integer(2119);
+ public Object testField2120 = new Integer(2120);
+ public Object testField2121 = new Integer(2121);
+ public Object testField2122 = new Integer(2122);
+ public Object testField2123 = new Integer(2123);
+ public Object testField2124 = new Integer(2124);
+ public Object testField2125 = new Integer(2125);
+ public Object testField2126 = new Integer(2126);
+ public Object testField2127 = new Integer(2127);
+ public Object testField2128 = new Integer(2128);
+ public Object testField2129 = new Integer(2129);
+ public Object testField2130 = new Integer(2130);
+ public Object testField2131 = new Integer(2131);
+ public Object testField2132 = new Integer(2132);
+ public Object testField2133 = new Integer(2133);
+ public Object testField2134 = new Integer(2134);
+ public Object testField2135 = new Integer(2135);
+ public Object testField2136 = new Integer(2136);
+ public Object testField2137 = new Integer(2137);
+ public Object testField2138 = new Integer(2138);
+ public Object testField2139 = new Integer(2139);
+ public Object testField2140 = new Integer(2140);
+ public Object testField2141 = new Integer(2141);
+ public Object testField2142 = new Integer(2142);
+ public Object testField2143 = new Integer(2143);
+ public Object testField2144 = new Integer(2144);
+ public Object testField2145 = new Integer(2145);
+ public Object testField2146 = new Integer(2146);
+ public Object testField2147 = new Integer(2147);
+ public Object testField2148 = new Integer(2148);
+ public Object testField2149 = new Integer(2149);
+ public Object testField2150 = new Integer(2150);
+ public Object testField2151 = new Integer(2151);
+ public Object testField2152 = new Integer(2152);
+ public Object testField2153 = new Integer(2153);
+ public Object testField2154 = new Integer(2154);
+ public Object testField2155 = new Integer(2155);
+ public Object testField2156 = new Integer(2156);
+ public Object testField2157 = new Integer(2157);
+ public Object testField2158 = new Integer(2158);
+ public Object testField2159 = new Integer(2159);
+ public Object testField2160 = new Integer(2160);
+ public Object testField2161 = new Integer(2161);
+ public Object testField2162 = new Integer(2162);
+ public Object testField2163 = new Integer(2163);
+ public Object testField2164 = new Integer(2164);
+ public Object testField2165 = new Integer(2165);
+ public Object testField2166 = new Integer(2166);
+ public Object testField2167 = new Integer(2167);
+ public Object testField2168 = new Integer(2168);
+ public Object testField2169 = new Integer(2169);
+ public Object testField2170 = new Integer(2170);
+ public Object testField2171 = new Integer(2171);
+ public Object testField2172 = new Integer(2172);
+ public Object testField2173 = new Integer(2173);
+ public Object testField2174 = new Integer(2174);
+ public Object testField2175 = new Integer(2175);
+ public Object testField2176 = new Integer(2176);
+ public Object testField2177 = new Integer(2177);
+ public Object testField2178 = new Integer(2178);
+ public Object testField2179 = new Integer(2179);
+ public Object testField2180 = new Integer(2180);
+ public Object testField2181 = new Integer(2181);
+ public Object testField2182 = new Integer(2182);
+ public Object testField2183 = new Integer(2183);
+ public Object testField2184 = new Integer(2184);
+ public Object testField2185 = new Integer(2185);
+ public Object testField2186 = new Integer(2186);
+ public Object testField2187 = new Integer(2187);
+ public Object testField2188 = new Integer(2188);
+ public Object testField2189 = new Integer(2189);
+ public Object testField2190 = new Integer(2190);
+ public Object testField2191 = new Integer(2191);
+ public Object testField2192 = new Integer(2192);
+ public Object testField2193 = new Integer(2193);
+ public Object testField2194 = new Integer(2194);
+ public Object testField2195 = new Integer(2195);
+ public Object testField2196 = new Integer(2196);
+ public Object testField2197 = new Integer(2197);
+ public Object testField2198 = new Integer(2198);
+ public Object testField2199 = new Integer(2199);
+ public Object testField2200 = new Integer(2200);
+ public Object testField2201 = new Integer(2201);
+ public Object testField2202 = new Integer(2202);
+ public Object testField2203 = new Integer(2203);
+ public Object testField2204 = new Integer(2204);
+ public Object testField2205 = new Integer(2205);
+ public Object testField2206 = new Integer(2206);
+ public Object testField2207 = new Integer(2207);
+ public Object testField2208 = new Integer(2208);
+ public Object testField2209 = new Integer(2209);
+ public Object testField2210 = new Integer(2210);
+ public Object testField2211 = new Integer(2211);
+ public Object testField2212 = new Integer(2212);
+ public Object testField2213 = new Integer(2213);
+ public Object testField2214 = new Integer(2214);
+ public Object testField2215 = new Integer(2215);
+ public Object testField2216 = new Integer(2216);
+ public Object testField2217 = new Integer(2217);
+ public Object testField2218 = new Integer(2218);
+ public Object testField2219 = new Integer(2219);
+ public Object testField2220 = new Integer(2220);
+ public Object testField2221 = new Integer(2221);
+ public Object testField2222 = new Integer(2222);
+ public Object testField2223 = new Integer(2223);
+ public Object testField2224 = new Integer(2224);
+ public Object testField2225 = new Integer(2225);
+ public Object testField2226 = new Integer(2226);
+ public Object testField2227 = new Integer(2227);
+ public Object testField2228 = new Integer(2228);
+ public Object testField2229 = new Integer(2229);
+ public Object testField2230 = new Integer(2230);
+ public Object testField2231 = new Integer(2231);
+ public Object testField2232 = new Integer(2232);
+ public Object testField2233 = new Integer(2233);
+ public Object testField2234 = new Integer(2234);
+ public Object testField2235 = new Integer(2235);
+ public Object testField2236 = new Integer(2236);
+ public Object testField2237 = new Integer(2237);
+ public Object testField2238 = new Integer(2238);
+ public Object testField2239 = new Integer(2239);
+ public Object testField2240 = new Integer(2240);
+ public Object testField2241 = new Integer(2241);
+ public Object testField2242 = new Integer(2242);
+ public Object testField2243 = new Integer(2243);
+ public Object testField2244 = new Integer(2244);
+ public Object testField2245 = new Integer(2245);
+ public Object testField2246 = new Integer(2246);
+ public Object testField2247 = new Integer(2247);
+ public Object testField2248 = new Integer(2248);
+ public Object testField2249 = new Integer(2249);
+ public Object testField2250 = new Integer(2250);
+ public Object testField2251 = new Integer(2251);
+ public Object testField2252 = new Integer(2252);
+ public Object testField2253 = new Integer(2253);
+ public Object testField2254 = new Integer(2254);
+ public Object testField2255 = new Integer(2255);
+ public Object testField2256 = new Integer(2256);
+ public Object testField2257 = new Integer(2257);
+ public Object testField2258 = new Integer(2258);
+ public Object testField2259 = new Integer(2259);
+ public Object testField2260 = new Integer(2260);
+ public Object testField2261 = new Integer(2261);
+ public Object testField2262 = new Integer(2262);
+ public Object testField2263 = new Integer(2263);
+ public Object testField2264 = new Integer(2264);
+ public Object testField2265 = new Integer(2265);
+ public Object testField2266 = new Integer(2266);
+ public Object testField2267 = new Integer(2267);
+ public Object testField2268 = new Integer(2268);
+ public Object testField2269 = new Integer(2269);
+ public Object testField2270 = new Integer(2270);
+ public Object testField2271 = new Integer(2271);
+ public Object testField2272 = new Integer(2272);
+ public Object testField2273 = new Integer(2273);
+ public Object testField2274 = new Integer(2274);
+ public Object testField2275 = new Integer(2275);
+ public Object testField2276 = new Integer(2276);
+ public Object testField2277 = new Integer(2277);
+ public Object testField2278 = new Integer(2278);
+ public Object testField2279 = new Integer(2279);
+ public Object testField2280 = new Integer(2280);
+ public Object testField2281 = new Integer(2281);
+ public Object testField2282 = new Integer(2282);
+ public Object testField2283 = new Integer(2283);
+ public Object testField2284 = new Integer(2284);
+ public Object testField2285 = new Integer(2285);
+ public Object testField2286 = new Integer(2286);
+ public Object testField2287 = new Integer(2287);
+ public Object testField2288 = new Integer(2288);
+ public Object testField2289 = new Integer(2289);
+ public Object testField2290 = new Integer(2290);
+ public Object testField2291 = new Integer(2291);
+ public Object testField2292 = new Integer(2292);
+ public Object testField2293 = new Integer(2293);
+ public Object testField2294 = new Integer(2294);
+ public Object testField2295 = new Integer(2295);
+ public Object testField2296 = new Integer(2296);
+ public Object testField2297 = new Integer(2297);
+ public Object testField2298 = new Integer(2298);
+ public Object testField2299 = new Integer(2299);
+ public Object testField2300 = new Integer(2300);
+ public Object testField2301 = new Integer(2301);
+ public Object testField2302 = new Integer(2302);
+ public Object testField2303 = new Integer(2303);
+ public Object testField2304 = new Integer(2304);
+ public Object testField2305 = new Integer(2305);
+ public Object testField2306 = new Integer(2306);
+ public Object testField2307 = new Integer(2307);
+ public Object testField2308 = new Integer(2308);
+ public Object testField2309 = new Integer(2309);
+ public Object testField2310 = new Integer(2310);
+ public Object testField2311 = new Integer(2311);
+ public Object testField2312 = new Integer(2312);
+ public Object testField2313 = new Integer(2313);
+ public Object testField2314 = new Integer(2314);
+ public Object testField2315 = new Integer(2315);
+ public Object testField2316 = new Integer(2316);
+ public Object testField2317 = new Integer(2317);
+ public Object testField2318 = new Integer(2318);
+ public Object testField2319 = new Integer(2319);
+ public Object testField2320 = new Integer(2320);
+ public Object testField2321 = new Integer(2321);
+ public Object testField2322 = new Integer(2322);
+ public Object testField2323 = new Integer(2323);
+ public Object testField2324 = new Integer(2324);
+ public Object testField2325 = new Integer(2325);
+ public Object testField2326 = new Integer(2326);
+ public Object testField2327 = new Integer(2327);
+ public Object testField2328 = new Integer(2328);
+ public Object testField2329 = new Integer(2329);
+ public Object testField2330 = new Integer(2330);
+ public Object testField2331 = new Integer(2331);
+ public Object testField2332 = new Integer(2332);
+ public Object testField2333 = new Integer(2333);
+ public Object testField2334 = new Integer(2334);
+ public Object testField2335 = new Integer(2335);
+ public Object testField2336 = new Integer(2336);
+ public Object testField2337 = new Integer(2337);
+ public Object testField2338 = new Integer(2338);
+ public Object testField2339 = new Integer(2339);
+ public Object testField2340 = new Integer(2340);
+ public Object testField2341 = new Integer(2341);
+ public Object testField2342 = new Integer(2342);
+ public Object testField2343 = new Integer(2343);
+ public Object testField2344 = new Integer(2344);
+ public Object testField2345 = new Integer(2345);
+ public Object testField2346 = new Integer(2346);
+ public Object testField2347 = new Integer(2347);
+ public Object testField2348 = new Integer(2348);
+ public Object testField2349 = new Integer(2349);
+ public Object testField2350 = new Integer(2350);
+ public Object testField2351 = new Integer(2351);
+ public Object testField2352 = new Integer(2352);
+ public Object testField2353 = new Integer(2353);
+ public Object testField2354 = new Integer(2354);
+ public Object testField2355 = new Integer(2355);
+ public Object testField2356 = new Integer(2356);
+ public Object testField2357 = new Integer(2357);
+ public Object testField2358 = new Integer(2358);
+ public Object testField2359 = new Integer(2359);
+ public Object testField2360 = new Integer(2360);
+ public Object testField2361 = new Integer(2361);
+ public Object testField2362 = new Integer(2362);
+ public Object testField2363 = new Integer(2363);
+ public Object testField2364 = new Integer(2364);
+ public Object testField2365 = new Integer(2365);
+ public Object testField2366 = new Integer(2366);
+ public Object testField2367 = new Integer(2367);
+ public Object testField2368 = new Integer(2368);
+ public Object testField2369 = new Integer(2369);
+ public Object testField2370 = new Integer(2370);
+ public Object testField2371 = new Integer(2371);
+ public Object testField2372 = new Integer(2372);
+ public Object testField2373 = new Integer(2373);
+ public Object testField2374 = new Integer(2374);
+ public Object testField2375 = new Integer(2375);
+ public Object testField2376 = new Integer(2376);
+ public Object testField2377 = new Integer(2377);
+ public Object testField2378 = new Integer(2378);
+ public Object testField2379 = new Integer(2379);
+ public Object testField2380 = new Integer(2380);
+ public Object testField2381 = new Integer(2381);
+ public Object testField2382 = new Integer(2382);
+ public Object testField2383 = new Integer(2383);
+ public Object testField2384 = new Integer(2384);
+ public Object testField2385 = new Integer(2385);
+ public Object testField2386 = new Integer(2386);
+ public Object testField2387 = new Integer(2387);
+ public Object testField2388 = new Integer(2388);
+ public Object testField2389 = new Integer(2389);
+ public Object testField2390 = new Integer(2390);
+ public Object testField2391 = new Integer(2391);
+ public Object testField2392 = new Integer(2392);
+ public Object testField2393 = new Integer(2393);
+ public Object testField2394 = new Integer(2394);
+ public Object testField2395 = new Integer(2395);
+ public Object testField2396 = new Integer(2396);
+ public Object testField2397 = new Integer(2397);
+ public Object testField2398 = new Integer(2398);
+ public Object testField2399 = new Integer(2399);
+ public Object testField2400 = new Integer(2400);
+ public Object testField2401 = new Integer(2401);
+ public Object testField2402 = new Integer(2402);
+ public Object testField2403 = new Integer(2403);
+ public Object testField2404 = new Integer(2404);
+ public Object testField2405 = new Integer(2405);
+ public Object testField2406 = new Integer(2406);
+ public Object testField2407 = new Integer(2407);
+ public Object testField2408 = new Integer(2408);
+ public Object testField2409 = new Integer(2409);
+ public Object testField2410 = new Integer(2410);
+ public Object testField2411 = new Integer(2411);
+ public Object testField2412 = new Integer(2412);
+ public Object testField2413 = new Integer(2413);
+ public Object testField2414 = new Integer(2414);
+ public Object testField2415 = new Integer(2415);
+ public Object testField2416 = new Integer(2416);
+ public Object testField2417 = new Integer(2417);
+ public Object testField2418 = new Integer(2418);
+ public Object testField2419 = new Integer(2419);
+ public Object testField2420 = new Integer(2420);
+ public Object testField2421 = new Integer(2421);
+ public Object testField2422 = new Integer(2422);
+ public Object testField2423 = new Integer(2423);
+ public Object testField2424 = new Integer(2424);
+ public Object testField2425 = new Integer(2425);
+ public Object testField2426 = new Integer(2426);
+ public Object testField2427 = new Integer(2427);
+ public Object testField2428 = new Integer(2428);
+ public Object testField2429 = new Integer(2429);
+ public Object testField2430 = new Integer(2430);
+ public Object testField2431 = new Integer(2431);
+ public Object testField2432 = new Integer(2432);
+ public Object testField2433 = new Integer(2433);
+ public Object testField2434 = new Integer(2434);
+ public Object testField2435 = new Integer(2435);
+ public Object testField2436 = new Integer(2436);
+ public Object testField2437 = new Integer(2437);
+ public Object testField2438 = new Integer(2438);
+ public Object testField2439 = new Integer(2439);
+ public Object testField2440 = new Integer(2440);
+ public Object testField2441 = new Integer(2441);
+ public Object testField2442 = new Integer(2442);
+ public Object testField2443 = new Integer(2443);
+ public Object testField2444 = new Integer(2444);
+ public Object testField2445 = new Integer(2445);
+ public Object testField2446 = new Integer(2446);
+ public Object testField2447 = new Integer(2447);
+ public Object testField2448 = new Integer(2448);
+ public Object testField2449 = new Integer(2449);
+ public Object testField2450 = new Integer(2450);
+ public Object testField2451 = new Integer(2451);
+ public Object testField2452 = new Integer(2452);
+ public Object testField2453 = new Integer(2453);
+ public Object testField2454 = new Integer(2454);
+ public Object testField2455 = new Integer(2455);
+ public Object testField2456 = new Integer(2456);
+ public Object testField2457 = new Integer(2457);
+ public Object testField2458 = new Integer(2458);
+ public Object testField2459 = new Integer(2459);
+ public Object testField2460 = new Integer(2460);
+ public Object testField2461 = new Integer(2461);
+ public Object testField2462 = new Integer(2462);
+ public Object testField2463 = new Integer(2463);
+ public Object testField2464 = new Integer(2464);
+ public Object testField2465 = new Integer(2465);
+ public Object testField2466 = new Integer(2466);
+ public Object testField2467 = new Integer(2467);
+ public Object testField2468 = new Integer(2468);
+ public Object testField2469 = new Integer(2469);
+ public Object testField2470 = new Integer(2470);
+ public Object testField2471 = new Integer(2471);
+ public Object testField2472 = new Integer(2472);
+ public Object testField2473 = new Integer(2473);
+ public Object testField2474 = new Integer(2474);
+ public Object testField2475 = new Integer(2475);
+ public Object testField2476 = new Integer(2476);
+ public Object testField2477 = new Integer(2477);
+ public Object testField2478 = new Integer(2478);
+ public Object testField2479 = new Integer(2479);
+ public Object testField2480 = new Integer(2480);
+ public Object testField2481 = new Integer(2481);
+ public Object testField2482 = new Integer(2482);
+ public Object testField2483 = new Integer(2483);
+ public Object testField2484 = new Integer(2484);
+ public Object testField2485 = new Integer(2485);
+ public Object testField2486 = new Integer(2486);
+ public Object testField2487 = new Integer(2487);
+ public Object testField2488 = new Integer(2488);
+ public Object testField2489 = new Integer(2489);
+ public Object testField2490 = new Integer(2490);
+ public Object testField2491 = new Integer(2491);
+ public Object testField2492 = new Integer(2492);
+ public Object testField2493 = new Integer(2493);
+ public Object testField2494 = new Integer(2494);
+ public Object testField2495 = new Integer(2495);
+ public Object testField2496 = new Integer(2496);
+ public Object testField2497 = new Integer(2497);
+ public Object testField2498 = new Integer(2498);
+ public Object testField2499 = new Integer(2499);
+ public Object testField2500 = new Integer(2500);
+ public Object testField2501 = new Integer(2501);
+ public Object testField2502 = new Integer(2502);
+ public Object testField2503 = new Integer(2503);
+ public Object testField2504 = new Integer(2504);
+ public Object testField2505 = new Integer(2505);
+ public Object testField2506 = new Integer(2506);
+ public Object testField2507 = new Integer(2507);
+ public Object testField2508 = new Integer(2508);
+ public Object testField2509 = new Integer(2509);
+ public Object testField2510 = new Integer(2510);
+ public Object testField2511 = new Integer(2511);
+ public Object testField2512 = new Integer(2512);
+ public Object testField2513 = new Integer(2513);
+ public Object testField2514 = new Integer(2514);
+ public Object testField2515 = new Integer(2515);
+ public Object testField2516 = new Integer(2516);
+ public Object testField2517 = new Integer(2517);
+ public Object testField2518 = new Integer(2518);
+ public Object testField2519 = new Integer(2519);
+ public Object testField2520 = new Integer(2520);
+ public Object testField2521 = new Integer(2521);
+ public Object testField2522 = new Integer(2522);
+ public Object testField2523 = new Integer(2523);
+ public Object testField2524 = new Integer(2524);
+ public Object testField2525 = new Integer(2525);
+ public Object testField2526 = new Integer(2526);
+ public Object testField2527 = new Integer(2527);
+ public Object testField2528 = new Integer(2528);
+ public Object testField2529 = new Integer(2529);
+ public Object testField2530 = new Integer(2530);
+ public Object testField2531 = new Integer(2531);
+ public Object testField2532 = new Integer(2532);
+ public Object testField2533 = new Integer(2533);
+ public Object testField2534 = new Integer(2534);
+ public Object testField2535 = new Integer(2535);
+ public Object testField2536 = new Integer(2536);
+ public Object testField2537 = new Integer(2537);
+ public Object testField2538 = new Integer(2538);
+ public Object testField2539 = new Integer(2539);
+ public Object testField2540 = new Integer(2540);
+ public Object testField2541 = new Integer(2541);
+ public Object testField2542 = new Integer(2542);
+ public Object testField2543 = new Integer(2543);
+ public Object testField2544 = new Integer(2544);
+ public Object testField2545 = new Integer(2545);
+ public Object testField2546 = new Integer(2546);
+ public Object testField2547 = new Integer(2547);
+ public Object testField2548 = new Integer(2548);
+ public Object testField2549 = new Integer(2549);
+ public Object testField2550 = new Integer(2550);
+ public Object testField2551 = new Integer(2551);
+ public Object testField2552 = new Integer(2552);
+ public Object testField2553 = new Integer(2553);
+ public Object testField2554 = new Integer(2554);
+ public Object testField2555 = new Integer(2555);
+ public Object testField2556 = new Integer(2556);
+ public Object testField2557 = new Integer(2557);
+ public Object testField2558 = new Integer(2558);
+ public Object testField2559 = new Integer(2559);
+ public Object testField2560 = new Integer(2560);
+ public Object testField2561 = new Integer(2561);
+ public Object testField2562 = new Integer(2562);
+ public Object testField2563 = new Integer(2563);
+ public Object testField2564 = new Integer(2564);
+ public Object testField2565 = new Integer(2565);
+ public Object testField2566 = new Integer(2566);
+ public Object testField2567 = new Integer(2567);
+ public Object testField2568 = new Integer(2568);
+ public Object testField2569 = new Integer(2569);
+ public Object testField2570 = new Integer(2570);
+ public Object testField2571 = new Integer(2571);
+ public Object testField2572 = new Integer(2572);
+ public Object testField2573 = new Integer(2573);
+ public Object testField2574 = new Integer(2574);
+ public Object testField2575 = new Integer(2575);
+ public Object testField2576 = new Integer(2576);
+ public Object testField2577 = new Integer(2577);
+ public Object testField2578 = new Integer(2578);
+ public Object testField2579 = new Integer(2579);
+ public Object testField2580 = new Integer(2580);
+ public Object testField2581 = new Integer(2581);
+ public Object testField2582 = new Integer(2582);
+ public Object testField2583 = new Integer(2583);
+ public Object testField2584 = new Integer(2584);
+ public Object testField2585 = new Integer(2585);
+ public Object testField2586 = new Integer(2586);
+ public Object testField2587 = new Integer(2587);
+ public Object testField2588 = new Integer(2588);
+ public Object testField2589 = new Integer(2589);
+ public Object testField2590 = new Integer(2590);
+ public Object testField2591 = new Integer(2591);
+ public Object testField2592 = new Integer(2592);
+ public Object testField2593 = new Integer(2593);
+ public Object testField2594 = new Integer(2594);
+ public Object testField2595 = new Integer(2595);
+ public Object testField2596 = new Integer(2596);
+ public Object testField2597 = new Integer(2597);
+ public Object testField2598 = new Integer(2598);
+ public Object testField2599 = new Integer(2599);
+ public Object testField2600 = new Integer(2600);
+ public Object testField2601 = new Integer(2601);
+ public Object testField2602 = new Integer(2602);
+ public Object testField2603 = new Integer(2603);
+ public Object testField2604 = new Integer(2604);
+ public Object testField2605 = new Integer(2605);
+ public Object testField2606 = new Integer(2606);
+ public Object testField2607 = new Integer(2607);
+ public Object testField2608 = new Integer(2608);
+ public Object testField2609 = new Integer(2609);
+ public Object testField2610 = new Integer(2610);
+ public Object testField2611 = new Integer(2611);
+ public Object testField2612 = new Integer(2612);
+ public Object testField2613 = new Integer(2613);
+ public Object testField2614 = new Integer(2614);
+ public Object testField2615 = new Integer(2615);
+ public Object testField2616 = new Integer(2616);
+ public Object testField2617 = new Integer(2617);
+ public Object testField2618 = new Integer(2618);
+ public Object testField2619 = new Integer(2619);
+ public Object testField2620 = new Integer(2620);
+ public Object testField2621 = new Integer(2621);
+ public Object testField2622 = new Integer(2622);
+ public Object testField2623 = new Integer(2623);
+ public Object testField2624 = new Integer(2624);
+ public Object testField2625 = new Integer(2625);
+ public Object testField2626 = new Integer(2626);
+ public Object testField2627 = new Integer(2627);
+ public Object testField2628 = new Integer(2628);
+ public Object testField2629 = new Integer(2629);
+ public Object testField2630 = new Integer(2630);
+ public Object testField2631 = new Integer(2631);
+ public Object testField2632 = new Integer(2632);
+ public Object testField2633 = new Integer(2633);
+ public Object testField2634 = new Integer(2634);
+ public Object testField2635 = new Integer(2635);
+ public Object testField2636 = new Integer(2636);
+ public Object testField2637 = new Integer(2637);
+ public Object testField2638 = new Integer(2638);
+ public Object testField2639 = new Integer(2639);
+ public Object testField2640 = new Integer(2640);
+ public Object testField2641 = new Integer(2641);
+ public Object testField2642 = new Integer(2642);
+ public Object testField2643 = new Integer(2643);
+ public Object testField2644 = new Integer(2644);
+ public Object testField2645 = new Integer(2645);
+ public Object testField2646 = new Integer(2646);
+ public Object testField2647 = new Integer(2647);
+ public Object testField2648 = new Integer(2648);
+ public Object testField2649 = new Integer(2649);
+ public Object testField2650 = new Integer(2650);
+ public Object testField2651 = new Integer(2651);
+ public Object testField2652 = new Integer(2652);
+ public Object testField2653 = new Integer(2653);
+ public Object testField2654 = new Integer(2654);
+ public Object testField2655 = new Integer(2655);
+ public Object testField2656 = new Integer(2656);
+ public Object testField2657 = new Integer(2657);
+ public Object testField2658 = new Integer(2658);
+ public Object testField2659 = new Integer(2659);
+ public Object testField2660 = new Integer(2660);
+ public Object testField2661 = new Integer(2661);
+ public Object testField2662 = new Integer(2662);
+ public Object testField2663 = new Integer(2663);
+ public Object testField2664 = new Integer(2664);
+ public Object testField2665 = new Integer(2665);
+ public Object testField2666 = new Integer(2666);
+ public Object testField2667 = new Integer(2667);
+ public Object testField2668 = new Integer(2668);
+ public Object testField2669 = new Integer(2669);
+ public Object testField2670 = new Integer(2670);
+ public Object testField2671 = new Integer(2671);
+ public Object testField2672 = new Integer(2672);
+ public Object testField2673 = new Integer(2673);
+ public Object testField2674 = new Integer(2674);
+ public Object testField2675 = new Integer(2675);
+ public Object testField2676 = new Integer(2676);
+ public Object testField2677 = new Integer(2677);
+ public Object testField2678 = new Integer(2678);
+ public Object testField2679 = new Integer(2679);
+ public Object testField2680 = new Integer(2680);
+ public Object testField2681 = new Integer(2681);
+ public Object testField2682 = new Integer(2682);
+ public Object testField2683 = new Integer(2683);
+ public Object testField2684 = new Integer(2684);
+ public Object testField2685 = new Integer(2685);
+ public Object testField2686 = new Integer(2686);
+ public Object testField2687 = new Integer(2687);
+ public Object testField2688 = new Integer(2688);
+ public Object testField2689 = new Integer(2689);
+ public Object testField2690 = new Integer(2690);
+ public Object testField2691 = new Integer(2691);
+ public Object testField2692 = new Integer(2692);
+ public Object testField2693 = new Integer(2693);
+ public Object testField2694 = new Integer(2694);
+ public Object testField2695 = new Integer(2695);
+ public Object testField2696 = new Integer(2696);
+ public Object testField2697 = new Integer(2697);
+ public Object testField2698 = new Integer(2698);
+ public Object testField2699 = new Integer(2699);
+ public Object testField2700 = new Integer(2700);
+ public Object testField2701 = new Integer(2701);
+ public Object testField2702 = new Integer(2702);
+ public Object testField2703 = new Integer(2703);
+ public Object testField2704 = new Integer(2704);
+ public Object testField2705 = new Integer(2705);
+ public Object testField2706 = new Integer(2706);
+ public Object testField2707 = new Integer(2707);
+ public Object testField2708 = new Integer(2708);
+ public Object testField2709 = new Integer(2709);
+ public Object testField2710 = new Integer(2710);
+ public Object testField2711 = new Integer(2711);
+ public Object testField2712 = new Integer(2712);
+ public Object testField2713 = new Integer(2713);
+ public Object testField2714 = new Integer(2714);
+ public Object testField2715 = new Integer(2715);
+ public Object testField2716 = new Integer(2716);
+ public Object testField2717 = new Integer(2717);
+ public Object testField2718 = new Integer(2718);
+ public Object testField2719 = new Integer(2719);
+ public Object testField2720 = new Integer(2720);
+ public Object testField2721 = new Integer(2721);
+ public Object testField2722 = new Integer(2722);
+ public Object testField2723 = new Integer(2723);
+ public Object testField2724 = new Integer(2724);
+ public Object testField2725 = new Integer(2725);
+ public Object testField2726 = new Integer(2726);
+ public Object testField2727 = new Integer(2727);
+ public Object testField2728 = new Integer(2728);
+ public Object testField2729 = new Integer(2729);
+ public Object testField2730 = new Integer(2730);
+ public Object testField2731 = new Integer(2731);
+ public Object testField2732 = new Integer(2732);
+ public Object testField2733 = new Integer(2733);
+ public Object testField2734 = new Integer(2734);
+ public Object testField2735 = new Integer(2735);
+ public Object testField2736 = new Integer(2736);
+ public Object testField2737 = new Integer(2737);
+ public Object testField2738 = new Integer(2738);
+ public Object testField2739 = new Integer(2739);
+ public Object testField2740 = new Integer(2740);
+ public Object testField2741 = new Integer(2741);
+ public Object testField2742 = new Integer(2742);
+ public Object testField2743 = new Integer(2743);
+ public Object testField2744 = new Integer(2744);
+ public Object testField2745 = new Integer(2745);
+ public Object testField2746 = new Integer(2746);
+ public Object testField2747 = new Integer(2747);
+ public Object testField2748 = new Integer(2748);
+ public Object testField2749 = new Integer(2749);
+ public Object testField2750 = new Integer(2750);
+ public Object testField2751 = new Integer(2751);
+ public Object testField2752 = new Integer(2752);
+ public Object testField2753 = new Integer(2753);
+ public Object testField2754 = new Integer(2754);
+ public Object testField2755 = new Integer(2755);
+ public Object testField2756 = new Integer(2756);
+ public Object testField2757 = new Integer(2757);
+ public Object testField2758 = new Integer(2758);
+ public Object testField2759 = new Integer(2759);
+ public Object testField2760 = new Integer(2760);
+ public Object testField2761 = new Integer(2761);
+ public Object testField2762 = new Integer(2762);
+ public Object testField2763 = new Integer(2763);
+ public Object testField2764 = new Integer(2764);
+ public Object testField2765 = new Integer(2765);
+ public Object testField2766 = new Integer(2766);
+ public Object testField2767 = new Integer(2767);
+ public Object testField2768 = new Integer(2768);
+ public Object testField2769 = new Integer(2769);
+ public Object testField2770 = new Integer(2770);
+ public Object testField2771 = new Integer(2771);
+ public Object testField2772 = new Integer(2772);
+ public Object testField2773 = new Integer(2773);
+ public Object testField2774 = new Integer(2774);
+ public Object testField2775 = new Integer(2775);
+ public Object testField2776 = new Integer(2776);
+ public Object testField2777 = new Integer(2777);
+ public Object testField2778 = new Integer(2778);
+ public Object testField2779 = new Integer(2779);
+ public Object testField2780 = new Integer(2780);
+ public Object testField2781 = new Integer(2781);
+ public Object testField2782 = new Integer(2782);
+ public Object testField2783 = new Integer(2783);
+ public Object testField2784 = new Integer(2784);
+ public Object testField2785 = new Integer(2785);
+ public Object testField2786 = new Integer(2786);
+ public Object testField2787 = new Integer(2787);
+ public Object testField2788 = new Integer(2788);
+ public Object testField2789 = new Integer(2789);
+ public Object testField2790 = new Integer(2790);
+ public Object testField2791 = new Integer(2791);
+ public Object testField2792 = new Integer(2792);
+ public Object testField2793 = new Integer(2793);
+ public Object testField2794 = new Integer(2794);
+ public Object testField2795 = new Integer(2795);
+ public Object testField2796 = new Integer(2796);
+ public Object testField2797 = new Integer(2797);
+ public Object testField2798 = new Integer(2798);
+ public Object testField2799 = new Integer(2799);
+ public Object testField2800 = new Integer(2800);
+ public Object testField2801 = new Integer(2801);
+ public Object testField2802 = new Integer(2802);
+ public Object testField2803 = new Integer(2803);
+ public Object testField2804 = new Integer(2804);
+ public Object testField2805 = new Integer(2805);
+ public Object testField2806 = new Integer(2806);
+ public Object testField2807 = new Integer(2807);
+ public Object testField2808 = new Integer(2808);
+ public Object testField2809 = new Integer(2809);
+ public Object testField2810 = new Integer(2810);
+ public Object testField2811 = new Integer(2811);
+ public Object testField2812 = new Integer(2812);
+ public Object testField2813 = new Integer(2813);
+ public Object testField2814 = new Integer(2814);
+ public Object testField2815 = new Integer(2815);
+ public Object testField2816 = new Integer(2816);
+ public Object testField2817 = new Integer(2817);
+ public Object testField2818 = new Integer(2818);
+ public Object testField2819 = new Integer(2819);
+ public Object testField2820 = new Integer(2820);
+ public Object testField2821 = new Integer(2821);
+ public Object testField2822 = new Integer(2822);
+ public Object testField2823 = new Integer(2823);
+ public Object testField2824 = new Integer(2824);
+ public Object testField2825 = new Integer(2825);
+ public Object testField2826 = new Integer(2826);
+ public Object testField2827 = new Integer(2827);
+ public Object testField2828 = new Integer(2828);
+ public Object testField2829 = new Integer(2829);
+ public Object testField2830 = new Integer(2830);
+ public Object testField2831 = new Integer(2831);
+ public Object testField2832 = new Integer(2832);
+ public Object testField2833 = new Integer(2833);
+ public Object testField2834 = new Integer(2834);
+ public Object testField2835 = new Integer(2835);
+ public Object testField2836 = new Integer(2836);
+ public Object testField2837 = new Integer(2837);
+ public Object testField2838 = new Integer(2838);
+ public Object testField2839 = new Integer(2839);
+ public Object testField2840 = new Integer(2840);
+ public Object testField2841 = new Integer(2841);
+ public Object testField2842 = new Integer(2842);
+ public Object testField2843 = new Integer(2843);
+ public Object testField2844 = new Integer(2844);
+ public Object testField2845 = new Integer(2845);
+ public Object testField2846 = new Integer(2846);
+ public Object testField2847 = new Integer(2847);
+ public Object testField2848 = new Integer(2848);
+ public Object testField2849 = new Integer(2849);
+ public Object testField2850 = new Integer(2850);
+ public Object testField2851 = new Integer(2851);
+ public Object testField2852 = new Integer(2852);
+ public Object testField2853 = new Integer(2853);
+ public Object testField2854 = new Integer(2854);
+ public Object testField2855 = new Integer(2855);
+ public Object testField2856 = new Integer(2856);
+ public Object testField2857 = new Integer(2857);
+ public Object testField2858 = new Integer(2858);
+ public Object testField2859 = new Integer(2859);
+ public Object testField2860 = new Integer(2860);
+ public Object testField2861 = new Integer(2861);
+ public Object testField2862 = new Integer(2862);
+ public Object testField2863 = new Integer(2863);
+ public Object testField2864 = new Integer(2864);
+ public Object testField2865 = new Integer(2865);
+ public Object testField2866 = new Integer(2866);
+ public Object testField2867 = new Integer(2867);
+ public Object testField2868 = new Integer(2868);
+ public Object testField2869 = new Integer(2869);
+ public Object testField2870 = new Integer(2870);
+ public Object testField2871 = new Integer(2871);
+ public Object testField2872 = new Integer(2872);
+ public Object testField2873 = new Integer(2873);
+ public Object testField2874 = new Integer(2874);
+ public Object testField2875 = new Integer(2875);
+ public Object testField2876 = new Integer(2876);
+ public Object testField2877 = new Integer(2877);
+ public Object testField2878 = new Integer(2878);
+ public Object testField2879 = new Integer(2879);
+ public Object testField2880 = new Integer(2880);
+ public Object testField2881 = new Integer(2881);
+ public Object testField2882 = new Integer(2882);
+ public Object testField2883 = new Integer(2883);
+ public Object testField2884 = new Integer(2884);
+ public Object testField2885 = new Integer(2885);
+ public Object testField2886 = new Integer(2886);
+ public Object testField2887 = new Integer(2887);
+ public Object testField2888 = new Integer(2888);
+ public Object testField2889 = new Integer(2889);
+ public Object testField2890 = new Integer(2890);
+ public Object testField2891 = new Integer(2891);
+ public Object testField2892 = new Integer(2892);
+ public Object testField2893 = new Integer(2893);
+ public Object testField2894 = new Integer(2894);
+ public Object testField2895 = new Integer(2895);
+ public Object testField2896 = new Integer(2896);
+ public Object testField2897 = new Integer(2897);
+ public Object testField2898 = new Integer(2898);
+ public Object testField2899 = new Integer(2899);
+ public Object testField2900 = new Integer(2900);
+ public Object testField2901 = new Integer(2901);
+ public Object testField2902 = new Integer(2902);
+ public Object testField2903 = new Integer(2903);
+ public Object testField2904 = new Integer(2904);
+ public Object testField2905 = new Integer(2905);
+ public Object testField2906 = new Integer(2906);
+ public Object testField2907 = new Integer(2907);
+ public Object testField2908 = new Integer(2908);
+ public Object testField2909 = new Integer(2909);
+ public Object testField2910 = new Integer(2910);
+ public Object testField2911 = new Integer(2911);
+ public Object testField2912 = new Integer(2912);
+ public Object testField2913 = new Integer(2913);
+ public Object testField2914 = new Integer(2914);
+ public Object testField2915 = new Integer(2915);
+ public Object testField2916 = new Integer(2916);
+ public Object testField2917 = new Integer(2917);
+ public Object testField2918 = new Integer(2918);
+ public Object testField2919 = new Integer(2919);
+ public Object testField2920 = new Integer(2920);
+ public Object testField2921 = new Integer(2921);
+ public Object testField2922 = new Integer(2922);
+ public Object testField2923 = new Integer(2923);
+ public Object testField2924 = new Integer(2924);
+ public Object testField2925 = new Integer(2925);
+ public Object testField2926 = new Integer(2926);
+ public Object testField2927 = new Integer(2927);
+ public Object testField2928 = new Integer(2928);
+ public Object testField2929 = new Integer(2929);
+ public Object testField2930 = new Integer(2930);
+ public Object testField2931 = new Integer(2931);
+ public Object testField2932 = new Integer(2932);
+ public Object testField2933 = new Integer(2933);
+ public Object testField2934 = new Integer(2934);
+ public Object testField2935 = new Integer(2935);
+ public Object testField2936 = new Integer(2936);
+ public Object testField2937 = new Integer(2937);
+ public Object testField2938 = new Integer(2938);
+ public Object testField2939 = new Integer(2939);
+ public Object testField2940 = new Integer(2940);
+ public Object testField2941 = new Integer(2941);
+ public Object testField2942 = new Integer(2942);
+ public Object testField2943 = new Integer(2943);
+ public Object testField2944 = new Integer(2944);
+ public Object testField2945 = new Integer(2945);
+ public Object testField2946 = new Integer(2946);
+ public Object testField2947 = new Integer(2947);
+ public Object testField2948 = new Integer(2948);
+ public Object testField2949 = new Integer(2949);
+ public Object testField2950 = new Integer(2950);
+ public Object testField2951 = new Integer(2951);
+ public Object testField2952 = new Integer(2952);
+ public Object testField2953 = new Integer(2953);
+ public Object testField2954 = new Integer(2954);
+ public Object testField2955 = new Integer(2955);
+ public Object testField2956 = new Integer(2956);
+ public Object testField2957 = new Integer(2957);
+ public Object testField2958 = new Integer(2958);
+ public Object testField2959 = new Integer(2959);
+ public Object testField2960 = new Integer(2960);
+ public Object testField2961 = new Integer(2961);
+ public Object testField2962 = new Integer(2962);
+ public Object testField2963 = new Integer(2963);
+ public Object testField2964 = new Integer(2964);
+ public Object testField2965 = new Integer(2965);
+ public Object testField2966 = new Integer(2966);
+ public Object testField2967 = new Integer(2967);
+ public Object testField2968 = new Integer(2968);
+ public Object testField2969 = new Integer(2969);
+ public Object testField2970 = new Integer(2970);
+ public Object testField2971 = new Integer(2971);
+ public Object testField2972 = new Integer(2972);
+ public Object testField2973 = new Integer(2973);
+ public Object testField2974 = new Integer(2974);
+ public Object testField2975 = new Integer(2975);
+ public Object testField2976 = new Integer(2976);
+ public Object testField2977 = new Integer(2977);
+ public Object testField2978 = new Integer(2978);
+ public Object testField2979 = new Integer(2979);
+ public Object testField2980 = new Integer(2980);
+ public Object testField2981 = new Integer(2981);
+ public Object testField2982 = new Integer(2982);
+ public Object testField2983 = new Integer(2983);
+ public Object testField2984 = new Integer(2984);
+ public Object testField2985 = new Integer(2985);
+ public Object testField2986 = new Integer(2986);
+ public Object testField2987 = new Integer(2987);
+ public Object testField2988 = new Integer(2988);
+ public Object testField2989 = new Integer(2989);
+ public Object testField2990 = new Integer(2990);
+ public Object testField2991 = new Integer(2991);
+ public Object testField2992 = new Integer(2992);
+ public Object testField2993 = new Integer(2993);
+ public Object testField2994 = new Integer(2994);
+ public Object testField2995 = new Integer(2995);
+ public Object testField2996 = new Integer(2996);
+ public Object testField2997 = new Integer(2997);
+ public Object testField2998 = new Integer(2998);
+ public Object testField2999 = new Integer(2999);
+}
diff --git a/test/160-read-barrier-stress/src/ManyFieldsBase3.java b/test/160-read-barrier-stress/src/ManyFieldsBase3.java
new file mode 100644
index 0000000000..e7cfaac4fe
--- /dev/null
+++ b/test/160-read-barrier-stress/src/ManyFieldsBase3.java
@@ -0,0 +1,1018 @@
+/*
+ * 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.
+ */
+
+class ManyFieldsBase3 extends ManyFieldsBase2 {
+ public Object testField3000 = new Integer(3000);
+ public Object testField3001 = new Integer(3001);
+ public Object testField3002 = new Integer(3002);
+ public Object testField3003 = new Integer(3003);
+ public Object testField3004 = new Integer(3004);
+ public Object testField3005 = new Integer(3005);
+ public Object testField3006 = new Integer(3006);
+ public Object testField3007 = new Integer(3007);
+ public Object testField3008 = new Integer(3008);
+ public Object testField3009 = new Integer(3009);
+ public Object testField3010 = new Integer(3010);
+ public Object testField3011 = new Integer(3011);
+ public Object testField3012 = new Integer(3012);
+ public Object testField3013 = new Integer(3013);
+ public Object testField3014 = new Integer(3014);
+ public Object testField3015 = new Integer(3015);
+ public Object testField3016 = new Integer(3016);
+ public Object testField3017 = new Integer(3017);
+ public Object testField3018 = new Integer(3018);
+ public Object testField3019 = new Integer(3019);
+ public Object testField3020 = new Integer(3020);
+ public Object testField3021 = new Integer(3021);
+ public Object testField3022 = new Integer(3022);
+ public Object testField3023 = new Integer(3023);
+ public Object testField3024 = new Integer(3024);
+ public Object testField3025 = new Integer(3025);
+ public Object testField3026 = new Integer(3026);
+ public Object testField3027 = new Integer(3027);
+ public Object testField3028 = new Integer(3028);
+ public Object testField3029 = new Integer(3029);
+ public Object testField3030 = new Integer(3030);
+ public Object testField3031 = new Integer(3031);
+ public Object testField3032 = new Integer(3032);
+ public Object testField3033 = new Integer(3033);
+ public Object testField3034 = new Integer(3034);
+ public Object testField3035 = new Integer(3035);
+ public Object testField3036 = new Integer(3036);
+ public Object testField3037 = new Integer(3037);
+ public Object testField3038 = new Integer(3038);
+ public Object testField3039 = new Integer(3039);
+ public Object testField3040 = new Integer(3040);
+ public Object testField3041 = new Integer(3041);
+ public Object testField3042 = new Integer(3042);
+ public Object testField3043 = new Integer(3043);
+ public Object testField3044 = new Integer(3044);
+ public Object testField3045 = new Integer(3045);
+ public Object testField3046 = new Integer(3046);
+ public Object testField3047 = new Integer(3047);
+ public Object testField3048 = new Integer(3048);
+ public Object testField3049 = new Integer(3049);
+ public Object testField3050 = new Integer(3050);
+ public Object testField3051 = new Integer(3051);
+ public Object testField3052 = new Integer(3052);
+ public Object testField3053 = new Integer(3053);
+ public Object testField3054 = new Integer(3054);
+ public Object testField3055 = new Integer(3055);
+ public Object testField3056 = new Integer(3056);
+ public Object testField3057 = new Integer(3057);
+ public Object testField3058 = new Integer(3058);
+ public Object testField3059 = new Integer(3059);
+ public Object testField3060 = new Integer(3060);
+ public Object testField3061 = new Integer(3061);
+ public Object testField3062 = new Integer(3062);
+ public Object testField3063 = new Integer(3063);
+ public Object testField3064 = new Integer(3064);
+ public Object testField3065 = new Integer(3065);
+ public Object testField3066 = new Integer(3066);
+ public Object testField3067 = new Integer(3067);
+ public Object testField3068 = new Integer(3068);
+ public Object testField3069 = new Integer(3069);
+ public Object testField3070 = new Integer(3070);
+ public Object testField3071 = new Integer(3071);
+ public Object testField3072 = new Integer(3072);
+ public Object testField3073 = new Integer(3073);
+ public Object testField3074 = new Integer(3074);
+ public Object testField3075 = new Integer(3075);
+ public Object testField3076 = new Integer(3076);
+ public Object testField3077 = new Integer(3077);
+ public Object testField3078 = new Integer(3078);
+ public Object testField3079 = new Integer(3079);
+ public Object testField3080 = new Integer(3080);
+ public Object testField3081 = new Integer(3081);
+ public Object testField3082 = new Integer(3082);
+ public Object testField3083 = new Integer(3083);
+ public Object testField3084 = new Integer(3084);
+ public Object testField3085 = new Integer(3085);
+ public Object testField3086 = new Integer(3086);
+ public Object testField3087 = new Integer(3087);
+ public Object testField3088 = new Integer(3088);
+ public Object testField3089 = new Integer(3089);
+ public Object testField3090 = new Integer(3090);
+ public Object testField3091 = new Integer(3091);
+ public Object testField3092 = new Integer(3092);
+ public Object testField3093 = new Integer(3093);
+ public Object testField3094 = new Integer(3094);
+ public Object testField3095 = new Integer(3095);
+ public Object testField3096 = new Integer(3096);
+ public Object testField3097 = new Integer(3097);
+ public Object testField3098 = new Integer(3098);
+ public Object testField3099 = new Integer(3099);
+ public Object testField3100 = new Integer(3100);
+ public Object testField3101 = new Integer(3101);
+ public Object testField3102 = new Integer(3102);
+ public Object testField3103 = new Integer(3103);
+ public Object testField3104 = new Integer(3104);
+ public Object testField3105 = new Integer(3105);
+ public Object testField3106 = new Integer(3106);
+ public Object testField3107 = new Integer(3107);
+ public Object testField3108 = new Integer(3108);
+ public Object testField3109 = new Integer(3109);
+ public Object testField3110 = new Integer(3110);
+ public Object testField3111 = new Integer(3111);
+ public Object testField3112 = new Integer(3112);
+ public Object testField3113 = new Integer(3113);
+ public Object testField3114 = new Integer(3114);
+ public Object testField3115 = new Integer(3115);
+ public Object testField3116 = new Integer(3116);
+ public Object testField3117 = new Integer(3117);
+ public Object testField3118 = new Integer(3118);
+ public Object testField3119 = new Integer(3119);
+ public Object testField3120 = new Integer(3120);
+ public Object testField3121 = new Integer(3121);
+ public Object testField3122 = new Integer(3122);
+ public Object testField3123 = new Integer(3123);
+ public Object testField3124 = new Integer(3124);
+ public Object testField3125 = new Integer(3125);
+ public Object testField3126 = new Integer(3126);
+ public Object testField3127 = new Integer(3127);
+ public Object testField3128 = new Integer(3128);
+ public Object testField3129 = new Integer(3129);
+ public Object testField3130 = new Integer(3130);
+ public Object testField3131 = new Integer(3131);
+ public Object testField3132 = new Integer(3132);
+ public Object testField3133 = new Integer(3133);
+ public Object testField3134 = new Integer(3134);
+ public Object testField3135 = new Integer(3135);
+ public Object testField3136 = new Integer(3136);
+ public Object testField3137 = new Integer(3137);
+ public Object testField3138 = new Integer(3138);
+ public Object testField3139 = new Integer(3139);
+ public Object testField3140 = new Integer(3140);
+ public Object testField3141 = new Integer(3141);
+ public Object testField3142 = new Integer(3142);
+ public Object testField3143 = new Integer(3143);
+ public Object testField3144 = new Integer(3144);
+ public Object testField3145 = new Integer(3145);
+ public Object testField3146 = new Integer(3146);
+ public Object testField3147 = new Integer(3147);
+ public Object testField3148 = new Integer(3148);
+ public Object testField3149 = new Integer(3149);
+ public Object testField3150 = new Integer(3150);
+ public Object testField3151 = new Integer(3151);
+ public Object testField3152 = new Integer(3152);
+ public Object testField3153 = new Integer(3153);
+ public Object testField3154 = new Integer(3154);
+ public Object testField3155 = new Integer(3155);
+ public Object testField3156 = new Integer(3156);
+ public Object testField3157 = new Integer(3157);
+ public Object testField3158 = new Integer(3158);
+ public Object testField3159 = new Integer(3159);
+ public Object testField3160 = new Integer(3160);
+ public Object testField3161 = new Integer(3161);
+ public Object testField3162 = new Integer(3162);
+ public Object testField3163 = new Integer(3163);
+ public Object testField3164 = new Integer(3164);
+ public Object testField3165 = new Integer(3165);
+ public Object testField3166 = new Integer(3166);
+ public Object testField3167 = new Integer(3167);
+ public Object testField3168 = new Integer(3168);
+ public Object testField3169 = new Integer(3169);
+ public Object testField3170 = new Integer(3170);
+ public Object testField3171 = new Integer(3171);
+ public Object testField3172 = new Integer(3172);
+ public Object testField3173 = new Integer(3173);
+ public Object testField3174 = new Integer(3174);
+ public Object testField3175 = new Integer(3175);
+ public Object testField3176 = new Integer(3176);
+ public Object testField3177 = new Integer(3177);
+ public Object testField3178 = new Integer(3178);
+ public Object testField3179 = new Integer(3179);
+ public Object testField3180 = new Integer(3180);
+ public Object testField3181 = new Integer(3181);
+ public Object testField3182 = new Integer(3182);
+ public Object testField3183 = new Integer(3183);
+ public Object testField3184 = new Integer(3184);
+ public Object testField3185 = new Integer(3185);
+ public Object testField3186 = new Integer(3186);
+ public Object testField3187 = new Integer(3187);
+ public Object testField3188 = new Integer(3188);
+ public Object testField3189 = new Integer(3189);
+ public Object testField3190 = new Integer(3190);
+ public Object testField3191 = new Integer(3191);
+ public Object testField3192 = new Integer(3192);
+ public Object testField3193 = new Integer(3193);
+ public Object testField3194 = new Integer(3194);
+ public Object testField3195 = new Integer(3195);
+ public Object testField3196 = new Integer(3196);
+ public Object testField3197 = new Integer(3197);
+ public Object testField3198 = new Integer(3198);
+ public Object testField3199 = new Integer(3199);
+ public Object testField3200 = new Integer(3200);
+ public Object testField3201 = new Integer(3201);
+ public Object testField3202 = new Integer(3202);
+ public Object testField3203 = new Integer(3203);
+ public Object testField3204 = new Integer(3204);
+ public Object testField3205 = new Integer(3205);
+ public Object testField3206 = new Integer(3206);
+ public Object testField3207 = new Integer(3207);
+ public Object testField3208 = new Integer(3208);
+ public Object testField3209 = new Integer(3209);
+ public Object testField3210 = new Integer(3210);
+ public Object testField3211 = new Integer(3211);
+ public Object testField3212 = new Integer(3212);
+ public Object testField3213 = new Integer(3213);
+ public Object testField3214 = new Integer(3214);
+ public Object testField3215 = new Integer(3215);
+ public Object testField3216 = new Integer(3216);
+ public Object testField3217 = new Integer(3217);
+ public Object testField3218 = new Integer(3218);
+ public Object testField3219 = new Integer(3219);
+ public Object testField3220 = new Integer(3220);
+ public Object testField3221 = new Integer(3221);
+ public Object testField3222 = new Integer(3222);
+ public Object testField3223 = new Integer(3223);
+ public Object testField3224 = new Integer(3224);
+ public Object testField3225 = new Integer(3225);
+ public Object testField3226 = new Integer(3226);
+ public Object testField3227 = new Integer(3227);
+ public Object testField3228 = new Integer(3228);
+ public Object testField3229 = new Integer(3229);
+ public Object testField3230 = new Integer(3230);
+ public Object testField3231 = new Integer(3231);
+ public Object testField3232 = new Integer(3232);
+ public Object testField3233 = new Integer(3233);
+ public Object testField3234 = new Integer(3234);
+ public Object testField3235 = new Integer(3235);
+ public Object testField3236 = new Integer(3236);
+ public Object testField3237 = new Integer(3237);
+ public Object testField3238 = new Integer(3238);
+ public Object testField3239 = new Integer(3239);
+ public Object testField3240 = new Integer(3240);
+ public Object testField3241 = new Integer(3241);
+ public Object testField3242 = new Integer(3242);
+ public Object testField3243 = new Integer(3243);
+ public Object testField3244 = new Integer(3244);
+ public Object testField3245 = new Integer(3245);
+ public Object testField3246 = new Integer(3246);
+ public Object testField3247 = new Integer(3247);
+ public Object testField3248 = new Integer(3248);
+ public Object testField3249 = new Integer(3249);
+ public Object testField3250 = new Integer(3250);
+ public Object testField3251 = new Integer(3251);
+ public Object testField3252 = new Integer(3252);
+ public Object testField3253 = new Integer(3253);
+ public Object testField3254 = new Integer(3254);
+ public Object testField3255 = new Integer(3255);
+ public Object testField3256 = new Integer(3256);
+ public Object testField3257 = new Integer(3257);
+ public Object testField3258 = new Integer(3258);
+ public Object testField3259 = new Integer(3259);
+ public Object testField3260 = new Integer(3260);
+ public Object testField3261 = new Integer(3261);
+ public Object testField3262 = new Integer(3262);
+ public Object testField3263 = new Integer(3263);
+ public Object testField3264 = new Integer(3264);
+ public Object testField3265 = new Integer(3265);
+ public Object testField3266 = new Integer(3266);
+ public Object testField3267 = new Integer(3267);
+ public Object testField3268 = new Integer(3268);
+ public Object testField3269 = new Integer(3269);
+ public Object testField3270 = new Integer(3270);
+ public Object testField3271 = new Integer(3271);
+ public Object testField3272 = new Integer(3272);
+ public Object testField3273 = new Integer(3273);
+ public Object testField3274 = new Integer(3274);
+ public Object testField3275 = new Integer(3275);
+ public Object testField3276 = new Integer(3276);
+ public Object testField3277 = new Integer(3277);
+ public Object testField3278 = new Integer(3278);
+ public Object testField3279 = new Integer(3279);
+ public Object testField3280 = new Integer(3280);
+ public Object testField3281 = new Integer(3281);
+ public Object testField3282 = new Integer(3282);
+ public Object testField3283 = new Integer(3283);
+ public Object testField3284 = new Integer(3284);
+ public Object testField3285 = new Integer(3285);
+ public Object testField3286 = new Integer(3286);
+ public Object testField3287 = new Integer(3287);
+ public Object testField3288 = new Integer(3288);
+ public Object testField3289 = new Integer(3289);
+ public Object testField3290 = new Integer(3290);
+ public Object testField3291 = new Integer(3291);
+ public Object testField3292 = new Integer(3292);
+ public Object testField3293 = new Integer(3293);
+ public Object testField3294 = new Integer(3294);
+ public Object testField3295 = new Integer(3295);
+ public Object testField3296 = new Integer(3296);
+ public Object testField3297 = new Integer(3297);
+ public Object testField3298 = new Integer(3298);
+ public Object testField3299 = new Integer(3299);
+ public Object testField3300 = new Integer(3300);
+ public Object testField3301 = new Integer(3301);
+ public Object testField3302 = new Integer(3302);
+ public Object testField3303 = new Integer(3303);
+ public Object testField3304 = new Integer(3304);
+ public Object testField3305 = new Integer(3305);
+ public Object testField3306 = new Integer(3306);
+ public Object testField3307 = new Integer(3307);
+ public Object testField3308 = new Integer(3308);
+ public Object testField3309 = new Integer(3309);
+ public Object testField3310 = new Integer(3310);
+ public Object testField3311 = new Integer(3311);
+ public Object testField3312 = new Integer(3312);
+ public Object testField3313 = new Integer(3313);
+ public Object testField3314 = new Integer(3314);
+ public Object testField3315 = new Integer(3315);
+ public Object testField3316 = new Integer(3316);
+ public Object testField3317 = new Integer(3317);
+ public Object testField3318 = new Integer(3318);
+ public Object testField3319 = new Integer(3319);
+ public Object testField3320 = new Integer(3320);
+ public Object testField3321 = new Integer(3321);
+ public Object testField3322 = new Integer(3322);
+ public Object testField3323 = new Integer(3323);
+ public Object testField3324 = new Integer(3324);
+ public Object testField3325 = new Integer(3325);
+ public Object testField3326 = new Integer(3326);
+ public Object testField3327 = new Integer(3327);
+ public Object testField3328 = new Integer(3328);
+ public Object testField3329 = new Integer(3329);
+ public Object testField3330 = new Integer(3330);
+ public Object testField3331 = new Integer(3331);
+ public Object testField3332 = new Integer(3332);
+ public Object testField3333 = new Integer(3333);
+ public Object testField3334 = new Integer(3334);
+ public Object testField3335 = new Integer(3335);
+ public Object testField3336 = new Integer(3336);
+ public Object testField3337 = new Integer(3337);
+ public Object testField3338 = new Integer(3338);
+ public Object testField3339 = new Integer(3339);
+ public Object testField3340 = new Integer(3340);
+ public Object testField3341 = new Integer(3341);
+ public Object testField3342 = new Integer(3342);
+ public Object testField3343 = new Integer(3343);
+ public Object testField3344 = new Integer(3344);
+ public Object testField3345 = new Integer(3345);
+ public Object testField3346 = new Integer(3346);
+ public Object testField3347 = new Integer(3347);
+ public Object testField3348 = new Integer(3348);
+ public Object testField3349 = new Integer(3349);
+ public Object testField3350 = new Integer(3350);
+ public Object testField3351 = new Integer(3351);
+ public Object testField3352 = new Integer(3352);
+ public Object testField3353 = new Integer(3353);
+ public Object testField3354 = new Integer(3354);
+ public Object testField3355 = new Integer(3355);
+ public Object testField3356 = new Integer(3356);
+ public Object testField3357 = new Integer(3357);
+ public Object testField3358 = new Integer(3358);
+ public Object testField3359 = new Integer(3359);
+ public Object testField3360 = new Integer(3360);
+ public Object testField3361 = new Integer(3361);
+ public Object testField3362 = new Integer(3362);
+ public Object testField3363 = new Integer(3363);
+ public Object testField3364 = new Integer(3364);
+ public Object testField3365 = new Integer(3365);
+ public Object testField3366 = new Integer(3366);
+ public Object testField3367 = new Integer(3367);
+ public Object testField3368 = new Integer(3368);
+ public Object testField3369 = new Integer(3369);
+ public Object testField3370 = new Integer(3370);
+ public Object testField3371 = new Integer(3371);
+ public Object testField3372 = new Integer(3372);
+ public Object testField3373 = new Integer(3373);
+ public Object testField3374 = new Integer(3374);
+ public Object testField3375 = new Integer(3375);
+ public Object testField3376 = new Integer(3376);
+ public Object testField3377 = new Integer(3377);
+ public Object testField3378 = new Integer(3378);
+ public Object testField3379 = new Integer(3379);
+ public Object testField3380 = new Integer(3380);
+ public Object testField3381 = new Integer(3381);
+ public Object testField3382 = new Integer(3382);
+ public Object testField3383 = new Integer(3383);
+ public Object testField3384 = new Integer(3384);
+ public Object testField3385 = new Integer(3385);
+ public Object testField3386 = new Integer(3386);
+ public Object testField3387 = new Integer(3387);
+ public Object testField3388 = new Integer(3388);
+ public Object testField3389 = new Integer(3389);
+ public Object testField3390 = new Integer(3390);
+ public Object testField3391 = new Integer(3391);
+ public Object testField3392 = new Integer(3392);
+ public Object testField3393 = new Integer(3393);
+ public Object testField3394 = new Integer(3394);
+ public Object testField3395 = new Integer(3395);
+ public Object testField3396 = new Integer(3396);
+ public Object testField3397 = new Integer(3397);
+ public Object testField3398 = new Integer(3398);
+ public Object testField3399 = new Integer(3399);
+ public Object testField3400 = new Integer(3400);
+ public Object testField3401 = new Integer(3401);
+ public Object testField3402 = new Integer(3402);
+ public Object testField3403 = new Integer(3403);
+ public Object testField3404 = new Integer(3404);
+ public Object testField3405 = new Integer(3405);
+ public Object testField3406 = new Integer(3406);
+ public Object testField3407 = new Integer(3407);
+ public Object testField3408 = new Integer(3408);
+ public Object testField3409 = new Integer(3409);
+ public Object testField3410 = new Integer(3410);
+ public Object testField3411 = new Integer(3411);
+ public Object testField3412 = new Integer(3412);
+ public Object testField3413 = new Integer(3413);
+ public Object testField3414 = new Integer(3414);
+ public Object testField3415 = new Integer(3415);
+ public Object testField3416 = new Integer(3416);
+ public Object testField3417 = new Integer(3417);
+ public Object testField3418 = new Integer(3418);
+ public Object testField3419 = new Integer(3419);
+ public Object testField3420 = new Integer(3420);
+ public Object testField3421 = new Integer(3421);
+ public Object testField3422 = new Integer(3422);
+ public Object testField3423 = new Integer(3423);
+ public Object testField3424 = new Integer(3424);
+ public Object testField3425 = new Integer(3425);
+ public Object testField3426 = new Integer(3426);
+ public Object testField3427 = new Integer(3427);
+ public Object testField3428 = new Integer(3428);
+ public Object testField3429 = new Integer(3429);
+ public Object testField3430 = new Integer(3430);
+ public Object testField3431 = new Integer(3431);
+ public Object testField3432 = new Integer(3432);
+ public Object testField3433 = new Integer(3433);
+ public Object testField3434 = new Integer(3434);
+ public Object testField3435 = new Integer(3435);
+ public Object testField3436 = new Integer(3436);
+ public Object testField3437 = new Integer(3437);
+ public Object testField3438 = new Integer(3438);
+ public Object testField3439 = new Integer(3439);
+ public Object testField3440 = new Integer(3440);
+ public Object testField3441 = new Integer(3441);
+ public Object testField3442 = new Integer(3442);
+ public Object testField3443 = new Integer(3443);
+ public Object testField3444 = new Integer(3444);
+ public Object testField3445 = new Integer(3445);
+ public Object testField3446 = new Integer(3446);
+ public Object testField3447 = new Integer(3447);
+ public Object testField3448 = new Integer(3448);
+ public Object testField3449 = new Integer(3449);
+ public Object testField3450 = new Integer(3450);
+ public Object testField3451 = new Integer(3451);
+ public Object testField3452 = new Integer(3452);
+ public Object testField3453 = new Integer(3453);
+ public Object testField3454 = new Integer(3454);
+ public Object testField3455 = new Integer(3455);
+ public Object testField3456 = new Integer(3456);
+ public Object testField3457 = new Integer(3457);
+ public Object testField3458 = new Integer(3458);
+ public Object testField3459 = new Integer(3459);
+ public Object testField3460 = new Integer(3460);
+ public Object testField3461 = new Integer(3461);
+ public Object testField3462 = new Integer(3462);
+ public Object testField3463 = new Integer(3463);
+ public Object testField3464 = new Integer(3464);
+ public Object testField3465 = new Integer(3465);
+ public Object testField3466 = new Integer(3466);
+ public Object testField3467 = new Integer(3467);
+ public Object testField3468 = new Integer(3468);
+ public Object testField3469 = new Integer(3469);
+ public Object testField3470 = new Integer(3470);
+ public Object testField3471 = new Integer(3471);
+ public Object testField3472 = new Integer(3472);
+ public Object testField3473 = new Integer(3473);
+ public Object testField3474 = new Integer(3474);
+ public Object testField3475 = new Integer(3475);
+ public Object testField3476 = new Integer(3476);
+ public Object testField3477 = new Integer(3477);
+ public Object testField3478 = new Integer(3478);
+ public Object testField3479 = new Integer(3479);
+ public Object testField3480 = new Integer(3480);
+ public Object testField3481 = new Integer(3481);
+ public Object testField3482 = new Integer(3482);
+ public Object testField3483 = new Integer(3483);
+ public Object testField3484 = new Integer(3484);
+ public Object testField3485 = new Integer(3485);
+ public Object testField3486 = new Integer(3486);
+ public Object testField3487 = new Integer(3487);
+ public Object testField3488 = new Integer(3488);
+ public Object testField3489 = new Integer(3489);
+ public Object testField3490 = new Integer(3490);
+ public Object testField3491 = new Integer(3491);
+ public Object testField3492 = new Integer(3492);
+ public Object testField3493 = new Integer(3493);
+ public Object testField3494 = new Integer(3494);
+ public Object testField3495 = new Integer(3495);
+ public Object testField3496 = new Integer(3496);
+ public Object testField3497 = new Integer(3497);
+ public Object testField3498 = new Integer(3498);
+ public Object testField3499 = new Integer(3499);
+ public Object testField3500 = new Integer(3500);
+ public Object testField3501 = new Integer(3501);
+ public Object testField3502 = new Integer(3502);
+ public Object testField3503 = new Integer(3503);
+ public Object testField3504 = new Integer(3504);
+ public Object testField3505 = new Integer(3505);
+ public Object testField3506 = new Integer(3506);
+ public Object testField3507 = new Integer(3507);
+ public Object testField3508 = new Integer(3508);
+ public Object testField3509 = new Integer(3509);
+ public Object testField3510 = new Integer(3510);
+ public Object testField3511 = new Integer(3511);
+ public Object testField3512 = new Integer(3512);
+ public Object testField3513 = new Integer(3513);
+ public Object testField3514 = new Integer(3514);
+ public Object testField3515 = new Integer(3515);
+ public Object testField3516 = new Integer(3516);
+ public Object testField3517 = new Integer(3517);
+ public Object testField3518 = new Integer(3518);
+ public Object testField3519 = new Integer(3519);
+ public Object testField3520 = new Integer(3520);
+ public Object testField3521 = new Integer(3521);
+ public Object testField3522 = new Integer(3522);
+ public Object testField3523 = new Integer(3523);
+ public Object testField3524 = new Integer(3524);
+ public Object testField3525 = new Integer(3525);
+ public Object testField3526 = new Integer(3526);
+ public Object testField3527 = new Integer(3527);
+ public Object testField3528 = new Integer(3528);
+ public Object testField3529 = new Integer(3529);
+ public Object testField3530 = new Integer(3530);
+ public Object testField3531 = new Integer(3531);
+ public Object testField3532 = new Integer(3532);
+ public Object testField3533 = new Integer(3533);
+ public Object testField3534 = new Integer(3534);
+ public Object testField3535 = new Integer(3535);
+ public Object testField3536 = new Integer(3536);
+ public Object testField3537 = new Integer(3537);
+ public Object testField3538 = new Integer(3538);
+ public Object testField3539 = new Integer(3539);
+ public Object testField3540 = new Integer(3540);
+ public Object testField3541 = new Integer(3541);
+ public Object testField3542 = new Integer(3542);
+ public Object testField3543 = new Integer(3543);
+ public Object testField3544 = new Integer(3544);
+ public Object testField3545 = new Integer(3545);
+ public Object testField3546 = new Integer(3546);
+ public Object testField3547 = new Integer(3547);
+ public Object testField3548 = new Integer(3548);
+ public Object testField3549 = new Integer(3549);
+ public Object testField3550 = new Integer(3550);
+ public Object testField3551 = new Integer(3551);
+ public Object testField3552 = new Integer(3552);
+ public Object testField3553 = new Integer(3553);
+ public Object testField3554 = new Integer(3554);
+ public Object testField3555 = new Integer(3555);
+ public Object testField3556 = new Integer(3556);
+ public Object testField3557 = new Integer(3557);
+ public Object testField3558 = new Integer(3558);
+ public Object testField3559 = new Integer(3559);
+ public Object testField3560 = new Integer(3560);
+ public Object testField3561 = new Integer(3561);
+ public Object testField3562 = new Integer(3562);
+ public Object testField3563 = new Integer(3563);
+ public Object testField3564 = new Integer(3564);
+ public Object testField3565 = new Integer(3565);
+ public Object testField3566 = new Integer(3566);
+ public Object testField3567 = new Integer(3567);
+ public Object testField3568 = new Integer(3568);
+ public Object testField3569 = new Integer(3569);
+ public Object testField3570 = new Integer(3570);
+ public Object testField3571 = new Integer(3571);
+ public Object testField3572 = new Integer(3572);
+ public Object testField3573 = new Integer(3573);
+ public Object testField3574 = new Integer(3574);
+ public Object testField3575 = new Integer(3575);
+ public Object testField3576 = new Integer(3576);
+ public Object testField3577 = new Integer(3577);
+ public Object testField3578 = new Integer(3578);
+ public Object testField3579 = new Integer(3579);
+ public Object testField3580 = new Integer(3580);
+ public Object testField3581 = new Integer(3581);
+ public Object testField3582 = new Integer(3582);
+ public Object testField3583 = new Integer(3583);
+ public Object testField3584 = new Integer(3584);
+ public Object testField3585 = new Integer(3585);
+ public Object testField3586 = new Integer(3586);
+ public Object testField3587 = new Integer(3587);
+ public Object testField3588 = new Integer(3588);
+ public Object testField3589 = new Integer(3589);
+ public Object testField3590 = new Integer(3590);
+ public Object testField3591 = new Integer(3591);
+ public Object testField3592 = new Integer(3592);
+ public Object testField3593 = new Integer(3593);
+ public Object testField3594 = new Integer(3594);
+ public Object testField3595 = new Integer(3595);
+ public Object testField3596 = new Integer(3596);
+ public Object testField3597 = new Integer(3597);
+ public Object testField3598 = new Integer(3598);
+ public Object testField3599 = new Integer(3599);
+ public Object testField3600 = new Integer(3600);
+ public Object testField3601 = new Integer(3601);
+ public Object testField3602 = new Integer(3602);
+ public Object testField3603 = new Integer(3603);
+ public Object testField3604 = new Integer(3604);
+ public Object testField3605 = new Integer(3605);
+ public Object testField3606 = new Integer(3606);
+ public Object testField3607 = new Integer(3607);
+ public Object testField3608 = new Integer(3608);
+ public Object testField3609 = new Integer(3609);
+ public Object testField3610 = new Integer(3610);
+ public Object testField3611 = new Integer(3611);
+ public Object testField3612 = new Integer(3612);
+ public Object testField3613 = new Integer(3613);
+ public Object testField3614 = new Integer(3614);
+ public Object testField3615 = new Integer(3615);
+ public Object testField3616 = new Integer(3616);
+ public Object testField3617 = new Integer(3617);
+ public Object testField3618 = new Integer(3618);
+ public Object testField3619 = new Integer(3619);
+ public Object testField3620 = new Integer(3620);
+ public Object testField3621 = new Integer(3621);
+ public Object testField3622 = new Integer(3622);
+ public Object testField3623 = new Integer(3623);
+ public Object testField3624 = new Integer(3624);
+ public Object testField3625 = new Integer(3625);
+ public Object testField3626 = new Integer(3626);
+ public Object testField3627 = new Integer(3627);
+ public Object testField3628 = new Integer(3628);
+ public Object testField3629 = new Integer(3629);
+ public Object testField3630 = new Integer(3630);
+ public Object testField3631 = new Integer(3631);
+ public Object testField3632 = new Integer(3632);
+ public Object testField3633 = new Integer(3633);
+ public Object testField3634 = new Integer(3634);
+ public Object testField3635 = new Integer(3635);
+ public Object testField3636 = new Integer(3636);
+ public Object testField3637 = new Integer(3637);
+ public Object testField3638 = new Integer(3638);
+ public Object testField3639 = new Integer(3639);
+ public Object testField3640 = new Integer(3640);
+ public Object testField3641 = new Integer(3641);
+ public Object testField3642 = new Integer(3642);
+ public Object testField3643 = new Integer(3643);
+ public Object testField3644 = new Integer(3644);
+ public Object testField3645 = new Integer(3645);
+ public Object testField3646 = new Integer(3646);
+ public Object testField3647 = new Integer(3647);
+ public Object testField3648 = new Integer(3648);
+ public Object testField3649 = new Integer(3649);
+ public Object testField3650 = new Integer(3650);
+ public Object testField3651 = new Integer(3651);
+ public Object testField3652 = new Integer(3652);
+ public Object testField3653 = new Integer(3653);
+ public Object testField3654 = new Integer(3654);
+ public Object testField3655 = new Integer(3655);
+ public Object testField3656 = new Integer(3656);
+ public Object testField3657 = new Integer(3657);
+ public Object testField3658 = new Integer(3658);
+ public Object testField3659 = new Integer(3659);
+ public Object testField3660 = new Integer(3660);
+ public Object testField3661 = new Integer(3661);
+ public Object testField3662 = new Integer(3662);
+ public Object testField3663 = new Integer(3663);
+ public Object testField3664 = new Integer(3664);
+ public Object testField3665 = new Integer(3665);
+ public Object testField3666 = new Integer(3666);
+ public Object testField3667 = new Integer(3667);
+ public Object testField3668 = new Integer(3668);
+ public Object testField3669 = new Integer(3669);
+ public Object testField3670 = new Integer(3670);
+ public Object testField3671 = new Integer(3671);
+ public Object testField3672 = new Integer(3672);
+ public Object testField3673 = new Integer(3673);
+ public Object testField3674 = new Integer(3674);
+ public Object testField3675 = new Integer(3675);
+ public Object testField3676 = new Integer(3676);
+ public Object testField3677 = new Integer(3677);
+ public Object testField3678 = new Integer(3678);
+ public Object testField3679 = new Integer(3679);
+ public Object testField3680 = new Integer(3680);
+ public Object testField3681 = new Integer(3681);
+ public Object testField3682 = new Integer(3682);
+ public Object testField3683 = new Integer(3683);
+ public Object testField3684 = new Integer(3684);
+ public Object testField3685 = new Integer(3685);
+ public Object testField3686 = new Integer(3686);
+ public Object testField3687 = new Integer(3687);
+ public Object testField3688 = new Integer(3688);
+ public Object testField3689 = new Integer(3689);
+ public Object testField3690 = new Integer(3690);
+ public Object testField3691 = new Integer(3691);
+ public Object testField3692 = new Integer(3692);
+ public Object testField3693 = new Integer(3693);
+ public Object testField3694 = new Integer(3694);
+ public Object testField3695 = new Integer(3695);
+ public Object testField3696 = new Integer(3696);
+ public Object testField3697 = new Integer(3697);
+ public Object testField3698 = new Integer(3698);
+ public Object testField3699 = new Integer(3699);
+ public Object testField3700 = new Integer(3700);
+ public Object testField3701 = new Integer(3701);
+ public Object testField3702 = new Integer(3702);
+ public Object testField3703 = new Integer(3703);
+ public Object testField3704 = new Integer(3704);
+ public Object testField3705 = new Integer(3705);
+ public Object testField3706 = new Integer(3706);
+ public Object testField3707 = new Integer(3707);
+ public Object testField3708 = new Integer(3708);
+ public Object testField3709 = new Integer(3709);
+ public Object testField3710 = new Integer(3710);
+ public Object testField3711 = new Integer(3711);
+ public Object testField3712 = new Integer(3712);
+ public Object testField3713 = new Integer(3713);
+ public Object testField3714 = new Integer(3714);
+ public Object testField3715 = new Integer(3715);
+ public Object testField3716 = new Integer(3716);
+ public Object testField3717 = new Integer(3717);
+ public Object testField3718 = new Integer(3718);
+ public Object testField3719 = new Integer(3719);
+ public Object testField3720 = new Integer(3720);
+ public Object testField3721 = new Integer(3721);
+ public Object testField3722 = new Integer(3722);
+ public Object testField3723 = new Integer(3723);
+ public Object testField3724 = new Integer(3724);
+ public Object testField3725 = new Integer(3725);
+ public Object testField3726 = new Integer(3726);
+ public Object testField3727 = new Integer(3727);
+ public Object testField3728 = new Integer(3728);
+ public Object testField3729 = new Integer(3729);
+ public Object testField3730 = new Integer(3730);
+ public Object testField3731 = new Integer(3731);
+ public Object testField3732 = new Integer(3732);
+ public Object testField3733 = new Integer(3733);
+ public Object testField3734 = new Integer(3734);
+ public Object testField3735 = new Integer(3735);
+ public Object testField3736 = new Integer(3736);
+ public Object testField3737 = new Integer(3737);
+ public Object testField3738 = new Integer(3738);
+ public Object testField3739 = new Integer(3739);
+ public Object testField3740 = new Integer(3740);
+ public Object testField3741 = new Integer(3741);
+ public Object testField3742 = new Integer(3742);
+ public Object testField3743 = new Integer(3743);
+ public Object testField3744 = new Integer(3744);
+ public Object testField3745 = new Integer(3745);
+ public Object testField3746 = new Integer(3746);
+ public Object testField3747 = new Integer(3747);
+ public Object testField3748 = new Integer(3748);
+ public Object testField3749 = new Integer(3749);
+ public Object testField3750 = new Integer(3750);
+ public Object testField3751 = new Integer(3751);
+ public Object testField3752 = new Integer(3752);
+ public Object testField3753 = new Integer(3753);
+ public Object testField3754 = new Integer(3754);
+ public Object testField3755 = new Integer(3755);
+ public Object testField3756 = new Integer(3756);
+ public Object testField3757 = new Integer(3757);
+ public Object testField3758 = new Integer(3758);
+ public Object testField3759 = new Integer(3759);
+ public Object testField3760 = new Integer(3760);
+ public Object testField3761 = new Integer(3761);
+ public Object testField3762 = new Integer(3762);
+ public Object testField3763 = new Integer(3763);
+ public Object testField3764 = new Integer(3764);
+ public Object testField3765 = new Integer(3765);
+ public Object testField3766 = new Integer(3766);
+ public Object testField3767 = new Integer(3767);
+ public Object testField3768 = new Integer(3768);
+ public Object testField3769 = new Integer(3769);
+ public Object testField3770 = new Integer(3770);
+ public Object testField3771 = new Integer(3771);
+ public Object testField3772 = new Integer(3772);
+ public Object testField3773 = new Integer(3773);
+ public Object testField3774 = new Integer(3774);
+ public Object testField3775 = new Integer(3775);
+ public Object testField3776 = new Integer(3776);
+ public Object testField3777 = new Integer(3777);
+ public Object testField3778 = new Integer(3778);
+ public Object testField3779 = new Integer(3779);
+ public Object testField3780 = new Integer(3780);
+ public Object testField3781 = new Integer(3781);
+ public Object testField3782 = new Integer(3782);
+ public Object testField3783 = new Integer(3783);
+ public Object testField3784 = new Integer(3784);
+ public Object testField3785 = new Integer(3785);
+ public Object testField3786 = new Integer(3786);
+ public Object testField3787 = new Integer(3787);
+ public Object testField3788 = new Integer(3788);
+ public Object testField3789 = new Integer(3789);
+ public Object testField3790 = new Integer(3790);
+ public Object testField3791 = new Integer(3791);
+ public Object testField3792 = new Integer(3792);
+ public Object testField3793 = new Integer(3793);
+ public Object testField3794 = new Integer(3794);
+ public Object testField3795 = new Integer(3795);
+ public Object testField3796 = new Integer(3796);
+ public Object testField3797 = new Integer(3797);
+ public Object testField3798 = new Integer(3798);
+ public Object testField3799 = new Integer(3799);
+ public Object testField3800 = new Integer(3800);
+ public Object testField3801 = new Integer(3801);
+ public Object testField3802 = new Integer(3802);
+ public Object testField3803 = new Integer(3803);
+ public Object testField3804 = new Integer(3804);
+ public Object testField3805 = new Integer(3805);
+ public Object testField3806 = new Integer(3806);
+ public Object testField3807 = new Integer(3807);
+ public Object testField3808 = new Integer(3808);
+ public Object testField3809 = new Integer(3809);
+ public Object testField3810 = new Integer(3810);
+ public Object testField3811 = new Integer(3811);
+ public Object testField3812 = new Integer(3812);
+ public Object testField3813 = new Integer(3813);
+ public Object testField3814 = new Integer(3814);
+ public Object testField3815 = new Integer(3815);
+ public Object testField3816 = new Integer(3816);
+ public Object testField3817 = new Integer(3817);
+ public Object testField3818 = new Integer(3818);
+ public Object testField3819 = new Integer(3819);
+ public Object testField3820 = new Integer(3820);
+ public Object testField3821 = new Integer(3821);
+ public Object testField3822 = new Integer(3822);
+ public Object testField3823 = new Integer(3823);
+ public Object testField3824 = new Integer(3824);
+ public Object testField3825 = new Integer(3825);
+ public Object testField3826 = new Integer(3826);
+ public Object testField3827 = new Integer(3827);
+ public Object testField3828 = new Integer(3828);
+ public Object testField3829 = new Integer(3829);
+ public Object testField3830 = new Integer(3830);
+ public Object testField3831 = new Integer(3831);
+ public Object testField3832 = new Integer(3832);
+ public Object testField3833 = new Integer(3833);
+ public Object testField3834 = new Integer(3834);
+ public Object testField3835 = new Integer(3835);
+ public Object testField3836 = new Integer(3836);
+ public Object testField3837 = new Integer(3837);
+ public Object testField3838 = new Integer(3838);
+ public Object testField3839 = new Integer(3839);
+ public Object testField3840 = new Integer(3840);
+ public Object testField3841 = new Integer(3841);
+ public Object testField3842 = new Integer(3842);
+ public Object testField3843 = new Integer(3843);
+ public Object testField3844 = new Integer(3844);
+ public Object testField3845 = new Integer(3845);
+ public Object testField3846 = new Integer(3846);
+ public Object testField3847 = new Integer(3847);
+ public Object testField3848 = new Integer(3848);
+ public Object testField3849 = new Integer(3849);
+ public Object testField3850 = new Integer(3850);
+ public Object testField3851 = new Integer(3851);
+ public Object testField3852 = new Integer(3852);
+ public Object testField3853 = new Integer(3853);
+ public Object testField3854 = new Integer(3854);
+ public Object testField3855 = new Integer(3855);
+ public Object testField3856 = new Integer(3856);
+ public Object testField3857 = new Integer(3857);
+ public Object testField3858 = new Integer(3858);
+ public Object testField3859 = new Integer(3859);
+ public Object testField3860 = new Integer(3860);
+ public Object testField3861 = new Integer(3861);
+ public Object testField3862 = new Integer(3862);
+ public Object testField3863 = new Integer(3863);
+ public Object testField3864 = new Integer(3864);
+ public Object testField3865 = new Integer(3865);
+ public Object testField3866 = new Integer(3866);
+ public Object testField3867 = new Integer(3867);
+ public Object testField3868 = new Integer(3868);
+ public Object testField3869 = new Integer(3869);
+ public Object testField3870 = new Integer(3870);
+ public Object testField3871 = new Integer(3871);
+ public Object testField3872 = new Integer(3872);
+ public Object testField3873 = new Integer(3873);
+ public Object testField3874 = new Integer(3874);
+ public Object testField3875 = new Integer(3875);
+ public Object testField3876 = new Integer(3876);
+ public Object testField3877 = new Integer(3877);
+ public Object testField3878 = new Integer(3878);
+ public Object testField3879 = new Integer(3879);
+ public Object testField3880 = new Integer(3880);
+ public Object testField3881 = new Integer(3881);
+ public Object testField3882 = new Integer(3882);
+ public Object testField3883 = new Integer(3883);
+ public Object testField3884 = new Integer(3884);
+ public Object testField3885 = new Integer(3885);
+ public Object testField3886 = new Integer(3886);
+ public Object testField3887 = new Integer(3887);
+ public Object testField3888 = new Integer(3888);
+ public Object testField3889 = new Integer(3889);
+ public Object testField3890 = new Integer(3890);
+ public Object testField3891 = new Integer(3891);
+ public Object testField3892 = new Integer(3892);
+ public Object testField3893 = new Integer(3893);
+ public Object testField3894 = new Integer(3894);
+ public Object testField3895 = new Integer(3895);
+ public Object testField3896 = new Integer(3896);
+ public Object testField3897 = new Integer(3897);
+ public Object testField3898 = new Integer(3898);
+ public Object testField3899 = new Integer(3899);
+ public Object testField3900 = new Integer(3900);
+ public Object testField3901 = new Integer(3901);
+ public Object testField3902 = new Integer(3902);
+ public Object testField3903 = new Integer(3903);
+ public Object testField3904 = new Integer(3904);
+ public Object testField3905 = new Integer(3905);
+ public Object testField3906 = new Integer(3906);
+ public Object testField3907 = new Integer(3907);
+ public Object testField3908 = new Integer(3908);
+ public Object testField3909 = new Integer(3909);
+ public Object testField3910 = new Integer(3910);
+ public Object testField3911 = new Integer(3911);
+ public Object testField3912 = new Integer(3912);
+ public Object testField3913 = new Integer(3913);
+ public Object testField3914 = new Integer(3914);
+ public Object testField3915 = new Integer(3915);
+ public Object testField3916 = new Integer(3916);
+ public Object testField3917 = new Integer(3917);
+ public Object testField3918 = new Integer(3918);
+ public Object testField3919 = new Integer(3919);
+ public Object testField3920 = new Integer(3920);
+ public Object testField3921 = new Integer(3921);
+ public Object testField3922 = new Integer(3922);
+ public Object testField3923 = new Integer(3923);
+ public Object testField3924 = new Integer(3924);
+ public Object testField3925 = new Integer(3925);
+ public Object testField3926 = new Integer(3926);
+ public Object testField3927 = new Integer(3927);
+ public Object testField3928 = new Integer(3928);
+ public Object testField3929 = new Integer(3929);
+ public Object testField3930 = new Integer(3930);
+ public Object testField3931 = new Integer(3931);
+ public Object testField3932 = new Integer(3932);
+ public Object testField3933 = new Integer(3933);
+ public Object testField3934 = new Integer(3934);
+ public Object testField3935 = new Integer(3935);
+ public Object testField3936 = new Integer(3936);
+ public Object testField3937 = new Integer(3937);
+ public Object testField3938 = new Integer(3938);
+ public Object testField3939 = new Integer(3939);
+ public Object testField3940 = new Integer(3940);
+ public Object testField3941 = new Integer(3941);
+ public Object testField3942 = new Integer(3942);
+ public Object testField3943 = new Integer(3943);
+ public Object testField3944 = new Integer(3944);
+ public Object testField3945 = new Integer(3945);
+ public Object testField3946 = new Integer(3946);
+ public Object testField3947 = new Integer(3947);
+ public Object testField3948 = new Integer(3948);
+ public Object testField3949 = new Integer(3949);
+ public Object testField3950 = new Integer(3950);
+ public Object testField3951 = new Integer(3951);
+ public Object testField3952 = new Integer(3952);
+ public Object testField3953 = new Integer(3953);
+ public Object testField3954 = new Integer(3954);
+ public Object testField3955 = new Integer(3955);
+ public Object testField3956 = new Integer(3956);
+ public Object testField3957 = new Integer(3957);
+ public Object testField3958 = new Integer(3958);
+ public Object testField3959 = new Integer(3959);
+ public Object testField3960 = new Integer(3960);
+ public Object testField3961 = new Integer(3961);
+ public Object testField3962 = new Integer(3962);
+ public Object testField3963 = new Integer(3963);
+ public Object testField3964 = new Integer(3964);
+ public Object testField3965 = new Integer(3965);
+ public Object testField3966 = new Integer(3966);
+ public Object testField3967 = new Integer(3967);
+ public Object testField3968 = new Integer(3968);
+ public Object testField3969 = new Integer(3969);
+ public Object testField3970 = new Integer(3970);
+ public Object testField3971 = new Integer(3971);
+ public Object testField3972 = new Integer(3972);
+ public Object testField3973 = new Integer(3973);
+ public Object testField3974 = new Integer(3974);
+ public Object testField3975 = new Integer(3975);
+ public Object testField3976 = new Integer(3976);
+ public Object testField3977 = new Integer(3977);
+ public Object testField3978 = new Integer(3978);
+ public Object testField3979 = new Integer(3979);
+ public Object testField3980 = new Integer(3980);
+ public Object testField3981 = new Integer(3981);
+ public Object testField3982 = new Integer(3982);
+ public Object testField3983 = new Integer(3983);
+ public Object testField3984 = new Integer(3984);
+ public Object testField3985 = new Integer(3985);
+ public Object testField3986 = new Integer(3986);
+ public Object testField3987 = new Integer(3987);
+ public Object testField3988 = new Integer(3988);
+ public Object testField3989 = new Integer(3989);
+ public Object testField3990 = new Integer(3990);
+ public Object testField3991 = new Integer(3991);
+ public Object testField3992 = new Integer(3992);
+ public Object testField3993 = new Integer(3993);
+ public Object testField3994 = new Integer(3994);
+ public Object testField3995 = new Integer(3995);
+ public Object testField3996 = new Integer(3996);
+ public Object testField3997 = new Integer(3997);
+ public Object testField3998 = new Integer(3998);
+ public Object testField3999 = new Integer(3999);
+}
diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java
index f0b327840c..2b30986ab3 100644
--- a/test/623-checker-loop-regressions/src/Main.java
+++ b/test/623-checker-loop-regressions/src/Main.java
@@ -288,6 +288,28 @@ public class Main {
}
}
+ // A strange function that does not inline.
+ private static void $noinline$foo(boolean x, int n) {
+ if (n < 0)
+ throw new Error("oh no");
+ if (n > 100) {
+ $noinline$foo(!x, n - 1);
+ $noinline$foo(!x, n - 2);
+ $noinline$foo(!x, n - 3);
+ $noinline$foo(!x, n - 4);
+ }
+ }
+
+ // A loop with environment uses of x (the terminating condition). As exposed by bug
+ // b/37247891, the loop can be unrolled, but should handle the (unlikely, but clearly
+ // not impossible) environment uses of the terminating condition in a correct manner.
+ private static void envUsesInCond() {
+ boolean x = false;
+ for (int i = 0; !(x = i >= 1); i++) {
+ $noinline$foo(true, i);
+ }
+ }
+
public static void main(String[] args) {
expectEquals(10, earlyExitFirst(-1));
for (int i = 0; i <= 10; i++) {
@@ -369,6 +391,8 @@ public class Main {
expectEquals(aa[i], bb.charAt(i));
}
+ envUsesInCond();
+
System.out.println("passed");
}
diff --git a/test/646-checker-arraycopy-large-cst-pos/expected.txt b/test/646-checker-arraycopy-large-cst-pos/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/646-checker-arraycopy-large-cst-pos/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/646-checker-arraycopy-large-cst-pos/info.txt b/test/646-checker-arraycopy-large-cst-pos/info.txt
new file mode 100644
index 0000000000..9ac21db411
--- /dev/null
+++ b/test/646-checker-arraycopy-large-cst-pos/info.txt
@@ -0,0 +1,4 @@
+Regression test for an issue with a depleted VIXL scratch register
+pool during the emission of a SystemArrayCopy intrinsic with a large
+constant destination position, on ARM64, with read barriers
+(b/37256530).
diff --git a/test/646-checker-arraycopy-large-cst-pos/src/Main.java b/test/646-checker-arraycopy-large-cst-pos/src/Main.java
new file mode 100644
index 0000000000..3144fc18e7
--- /dev/null
+++ b/test/646-checker-arraycopy-large-cst-pos/src/Main.java
@@ -0,0 +1,37 @@
+/*
+ * 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) {
+ System.out.println("passed");
+ }
+
+ /// CHECK-START-ARM64: void Main.test() disassembly (after)
+ /// CHECK: InvokeStaticOrDirect method_name:java.lang.System.arraycopy intrinsic:SystemArrayCopy
+ /// CHECK-NOT: blr
+ /// CHECK: ReturnVoid
+
+ static void test() {
+ Object[] src = new Object[1024];
+ Object[] dst = new Object[2048];
+ // The length of the copied data must not be too large (smaller
+ // than kSystemArrayCopyThreshold = 128) for the call to
+ // System.arraycopy to be intrinsified.
+ System.arraycopy(src, 0, dst, 1024, 64);
+ }
+
+}
diff --git a/test/646-checker-hadd-alt-byte/expected.txt b/test/646-checker-hadd-alt-byte/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/646-checker-hadd-alt-byte/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/646-checker-hadd-alt-byte/info.txt b/test/646-checker-hadd-alt-byte/info.txt
new file mode 100644
index 0000000000..46e73345d8
--- /dev/null
+++ b/test/646-checker-hadd-alt-byte/info.txt
@@ -0,0 +1 @@
+Functional tests on halving-add SIMD vectorization.
diff --git a/test/646-checker-hadd-alt-byte/src/Main.java b/test/646-checker-hadd-alt-byte/src/Main.java
new file mode 100644
index 0000000000..d1b33ea0da
--- /dev/null
+++ b/test/646-checker-hadd-alt-byte/src/Main.java
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+/**
+ * Tests for halving-add idiomatic vectorization.
+ *
+ * Alternative version expressed with logical shift right
+ * in the higher precision (has no impact on idiom).
+ */
+public class Main {
+
+ private static final int N = 256;
+ private static final int M = N * N + 15;
+
+ static byte[] sB1 = new byte[M];
+ static byte[] sB2 = new byte[M];
+ static byte[] sBo = new byte[M];
+
+ /// CHECK-START: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) ((b1[i] + b2[i]) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) (((b1[i] & 0xff) + (b2[i] & 0xff)) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_signed(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) ((b1[i] + b2[i] + 1) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) (((b1[i] & 0xff) + (b2[i] & 0xff) + 1) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I127:i\d+>> IntConstant 127 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<I127>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<I127:i\d+>> IntConstant 127 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed_constant(byte[] b1, byte[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) ((b1[i] + 0x7f) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned_constant(byte[] b1, byte[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) (((b1[i] & 0xff) + 0xff) >>> 1);
+ }
+ }
+
+ public static void main(String[] args) {
+ // Initialize cross-values to test all cases, and also
+ // set up some extra values to exercise the cleanup loop.
+ int k = 0;
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < N; j++) {
+ sB1[k] = (byte) i;
+ sB2[k] = (byte) j;
+ k++;
+ }
+ }
+ for (int i = 0; i < 15; i++) {
+ sB1[k] = (byte) i;
+ sB2[k] = 100;
+ k++;
+ }
+ expectEquals(k, M);
+
+ // Test halving add idioms. Note that the expected result is computed
+ // with the arithmetic >> to demonstrate the computed narrower result
+ // does not depend on the wider >> or >>>.
+ halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) (((sB1[i] & 0xff) + (sB2[i] & 0xff)) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) (((sB1[i] & 0xff) + (sB2[i] & 0xff) + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_signed_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) ((sB1[i] + 0x7f) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) (((sB1[i] & 0xff) + 0xff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/646-checker-hadd-alt-char/expected.txt b/test/646-checker-hadd-alt-char/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/646-checker-hadd-alt-char/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/646-checker-hadd-alt-char/info.txt b/test/646-checker-hadd-alt-char/info.txt
new file mode 100644
index 0000000000..46e73345d8
--- /dev/null
+++ b/test/646-checker-hadd-alt-char/info.txt
@@ -0,0 +1 @@
+Functional tests on halving-add SIMD vectorization.
diff --git a/test/646-checker-hadd-alt-char/src/Main.java b/test/646-checker-hadd-alt-char/src/Main.java
new file mode 100644
index 0000000000..1ea8d3fe07
--- /dev/null
+++ b/test/646-checker-hadd-alt-char/src/Main.java
@@ -0,0 +1,251 @@
+/*
+ * 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.
+ */
+
+/**
+ * Tests for halving-add idiomatic vectorization.
+ *
+ * Alternative version expressed with logical shift right
+ * in the higher precision (has no impact on idiom).
+ */
+public class Main {
+
+ private static final int N = 64 * 1024;
+ private static final int M = N + 31;
+
+ static char[] sB1 = new char[M];
+ static char[] sB2 = new char[M];
+ static char[] sBo = new char[M];
+
+ /// CHECK-START: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) ((b1[i] + b2[i]) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ //
+ // Note: HAnd has no impact (already a zero extension).
+ //
+ private static void halving_add_also_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) (((b1[i] & 0xffff) + (b2[i] & 0xffff)) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) ((b1[i] + b2[i] + 1) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ //
+ // Note: HAnd has no impact (already a zero extension).
+ //
+ private static void rounding_halving_add_also_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) (((b1[i] & 0xffff) + (b2[i] & 0xffff) + 1) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned_constant(char[] b1, char[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) ((b1[i] + 0xffff) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_also_unsigned_constant(char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_also_unsigned_constant(char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ //
+ // Note: HAnd has no impact (already a zero extension).
+ //
+ private static void halving_add_also_unsigned_constant(char[] b1, char[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) (((b1[i] & 0xffff) + 0xffff) >>> 1);
+ }
+ }
+
+ public static void main(String[] args) {
+ // Some interesting values.
+ char[] interesting = {
+ (char) 0x0000,
+ (char) 0x0001,
+ (char) 0x0002,
+ (char) 0x1234,
+ (char) 0x8000,
+ (char) 0x8001,
+ (char) 0x7fff,
+ (char) 0xffff
+ };
+ // Initialize cross-values to test all cases, and also
+ // set up some extra values to exercise the cleanup loop.
+ for (int i = 0; i < M; i++) {
+ sB1[i] = (char) i;
+ sB2[i] = interesting[i & 7];
+ }
+
+ // Test halving add idioms. Note that the expected result is computed
+ // with the arithmetic >> to demonstrate the computed narrower result
+ // does not depend on the wider >> or >>>.
+ halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_also_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_also_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + 0xffff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_also_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + 0xffff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/646-checker-hadd-alt-short/expected.txt b/test/646-checker-hadd-alt-short/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/646-checker-hadd-alt-short/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/646-checker-hadd-alt-short/info.txt b/test/646-checker-hadd-alt-short/info.txt
new file mode 100644
index 0000000000..46e73345d8
--- /dev/null
+++ b/test/646-checker-hadd-alt-short/info.txt
@@ -0,0 +1 @@
+Functional tests on halving-add SIMD vectorization.
diff --git a/test/646-checker-hadd-alt-short/src/Main.java b/test/646-checker-hadd-alt-short/src/Main.java
new file mode 100644
index 0000000000..269e6183b4
--- /dev/null
+++ b/test/646-checker-hadd-alt-short/src/Main.java
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+/**
+ * Tests for halving-add idiomatic vectorization.
+ *
+ * Alternative version expressed with logical shift right
+ * in the higher precision (has no impact on idiom).
+ */
+public class Main {
+
+ private static final int N = 64 * 1024;
+ private static final int M = N + 31;
+
+ static short[] sB1 = new short[M];
+ static short[] sB2 = new short[M];
+ static short[] sBo = new short[M];
+
+ /// CHECK-START: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) ((b1[i] + b2[i]) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) (((b1[i] & 0xffff) + (b2[i] & 0xffff)) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_signed(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) ((b1[i] + b2[i] + 1) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_unsigned(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) (((b1[i] & 0xffff) + (b2[i] & 0xffff) + 1) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<SMAX:i\d+>> IntConstant 32767 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<SMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<SMAX:i\d+>> IntConstant 32767 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed_constant(short[] b1, short[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) ((b1[i] + 0x7fff) >>> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<UShr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned_constant(short[] b1, short[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) (((b1[i] & 0xffff) + 0xffff) >>> 1);
+ }
+ }
+
+ public static void main(String[] args) {
+ // Some interesting values.
+ short[] interesting = {
+ (short) 0x0000,
+ (short) 0x0001,
+ (short) 0x0002,
+ (short) 0x1234,
+ (short) 0x8000,
+ (short) 0x8001,
+ (short) 0x7fff,
+ (short) 0xffff
+ };
+ // Initialize cross-values to test all cases, and also
+ // set up some extra values to exercise the cleanup loop.
+ for (int i = 0; i < M; i++) {
+ sB1[i] = (short) i;
+ sB2[i] = interesting[i & 7];
+ }
+
+ // Test halving add idioms. Note that the expected result is computed
+ // with the arithmetic >> to demonstrate the computed narrower result
+ // does not depend on the wider >> or >>>.
+ halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) (((sB1[i] & 0xffff) + (sB2[i] & 0xffff)) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) (((sB1[i] & 0xffff) + (sB2[i] & 0xffff) + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_signed_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) ((sB1[i] + 0x7fff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) (((sB1[i] & 0xffff) + 0xffff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/646-checker-hadd-byte/expected.txt b/test/646-checker-hadd-byte/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/646-checker-hadd-byte/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/646-checker-hadd-byte/info.txt b/test/646-checker-hadd-byte/info.txt
new file mode 100644
index 0000000000..46e73345d8
--- /dev/null
+++ b/test/646-checker-hadd-byte/info.txt
@@ -0,0 +1 @@
+Functional tests on halving-add SIMD vectorization.
diff --git a/test/646-checker-hadd-byte/src/Main.java b/test/646-checker-hadd-byte/src/Main.java
new file mode 100644
index 0000000000..7e29a7e60b
--- /dev/null
+++ b/test/646-checker-hadd-byte/src/Main.java
@@ -0,0 +1,236 @@
+/*
+ * 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.
+ */
+
+/**
+ * Tests for halving-add idiomatic vectorization.
+ */
+public class Main {
+
+ private static final int N = 256;
+ private static final int M = N * N + 15;
+
+ static byte[] sB1 = new byte[M];
+ static byte[] sB2 = new byte[M];
+ static byte[] sBo = new byte[M];
+
+ /// CHECK-START: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) ((b1[i] + b2[i]) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) (((b1[i] & 0xff) + (b2[i] & 0xff)) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_signed(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) ((b1[i] + b2[i] + 1) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) (((b1[i] & 0xff) + (b2[i] & 0xff) + 1) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I127:i\d+>> IntConstant 127 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<I127>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<I127:i\d+>> IntConstant 127 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed_constant(byte[] b1, byte[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) ((b1[i] + 0x7f) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And>>,<<I255>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (after)
+ /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned_constant(byte[] b1, byte[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (byte) (((b1[i] & 0xff) + 0xff) >> 1);
+ }
+ }
+
+ public static void main(String[] args) {
+ // Initialize cross-values to test all cases, and also
+ // set up some extra values to exercise the cleanup loop.
+ int k = 0;
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < N; j++) {
+ sB1[k] = (byte) i;
+ sB2[k] = (byte) j;
+ k++;
+ }
+ }
+ for (int i = 0; i < 15; i++) {
+ sB1[k] = (byte) i;
+ sB2[k] = 100;
+ k++;
+ }
+ expectEquals(k, M);
+
+ // Test halving add idioms.
+ halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) (((sB1[i] & 0xff) + (sB2[i] & 0xff)) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) (((sB1[i] & 0xff) + (sB2[i] & 0xff) + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_signed_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) ((sB1[i] + 0x7f) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ byte e = (byte) (((sB1[i] & 0xff) + 0xff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/646-checker-hadd-char/expected.txt b/test/646-checker-hadd-char/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/646-checker-hadd-char/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/646-checker-hadd-char/info.txt b/test/646-checker-hadd-char/info.txt
new file mode 100644
index 0000000000..46e73345d8
--- /dev/null
+++ b/test/646-checker-hadd-char/info.txt
@@ -0,0 +1 @@
+Functional tests on halving-add SIMD vectorization.
diff --git a/test/646-checker-hadd-char/src/Main.java b/test/646-checker-hadd-char/src/Main.java
new file mode 100644
index 0000000000..d24608f5af
--- /dev/null
+++ b/test/646-checker-hadd-char/src/Main.java
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+/**
+ * Tests for halving-add idiomatic vectorization.
+ */
+public class Main {
+
+ private static final int N = 64 * 1024;
+ private static final int M = N + 31;
+
+ static char[] sB1 = new char[M];
+ static char[] sB2 = new char[M];
+ static char[] sBo = new char[M];
+
+ /// CHECK-START: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) ((b1[i] + b2[i]) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ //
+ // Note: HAnd has no impact (already a zero extension).
+ //
+ private static void halving_add_also_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) (((b1[i] & 0xffff) + (b2[i] & 0xffff)) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) ((b1[i] + b2[i] + 1) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ //
+ // Note: HAnd has no impact (already a zero extension).
+ //
+ private static void rounding_halving_add_also_unsigned(char[] b1, char[] b2, char[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) (((b1[i] & 0xffff) + (b2[i] & 0xffff) + 1) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned_constant(char[] b1, char[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) ((b1[i] + 0xffff) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_also_unsigned_constant(char[], char[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_also_unsigned_constant(char[], char[]) loop_optimization (after)
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ //
+ // Note: HAnd has no impact (already a zero extension).
+ //
+ private static void halving_add_also_unsigned_constant(char[] b1, char[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (char) (((b1[i] & 0xffff) + 0xffff) >> 1);
+ }
+ }
+
+ public static void main(String[] args) {
+ // Some interesting values.
+ char[] interesting = {
+ (char) 0x0000,
+ (char) 0x0001,
+ (char) 0x0002,
+ (char) 0x1234,
+ (char) 0x8000,
+ (char) 0x8001,
+ (char) 0x7fff,
+ (char) 0xffff
+ };
+ // Initialize cross-values to test all cases, and also
+ // set up some extra values to exercise the cleanup loop.
+ for (int i = 0; i < M; i++) {
+ sB1[i] = (char) i;
+ sB2[i] = interesting[i & 7];
+ }
+
+ // Test halving add idioms.
+ halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_also_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_also_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + 0xffff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_also_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ char e = (char) ((sB1[i] + 0xffff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/646-checker-hadd-short/expected.txt b/test/646-checker-hadd-short/expected.txt
new file mode 100644
index 0000000000..b0aad4deb5
--- /dev/null
+++ b/test/646-checker-hadd-short/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/646-checker-hadd-short/info.txt b/test/646-checker-hadd-short/info.txt
new file mode 100644
index 0000000000..46e73345d8
--- /dev/null
+++ b/test/646-checker-hadd-short/info.txt
@@ -0,0 +1 @@
+Functional tests on halving-add SIMD vectorization.
diff --git a/test/646-checker-hadd-short/src/Main.java b/test/646-checker-hadd-short/src/Main.java
new file mode 100644
index 0000000000..db495f6433
--- /dev/null
+++ b/test/646-checker-hadd-short/src/Main.java
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+/**
+ * Tests for halving-add idiomatic vectorization.
+ */
+public class Main {
+
+ private static final int N = 64 * 1024;
+ private static final int M = N + 31;
+
+ static short[] sB1 = new short[M];
+ static short[] sB2 = new short[M];
+ static short[] sBo = new short[M];
+
+ /// CHECK-START: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) ((b1[i] + b2[i]) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) (((b1[i] & 0xffff) + (b2[i] & 0xffff)) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_signed(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) ((b1[i] + b2[i] + 1) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<And1>>,<<And2>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add2>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void rounding_halving_add_unsigned(short[] b1, short[] b2, short[] bo) {
+ int min_length = Math.min(bo.length, Math.min(b1.length, b2.length));
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) (((b1[i] & 0xffff) + (b2[i] & 0xffff) + 1) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<SMAX:i\d+>> IntConstant 32767 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Get>>,<<SMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<SMAX:i\d+>> IntConstant 32767 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_signed_constant(short[] b1, short[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) ((b1[i] + 0x7fff) >> 1);
+ }
+ }
+
+ /// CHECK-START: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (before)
+ /// CHECK-DAG: <<I1:i\d+>> IntConstant 1 loop:none
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<And:i\d+>> And [<<Get>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<And>>,<<UMAX>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Add>>,<<I1>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Shr>>] loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none
+ //
+ /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (after)
+ /// CHECK-DAG: <<UMAX:i\d+>> IntConstant 65535 loop:none
+ /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none
+ /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none
+ private static void halving_add_unsigned_constant(short[] b1, short[] bo) {
+ int min_length = Math.min(bo.length, b1.length);
+ for (int i = 0; i < min_length; i++) {
+ bo[i] = (short) (((b1[i] & 0xffff) + 0xffff) >> 1);
+ }
+ }
+
+ public static void main(String[] args) {
+ // Some interesting values.
+ short[] interesting = {
+ (short) 0x0000,
+ (short) 0x0001,
+ (short) 0x0002,
+ (short) 0x1234,
+ (short) 0x8000,
+ (short) 0x8001,
+ (short) 0x7fff,
+ (short) 0xffff
+ };
+ // Initialize cross-values to test all cases, and also
+ // set up some extra values to exercise the cleanup loop.
+ for (int i = 0; i < M; i++) {
+ sB1[i] = (short) i;
+ sB2[i] = interesting[i & 7];
+ }
+
+ // Test halving add idioms.
+ halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) ((sB1[i] + sB2[i]) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) (((sB1[i] & 0xffff) + (sB2[i] & 0xffff)) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_signed(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) ((sB1[i] + sB2[i] + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ rounding_halving_add_unsigned(sB1, sB2, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) (((sB1[i] & 0xffff) + (sB2[i] & 0xffff) + 1) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_signed_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) ((sB1[i] + 0x7fff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+ halving_add_unsigned_constant(sB1, sBo);
+ for (int i = 0; i < M; i++) {
+ short e = (short) (((sB1[i] & 0xffff) + 0xffff) >> 1);
+ expectEquals(e, sBo[i]);
+ }
+
+ System.out.println("passed");
+ }
+
+ private static void expectEquals(int expected, int result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+}
diff --git a/test/646-checker-long-const-to-int/expected.txt b/test/646-checker-long-const-to-int/expected.txt
new file mode 100644
index 0000000000..9abd696f97
--- /dev/null
+++ b/test/646-checker-long-const-to-int/expected.txt
@@ -0,0 +1 @@
+305419896
diff --git a/test/646-checker-long-const-to-int/info.txt b/test/646-checker-long-const-to-int/info.txt
new file mode 100644
index 0000000000..3f560c319a
--- /dev/null
+++ b/test/646-checker-long-const-to-int/info.txt
@@ -0,0 +1 @@
+Regression test for bogus checks that a constant input of long-to-int conversion fits into int.
diff --git a/test/646-checker-long-const-to-int/src/Main.java b/test/646-checker-long-const-to-int/src/Main.java
new file mode 100644
index 0000000000..85738dc8c3
--- /dev/null
+++ b/test/646-checker-long-const-to-int/src/Main.java
@@ -0,0 +1,56 @@
+/*
+ * 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) {
+ System.out.println(test());
+ }
+
+ public static long testField = 0;
+ public static long longField0 = 0;
+ public static long longField1 = 0;
+ public static long longField2 = 0;
+ public static long longField3 = 0;
+ public static long longField4 = 0;
+ public static long longField5 = 0;
+ public static long longField6 = 0;
+ public static long longField7 = 0;
+
+ /// CHECK-START-ARM: int Main.test() register (after)
+ /// CHECK: TypeConversion locations:[#-8690466096623102344]->{{.*}}
+ public static int test() {
+ // To avoid constant folding TypeConversion(const), hide the constant in a field.
+ // We do not run constant folding after load-store-elimination.
+ testField = 0x8765432112345678L;
+ long value = testField;
+ // Now, the `value` is in a register because of the store but we need
+ // a constant location to trigger the bug, so load a bunch of other fields.
+ long l0 = longField0;
+ long l1 = longField1;
+ long l2 = longField2;
+ long l3 = longField3;
+ long l4 = longField4;
+ long l5 = longField5;
+ long l6 = longField6;
+ long l7 = longField7;
+ if (l0 != 0 || l1 != 0 || l2 != 0 || l3 != 0 || l4 != 0 || l5 != 0 || l6 != 0 || l7 != 0) {
+ throw new Error();
+ }
+ // Do the conversion from constant location.
+ return (int)value;
+ }
+}
diff --git a/test/902-hello-transformation/src/Main.java b/test/902-hello-transformation/src/Main.java
index ed8a5007c8..af49cb4eaa 100644
--- a/test/902-hello-transformation/src/Main.java
+++ b/test/902-hello-transformation/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,53 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
public class Main {
-
- /**
- * 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 static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test902.run();
}
-
- public static void doTest(Transform t) {
- t.sayHi();
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- t.sayHi();
- }
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
}
diff --git a/test/902-hello-transformation/src/Transform.java b/test/902-hello-transformation/src/Transform.java
deleted file mode 100644
index 8e8af355da..0000000000
--- a/test/902-hello-transformation/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi() {
- // 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:
- // "Goodbye" < "LTransform;" < "hello".
- System.out.println("hello");
- }
-}
diff --git a/test/902-hello-transformation/src/art/Redefinition.java b/test/902-hello-transformation/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/902-hello-transformation/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/902-hello-transformation/src/art/Test902.java b/test/902-hello-transformation/src/art/Test902.java
new file mode 100644
index 0000000000..e95558f7c7
--- /dev/null
+++ b/test/902-hello-transformation/src/art/Test902.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+public class Test902 {
+
+ static class Transform {
+ public void sayHi() {
+ // 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:
+ // "Goodbye" < "LTransform;" < "hello".
+ System.out.println("hello");
+ }
+ }
+
+ /**
+ * base64 encoded class/dex file for
+ * class Transform {
+ * public void sayHi() {
+ * System.out.println("Goodbye");
+ * }
+ * }
+ */
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAIAoABgAOCQAPABAIABEKABIAEwcAFQcAGAEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAAxUZXN0OTAyLmphdmEMAAcA" +
+ "CAcAGQwAGgAbAQAHR29vZGJ5ZQcAHAwAHQAeBwAfAQAVYXJ0L1Rlc3Q5MDIkVHJhbnNmb3JtAQAJ" +
+ "VHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9T" +
+ "eXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFt" +
+ "AQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAC2FydC9UZXN0OTAyACAABQAGAAAA" +
+ "AAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAJQABAAsACAABAAkA" +
+ "AAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAnAAgAKAACAAwAAAACAA0AFwAAAAoA" +
+ "AQAFABQAFgAI");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQCpghS3AAAAAAAAAAAAAAAAAAAAAAAAAAC4AwAAcAAAAHhWNBIAAAAAAAAAAPQCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB0AgAARAEAAEQB" +
+ "AABMAQAAVQEAAG4BAAB9AQAAoQEAAMEBAADYAQAA7AEAAAACAAAUAgAAIgIAAC0CAAAwAgAANAIA" +
+ "AEECAABHAgAATAIAAFUCAABcAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABkAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA5AIAALgCAAAAAAAABjxpbml0PgAHR29vZGJ5ZQAX" +
+ "TGFydC9UZXN0OTAyJFRyYW5zZm9ybTsADUxhcnQvVGVzdDkwMjsAIkxkYWx2aWsvYW5ub3RhdGlv" +
+ "bi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEv" +
+ "aW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAS" +
+ "TGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTAyLmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vz" +
+ "c0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAQAAAAYAAAAlAAcOACcA" +
+ "Bw4BCA8AAAAAAQABAAEAAABsAgAABAAAAHAQAwAAAA4AAwABAAIAAABxAgAACQAAAGIAAAAbAQEA" +
+ "AABuIAIAEAAOAAAAAAABAQCAgAT8BAEBlAUAAAICARMYAQIDAg4ECA8XCwACAAAAyAIAAM4CAADY" +
+ "AgAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAUAAAAcAAAAAIAAAAJAAAAwAAAAAMA" +
+ "AAACAAAA5AAAAAQAAAABAAAA/AAAAAUAAAAEAAAABAEAAAYAAAABAAAAJAEAAAIgAAAUAAAARAEA" +
+ "AAEQAAABAAAAZAIAAAMgAAACAAAAbAIAAAEgAAACAAAAfAIAAAAgAAABAAAAuAIAAAQgAAACAAAA" +
+ "yAIAAAMQAAABAAAA2AIAAAYgAAABAAAA5AIAAAAQAAABAAAA9AIAAA==");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ doTest(new Transform());
+ }
+
+ public static void doTest(Transform t) {
+ t.sayHi();
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ t.sayHi();
+ }
+}
diff --git a/test/904-object-allocation/expected.txt b/test/904-object-allocation/expected.txt
index 371d2b7593..fdec470529 100644
--- a/test/904-object-allocation/expected.txt
+++ b/test/904-object-allocation/expected.txt
@@ -1,8 +1,8 @@
-ObjectAllocated type java.lang.Object/java.lang.Object size 8
-ObjectAllocated type java.lang.Integer/java.lang.Integer size 16
-ObjectAllocated type java.lang.Short/java.lang.Short size 16
+[]
+[ObjectAllocated type java.lang.Object/java.lang.Object size 8, ObjectAllocated type java.lang.Integer/java.lang.Integer size 16, ObjectAllocated type java.lang.Short/java.lang.Short size 16]
Tracking on same thread
-ObjectAllocated type java.lang.Double/java.lang.Double size 16
+[ObjectAllocated type java.lang.Double/java.lang.Double size 16]
Tracking on same thread, not disabling tracking
-ObjectAllocated type java.lang.Double/java.lang.Double size 16
+[ObjectAllocated type java.lang.Double/java.lang.Double size 16]
Tracking on different thread
+[]
diff --git a/test/904-object-allocation/src/art/Test904.java b/test/904-object-allocation/src/art/Test904.java
index 31e0c8c1ae..70a4b9847f 100644
--- a/test/904-object-allocation/src/art/Test904.java
+++ b/test/904-object-allocation/src/art/Test904.java
@@ -17,6 +17,7 @@
package art;
import java.util.ArrayList;
+import java.util.Arrays;
public class Test904 {
public static void run() throws Exception {
@@ -48,6 +49,8 @@ public class Test904 {
// Enable actual logging callback.
setupObjectAllocCallback(true);
+ System.out.println(Arrays.toString(getTrackingEventMessages()));
+
enableAllocationTracking(null, true);
l.add(new Object());
@@ -65,16 +68,19 @@ public class Test904 {
l.add(new Byte((byte)0));
+ System.out.println(Arrays.toString(getTrackingEventMessages()));
System.out.println("Tracking on same thread");
testThread(l, true, true);
l.add(new Byte((byte)0));
+ System.out.println(Arrays.toString(getTrackingEventMessages()));
System.out.println("Tracking on same thread, not disabling tracking");
testThread(l, true, false);
+ System.out.println(Arrays.toString(getTrackingEventMessages()));
System.out.println("Tracking on different thread");
testThread(l, false, true);
@@ -84,6 +90,9 @@ public class Test904 {
// Disable actual logging callback and re-enable tracking, so we can keep the event enabled and
// check that shutdown works correctly.
setupObjectAllocCallback(false);
+
+ System.out.println(Arrays.toString(getTrackingEventMessages()));
+
enableAllocationTracking(null, true);
}
@@ -142,4 +151,5 @@ public class Test904 {
private static native void setupObjectAllocCallback(boolean enable);
private static native void enableAllocationTracking(Thread thread, boolean enable);
+ private static native String[] getTrackingEventMessages();
}
diff --git a/test/904-object-allocation/tracking.cc b/test/904-object-allocation/tracking.cc
index 8de350b06c..20b53281a2 100644
--- a/test/904-object-allocation/tracking.cc
+++ b/test/904-object-allocation/tracking.cc
@@ -15,11 +15,13 @@
*/
#include <iostream>
+#include <mutex>
#include <pthread.h>
#include <stdio.h>
#include <vector>
#include "android-base/logging.h"
+#include "android-base/stringprintf.h"
#include "jni.h"
#include "jvmti.h"
#include "scoped_local_ref.h"
@@ -41,6 +43,9 @@ static std::string GetClassName(JNIEnv* jni_env, jclass cls) {
return utf_chars.c_str();
}
+static std::mutex gEventsMutex;
+static std::vector<std::string> gEvents;
+
static void JNICALL ObjectAllocated(jvmtiEnv* ti_env ATTRIBUTE_UNUSED,
JNIEnv* jni_env,
jthread thread ATTRIBUTE_UNUSED,
@@ -51,10 +56,11 @@ static void JNICALL ObjectAllocated(jvmtiEnv* ti_env ATTRIBUTE_UNUSED,
ScopedLocalRef<jclass> object_klass2(jni_env, jni_env->GetObjectClass(object));
std::string object_klass_descriptor2 = GetClassName(jni_env, object_klass2.get());
- printf("ObjectAllocated type %s/%s size %zu\n",
- object_klass_descriptor.c_str(),
- object_klass_descriptor2.c_str(),
- static_cast<size_t>(size));
+ std::lock_guard<std::mutex> guard(gEventsMutex);
+ gEvents.push_back(android::base::StringPrintf("ObjectAllocated type %s/%s size %zu",
+ object_klass_descriptor.c_str(),
+ object_klass_descriptor2.c_str(),
+ static_cast<size_t>(size)));
}
extern "C" JNIEXPORT void JNICALL Java_art_Test904_setupObjectAllocCallback(
@@ -76,5 +82,18 @@ extern "C" JNIEXPORT void JNICALL Java_art_Test904_enableAllocationTracking(
JvmtiErrorToException(env, jvmti_env, ret);
}
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test904_getTrackingEventMessages(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+ std::lock_guard<std::mutex> guard(gEventsMutex);
+ jobjectArray ret = CreateObjectArray(env,
+ static_cast<jint>(gEvents.size()),
+ "java/lang/String",
+ [&](jint i) {
+ return env->NewStringUTF(gEvents[i].c_str());
+ });
+ gEvents.clear();
+ return ret;
+}
+
} // namespace Test904ObjectAllocation
} // namespace art
diff --git a/test/910-methods/expected.txt b/test/910-methods/expected.txt
index 8e6b6e76d9..c14c6c49e1 100644
--- a/test/910-methods/expected.txt
+++ b/test/910-methods/expected.txt
@@ -32,19 +32,19 @@ Is synthetic: false
interface java.util.List
1025
Max locals: 0
-Argument size: 0
-Location start: 0
-Location end: 0
+Argument size: 2
+Location start: -1
+Location end: -1
Is native: false
Is obsolete: false
Is synthetic: false
[run, ()V, null]
-class $Proxy0
+class $Proxy20
17
Max locals: 0
-Argument size: 0
-Location start: 0
-Location end: 0
+Argument size: 1
+Location start: -1
+Location end: -1
Is native: false
Is obsolete: false
Is synthetic: false
diff --git a/test/910-methods/src/art/Test910.java b/test/910-methods/src/art/Test910.java
index b3490e9518..aa6d13af9a 100644
--- a/test/910-methods/src/art/Test910.java
+++ b/test/910-methods/src/art/Test910.java
@@ -39,17 +39,6 @@ public class Test910 {
testMethod(findSyntheticMethod(), NestedSynthetic.class, false);
}
- private static Class<?> proxyClass = null;
-
- private static Class<?> getProxyClass() throws Exception {
- if (proxyClass != null) {
- return proxyClass;
- }
-
- proxyClass = Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Runnable.class });
- return proxyClass;
- }
-
private static void testMethod(String className, String methodName, Class<?>... types)
throws Exception {
Class<?> base = Class.forName(className);
@@ -145,4 +134,62 @@ public class Test910 {
private static native boolean isMethodNative(Method m);
private static native boolean isMethodObsolete(Method m);
private static native boolean isMethodSynthetic(Method m);
+
+ // We need this machinery for a consistent proxy name. Names of proxy classes include a
+ // unique number (derived by counting). This means that a simple call to getProxyClass
+ // depends on the test environment.
+ //
+ // To work around this, we assume that at most twenty proxies have been created before
+ // the test is run, and canonicalize on "$Proxy20". We add infrastructure to create
+ // as many proxy classes but cycling through subsets of the test-provided interfaces
+ // I0...I4.
+ //
+ //
+ // (This is made under the judgment that we do not want to have proxy-specific behavior
+ // for testMethod.)
+
+ private static Class<?> proxyClass = null;
+
+ private static Class<?> getProxyClass() throws Exception {
+ if (proxyClass != null) {
+ return proxyClass;
+ }
+
+ for (int i = 1; i <= 21; i++) {
+ proxyClass = createProxyClass(i);
+ String name = proxyClass.getName();
+ if (name.equals("$Proxy20")) {
+ return proxyClass;
+ }
+ }
+ return proxyClass;
+ }
+
+ private static Class<?> createProxyClass(int i) throws Exception {
+ int count = Integer.bitCount(i);
+ Class<?>[] input = new Class<?>[count + 1];
+ input[0] = Runnable.class;
+ int inputIndex = 1;
+ int bitIndex = 0;
+ while (i != 0) {
+ if ((i & 1) != 0) {
+ input[inputIndex++] = Class.forName("art.Test910$I" + bitIndex);
+ }
+ i >>>= 1;
+ bitIndex++;
+ }
+ return Proxy.getProxyClass(Test910.class.getClassLoader(), input);
+ }
+
+ // Need this for the proxy naming.
+ public static interface I0 {
+ }
+ public static interface I1 {
+ }
+ public static interface I2 {
+ }
+ public static interface I3 {
+ }
+ public static interface I4 {
+ }
}
diff --git a/test/912-classes/classes.cc b/test/912-classes/classes.cc
index 2636367548..869eacd82c 100644
--- a/test/912-classes/classes.cc
+++ b/test/912-classes/classes.cc
@@ -16,50 +16,39 @@
#include <stdio.h>
+#include <mutex>
+#include <vector>
+
#include "android-base/macros.h"
+#include "android-base/stringprintf.h"
-#include "class_linker.h"
#include "jni.h"
-#include "mirror/class_loader.h"
#include "jvmti.h"
-#include "runtime.h"
-#include "scoped_local_ref.h"
-#include "scoped_utf_chars.h"
-#include "scoped_thread_state_change-inl.h"
-#include "thread-inl.h"
// Test infrastructure
#include "jni_helper.h"
#include "jvmti_helper.h"
+#include "scoped_local_ref.h"
+#include "scoped_utf_chars.h"
#include "test_env.h"
namespace art {
namespace Test912Classes {
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_isModifiableClass(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912_isModifiableClass(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jboolean res = JNI_FALSE;
jvmtiError result = jvmti_env->IsModifiableClass(klass, &res);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running IsModifiableClass: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
- return JNI_FALSE;
- }
+ JvmtiErrorToException(env, jvmti_env, result);
return res;
}
-extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassSignature(
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test912_getClassSignature(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
char* sig;
char* gen;
jvmtiError result = jvmti_env->GetClassSignature(klass, &sig, &gen);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running GetClassSignature: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
+ if (JvmtiErrorToException(env, jvmti_env, result)) {
return nullptr;
}
@@ -83,57 +72,36 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassSignature(
return ret;
}
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterface(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912_isInterface(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jboolean is_interface = JNI_FALSE;
jvmtiError result = jvmti_env->IsInterface(klass, &is_interface);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running IsInterface: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
- return JNI_FALSE;
- }
+ JvmtiErrorToException(env, jvmti_env, result);
return is_interface;
}
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_isArrayClass(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912_isArrayClass(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jboolean is_array_class = JNI_FALSE;
jvmtiError result = jvmti_env->IsArrayClass(klass, &is_array_class);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running IsArrayClass: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
- return JNI_FALSE;
- }
+ JvmtiErrorToException(env, jvmti_env, result);
return is_array_class;
}
-extern "C" JNIEXPORT jint JNICALL Java_Main_getClassModifiers(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+extern "C" JNIEXPORT jint JNICALL Java_art_Test912_getClassModifiers(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jint mod;
jvmtiError result = jvmti_env->GetClassModifiers(klass, &mod);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running GetClassModifiers: %s\n", err);
- return JNI_FALSE;
- }
+ JvmtiErrorToException(env, jvmti_env, result);
return mod;
}
-extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassFields(
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test912_getClassFields(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jint count = 0;
jfieldID* fields = nullptr;
jvmtiError result = jvmti_env->GetClassFields(klass, &count, &fields);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running GetClassFields: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
+ if (JvmtiErrorToException(env, jvmti_env, result)) {
return nullptr;
}
@@ -153,15 +121,12 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassFields(
return ret;
}
-extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassMethods(
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test912_getClassMethods(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jint count = 0;
jmethodID* methods = nullptr;
jvmtiError result = jvmti_env->GetClassMethods(klass, &count, &methods);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running GetClassMethods: %s\n", err);
+ if (JvmtiErrorToException(env, jvmti_env, result)) {
return nullptr;
}
@@ -181,15 +146,12 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassMethods(
return ret;
}
-extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getImplementedInterfaces(
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test912_getImplementedInterfaces(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jint count = 0;
jclass* classes = nullptr;
jvmtiError result = jvmti_env->GetImplementedInterfaces(klass, &count, &classes);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running GetImplementedInterfaces: %s\n", err);
+ if (JvmtiErrorToException(env, jvmti_env, result)) {
return nullptr;
}
@@ -203,35 +165,23 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getImplementedInterfaces(
return ret;
}
-extern "C" JNIEXPORT jint JNICALL Java_Main_getClassStatus(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+extern "C" JNIEXPORT jint JNICALL Java_art_Test912_getClassStatus(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jint status;
jvmtiError result = jvmti_env->GetClassStatus(klass, &status);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running GetClassStatus: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
- return JNI_FALSE;
- }
+ JvmtiErrorToException(env, jvmti_env, result);
return status;
}
-extern "C" JNIEXPORT jobject JNICALL Java_Main_getClassLoader(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+extern "C" JNIEXPORT jobject JNICALL Java_art_Test912_getClassLoader(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jobject classloader;
jvmtiError result = jvmti_env->GetClassLoader(klass, &classloader);
- if (result != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(result, &err);
- printf("Failure running GetClassLoader: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
- return nullptr;
- }
+ JvmtiErrorToException(env, jvmti_env, result);
return classloader;
}
-extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassLoaderClasses(
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test912_getClassLoaderClasses(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jobject jclassloader) {
jint count = 0;
jclass* classes = nullptr;
@@ -250,7 +200,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getClassLoaderClasses(
return ret;
}
-extern "C" JNIEXPORT jintArray JNICALL Java_Main_getClassVersion(
+extern "C" JNIEXPORT jintArray JNICALL Java_art_Test912_getClassVersion(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
jint major, minor;
jvmtiError result = jvmti_env->GetClassVersionNumbers(klass, &minor, &major);
@@ -325,6 +275,22 @@ static void EnableEvents(JNIEnv* env,
JvmtiErrorToException(env, jvmti_env, ret);
}
+static std::mutex gEventsMutex;
+static std::vector<std::string> gEvents;
+
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test912_getClassLoadMessages(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+ std::lock_guard<std::mutex> guard(gEventsMutex);
+ jobjectArray ret = CreateObjectArray(env,
+ static_cast<jint>(gEvents.size()),
+ "java/lang/String",
+ [&](jint i) {
+ return env->NewStringUTF(gEvents[i].c_str());
+ });
+ gEvents.clear();
+ return ret;
+}
+
class ClassLoadPreparePrinter {
public:
static void JNICALL ClassLoadCallback(jvmtiEnv* jenv,
@@ -339,7 +305,14 @@ class ClassLoadPreparePrinter {
if (thread_name == "") {
return;
}
- printf("Load: %s on %s\n", name.c_str(), thread_name.c_str());
+ if (thread_name_filter_ != "" && thread_name_filter_ != thread_name) {
+ return;
+ }
+
+ std::lock_guard<std::mutex> guard(gEventsMutex);
+ gEvents.push_back(android::base::StringPrintf("Load: %s on %s",
+ name.c_str(),
+ thread_name.c_str()));
}
static void JNICALL ClassPrepareCallback(jvmtiEnv* jenv,
@@ -354,14 +327,18 @@ class ClassLoadPreparePrinter {
if (thread_name == "") {
return;
}
- std::string cur_thread_name = GetThreadName(Thread::Current());
- printf("Prepare: %s on %s (cur=%s)\n",
- name.c_str(),
- thread_name.c_str(),
- cur_thread_name.c_str());
+ if (thread_name_filter_ != "" && thread_name_filter_ != thread_name) {
+ return;
+ }
+ std::string cur_thread_name = GetThreadName(jenv, jni_env, nullptr);
+
+ std::lock_guard<std::mutex> guard(gEventsMutex);
+ gEvents.push_back(android::base::StringPrintf("Prepare: %s on %s (cur=%s)",
+ name.c_str(),
+ thread_name.c_str(),
+ cur_thread_name.c_str()));
}
- private:
static std::string GetThreadName(jvmtiEnv* jenv, JNIEnv* jni_env, jthread thread) {
jvmtiThreadInfo info;
jvmtiError result = jenv->GetThreadInfo(thread, &info);
@@ -382,60 +359,28 @@ class ClassLoadPreparePrinter {
return tmp;
}
- static std::string GetThreadName(Thread* thread) {
- std::string tmp;
- thread->GetThreadName(tmp);
- return tmp;
- }
+ static std::string thread_name_filter_;
};
+std::string ClassLoadPreparePrinter::thread_name_filter_;
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test912_enableClassLoadPreparePrintEvents(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jboolean enable, jthread thread) {
+ if (thread != nullptr) {
+ ClassLoadPreparePrinter::thread_name_filter_ =
+ ClassLoadPreparePrinter::GetThreadName(jvmti_env, env, thread);
+ } else {
+ ClassLoadPreparePrinter::thread_name_filter_ = "";
+ }
-extern "C" JNIEXPORT void JNICALL Java_Main_enableClassLoadPreparePrintEvents(
- JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jboolean enable) {
EnableEvents(env,
enable,
ClassLoadPreparePrinter::ClassLoadCallback,
ClassLoadPreparePrinter::ClassPrepareCallback);
}
-struct ClassLoadSeen {
- static void JNICALL ClassLoadSeenCallback(jvmtiEnv* jenv ATTRIBUTE_UNUSED,
- JNIEnv* jni_env ATTRIBUTE_UNUSED,
- jthread thread ATTRIBUTE_UNUSED,
- jclass klass ATTRIBUTE_UNUSED) {
- saw_event = true;
- }
-
- static bool saw_event;
-};
-bool ClassLoadSeen::saw_event = false;
-
-extern "C" JNIEXPORT void JNICALL Java_Main_enableClassLoadSeenEvents(
- JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jboolean b) {
- EnableEvents(env, b, ClassLoadSeen::ClassLoadSeenCallback, nullptr);
-}
-
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_hadLoadEvent(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED) {
- return ClassLoadSeen::saw_event ? JNI_TRUE : JNI_FALSE;
-}
-
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_isLoadedClass(
- JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jstring class_name) {
- ScopedUtfChars name(env, class_name);
- ScopedObjectAccess soa(Thread::Current());
- Runtime* current = Runtime::Current();
- ClassLinker* class_linker = current->GetClassLinker();
- bool found =
- class_linker->LookupClass(
- soa.Self(),
- name.c_str(),
- soa.Decode<mirror::ClassLoader>(current->GetSystemClassLoader())) != nullptr;
- return found ? JNI_TRUE : JNI_FALSE;
-}
-
class ClassLoadPrepareEquality {
public:
- static constexpr const char* kClassName = "LMain$ClassE;";
+ static constexpr const char* kClassName = "Lart/Test912$ClassE;";
static constexpr const char* kStorageFieldName = "STATIC";
static constexpr const char* kStorageFieldSig = "Ljava/lang/Object;";
static constexpr const char* kStorageWeakFieldName = "WEAK";
@@ -553,13 +498,13 @@ jobject ClassLoadPrepareEquality::local_stored_class_ = nullptr;
bool ClassLoadPrepareEquality::found_ = false;
bool ClassLoadPrepareEquality::compared_ = false;
-extern "C" JNIEXPORT void JNICALL Java_Main_setEqualityEventStorageClass(
+extern "C" JNIEXPORT void JNICALL Java_art_Test912_setEqualityEventStorageClass(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
ClassLoadPrepareEquality::storage_class_ =
reinterpret_cast<jclass>(env->NewGlobalRef(klass));
}
-extern "C" JNIEXPORT void JNICALL Java_Main_enableClassLoadPrepareEqualityEvents(
+extern "C" JNIEXPORT void JNICALL Java_art_Test912_enableClassLoadPrepareEqualityEvents(
JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jboolean b) {
EnableEvents(env,
b,
diff --git a/test/912-classes/classes_art.cc b/test/912-classes/classes_art.cc
new file mode 100644
index 0000000000..de2e456a53
--- /dev/null
+++ b/test/912-classes/classes_art.cc
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include <stdio.h>
+
+#include <mutex>
+#include <vector>
+
+#include "android-base/macros.h"
+#include "android-base/stringprintf.h"
+
+#include "jni.h"
+#include "jvmti.h"
+
+// Test infrastructure
+#include "jni_helper.h"
+#include "jvmti_helper.h"
+#include "scoped_local_ref.h"
+#include "scoped_utf_chars.h"
+#include "test_env.h"
+
+namespace art {
+namespace Test912ArtClasses {
+
+static void EnableEvents(JNIEnv* env,
+ jboolean enable,
+ decltype(jvmtiEventCallbacks().ClassLoad) class_load,
+ decltype(jvmtiEventCallbacks().ClassPrepare) class_prepare) {
+ if (enable == JNI_FALSE) {
+ jvmtiError ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_CLASS_LOAD,
+ nullptr);
+ if (JvmtiErrorToException(env, jvmti_env, ret)) {
+ return;
+ }
+ ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
+ JVMTI_EVENT_CLASS_PREPARE,
+ nullptr);
+ JvmtiErrorToException(env, jvmti_env, ret);
+ return;
+ }
+
+ jvmtiEventCallbacks callbacks;
+ memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
+ callbacks.ClassLoad = class_load;
+ callbacks.ClassPrepare = class_prepare;
+ jvmtiError ret = jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
+ if (JvmtiErrorToException(env, jvmti_env, ret)) {
+ return;
+ }
+
+ ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
+ JVMTI_EVENT_CLASS_LOAD,
+ nullptr);
+ if (JvmtiErrorToException(env, jvmti_env, ret)) {
+ return;
+ }
+ ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
+ JVMTI_EVENT_CLASS_PREPARE,
+ nullptr);
+ JvmtiErrorToException(env, jvmti_env, ret);
+}
+
+struct ClassLoadSeen {
+ static void JNICALL ClassLoadSeenCallback(jvmtiEnv* jenv ATTRIBUTE_UNUSED,
+ JNIEnv* jni_env ATTRIBUTE_UNUSED,
+ jthread thread ATTRIBUTE_UNUSED,
+ jclass klass ATTRIBUTE_UNUSED) {
+ saw_event = true;
+ }
+
+ static bool saw_event;
+};
+bool ClassLoadSeen::saw_event = false;
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test912Art_enableClassLoadSeenEvents(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jboolean b) {
+ EnableEvents(env, b, ClassLoadSeen::ClassLoadSeenCallback, nullptr);
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_hadLoadEvent(
+ JNIEnv* env ATTRIBUTE_UNUSED, jclass Main_klass ATTRIBUTE_UNUSED) {
+ return ClassLoadSeen::saw_event ? JNI_TRUE : JNI_FALSE;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_isLoadedClass(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jstring class_name) {
+ ScopedUtfChars name(env, class_name);
+
+ jint class_count;
+ jclass* classes;
+ jvmtiError res = jvmti_env->GetLoadedClasses(&class_count, &classes);
+ if (JvmtiErrorToException(env, jvmti_env, res)) {
+ return JNI_FALSE;
+ }
+
+ bool found = false;
+ for (jint i = 0; !found && i < class_count; ++i) {
+ char* sig;
+ jvmtiError res2 = jvmti_env->GetClassSignature(classes[i], &sig, nullptr);
+ if (JvmtiErrorToException(env, jvmti_env, res2)) {
+ return JNI_FALSE;
+ }
+
+ found = strcmp(name.c_str(), sig) == 0;
+
+ CheckJvmtiError(jvmti_env, jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(sig)));
+ }
+
+ CheckJvmtiError(jvmti_env, jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(classes)));
+
+ return found;
+}
+
+// We use the implementations from runtime_state.cc.
+
+extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env,
+ jclass,
+ jclass cls,
+ jstring method_name);
+extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasJit(JNIEnv*, jclass);
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test912Art_ensureJitCompiled(
+ JNIEnv* env, jclass klass, jclass test_class, jstring name) {
+ Java_Main_ensureJitCompiled(env, klass, test_class, name);
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_art_Test912Art_hasJit(JNIEnv* env, jclass klass) {
+ return Java_Main_hasJit(env, klass);
+}
+
+} // namespace Test912ArtClasses
+} // namespace art
diff --git a/test/912-classes/expected.txt b/test/912-classes/expected.txt
index 0f2920a0c2..9dcc5f9c90 100644
--- a/test/912-classes/expected.txt
+++ b/test/912-classes/expected.txt
@@ -6,14 +6,14 @@
11
[Ljava/util/List;, <E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;]
601
-[L$Proxy0;, null]
+[L$Proxy20;, null]
11
[I, null]
411
[[D, null]
411
int interface=false array=false modifiable=false
-$Proxy0 interface=false array=false modifiable=false
+$Proxy20 interface=false array=false modifiable=false
java.lang.Runnable interface=true array=false modifiable=false
java.lang.String interface=false array=false modifiable=false
java.util.ArrayList interface=false array=false modifiable=true
@@ -29,70 +29,65 @@ java.util.ArrayList interface=false array=false modifiable=true
int 100000
class [Ljava.lang.String; 10000
class java.lang.Object 111
-class Main$TestForNonInit 11
-class Main$TestForInitFail 1011
+class art.Test912$TestForNonInit 11
+class art.Test912$TestForInitFail 1011
int []
class [Ljava.lang.String; []
class java.lang.Object []
-interface Main$InfA []
-interface Main$InfB [interface Main$InfA]
-interface Main$InfC [interface Main$InfB]
-class Main$ClassA [interface Main$InfA]
-class Main$ClassB [interface Main$InfB]
-class Main$ClassC [interface Main$InfA, interface Main$InfC]
+interface art.Test912$InfA []
+interface art.Test912$InfB [interface art.Test912$InfA]
+interface art.Test912$InfC [interface art.Test912$InfB]
+class art.Test912$ClassA [interface art.Test912$InfA]
+class art.Test912$ClassB [interface art.Test912$InfB]
+class art.Test912$ClassC [interface art.Test912$InfA, interface art.Test912$InfC]
class java.lang.String null
class [Ljava.lang.String; null
-interface Main$InfA dalvik.system.PathClassLoader
-class $Proxy0 dalvik.system.PathClassLoader
+interface art.Test912$InfA dalvik.system.PathClassLoader
+class $Proxy20 dalvik.system.PathClassLoader
-boot <- src <- src-ex (A,B)
-912-classes-ex.jar+ -> 912-classes.jar+ ->
+boot <- (B) <- (A,C)
[class A, class B, class java.lang.Object]
-912-classes.jar+ ->
[class B, class java.lang.Object]
-boot <- src (B) <- src-ex (A, List)
-912-classes-ex.jar+ -> 912-classes.jar+ ->
+boot <- (B) <- (A, List)
[class A, class java.lang.Object, interface java.util.List]
-912-classes.jar+ ->
[class B, class java.lang.Object]
-boot <- src+src-ex (A,B)
-912-classes.jar+ ->
+boot <- 1+2 (A,B)
[class A, class B, class java.lang.Object]
[37, 0]
B, false
-Load: LB; on main
-Prepare: LB; on main (cur=main)
+Load: LB; on ClassEvents
+Prepare: LB; on ClassEvents (cur=ClassEvents)
B, true
-Load: LB; on main
-Prepare: LB; on main (cur=main)
+Load: LB; on ClassEvents
+Prepare: LB; on ClassEvents (cur=ClassEvents)
C, false
-Load: LA; on main
-Prepare: LA; on main (cur=main)
-Load: LC; on main
-Prepare: LC; on main (cur=main)
+Load: LA; on ClassEvents
+Prepare: LA; on ClassEvents (cur=ClassEvents)
+Load: LC; on ClassEvents
+Prepare: LC; on ClassEvents (cur=ClassEvents)
A, false
C, true
-Load: LA; on main
-Prepare: LA; on main (cur=main)
-Load: LC; on main
-Prepare: LC; on main (cur=main)
+Load: LA; on ClassEvents
+Prepare: LA; on ClassEvents (cur=ClassEvents)
+Load: LC; on ClassEvents
+Prepare: LC; on ClassEvents (cur=ClassEvents)
A, true
A, true
-Load: LA; on main
-Prepare: LA; on main (cur=main)
+Load: LA; on ClassEvents
+Prepare: LA; on ClassEvents (cur=ClassEvents)
C, true
-Load: LC; on main
-Prepare: LC; on main (cur=main)
+Load: LC; on ClassEvents
+Prepare: LC; on ClassEvents (cur=ClassEvents)
C, true
Load: LA; on TestRunner
Prepare: LA; on TestRunner (cur=TestRunner)
Load: LC; on TestRunner
Prepare: LC; on TestRunner (cur=TestRunner)
-Load: L$Proxy1; on main
-Prepare: L$Proxy1; on main (cur=main)
-Load: [LMain; on main
-Prepare: [LMain; on main (cur=main)
+Load: L$Proxy21; on ClassEvents
+Prepare: L$Proxy21; on ClassEvents (cur=ClassEvents)
+Load: [Lart/Test912; on ClassEvents
+Prepare: [Lart/Test912; on ClassEvents (cur=ClassEvents)
diff --git a/test/912-classes/src/B.java b/test/912-classes/src/B.java
deleted file mode 100644
index 52ce4dd58e..0000000000
--- a/test/912-classes/src/B.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * 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 B {
-}
diff --git a/test/912-classes/src/Main.java b/test/912-classes/src/Main.java
index 6c8858ab65..395cf6fb98 100644
--- a/test/912-classes/src/Main.java
+++ b/test/912-classes/src/Main.java
@@ -14,452 +14,9 @@
* limitations under the License.
*/
-import java.lang.ref.Reference;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-
public class Main {
public static void main(String[] args) throws Exception {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest();
- }
-
- public static void doTest() throws Exception {
- testClass("java.lang.Object");
- testClass("java.lang.String");
- testClass("java.lang.Math");
- testClass("java.util.List");
-
- testClass(getProxyClass());
-
- testClass(int.class);
- testClass(double[].class);
-
- testClassType(int.class);
- testClassType(getProxyClass());
- testClassType(Runnable.class);
- testClassType(String.class);
- testClassType(ArrayList.class);
-
- testClassType(int[].class);
- testClassType(Runnable[].class);
- testClassType(String[].class);
-
- testClassFields(Integer.class);
- testClassFields(int.class);
- testClassFields(String[].class);
-
- testClassMethods(Integer.class);
- testClassMethods(int.class);
- testClassMethods(String[].class);
-
- testClassStatus(int.class);
- testClassStatus(String[].class);
- testClassStatus(Object.class);
- testClassStatus(TestForNonInit.class);
- try {
- System.out.println(TestForInitFail.dummy);
- } catch (ExceptionInInitializerError e) {
- }
- testClassStatus(TestForInitFail.class);
-
- testInterfaces(int.class);
- testInterfaces(String[].class);
- testInterfaces(Object.class);
- testInterfaces(InfA.class);
- testInterfaces(InfB.class);
- testInterfaces(InfC.class);
- testInterfaces(ClassA.class);
- testInterfaces(ClassB.class);
- testInterfaces(ClassC.class);
-
- testClassLoader(String.class);
- testClassLoader(String[].class);
- testClassLoader(InfA.class);
- testClassLoader(getProxyClass());
-
- testClassLoaderClasses();
-
- System.out.println();
-
- testClassVersion();
-
- System.out.println();
-
- testClassEvents();
- }
-
- private static Class<?> proxyClass = null;
-
- private static Class<?> getProxyClass() throws Exception {
- if (proxyClass != null) {
- return proxyClass;
- }
-
- proxyClass = Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Runnable.class });
- return proxyClass;
- }
-
- private static void testClass(String className) throws Exception {
- Class<?> base = Class.forName(className);
- testClass(base);
- }
-
- private static void testClass(Class<?> base) throws Exception {
- String[] result = getClassSignature(base);
- System.out.println(Arrays.toString(result));
- int mod = getClassModifiers(base);
- if (mod != base.getModifiers()) {
- throw new RuntimeException("Unexpected modifiers: " + base.getModifiers() + " vs " + mod);
- }
- System.out.println(Integer.toHexString(mod));
- }
-
- private static void testClassType(Class<?> c) throws Exception {
- boolean isInterface = isInterface(c);
- boolean isArray = isArrayClass(c);
- boolean isModifiable = isModifiableClass(c);
- System.out.println(c.getName() + " interface=" + isInterface + " array=" + isArray +
- " modifiable=" + isModifiable);
- }
-
- private static void testClassFields(Class<?> c) throws Exception {
- System.out.println(Arrays.toString(getClassFields(c)));
- }
-
- private static void testClassMethods(Class<?> c) throws Exception {
- System.out.println(Arrays.toString(getClassMethods(c)));
- }
-
- private static void testClassStatus(Class<?> c) {
- System.out.println(c + " " + Integer.toBinaryString(getClassStatus(c)));
- }
-
- private static void testInterfaces(Class<?> c) {
- System.out.println(c + " " + Arrays.toString(getImplementedInterfaces(c)));
- }
-
- private static boolean IsBootClassLoader(ClassLoader l) {
- // Hacky check for Android's fake boot classloader.
- return l.getClass().getName().equals("java.lang.BootClassLoader");
- }
-
- private static void testClassLoader(Class<?> c) {
- Object cl = getClassLoader(c);
- System.out.println(c + " " + (cl != null ? cl.getClass().getName() : "null"));
- if (cl == null) {
- if (c.getClassLoader() != null && !IsBootClassLoader(c.getClassLoader())) {
- throw new RuntimeException("Expected " + c.getClassLoader() + ", but got null.");
- }
- } else {
- if (!(cl instanceof ClassLoader)) {
- throw new RuntimeException("Unexpected \"classloader\": " + cl + " (" + cl.getClass() +
- ")");
- }
- if (cl != c.getClassLoader()) {
- throw new RuntimeException("Unexpected classloader: " + c.getClassLoader() + " vs " + cl);
- }
- }
- }
-
- private static void testClassLoaderClasses() throws Exception {
- ClassLoader boot = ClassLoader.getSystemClassLoader().getParent();
- while (boot.getParent() != null) {
- boot = boot.getParent();
- }
-
- System.out.println();
- System.out.println("boot <- src <- src-ex (A,B)");
- ClassLoader cl1 = create(create(boot, DEX1), DEX2);
- Class.forName("B", false, cl1);
- Class.forName("A", false, cl1);
- printClassLoaderClasses(cl1);
-
- System.out.println();
- System.out.println("boot <- src (B) <- src-ex (A, List)");
- ClassLoader cl2 = create(create(boot, DEX1), DEX2);
- Class.forName("A", false, cl2);
- Class.forName("java.util.List", false, cl2);
- Class.forName("B", false, cl2.getParent());
- printClassLoaderClasses(cl2);
-
- System.out.println();
- System.out.println("boot <- src+src-ex (A,B)");
- ClassLoader cl3 = create(boot, DEX1, DEX2);
- Class.forName("B", false, cl3);
- Class.forName("A", false, cl3);
- printClassLoaderClasses(cl3);
-
- // Check that the boot classloader dumps something non-empty.
- Class<?>[] bootClasses = getClassLoaderClasses(boot);
- if (bootClasses.length == 0) {
- throw new RuntimeException("No classes initiated by boot classloader.");
- }
- // Check that at least java.util.List is loaded.
- boolean foundList = false;
- for (Class<?> c : bootClasses) {
- if (c == java.util.List.class) {
- foundList = true;
- break;
- }
- }
- if (!foundList) {
- System.out.println(Arrays.toString(bootClasses));
- throw new RuntimeException("Could not find class java.util.List.");
- }
- }
-
- private static void testClassVersion() {
- System.out.println(Arrays.toString(getClassVersion(Main.class)));
- }
-
- private static void testClassEvents() throws Exception {
- ClassLoader cl = Main.class.getClassLoader();
- while (cl.getParent() != null) {
- cl = cl.getParent();
- }
- final ClassLoader boot = cl;
-
- // The JIT may deeply inline and load some classes. Preload these for test determinism.
- final String PRELOAD_FOR_JIT[] = {
- "java.nio.charset.CoderMalfunctionError",
- "java.util.NoSuchElementException"
- };
- for (String s : PRELOAD_FOR_JIT) {
- Class.forName(s);
- }
-
- Runnable r = new Runnable() {
- @Override
- public void run() {
- try {
- ClassLoader cl6 = create(boot, DEX1, DEX2);
- System.out.println("C, true");
- Class.forName("C", true, cl6);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- };
-
- Thread dummyThread = new Thread();
- dummyThread.start();
- dummyThread.join();
-
- ensureJitCompiled(Main.class, "testClassEvents");
-
- enableClassLoadPreparePrintEvents(true);
-
- ClassLoader cl1 = create(boot, DEX1, DEX2);
- System.out.println("B, false");
- Class.forName("B", false, cl1);
-
- ClassLoader cl2 = create(boot, DEX1, DEX2);
- System.out.println("B, true");
- Class.forName("B", true, cl2);
-
- ClassLoader cl3 = create(boot, DEX1, DEX2);
- System.out.println("C, false");
- Class.forName("C", false, cl3);
- System.out.println("A, false");
- Class.forName("A", false, cl3);
-
- ClassLoader cl4 = create(boot, DEX1, DEX2);
- System.out.println("C, true");
- Class.forName("C", true, cl4);
- System.out.println("A, true");
- Class.forName("A", true, cl4);
-
- ClassLoader cl5 = create(boot, DEX1, DEX2);
- System.out.println("A, true");
- Class.forName("A", true, cl5);
- System.out.println("C, true");
- Class.forName("C", true, cl5);
-
- Thread t = new Thread(r, "TestRunner");
- t.start();
- t.join();
-
- // Check creation of arrays and proxies.
- Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Comparable.class });
- Class.forName("[LMain;");
-
- enableClassLoadPreparePrintEvents(false);
-
- // Note: the JIT part of this test is about the JIT pulling in a class not yet touched by
- // anything else in the system. This could be the verifier or the interpreter. We
- // block the interpreter by calling ensureJitCompiled. The verifier, however, must
- // run in configurations where dex2oat didn't verify the class itself. So explicitly
- // check whether the class has been already loaded, and skip then.
- // TODO: Add multiple configurations to the run script once that becomes easier to do.
- if (hasJit() && !isLoadedClass("Main$ClassD")) {
- testClassEventsJit();
- }
-
- testClassLoadPrepareEquality();
- }
-
- private static void testClassEventsJit() throws Exception {
- enableClassLoadSeenEvents(true);
-
- testClassEventsJitImpl();
-
- enableClassLoadSeenEvents(false);
-
- if (!hadLoadEvent()) {
- throw new RuntimeException("Did not get expected load event.");
- }
- }
-
- private static void testClassEventsJitImpl() throws Exception {
- ensureJitCompiled(Main.class, "testClassEventsJitImpl");
-
- if (ClassD.x != 1) {
- throw new RuntimeException("Unexpected value");
- }
- }
-
- private static void testClassLoadPrepareEquality() throws Exception {
- setEqualityEventStorageClass(ClassF.class);
-
- enableClassLoadPrepareEqualityEvents(true);
-
- Class.forName("Main$ClassE");
-
- enableClassLoadPrepareEqualityEvents(false);
- }
-
- private static void printClassLoaderClasses(ClassLoader cl) {
- for (;;) {
- if (cl == null || !cl.getClass().getName().startsWith("dalvik.system")) {
- break;
- }
-
- ClassLoader saved = cl;
- for (;;) {
- if (cl == null || !cl.getClass().getName().startsWith("dalvik.system")) {
- break;
- }
- String s = cl.toString();
- int index1 = s.indexOf("zip file");
- int index2 = s.indexOf(']', index1);
- if (index2 < 0) {
- throw new RuntimeException("Unexpected classloader " + s);
- }
- String zip_file = s.substring(index1, index2);
- int index3 = zip_file.indexOf('"');
- int index4 = zip_file.indexOf('"', index3 + 1);
- if (index4 < 0) {
- throw new RuntimeException("Unexpected classloader " + s);
- }
- String paths = zip_file.substring(index3 + 1, index4);
- String pathArray[] = paths.split(":");
- for (String path : pathArray) {
- int index5 = path.lastIndexOf('/');
- System.out.print(path.substring(index5 + 1));
- System.out.print('+');
- }
- System.out.print(" -> ");
- cl = cl.getParent();
- }
- System.out.println();
- Class<?> classes[] = getClassLoaderClasses(saved);
- Arrays.sort(classes, new ClassNameComparator());
- System.out.println(Arrays.toString(classes));
-
- cl = saved.getParent();
- }
- }
-
- private static native boolean isModifiableClass(Class<?> c);
- private static native String[] getClassSignature(Class<?> c);
-
- private static native boolean isInterface(Class<?> c);
- private static native boolean isArrayClass(Class<?> c);
-
- private static native int getClassModifiers(Class<?> c);
-
- private static native Object[] getClassFields(Class<?> c);
- private static native Object[] getClassMethods(Class<?> c);
- private static native Class<?>[] getImplementedInterfaces(Class<?> c);
-
- private static native int getClassStatus(Class<?> c);
-
- private static native Object getClassLoader(Class<?> c);
-
- private static native Class<?>[] getClassLoaderClasses(ClassLoader cl);
-
- private static native int[] getClassVersion(Class<?> c);
-
- private static native void enableClassLoadPreparePrintEvents(boolean b);
-
- private static native void ensureJitCompiled(Class<?> c, String name);
-
- private static native boolean hasJit();
- private static native boolean isLoadedClass(String name);
- private static native void enableClassLoadSeenEvents(boolean b);
- private static native boolean hadLoadEvent();
-
- private static native void setEqualityEventStorageClass(Class<?> c);
- private static native void enableClassLoadPrepareEqualityEvents(boolean b);
-
- private static class TestForNonInit {
- public static double dummy = Math.random(); // So it can't be compile-time initialized.
- }
-
- private static class TestForInitFail {
- public static int dummy = ((int)Math.random())/0; // So it throws when initializing.
- }
-
- public static interface InfA {
- }
- public static interface InfB extends InfA {
- }
- public static interface InfC extends InfB {
- }
-
- public abstract static class ClassA implements InfA {
- }
- public abstract static class ClassB extends ClassA implements InfB {
- }
- public abstract static class ClassC implements InfA, InfC {
- }
-
- public static class ClassD {
- static int x = 1;
- }
-
- public static class ClassE {
- public void foo() {
- }
- public void bar() {
- }
- }
-
- public static class ClassF {
- public static Object STATIC = null;
- public static Reference<Object> WEAK = null;
- }
-
- private static final String DEX1 = System.getenv("DEX_LOCATION") + "/912-classes.jar";
- private static final String DEX2 = System.getenv("DEX_LOCATION") + "/912-classes-ex.jar";
-
- private static ClassLoader create(ClassLoader parent, String... elements) throws Exception {
- // Note: We use a PathClassLoader, as we do not care about code performance. We only load
- // the classes, and they're empty.
- Class<?> pathClassLoaderClass = Class.forName("dalvik.system.PathClassLoader");
- Constructor<?> pathClassLoaderInit = pathClassLoaderClass.getConstructor(String.class,
- ClassLoader.class);
- String path = String.join(":", elements);
- return (ClassLoader) pathClassLoaderInit.newInstance(path, parent);
- }
-
- private static class ClassNameComparator implements Comparator<Class<?>> {
- public int compare(Class<?> c1, Class<?> c2) {
- return c1.getName().compareTo(c2.getName());
- }
+ art.Test912.run();
+ art.Test912Art.run();
}
}
diff --git a/test/912-classes/src/art/DexData.java b/test/912-classes/src/art/DexData.java
new file mode 100644
index 0000000000..7d150322ca
--- /dev/null
+++ b/test/912-classes/src/art/DexData.java
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.nio.ByteBuffer;
+import java.util.Base64;
+
+import dalvik.system.InMemoryDexClassLoader;
+
+public class DexData {
+ public static ClassLoader getBootClassLoader() {
+ ClassLoader cl = DexData.class.getClassLoader();
+ while (cl.getParent() != null) {
+ cl = cl.getParent();
+ }
+ return cl;
+ }
+
+ public static ClassLoader create1() {
+ return create1(getBootClassLoader());
+ }
+ public static ClassLoader create1(ClassLoader parent) {
+ return create(parent, DEX_DATA_B);
+ }
+
+ public static ClassLoader create2() {
+ return create2(getBootClassLoader());
+ }
+ public static ClassLoader create2(ClassLoader parent) {
+ return create(parent, DEX_DATA_AC);
+ }
+
+ public static ClassLoader create12() {
+ return create12(getBootClassLoader());
+ }
+ public static ClassLoader create12(ClassLoader parent) {
+ return create(parent, DEX_DATA_AC, DEX_DATA_B);
+ }
+
+ private static ClassLoader create(ClassLoader parent, String... stringData) {
+ ByteBuffer byteBuffers[] = new ByteBuffer[stringData.length];
+ for (int i = 0; i < stringData.length; i++) {
+ byteBuffers[i] = ByteBuffer.wrap(Base64.getDecoder().decode(stringData[i]));
+ }
+ return new InMemoryDexClassLoader(byteBuffers, parent);
+ }
+
+ /*
+ * Derived from:
+ *
+ * public class A {
+ * }
+ *
+ * public class C extends A {
+ * }
+ *
+ */
+ private final static String DEX_DATA_AC =
+ "ZGV4CjAzNQD5KyH7WmGuqVEyL+2aKG1nyb27UJaCjFwQAgAAcAAAAHhWNBIAAAAAAAAAAIgBAAAH" +
+ "AAAAcAAAAAQAAACMAAAAAQAAAJwAAAAAAAAAAAAAAAMAAACoAAAAAgAAAMAAAAAQAQAAAAEAADAB" +
+ "AAA4AQAAQAEAAEgBAABNAQAAUgEAAGYBAAADAAAABAAAAAUAAAAGAAAABgAAAAMAAAAAAAAAAAAA" +
+ "AAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAEAAAAAAAAAcwEAAAAAAAABAAAA" +
+ "AQAAAAAAAAAAAAAAAgAAAAAAAAB9AQAAAAAAAAEAAQABAAAAaQEAAAQAAABwEAIAAAAOAAEAAQAB" +
+ "AAAAbgEAAAQAAABwEAAAAAAOAAY8aW5pdD4ABkEuamF2YQAGQy5qYXZhAANMQTsAA0xDOwASTGph" +
+ "dmEvbGFuZy9PYmplY3Q7AAFWABEABw4AEQAHDgAAAAEAAIGABIACAAABAAGBgASYAgALAAAAAAAA" +
+ "AAEAAAAAAAAAAQAAAAcAAABwAAAAAgAAAAQAAACMAAAAAwAAAAEAAACcAAAABQAAAAMAAACoAAAA" +
+ "BgAAAAIAAADAAAAAASAAAAIAAAAAAQAAAiAAAAcAAAAwAQAAAyAAAAIAAABpAQAAACAAAAIAAABz" +
+ "AQAAABAAAAEAAACIAQAA";
+
+ /*
+ * Derived from:
+ *
+ * public class B {
+ * }
+ *
+ */
+ private final static String DEX_DATA_B =
+ "ZGV4CjAzNQBgKV6iWFG4aOm5WEy8oGtDZjqsftBgwJ2oAQAAcAAAAHhWNBIAAAAAAAAAACABAAAF" +
+ "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADcAAAAzAAAAOQA" +
+ "AADsAAAA9AAAAPkAAAANAQAAAgAAAAMAAAAEAAAABAAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAA" +
+ "AAAAAAABAAAAAQAAAAAAAAABAAAAAAAAABUBAAAAAAAAAQABAAEAAAAQAQAABAAAAHAQAQAAAA4A" +
+ "Bjxpbml0PgAGQi5qYXZhAANMQjsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgARAAcOAAAAAQAAgYAE" +
+ "zAEACwAAAAAAAAABAAAAAAAAAAEAAAAFAAAAcAAAAAIAAAADAAAAhAAAAAMAAAABAAAAkAAAAAUA" +
+ "AAACAAAAnAAAAAYAAAABAAAArAAAAAEgAAABAAAAzAAAAAIgAAAFAAAA5AAAAAMgAAABAAAAEAEA" +
+ "AAAgAAABAAAAFQEAAAAQAAABAAAAIAEAAA==";
+}
diff --git a/test/912-classes/src/art/Test912.java b/test/912-classes/src/art/Test912.java
new file mode 100644
index 0000000000..f3ff2b0668
--- /dev/null
+++ b/test/912-classes/src/art/Test912.java
@@ -0,0 +1,454 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.lang.ref.Reference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+public class Test912 {
+ public static void run() throws Exception {
+ art.Main.bindAgentJNIForClass(Test912.class);
+ doTest();
+ }
+
+ public static void doTest() throws Exception {
+ testClass("java.lang.Object");
+ testClass("java.lang.String");
+ testClass("java.lang.Math");
+ testClass("java.util.List");
+
+ testClass(getProxyClass());
+
+ testClass(int.class);
+ testClass(double[].class);
+
+ testClassType(int.class);
+ testClassType(getProxyClass());
+ testClassType(Runnable.class);
+ testClassType(String.class);
+ testClassType(ArrayList.class);
+
+ testClassType(int[].class);
+ testClassType(Runnable[].class);
+ testClassType(String[].class);
+
+ testClassFields(Integer.class);
+ testClassFields(int.class);
+ testClassFields(String[].class);
+
+ testClassMethods(Integer.class);
+ testClassMethods(int.class);
+ testClassMethods(String[].class);
+
+ testClassStatus(int.class);
+ testClassStatus(String[].class);
+ testClassStatus(Object.class);
+ testClassStatus(TestForNonInit.class);
+ try {
+ System.out.println(TestForInitFail.dummy);
+ } catch (ExceptionInInitializerError e) {
+ }
+ testClassStatus(TestForInitFail.class);
+
+ testInterfaces(int.class);
+ testInterfaces(String[].class);
+ testInterfaces(Object.class);
+ testInterfaces(InfA.class);
+ testInterfaces(InfB.class);
+ testInterfaces(InfC.class);
+ testInterfaces(ClassA.class);
+ testInterfaces(ClassB.class);
+ testInterfaces(ClassC.class);
+
+ testClassLoader(String.class);
+ testClassLoader(String[].class);
+ testClassLoader(InfA.class);
+ testClassLoader(getProxyClass());
+
+ testClassLoaderClasses();
+
+ System.out.println();
+
+ testClassVersion();
+
+ System.out.println();
+
+ // Use a dedicated thread to have a well-defined current thread.
+ Thread classEventsThread = new Thread("ClassEvents") {
+ @Override
+ public void run() {
+ try {
+ testClassEvents();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ classEventsThread.start();
+ classEventsThread.join();
+ }
+
+ private static void testClass(String className) throws Exception {
+ Class<?> base = Class.forName(className);
+ testClass(base);
+ }
+
+ private static void testClass(Class<?> base) throws Exception {
+ String[] result = getClassSignature(base);
+ System.out.println(Arrays.toString(result));
+ int mod = getClassModifiers(base);
+ if (mod != base.getModifiers()) {
+ throw new RuntimeException("Unexpected modifiers: " + base.getModifiers() + " vs " + mod);
+ }
+ System.out.println(Integer.toHexString(mod));
+ }
+
+ private static void testClassType(Class<?> c) throws Exception {
+ boolean isInterface = isInterface(c);
+ boolean isArray = isArrayClass(c);
+ boolean isModifiable = isModifiableClass(c);
+ System.out.println(c.getName() + " interface=" + isInterface + " array=" + isArray +
+ " modifiable=" + isModifiable);
+ }
+
+ private static void testClassFields(Class<?> c) throws Exception {
+ System.out.println(Arrays.toString(getClassFields(c)));
+ }
+
+ private static void testClassMethods(Class<?> c) throws Exception {
+ System.out.println(Arrays.toString(getClassMethods(c)));
+ }
+
+ private static void testClassStatus(Class<?> c) {
+ System.out.println(c + " " + Integer.toBinaryString(getClassStatus(c)));
+ }
+
+ private static void testInterfaces(Class<?> c) {
+ System.out.println(c + " " + Arrays.toString(getImplementedInterfaces(c)));
+ }
+
+ private static boolean IsBootClassLoader(ClassLoader l) {
+ // Hacky check for Android's fake boot classloader.
+ return l.getClass().getName().equals("java.lang.BootClassLoader");
+ }
+
+ private static void testClassLoader(Class<?> c) {
+ Object cl = getClassLoader(c);
+ System.out.println(c + " " + (cl != null ? cl.getClass().getName() : "null"));
+ if (cl == null) {
+ if (c.getClassLoader() != null && !IsBootClassLoader(c.getClassLoader())) {
+ throw new RuntimeException("Expected " + c.getClassLoader() + ", but got null.");
+ }
+ } else {
+ if (!(cl instanceof ClassLoader)) {
+ throw new RuntimeException("Unexpected \"classloader\": " + cl + " (" + cl.getClass() +
+ ")");
+ }
+ if (cl != c.getClassLoader()) {
+ throw new RuntimeException("Unexpected classloader: " + c.getClassLoader() + " vs " + cl);
+ }
+ }
+ }
+
+ private static void testClassLoaderClasses() throws Exception {
+ System.out.println();
+ System.out.println("boot <- (B) <- (A,C)");
+ ClassLoader cl1 = DexData.create2(DexData.create1());
+ Class.forName("B", false, cl1);
+ Class.forName("A", false, cl1);
+ printClassLoaderClasses(cl1);
+
+ System.out.println();
+ System.out.println("boot <- (B) <- (A, List)");
+ ClassLoader cl2 = DexData.create2(DexData.create1());
+ Class.forName("A", false, cl2);
+ Class.forName("java.util.List", false, cl2);
+ Class.forName("B", false, cl2.getParent());
+ printClassLoaderClasses(cl2);
+
+ System.out.println();
+ System.out.println("boot <- 1+2 (A,B)");
+ ClassLoader cl3 = DexData.create12();
+ Class.forName("B", false, cl3);
+ Class.forName("A", false, cl3);
+ printClassLoaderClasses(cl3);
+
+ // Check that the boot classloader dumps something non-empty.
+ ClassLoader boot = ClassLoader.getSystemClassLoader().getParent();
+ while (boot.getParent() != null) {
+ boot = boot.getParent();
+ }
+
+ Class<?>[] bootClasses = getClassLoaderClasses(boot);
+ if (bootClasses.length == 0) {
+ throw new RuntimeException("No classes initiated by boot classloader.");
+ }
+ // Check that at least java.util.List is loaded.
+ boolean foundList = false;
+ for (Class<?> c : bootClasses) {
+ if (c == java.util.List.class) {
+ foundList = true;
+ break;
+ }
+ }
+ if (!foundList) {
+ System.out.println(Arrays.toString(bootClasses));
+ throw new RuntimeException("Could not find class java.util.List.");
+ }
+ }
+
+ private static void testClassVersion() {
+ System.out.println(Arrays.toString(getClassVersion(Main.class)));
+ }
+
+ private static void testClassEvents() throws Exception {
+ ClassLoader cl = Main.class.getClassLoader();
+ while (cl.getParent() != null) {
+ cl = cl.getParent();
+ }
+ final ClassLoader boot = cl;
+
+ // The JIT may deeply inline and load some classes. Preload these for test determinism.
+ final String PRELOAD_FOR_JIT[] = {
+ "java.nio.charset.CoderMalfunctionError",
+ "java.util.NoSuchElementException"
+ };
+ for (String s : PRELOAD_FOR_JIT) {
+ Class.forName(s);
+ }
+
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ ClassLoader cl6 = DexData.create12();
+ System.out.println("C, true");
+ Class.forName("C", true, cl6);
+ printClassLoadMessages();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+
+ Thread dummyThread = new Thread();
+ dummyThread.start();
+ dummyThread.join();
+
+ enableClassLoadPreparePrintEvents(true, Thread.currentThread());
+
+ ClassLoader cl1 = DexData.create12();
+ System.out.println("B, false");
+ Class.forName("B", false, cl1);
+ printClassLoadMessages();
+
+ ClassLoader cl2 = DexData.create12();
+ System.out.println("B, true");
+ Class.forName("B", true, cl2);
+ printClassLoadMessages();
+
+ ClassLoader cl3 = DexData.create12();
+ System.out.println("C, false");
+ Class.forName("C", false, cl3);
+ printClassLoadMessages();
+ System.out.println("A, false");
+ Class.forName("A", false, cl3);
+ printClassLoadMessages();
+
+ ClassLoader cl4 = DexData.create12();
+ System.out.println("C, true");
+ Class.forName("C", true, cl4);
+ printClassLoadMessages();
+ System.out.println("A, true");
+ Class.forName("A", true, cl4);
+ printClassLoadMessages();
+
+ ClassLoader cl5 = DexData.create12();
+ System.out.println("A, true");
+ Class.forName("A", true, cl5);
+ printClassLoadMessages();
+ System.out.println("C, true");
+ Class.forName("C", true, cl5);
+ printClassLoadMessages();
+
+ enableClassLoadPreparePrintEvents(false, null);
+
+ Thread t = new Thread(r, "TestRunner");
+ enableClassLoadPreparePrintEvents(true, t);
+ t.start();
+ t.join();
+ enableClassLoadPreparePrintEvents(false, null);
+
+ enableClassLoadPreparePrintEvents(true, Thread.currentThread());
+
+ // Check creation of arrays and proxies.
+ Proxy.getProxyClass(Main.class.getClassLoader(), new Class[] { Comparable.class, I0.class });
+ Class.forName("[Lart.Test912;");
+ printClassLoadMessages();
+
+ enableClassLoadPreparePrintEvents(false, null);
+
+ testClassLoadPrepareEquality();
+ }
+
+ private static void testClassLoadPrepareEquality() throws Exception {
+ setEqualityEventStorageClass(ClassF.class);
+
+ enableClassLoadPrepareEqualityEvents(true);
+
+ Class.forName("art.Test912$ClassE");
+
+ enableClassLoadPrepareEqualityEvents(false);
+ }
+
+ private static void printClassLoaderClasses(ClassLoader cl) {
+ for (;;) {
+ if (cl == null || !cl.getClass().getName().startsWith("dalvik.system")) {
+ break;
+ }
+
+ Class<?> classes[] = getClassLoaderClasses(cl);
+ Arrays.sort(classes, new ClassNameComparator());
+ System.out.println(Arrays.toString(classes));
+
+ cl = cl.getParent();
+ }
+ }
+
+ private static void printClassLoadMessages() {
+ for (String s : getClassLoadMessages()) {
+ System.out.println(s);
+ }
+ }
+
+ private static native boolean isModifiableClass(Class<?> c);
+ private static native String[] getClassSignature(Class<?> c);
+
+ private static native boolean isInterface(Class<?> c);
+ private static native boolean isArrayClass(Class<?> c);
+
+ private static native int getClassModifiers(Class<?> c);
+
+ private static native Object[] getClassFields(Class<?> c);
+ private static native Object[] getClassMethods(Class<?> c);
+ private static native Class<?>[] getImplementedInterfaces(Class<?> c);
+
+ private static native int getClassStatus(Class<?> c);
+
+ private static native Object getClassLoader(Class<?> c);
+
+ private static native Class<?>[] getClassLoaderClasses(ClassLoader cl);
+
+ private static native int[] getClassVersion(Class<?> c);
+
+ private static native void enableClassLoadPreparePrintEvents(boolean b, Thread filter);
+ private static native String[] getClassLoadMessages();
+
+ private static native void setEqualityEventStorageClass(Class<?> c);
+ private static native void enableClassLoadPrepareEqualityEvents(boolean b);
+
+ private static class TestForNonInit {
+ public static double dummy = Math.random(); // So it can't be compile-time initialized.
+ }
+
+ private static class TestForInitFail {
+ public static int dummy = ((int)Math.random())/0; // So it throws when initializing.
+ }
+
+ public static interface InfA {
+ }
+ public static interface InfB extends InfA {
+ }
+ public static interface InfC extends InfB {
+ }
+
+ public abstract static class ClassA implements InfA {
+ }
+ public abstract static class ClassB extends ClassA implements InfB {
+ }
+ public abstract static class ClassC implements InfA, InfC {
+ }
+
+ public static class ClassE {
+ public void foo() {
+ }
+ public void bar() {
+ }
+ }
+
+ public static class ClassF {
+ public static Object STATIC = null;
+ public static Reference<Object> WEAK = null;
+ }
+
+ private static class ClassNameComparator implements Comparator<Class<?>> {
+ public int compare(Class<?> c1, Class<?> c2) {
+ return c1.getName().compareTo(c2.getName());
+ }
+ }
+
+ // See run-test 910 for an explanation.
+
+ private static Class<?> proxyClass = null;
+
+ private static Class<?> getProxyClass() throws Exception {
+ if (proxyClass != null) {
+ return proxyClass;
+ }
+
+ for (int i = 1; i <= 21; i++) {
+ proxyClass = createProxyClass(i);
+ String name = proxyClass.getName();
+ if (name.equals("$Proxy20")) {
+ return proxyClass;
+ }
+ }
+ return proxyClass;
+ }
+
+ private static Class<?> createProxyClass(int i) throws Exception {
+ int count = Integer.bitCount(i);
+ Class<?>[] input = new Class<?>[count + 1];
+ input[0] = Runnable.class;
+ int inputIndex = 1;
+ int bitIndex = 0;
+ while (i != 0) {
+ if ((i & 1) != 0) {
+ input[inputIndex++] = Class.forName("art.Test912$I" + bitIndex);
+ }
+ i >>>= 1;
+ bitIndex++;
+ }
+ return Proxy.getProxyClass(Test912.class.getClassLoader(), input);
+ }
+
+ // Need this for the proxy naming.
+ public static interface I0 {
+ }
+ public static interface I1 {
+ }
+ public static interface I2 {
+ }
+ public static interface I3 {
+ }
+ public static interface I4 {
+ }
+}
diff --git a/test/912-classes/src/art/Test912Art.java b/test/912-classes/src/art/Test912Art.java
new file mode 100644
index 0000000000..e4384734d8
--- /dev/null
+++ b/test/912-classes/src/art/Test912Art.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.lang.ref.Reference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+public class Test912Art {
+ public static void run() throws Exception {
+ art.Main.bindAgentJNIForClass(Test912Art.class);
+ doTest();
+ }
+
+ public static void doTest() throws Exception {
+ testClassEvents();
+ }
+
+ private static void testClassEvents() throws Exception {
+ // Note: the JIT part of this test is about the JIT pulling in a class not yet touched by
+ // anything else in the system. This could be the verifier or the interpreter. We
+ // block the interpreter by calling ensureJitCompiled. The verifier, however, must
+ // run in configurations where dex2oat didn't verify the class itself. So explicitly
+ // check whether the class has been already loaded, and skip then.
+ // TODO: Add multiple configurations to the run script once that becomes easier to do.
+ if (hasJit() && !isLoadedClass("art.Test912Art$ClassD")) {
+ testClassEventsJit();
+ }
+ }
+
+ private static void testClassEventsJit() throws Exception {
+ enableClassLoadSeenEvents(true);
+
+ testClassEventsJitImpl();
+
+ enableClassLoadSeenEvents(false);
+
+ if (!hadLoadEvent()) {
+ throw new RuntimeException("Did not get expected load event.");
+ }
+ }
+
+ private static void testClassEventsJitImpl() throws Exception {
+ ensureJitCompiled(Test912Art.class, "testClassEventsJitImpl");
+
+ if (ClassD.x != 1) {
+ throw new RuntimeException("Unexpected value");
+ }
+ }
+
+ private static native void ensureJitCompiled(Class<?> c, String name);
+
+ private static native boolean hasJit();
+ private static native boolean isLoadedClass(String name);
+ private static native void enableClassLoadSeenEvents(boolean b);
+ private static native boolean hadLoadEvent();
+
+ public static class ClassD {
+ static int x = 1;
+ }
+}
diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt
index 2a183ee06b..702b247819 100644
--- a/test/913-heaps/expected.txt
+++ b/test/913-heaps/expected.txt
@@ -1,9 +1,10 @@
---
true true
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
-root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1]
-root@root --(thread)--> 3000@0 [size=132, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -14,11 +15,13 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -31,20 +34,24 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=13,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=5,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot,vreg=4,location= 19])--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 1@1000 [size=16, length=-1]
-root@root --(thread)--> 3000@0 [size=132, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -55,11 +62,13 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -72,43 +81,48 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
-root@root --(thread)--> 3000@0 [size=132, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
---
3@1001 --(class)--> 1001@0 [size=123, length=-1]
---
-root@root --(thread)--> 3000@0 [size=132, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
---
3@1001 --(class)--> 1001@0 [size=123, length=-1]
---
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
-root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1]
-root@root --(thread)--> 3000@0 [size=132, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=13,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=5,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot,vreg=4,location= 19])--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 1@1000 [size=16, length=-1]
-root@root --(thread)--> 3000@0 [size=132, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
---
[1@0 (32, 'HelloWorld'), 2@0 (16, '')]
2
@@ -148,16 +162,17 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
10008
--- klass ---
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
@@ -167,13 +182,15 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot
root@root --(thread)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
--- heap_filter ---
---- tagged objects
@@ -182,10 +199,11 @@ root@root --(thread)--> 1@1000 [size=16, length=-1]
---
---
---- untagged objects
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
-root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1]
-root@root --(thread)--> 3000@0 [size=132, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -196,11 +214,13 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -213,20 +233,24 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=13,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=5,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot,vreg=4,location= 19])--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
root@root --(thread)--> 1@1000 [size=16, length=-1]
-root@root --(thread)--> 3000@0 [size=132, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -237,11 +261,13 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -254,16 +280,20 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
---- tagged classes
-root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1]
-root@root --(thread)--> 3000@0 [size=132, length=-1]
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=136, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -273,6 +303,7 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -284,9 +315,12 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
-root@root --(thread)--> 3000@0 [size=132, length=-1]
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 3000@0 [size=136, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=5,method=run,vreg=2,location= 0])--> 3000@0 [size=136, length=-1]
+root@root --(thread)--> 3000@0 [size=136, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
@@ -296,6 +330,7 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -307,24 +342,26 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
4@1000 --(class)--> 1000@0 [size=123, length=-1]
5@1002 --(class)--> 1002@0 [size=123, length=-1]
+5@1002 --(field@8)--> 500@0 [size=20, length=2]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
---- untagged classes
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
-0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
root@root --(jni-global)--> 1@1000 [size=16, length=-1]
root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
@@ -335,14 +372,16 @@ root@root --(thread)--> 1@1000 [size=16, length=-1]
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
1@1000 --(field@2)--> 2@1000 [size=16, length=-1]
1@1000 --(field@3)--> 3@1001 [size=24, length=-1]
3@1001 --(field@4)--> 4@1000 [size=16, length=-1]
-3@1001 --(field@5)--> 5@1002 [size=32, length=-1]
-5@1002 --(field@8)--> 6@1000 [size=16, length=-1]
-5@1002 --(field@9)--> 1@1000 [size=16, length=-1]
+3@1001 --(field@5)--> 5@1002 [size=36, length=-1]
+500@0 --(array-element@1)--> 2@1000 [size=16, length=-1]
+5@1002 --(field@10)--> 1@1000 [size=16, length=-1]
+5@1002 --(field@9)--> 6@1000 [size=16, length=-1]
---
diff --git a/test/913-heaps/heaps.cc b/test/913-heaps/heaps.cc
index 6a06b29152..e319f7d98c 100644
--- a/test/913-heaps/heaps.cc
+++ b/test/913-heaps/heaps.cc
@@ -19,40 +19,35 @@
#include <string.h>
#include <iostream>
+#include <sstream>
#include <vector>
#include "android-base/macros.h"
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
-#include "jit/jit.h"
#include "jni.h"
-#include "native_stack_dump.h"
#include "jvmti.h"
-#include "runtime.h"
-#include "scoped_thread_state_change-inl.h"
-#include "thread-inl.h"
-#include "thread_list.h"
// Test infrastructure
#include "jni_helper.h"
#include "jvmti_helper.h"
#include "test_env.h"
+#include "ti_utf.h"
namespace art {
namespace Test913Heaps {
using android::base::StringPrintf;
+#define FINAL final
+#define OVERRIDE override
+#define UNREACHABLE __builtin_unreachable
+
extern "C" JNIEXPORT void JNICALL Java_art_Test913_forceGarbageCollection(
- JNIEnv* env ATTRIBUTE_UNUSED, jclass klass ATTRIBUTE_UNUSED) {
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED) {
jvmtiError ret = jvmti_env->ForceGarbageCollection();
- if (ret != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(ret, &err);
- printf("Error forcing a garbage collection: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
- }
+ JvmtiErrorToException(env, jvmti_env, ret);
}
class IterationConfig {
@@ -92,7 +87,8 @@ static jint JNICALL HeapReferenceCallback(jvmtiHeapReferenceKind reference_kind,
user_data);
}
-static bool Run(jint heap_filter,
+static bool Run(JNIEnv* env,
+ jint heap_filter,
jclass klass_filter,
jobject initial_object,
IterationConfig* config) {
@@ -105,14 +101,7 @@ static bool Run(jint heap_filter,
initial_object,
&callbacks,
config);
- if (ret != JVMTI_ERROR_NONE) {
- char* err;
- jvmti_env->GetErrorName(ret, &err);
- printf("Failure running FollowReferences: %s\n", err);
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(err));
- return false;
- }
- return true;
+ return !JvmtiErrorToException(env, jvmti_env, ret);
}
extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
@@ -142,6 +131,27 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
jint length,
void* user_data ATTRIBUTE_UNUSED) OVERRIDE {
jlong tag = *tag_ptr;
+
+ // Ignore any jni-global roots with untagged classes. These can be from the environment,
+ // or the JIT.
+ if (reference_kind == JVMTI_HEAP_REFERENCE_JNI_GLOBAL && class_tag == 0) {
+ return 0;
+ }
+ // Ignore classes (1000 <= tag < 3000) for thread objects. These can be held by the JIT.
+ if (reference_kind == JVMTI_HEAP_REFERENCE_THREAD && class_tag == 0 &&
+ (1000 <= *tag_ptr && *tag_ptr < 3000)) {
+ return 0;
+ }
+ // Ignore stack-locals of untagged threads. That is the environment.
+ if (reference_kind == JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
+ reference_info->stack_local.thread_tag != 3000) {
+ return 0;
+ }
+ // Ignore array elements with an untagged source. These are from the environment.
+ if (reference_kind == JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT && *referrer_tag_ptr == 0) {
+ return 0;
+ }
+
// Only check tagged objects.
if (tag == 0) {
return JVMTI_VISIT_OBJECTS;
@@ -201,10 +211,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
reference_info,
adapted_size,
length));
-
- if (reference_kind == JVMTI_HEAP_REFERENCE_THREAD && *tag_ptr == 1000) {
- DumpStacks();
- }
}
std::vector<std::string> GetLines() const {
@@ -259,9 +265,15 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
if (info_.jni_local.method != nullptr) {
jvmti_env->GetMethodName(info_.jni_local.method, &name, nullptr, nullptr);
}
+ // Normalize the thread id, as this depends on the number of other threads
+ // and which thread is running the test. Should be:
+ // jlong thread_id = info_.jni_local.thread_id;
+ // TODO: A pre-pass before the test should be able fetch this number, so it can
+ // be compared explicitly.
+ jlong thread_id = 1;
std::string ret = StringPrintf("jni-local[id=%" PRId64 ",tag=%" PRId64 ",depth=%d,"
"method=%s]",
- info_.jni_local.thread_id,
+ thread_id,
info_.jni_local.thread_tag,
info_.jni_local.depth,
name == nullptr ? "<null>" : name);
@@ -284,13 +296,12 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
jlong size,
jint length,
const jvmtiHeapReferenceInfo* reference_info)
- REQUIRES_SHARED(Locks::mutator_lock_)
: Elem(referrer, referree, size, length) {
memcpy(&info_, reference_info, sizeof(jvmtiHeapReferenceInfo));
- // Debug stack trace for failure condition. Remove when done.
- if (info_.stack_local.depth == 3 && info_.stack_local.slot == 13) {
- DumpNativeStack(std::cerr, GetTid());
- Thread::Current()->DumpJavaStack(std::cerr, false, false);
+
+ // Debug code. Try to figure out where bad depth is coming from.
+ if (reference_info->stack_local.depth == 6) {
+ LOG(FATAL) << "Unexpected depth of 6";
}
}
@@ -300,9 +311,15 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
if (info_.stack_local.method != nullptr) {
jvmti_env->GetMethodName(info_.stack_local.method, &name, nullptr, nullptr);
}
+ // Normalize the thread id, as this depends on the number of other threads
+ // and which thread is running the test. Should be:
+ // jlong thread_id = info_.stack_local.thread_id;
+ // TODO: A pre-pass before the test should be able fetch this number, so it can
+ // be compared explicitly.
+ jlong thread_id = 1;
std::string ret = StringPrintf("stack-local[id=%" PRId64 ",tag=%" PRId64 ",depth=%d,"
"method=%s,vreg=%d,location=% " PRId64 "]",
- info_.stack_local.thread_id,
+ thread_id,
info_.stack_local.thread_tag,
info_.stack_local.depth,
name == nullptr ? "<null>" : name,
@@ -361,7 +378,13 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
tmp));
}
case JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT: {
- std::string tmp = StringPrintf("array-element@%d", reference_info->array.index);
+ jint index = reference_info->array.index;
+ // Normalize if it's "0@0" -> "3000@1".
+ // TODO: A pre-pass could probably give us this index to check explicitly.
+ if (referrer == "0@0" && referree == "3000@0") {
+ index = 0;
+ }
+ std::string tmp = StringPrintf("array-element@%d", index);
return std::unique_ptr<Elem>(new StringElement(referrer,
referree,
size,
@@ -459,16 +482,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
UNREACHABLE();
}
- static void DumpStacks() NO_THREAD_SAFETY_ANALYSIS {
- auto dump_function = [](art::Thread* t, void* data ATTRIBUTE_UNUSED) {
- std::string name;
- t->GetThreadName(name);
- LOG(ERROR) << name;
- art::DumpNativeStack(LOG_STREAM(ERROR), t->GetTid());
- };
- art::Runtime::Current()->GetThreadList()->ForEach(dump_function, nullptr);
- }
-
jint counter_;
const jint stop_after_;
const jint follow_set_;
@@ -476,8 +489,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
std::vector<std::unique_ptr<Elem>> lines_;
};
- jit::ScopedJitSuspend sjs; // Wait to avoid JIT influence (e.g., JNI globals).
-
// If jniRef isn't null, add a local and a global ref.
ScopedLocalRef<jobject> jni_local_ref(env, nullptr);
jobject jni_global_ref = nullptr;
@@ -487,7 +498,9 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferences(
}
PrintIterationConfig config(stop_after, follow_set);
- Run(heap_filter, klass_filter, initial_object, &config);
+ if (!Run(env, heap_filter, klass_filter, initial_object, &config)) {
+ return nullptr;
+ }
std::vector<std::string> lines = config.GetLines();
jobjectArray ret = CreateObjectArray(env,
@@ -528,10 +541,10 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test913_followReferencesStrin
void* user_data) {
FindStringCallbacks* p = reinterpret_cast<FindStringCallbacks*>(user_data);
if (*tag_ptr != 0) {
- size_t utf_byte_count = CountUtf8Bytes(value, value_length);
+ size_t utf_byte_count = ti::CountUtf8Bytes(value, value_length);
std::unique_ptr<char[]> mod_utf(new char[utf_byte_count + 1]);
memset(mod_utf.get(), 0, utf_byte_count + 1);
- ConvertUtf16ToModifiedUtf8(mod_utf.get(), utf_byte_count, value, value_length);
+ ti::ConvertUtf16ToModifiedUtf8(mod_utf.get(), utf_byte_count, value, value_length);
p->data.push_back(android::base::StringPrintf("%" PRId64 "@%" PRId64 " (%" PRId64 ", '%s')",
*tag_ptr,
class_tag,
diff --git a/test/913-heaps/src/art/Test913.java b/test/913-heaps/src/art/Test913.java
index c54ecb049f..d3b29cf2b5 100644
--- a/test/913-heaps/src/art/Test913.java
+++ b/test/913-heaps/src/art/Test913.java
@@ -21,12 +21,34 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.concurrent.CountDownLatch;
public class Test913 {
public static void run() throws Exception {
Main.bindAgentJNIForClass(Test913.class);
doTest();
+
+ // Use a countdown latch for synchronization, as join() will introduce more roots.
+ final CountDownLatch cdl1 = new CountDownLatch(1);
+
+ // Run the follow-references tests on a dedicated thread so we know the specific Thread type.
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ Test913.runFollowReferences();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ cdl1.countDown();
+ }
+ };
+ t.start();
+ cdl1.await();
+ }
+
+ public static void runFollowReferences() throws Exception {
new TestConfig().doFollowReferencesTest();
Runtime.getRuntime().gc();
@@ -349,6 +371,14 @@ public class Test913 {
cInst.baz2 = aInst;
v.add(cInstStr, aInstStr); // C -->(field) --> A.
+ A[] aArray = new A[2];
+ setTag(aArray, 500);
+ aArray[1] = a2Inst;
+ cInst.array = aArray;
+ String aArrayStr = "500@0";
+ v.add(cInstStr, aArrayStr);
+ v.add(aArrayStr, a2InstStr);
+
return aInst;
}
}
@@ -386,6 +416,7 @@ public class Test913 {
public static class C extends B implements I2 {
public A baz;
public A baz2;
+ public A[] array;
public C() {}
public C(A a, A b) {
@@ -481,7 +512,8 @@ public class Test913 {
if (currentHead == null) {
currentHead = referrer;
} else {
- if (!currentHead.equals(referrer)) {
+ // Ignore 0@0, as it can happen at any time (as it stands for all other objects).
+ if (!currentHead.equals(referrer) && !referrer.equals("0@0")) {
completedReferrers.add(currentHead);
currentHead = referrer;
if (completedReferrers.contains(referrer)) {
diff --git a/test/914-hello-obsolescence/src/Main.java b/test/914-hello-obsolescence/src/Main.java
index 2ec7664f0f..ab5c7f421f 100644
--- a/test/914-hello-obsolescence/src/Main.java
+++ b/test/914-hello-obsolescence/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,60 +14,8 @@
* 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) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test914.run();
}
-
- 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
deleted file mode 100644
index 8cda6cdf53..0000000000
--- a/test/914-hello-obsolescence/src/Transform.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class 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/914-hello-obsolescence/src/art/Redefinition.java b/test/914-hello-obsolescence/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/914-hello-obsolescence/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/914-hello-obsolescence/src/art/Test914.java b/test/914-hello-obsolescence/src/art/Test914.java
new file mode 100644
index 0000000000..ef2710da5b
--- /dev/null
+++ b/test/914-hello-obsolescence/src/art/Test914.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Test914 {
+
+ // The class we will be transforming.
+ static class Transform {
+ public void sayHi(Runnable r) {
+ System.out.println("hello");
+ r.run();
+ System.out.println("goodbye");
+ }
+ }
+
+ // static 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(
+ "yv66vgAAADQAKAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAbBwAeAQAGPGluaXQ+AQADKClW" +
+ "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
+ "KVYBAApTb3VyY2VGaWxlAQAMVGVzdDkxNC5qYXZhDAAJAAoHAB8MACAAIQEAE0hlbGxvIC0gVHJh" +
+ "bnNmb3JtZWQHACIMACMAJAcAJQwAJgAKAQAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkBwAnAQAVYXJ0" +
+ "L1Rlc3Q5MTQkVHJhbnNmb3JtAQAJVHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5n" +
+ "L09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsB" +
+ "ABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEA" +
+ "EmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgEAC2FydC9UZXN0OTE0ACAABwAIAAAAAAACAAAACQAK" +
+ "AAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAABQABAA0ADgABAAsAAAA7AAIAAgAA" +
+ "ABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAcACAAIAA4ACQAWAAoAAgAP" +
+ "AAAAAgAQAB0AAAAKAAEABwAaABwACA==");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQBlmxNYAAAAAAAAAAAAAAAAAAAAAAAAAAA8BAAAcAAAAHhWNBIAAAAAAAAAAHgDAAAX" +
+ "AAAAcAAAAAoAAADMAAAAAwAAAPQAAAABAAAAGAEAAAUAAAAgAQAAAQAAAEgBAADUAgAAaAEAAGgB" +
+ "AABwAQAAhwEAAJwBAAC1AQAAxAEAAOgBAAAIAgAAHwIAADMCAABJAgAAXQIAAHECAAB/AgAAigIA" +
+ "AI0CAACRAgAAngIAAKQCAACpAgAAsgIAALcCAAC+AgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAA" +
+ "CQAAAAoAAAALAAAADgAAAA4AAAAJAAAAAAAAAA8AAAAJAAAAyAIAAA8AAAAJAAAA0AIAAAgABAAS" +
+ "AAAAAAAAAAAAAAAAAAEAFQAAAAQAAgATAAAABQAAAAAAAAAGAAAAFAAAAAAAAAAAAAAABQAAAAAA" +
+ "AAAMAAAAaAMAADwDAAAAAAAABjxpbml0PgAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkABNIZWxsbyAt" +
+ "IFRyYW5zZm9ybWVkABdMYXJ0L1Rlc3Q5MTQkVHJhbnNmb3JtOwANTGFydC9UZXN0OTE0OwAiTGRh" +
+ "bHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVy" +
+ "Q2xhc3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEv" +
+ "bGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AAxU" +
+ "ZXN0OTE0LmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vzc0ZsYWdzAARuYW1lAANvdXQAB3By" +
+ "aW50bG4AA3J1bgAFc2F5SGkABXZhbHVlAAAAAAEAAAAGAAAAAQAAAAcAAAAFAAcOAAcBAAcOAQgP" +
+ "AQMPAQgPAAEAAQABAAAA2AIAAAQAAABwEAMAAAAOAAQAAgACAAAA3QIAABQAAABiAAAAGwECAAAA" +
+ "biACABAAchAEAAMAYgAAABsBAQAAAG4gAgAQAA4AAAABAQCAgATsBQEBhAYAAAICARYYAQIDAhAE" +
+ "CBEXDQACAAAATAMAAFIDAABcAwAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAXAAAA" +
+ "cAAAAAIAAAAKAAAAzAAAAAMAAAADAAAA9AAAAAQAAAABAAAAGAEAAAUAAAAFAAAAIAEAAAYAAAAB" +
+ "AAAASAEAAAIgAAAXAAAAaAEAAAEQAAACAAAAyAIAAAMgAAACAAAA2AIAAAEgAAACAAAA7AIAAAAg" +
+ "AAABAAAAPAMAAAQgAAACAAAATAMAAAMQAAABAAAAXAMAAAYgAAABAAAAaAMAAAAQAAABAAAAeAMA" +
+ "AA==");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ 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");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ });
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/915-obsolete-2/src/Main.java b/test/915-obsolete-2/src/Main.java
index fc73ee86fc..be51234c87 100644
--- a/test/915-obsolete-2/src/Main.java
+++ b/test/915-obsolete-2/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,86 +14,8 @@
* 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) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test915.run();
}
-
- 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/art/Redefinition.java b/test/915-obsolete-2/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/915-obsolete-2/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/915-obsolete-2/src/art/Test915.java b/test/915-obsolete-2/src/art/Test915.java
new file mode 100644
index 0000000000..63c7f344dd
--- /dev/null
+++ b/test/915-obsolete-2/src/art/Test915.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Test915 {
+
+ static 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");
+ }
+ }
+
+ // static 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(
+ "yv66vgAAADQANgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" +
+ "JwcAKQcALAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" +
+ "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAM" +
+ "VGVzdDkxNS5qYXZhDAAPABAHAC0MAC4ALwEAHUhlbGxvIC0gcHJpdmF0ZSAtIFRyYW5zZm9ybWVk" +
+ "BwAwDAAxADIBAB9Hb29kYnllIC0gcHJpdmF0ZSAtIFRyYW5zZm9ybWVkAQArUHJlIFN0YXJ0IHBy" +
+ "aXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAwAEwAQAQAsUG9zdCBTdGFydCBwcml2YXRl" +
+ "IG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQHADMMADQAEAEALFByZSBGaW5pc2ggcHJpdmF0ZSBt" +
+ "ZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAAUABABAC1Qb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhv" +
+ "ZCBjYWxsIC0gVHJhbnNmb3JtZWQHADUBABVhcnQvVGVzdDkxNSRUcmFuc2Zvcm0BAAlUcmFuc2Zv" +
+ "cm0BAAxJbm5lckNsYXNzZXMBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEA" +
+ "A291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmlu" +
+ "dGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuAQAL" +
+ "YXJ0L1Rlc3Q5MTUAIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAABABIA" +
+ "AAAGAAEAAAAFAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAAAAcA" +
+ "CAAIAAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAoACAALAAEA" +
+ "FQAWAAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQqtwAL" +
+ "sgACEgy2AASxAAAAAQASAAAAIgAIAAAADQAIAA4ADAAPABQAEAAaABEAIgASACYAEwAuABQAAgAX" +
+ "AAAAAgAYACsAAAAKAAEADQAoACoACA==");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQAQ+GYcAAAAAAAAAAAAAAAAAAAAAAAAAADUBQAAcAAAAHhWNBIAAAAAAAAAABAFAAAd" +
+ "AAAAcAAAAAoAAADkAAAAAwAAAAwBAAABAAAAMAEAAAcAAAA4AQAAAQAAAHABAABEBAAAkAEAAJAB" +
+ "AACYAQAAoAEAAMEBAADgAQAA+QEAAAgCAAAsAgAATAIAAGMCAAB3AgAAjQIAAKECAAC1AgAA5AIA" +
+ "ABIDAABAAwAAbQMAAHQDAACCAwAAjQMAAJADAACUAwAAoQMAAKcDAACsAwAAtQMAALoDAADBAwAA" +
+ "BAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAAFAAAABQAAAAJAAAAAAAAABUAAAAJ" +
+ "AAAA0AMAABUAAAAJAAAAyAMAAAgABAAYAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAARAAAAAAABABsA" +
+ "AAAEAAIAGQAAAAUAAAAAAAAABgAAABoAAAAAAAAAAAAAAAUAAAAAAAAAEgAAAAAFAADMBAAAAAAA" +
+ "AAY8aW5pdD4ABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVsbG8g" +
+ "LSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAF0xhcnQvVGVzdDkxNSRUcmFuc2Zvcm07AA1MYXJ0L1Rl" +
+ "c3Q5MTU7ACJMZGFsdmlrL2Fubm90YXRpb24vRW5jbG9zaW5nQ2xhc3M7AB5MZGFsdmlrL2Fubm90" +
+ "YXRpb24vSW5uZXJDbGFzczsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmpl" +
+ "Y3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5n" +
+ "L1N5c3RlbTsALVBvc3QgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAs" +
+ "UG9zdCBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQALFByZSBGaW5pc2gg" +
+ "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkACtQcmUgU3RhcnQgcHJpdmF0ZSBtZXRo" +
+ "b2QgY2FsbCAtIFRyYW5zZm9ybWVkAAVTdGFydAAMVGVzdDkxNS5qYXZhAAlUcmFuc2Zvcm0AAVYA" +
+ "AlZMAAthY2Nlc3NGbGFncwAEbmFtZQADb3V0AAdwcmludGxuAANydW4ABXNheUhpAAV2YWx1ZQAB" +
+ "AAAABwAAAAEAAAAGAAAABQAHDgAKAAcOAQgPAAcABw4BCA8ADQEABw4BCA8BAw8BCA8BAw8BCA8B" +
+ "Aw8BCA8AAQABAAEAAADYAwAABAAAAHAQBQAAAA4AAwABAAIAAADdAwAACQAAAGIAAAAbAQIAAABu" +
+ "IAQAEAAOAAAAAwABAAIAAADlAwAACQAAAGIAAAAbAQMAAABuIAQAEAAOAAAABAACAAIAAADtAwAA" +
+ "KgAAAGIAAAAbARAAAABuIAQAEABwEAIAAgBiAAAAGwEOAAAAbiAEABAAchAGAAMAYgAAABsBDwAA" +
+ "AG4gBAAQAHAQAQACAGIAAAAbAQ0AAABuIAQAEAAOAAAAAwEAgIAEiAgBAqAIAQLECAMB6AgAAAIC" +
+ "ARwYAQIDAhYECBcXEwACAAAA5AQAAOoEAAD0BAAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAA" +
+ "AAEAAAAdAAAAcAAAAAIAAAAKAAAA5AAAAAMAAAADAAAADAEAAAQAAAABAAAAMAEAAAUAAAAHAAAA" +
+ "OAEAAAYAAAABAAAAcAEAAAIgAAAdAAAAkAEAAAEQAAACAAAAyAMAAAMgAAAEAAAA2AMAAAEgAAAE" +
+ "AAAACAQAAAAgAAABAAAAzAQAAAQgAAACAAAA5AQAAAMQAAABAAAA9AQAAAYgAAABAAAAAAUAAAAQ" +
+ "AAABAAAAEAUAAA==");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ 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");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ });
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/916-obsolete-jit/src/Main.java b/test/916-obsolete-jit/src/Main.java
index 3453261f44..cb202e400d 100644
--- a/test/916-obsolete-jit/src/Main.java
+++ b/test/916-obsolete-jit/src/Main.java
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+
+import art.Redefinition;
+
import java.util.function.Consumer;
import java.lang.reflect.Method;
import java.util.Base64;
@@ -144,7 +147,7 @@ public class Main {
// Actually do the redefinition. The stack looks good.
retry = false;
w.accept("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
}
};
// This just prints something out to show we are running the Runnable.
@@ -168,9 +171,4 @@ public class Main {
private static native boolean isInterpretedFunction(Method m, boolean require_deoptimizable);
private static native void ensureJitCompiled(Class c, String name);
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
}
diff --git a/test/916-obsolete-jit/src/art/Redefinition.java b/test/916-obsolete-jit/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/916-obsolete-jit/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/917-fields-transformation/src/Main.java b/test/917-fields-transformation/src/Main.java
index 588af49cca..289b89f2f6 100644
--- a/test/917-fields-transformation/src/Main.java
+++ b/test/917-fields-transformation/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,67 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
public class Main {
-
- // base64 encoded class/dex file for
- // class Transform {
- // public String take1;
- // public String take2;
- //
- // public Transform(String a, String b) {
- // take1 = a;
- // take2 = b;
- // }
- //
- // public String getResult() {
- // return take2;
- // }
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQAFwoABQARCQAEABIJAAQAEwcAFAcAFQEABXRha2UxAQASTGphdmEvbGFuZy9TdHJp" +
- "bmc7AQAFdGFrZTIBAAY8aW5pdD4BACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJp" +
- "bmc7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAJZ2V0UmVzdWx0AQAUKClMamF2YS9sYW5n" +
- "L1N0cmluZzsBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkAFgwABgAHDAAIAAcBAAlU" +
- "cmFuc2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQADKClWACAABAAFAAAAAgABAAYABwAAAAEACAAH" +
- "AAAAAgABAAkACgABAAsAAAAzAAIAAwAAAA8qtwABKiu1AAIqLLUAA7EAAAABAAwAAAASAAQAAAAU" +
- "AAQAFQAJABYADgAXAAEADQAOAAEACwAAAB0AAQABAAAABSq0AAOwAAAAAQAMAAAABgABAAAAGgAB" +
- "AA8AAAACABA=");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQAGUTBb4jIABRlaI9rejdk7RCfyqR2kmNSkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAM" +
- "AAAAcAAAAAQAAACgAAAAAwAAALAAAAACAAAA1AAAAAMAAADkAAAAAQAAAPwAAACIAQAAHAEAAFwB" +
- "AABkAQAAZwEAAHQBAACIAQAAnAEAAKwBAACvAQAAtAEAAMgBAADTAQAA2gEAAAIAAAADAAAABAAA" +
- "AAYAAAABAAAAAgAAAAAAAAAGAAAAAwAAAAAAAAAHAAAAAwAAAFQBAAAAAAIACgAAAAAAAgALAAAA" +
- "AAACAAAAAAAAAAAACQAAAAEAAQAAAAAAAAAAAAAAAAABAAAAAAAAAAUAAAAAAAAA8AEAAAAAAAAD" +
- "AAMAAQAAAOEBAAAIAAAAcBACAAAAWwEAAFsCAQAOAAIAAQAAAAAA6wEAAAMAAABUEAEAEQAAAAIA" +
- "AAACAAIABjxpbml0PgABTAALTFRyYW5zZm9ybTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEv" +
- "bGFuZy9TdHJpbmc7AA5UcmFuc2Zvcm0uamF2YQABVgADVkxMABJlbWl0dGVyOiBqYWNrLTQuMTkA" +
- "CWdldFJlc3VsdAAFdGFrZTEABXRha2UyABQCAAAHDjwtLQAaAAcOAAACAQEAAQEBAIGABJwCAQG8" +
- "AgAADQAAAAAAAAABAAAAAAAAAAEAAAAMAAAAcAAAAAIAAAAEAAAAoAAAAAMAAAADAAAAsAAAAAQA" +
- "AAACAAAA1AAAAAUAAAADAAAA5AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA" +
- "AAIgAAAMAAAAXAEAAAMgAAACAAAA4QEAAAAgAAABAAAA8AEAAAAQAAABAAAABAIAAA==");
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform("Hello", "Goodbye"),
- new Transform("start", "end"));
- }
-
- private static void printTransform(Transform t) {
- System.out.println("Result is " + t.getResult());
- System.out.println("take1 is " + t.take1);
- System.out.println("take2 is " + t.take2);
- }
- public static void doTest(Transform t1, Transform t2) {
- printTransform(t1);
- printTransform(t2);
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- printTransform(t1);
- printTransform(t2);
+ public static void main(String[] args) throws Exception {
+ art.Test917.run();
}
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
}
diff --git a/test/917-fields-transformation/src/Transform.java b/test/917-fields-transformation/src/Transform.java
deleted file mode 100644
index 6fe6223776..0000000000
--- a/test/917-fields-transformation/src/Transform.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public String take1;
- public String take2;
-
- public Transform(String take1, String take2) {
- this.take1 = take1;
- this.take2 = take2;
- }
-
- public String getResult() {
- return take1;
- }
-}
diff --git a/test/917-fields-transformation/src/art/Redefinition.java b/test/917-fields-transformation/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/917-fields-transformation/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/917-fields-transformation/src/art/Test917.java b/test/917-fields-transformation/src/art/Test917.java
new file mode 100644
index 0000000000..245e92e200
--- /dev/null
+++ b/test/917-fields-transformation/src/art/Test917.java
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+public class Test917 {
+
+ static class Transform {
+ public String take1;
+ public String take2;
+
+ public Transform(String take1, String take2) {
+ this.take1 = take1;
+ this.take2 = take2;
+ }
+
+ public String getResult() {
+ return take1;
+ }
+ }
+
+
+ // base64 encoded class/dex file for
+ // static class Transform {
+ // public String take1;
+ // public String take2;
+ //
+ // public Transform(String a, String b) {
+ // take1 = a;
+ // take2 = b;
+ // }
+ //
+ // public String getResult() {
+ // return take2;
+ // }
+ // }
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAGwoABQARCQAEABIJAAQAEwcAFQcAGAEABXRha2UxAQASTGphdmEvbGFuZy9TdHJp" +
+ "bmc7AQAFdGFrZTIBAAY8aW5pdD4BACcoTGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJp" +
+ "bmc7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAJZ2V0UmVzdWx0AQAUKClMamF2YS9sYW5n" +
+ "L1N0cmluZzsBAApTb3VyY2VGaWxlAQAMVGVzdDkxNy5qYXZhDAAJABkMAAYABwwACAAHBwAaAQAV" +
+ "YXJ0L1Rlc3Q5MTckVHJhbnNmb3JtAQAJVHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9s" +
+ "YW5nL09iamVjdAEAAygpVgEAC2FydC9UZXN0OTE3ACAABAAFAAAAAgABAAYABwAAAAEACAAHAAAA" +
+ "AgABAAkACgABAAsAAAAzAAIAAwAAAA8qtwABKiu1AAIqLLUAA7EAAAABAAwAAAASAAQAAAAJAAQA" +
+ "CgAJAAsADgAMAAEADQAOAAEACwAAAB0AAQABAAAABSq0AAOwAAAAAQAMAAAABgABAAAADwACAA8A" +
+ "AAACABAAFwAAAAoAAQAEABQAFgAI");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQBdcPySAAAAAAAAAAAAAAAAAAAAAAAAAACQAwAAcAAAAHhWNBIAAAAAAAAAAMwCAAAS" +
+ "AAAAcAAAAAcAAAC4AAAAAwAAANQAAAACAAAA+AAAAAMAAAAIAQAAAQAAACABAABQAgAAQAEAAEAB" +
+ "AABIAQAASwEAAGQBAABzAQAAlwEAALcBAADLAQAA3wEAAO0BAAD4AQAA+wEAAAACAAANAgAAGAIA" +
+ "AB4CAAAlAgAALAIAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAoAAAABAAAABQAAAAAAAAAKAAAA" +
+ "BgAAAAAAAAALAAAABgAAADQCAAAAAAUADwAAAAAABQAQAAAAAAACAAAAAAAAAAAADQAAAAQAAQAA" +
+ "AAAAAAAAAAAAAAAEAAAAAAAAAAgAAAC8AgAAjAIAAAAAAAAGPGluaXQ+AAFMABdMYXJ0L1Rlc3Q5" +
+ "MTckVHJhbnNmb3JtOwANTGFydC9UZXN0OTE3OwAiTGRhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2lu" +
+ "Z0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xhc3M7ABJMamF2YS9sYW5nL09iamVj" +
+ "dDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAMVGVzdDkxNy5qYXZhAAlUcmFuc2Zvcm0AAVYAA1ZMTAAL" +
+ "YWNjZXNzRmxhZ3MACWdldFJlc3VsdAAEbmFtZQAFdGFrZTEABXRha2UyAAV2YWx1ZQAAAgAAAAUA" +
+ "BQAJAgAABw4BAw8BAg8BAg8ADwAHDgAAAAADAAMAAQAAADwCAAAIAAAAcBACAAAAWwEAAFsCAQAO" +
+ "AAIAAQAAAAAATAIAAAMAAABUEAEAEQAAAAACAQEAAQEBAIGABNQEAQH0BAAAAgIBERgBAgMCDAQI" +
+ "DhcJAAIAAACgAgAApgIAALACAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAEAAAAAAAAAAQAAABIAAABw" +
+ "AAAAAgAAAAcAAAC4AAAAAwAAAAMAAADUAAAABAAAAAIAAAD4AAAABQAAAAMAAAAIAQAABgAAAAEA" +
+ "AAAgAQAAAiAAABIAAABAAQAAARAAAAEAAAA0AgAAAyAAAAIAAAA8AgAAASAAAAIAAABUAgAAACAA" +
+ "AAEAAACMAgAABCAAAAIAAACgAgAAAxAAAAEAAACwAgAABiAAAAEAAAC8AgAAABAAAAEAAADMAgAA");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ doTest(new Transform("Hello", "Goodbye"),
+ new Transform("start", "end"));
+ }
+
+ private static void printTransform(Transform t) {
+ System.out.println("Result is " + t.getResult());
+ System.out.println("take1 is " + t.take1);
+ System.out.println("take2 is " + t.take2);
+ }
+ public static void doTest(Transform t1, Transform t2) {
+ printTransform(t1);
+ printTransform(t2);
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ printTransform(t1);
+ printTransform(t2);
+ }
+}
diff --git a/test/919-obsolete-fields/src/Main.java b/test/919-obsolete-fields/src/Main.java
index 34ee2a97f5..10eadb271e 100644
--- a/test/919-obsolete-fields/src/Main.java
+++ b/test/919-obsolete-fields/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,135 +14,8 @@
* limitations under the License.
*/
-import java.util.function.Consumer;
-import java.util.Base64;
-
public class Main {
-
- // What follows is the base64 encoded representation of the following class:
- //
- // import java.util.function.Consumer;
- //
- // class Transform {
- // private Consumer<String> reporter;
- // public Transform(Consumer<String> reporter) {
- // this.reporter = reporter;
- // }
- //
- // private void Start() {
- // reporter.accept("Hello - private - Transformed");
- // }
- //
- // private void Finish() {
- // reporter.accept("Goodbye - private - Transformed");
- // }
- //
- // public void sayHi(Runnable r) {
- // reporter.accept("pre Start private method call - Transformed");
- // Start();
- // reporter.accept("post Start private method call - Transformed");
- // r.run();
- // reporter.accept("pre Finish private method call - Transformed");
- // Finish();
- // reporter.accept("post Finish private method call - Transformed");
- // }
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQANAoADgAfCQANACAIACELACIAIwgAJAgAJQoADQAmCAAnCwAoACkIACoKAA0AKwgA" +
- "LAcALQcALgEACHJlcG9ydGVyAQAdTGphdmEvdXRpbC9mdW5jdGlvbi9Db25zdW1lcjsBAAlTaWdu" +
- "YXR1cmUBADFMamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyPExqYXZhL2xhbmcvU3RyaW5nOz47" +
- "AQAGPGluaXQ+AQAgKExqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXI7KVYBAARDb2RlAQAPTGlu" +
- "ZU51bWJlclRhYmxlAQA0KExqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXI8TGphdmEvbGFuZy9T" +
- "dHJpbmc7PjspVgEABVN0YXJ0AQADKClWAQAGRmluaXNoAQAFc2F5SGkBABcoTGphdmEvbGFuZy9S" +
- "dW5uYWJsZTspVgEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwAEwAZDAAPABABAB1IZWxs" +
- "byAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAcALwwAMAAxAQAfR29vZGJ5ZSAtIHByaXZhdGUgLSBU" +
- "cmFuc2Zvcm1lZAEAK3ByZSBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQM" +
- "ABgAGQEALHBvc3QgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkBwAyDAAz" +
- "ABkBACxwcmUgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAwAGgAZAQAt" +
- "cG9zdCBGaW5pc2ggcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkAQAJVHJhbnNmb3Jt" +
- "AQAQamF2YS9sYW5nL09iamVjdAEAG2phdmEvdXRpbC9mdW5jdGlvbi9Db25zdW1lcgEABmFjY2Vw" +
- "dAEAFShMamF2YS9sYW5nL09iamVjdDspVgEAEmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgAgAA0A" +
- "DgAAAAEAAgAPABAAAQARAAAAAgASAAQAAQATABQAAgAVAAAAKgACAAIAAAAKKrcAASortQACsQAA" +
- "AAEAFgAAAA4AAwAAABUABAAWAAkAFwARAAAAAgAXAAIAGAAZAAEAFQAAACgAAgABAAAADCq0AAIS" +
- "A7kABAIAsQAAAAEAFgAAAAoAAgAAABoACwAbAAIAGgAZAAEAFQAAACgAAgABAAAADCq0AAISBbkA" +
- "BAIAsQAAAAEAFgAAAAoAAgAAAB4ACwAfAAEAGwAcAAEAFQAAAG8AAgACAAAAOyq0AAISBrkABAIA" +
- "KrcAByq0AAISCLkABAIAK7kACQEAKrQAAhIKuQAEAgAqtwALKrQAAhIMuQAEAgCxAAAAAQAWAAAA" +
- "IgAIAAAAIgALACMADwAkABoAJQAgACYAKwAnAC8AKAA6ACkAAQAdAAAAAgAe");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQAw/b59wCwTlSVDmuhPEezuK3oe0rtT4ujMBQAAcAAAAHhWNBIAAAAAAAAAAAgFAAAd" +
- "AAAAcAAAAAYAAADkAAAABAAAAPwAAAABAAAALAEAAAcAAAA0AQAAAQAAAGwBAABABAAAjAEAAJoC" +
- "AACdAgAAoAIAAKgCAACsAgAAsgIAALoCAADbAgAA+gIAAAcDAAAmAwAAOgMAAFADAABkAwAAggMA" +
- "AKEDAACoAwAAuAMAALsDAAC/AwAAxwMAANsDAAAKBAAAOAQAAGYEAACTBAAAnQQAAKIEAACpBAAA" +
- "CAAAAAkAAAAKAAAACwAAAA4AAAARAAAAEQAAAAUAAAAAAAAAEgAAAAUAAACEAgAAEgAAAAUAAACM" +
- "AgAAEgAAAAUAAACUAgAAAAAEABkAAAAAAAMAAgAAAAAAAAAFAAAAAAAAAA8AAAAAAAIAGwAAAAIA" +
- "AAACAAAAAwAAABoAAAAEAAEAEwAAAAAAAAAAAAAAAgAAAAAAAAAQAAAAZAIAAO8EAAAAAAAAAQAA" +
- "ANEEAAABAAAA3wQAAAIAAgABAAAAsAQAAAYAAABwEAQAAABbAQAADgADAAEAAgAAALgEAAAJAAAA" +
- "VCAAABsBBgAAAHIgBgAQAA4AAAADAAEAAgAAAL4EAAAJAAAAVCAAABsBBwAAAHIgBgAQAA4AAAAE" +
- "AAIAAgAAAMQEAAAqAAAAVCAAABsBGAAAAHIgBgAQAHAQAgACAFQgAAAbARYAAAByIAYAEAByEAUA" +
- "AwBUIAAAGwEXAAAAciAGABAAcBABAAIAVCAAABsBFQAAAHIgBgAQAA4AAAAAAAEAAAABAAAAAAAA" +
- "AAAAAACMAQAAAAAAAJQBAAABAAAAAgAAAAEAAAADAAAAAQAAAAQAASgAATwABjxpbml0PgACPjsA" +
- "BD47KVYABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVsbG8gLSBw" +
- "cml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07AB1MZGFsdmlrL2Fubm90YXRpb24vU2ln" +
- "bmF0dXJlOwASTGphdmEvbGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEv" +
- "bGFuZy9TdHJpbmc7ABxMamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyAB1MamF2YS91dGlsL2Z1" +
- "bmN0aW9uL0NvbnN1bWVyOwAFU3RhcnQADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAAGYWNjZXB0ABJl" +
- "bWl0dGVyOiBqYWNrLTQuMTkALXBvc3QgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFu" +
- "c2Zvcm1lZAAscG9zdCBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQALHBy" +
- "ZSBGaW5pc2ggcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkACtwcmUgU3RhcnQgcHJp" +
- "dmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkAAhyZXBvcnRlcgADcnVuAAVzYXlIaQAFdmFs" +
- "dWUAFQEABw48LQAeAAcOhwAaAAcOhwAiAQAHDoc8hzyHPIcAAgEBHBwEFw0XARcMFwMCAQEcHAUX" +
- "ABcNFwEXDBcEAAEDAQACAIGABJwDAQK4AwEC3AMDAYAEABAAAAAAAAAAAQAAAAAAAAABAAAAHQAA" +
- "AHAAAAACAAAABgAAAOQAAAADAAAABAAAAPwAAAAEAAAAAQAAACwBAAAFAAAABwAAADQBAAAGAAAA" +
- "AQAAAGwBAAADEAAAAgAAAIwBAAABIAAABAAAAJwBAAAGIAAAAQAAAGQCAAABEAAAAwAAAIQCAAAC" +
- "IAAAHQAAAJoCAAADIAAABAAAALAEAAAEIAAAAgAAANEEAAAAIAAAAQAAAO8EAAAAEAAAAQAAAAgF" +
- "AAA=");
-
- // 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 static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- TestWatcher w = new TestWatcher();
- doTest(new Transform(w), w);
+ public static void main(String[] args) throws Exception {
+ art.Test919.run();
}
-
- private static boolean interpreting = true;
- private static boolean retry = false;
-
- public static void doTest(Transform t, TestWatcher w) {
- Runnable do_redefinition = () -> {
- w.accept("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- };
- // This just prints something out to show we are running the Runnable.
- Runnable say_nothing = () -> { w.accept("Not doing anything here"); };
-
- // Try and redefine.
- t.sayHi(say_nothing);
- t.sayHi(do_redefinition);
- t.sayHi(say_nothing);
-
- // Print output of last run.
- System.out.print(w.getOutput());
- }
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
}
diff --git a/test/919-obsolete-fields/src/Transform.java b/test/919-obsolete-fields/src/Transform.java
deleted file mode 100644
index c8e3cbd934..0000000000
--- a/test/919-obsolete-fields/src/Transform.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.util.function.Consumer;
-
-class Transform {
- private Consumer<String> reporter;
- public Transform(Consumer<String> reporter) {
- this.reporter = reporter;
- }
-
- private void Start() {
- reporter.accept("hello - private");
- }
-
- private void Finish() {
- reporter.accept("goodbye - private");
- }
-
- public void sayHi(Runnable r) {
- reporter.accept("Pre Start private method call");
- Start();
- reporter.accept("Post Start private method call");
- r.run();
- reporter.accept("Pre Finish private method call");
- Finish();
- reporter.accept("Post Finish private method call");
- }
-}
diff --git a/test/919-obsolete-fields/src/art/Redefinition.java b/test/919-obsolete-fields/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/919-obsolete-fields/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/919-obsolete-fields/src/art/Test919.java b/test/919-obsolete-fields/src/art/Test919.java
new file mode 100644
index 0000000000..11971ef2e8
--- /dev/null
+++ b/test/919-obsolete-fields/src/art/Test919.java
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.function.Consumer;
+import java.util.Base64;
+
+public class Test919 {
+
+ static class Transform {
+ private Consumer<String> reporter;
+ public Transform(Consumer<String> reporter) {
+ this.reporter = reporter;
+ }
+
+ private void Start() {
+ reporter.accept("hello - private");
+ }
+
+ private void Finish() {
+ reporter.accept("goodbye - private");
+ }
+
+ public void sayHi(Runnable r) {
+ reporter.accept("Pre Start private method call");
+ Start();
+ reporter.accept("Post Start private method call");
+ r.run();
+ reporter.accept("Pre Finish private method call");
+ Finish();
+ reporter.accept("Post Finish private method call");
+ }
+ }
+
+
+ // What follows is the base64 encoded representation of the following class:
+ //
+ // import java.util.function.Consumer;
+ //
+ // static class Transform {
+ // private Consumer<String> reporter;
+ // public Transform(Consumer<String> reporter) {
+ // this.reporter = reporter;
+ // }
+ //
+ // private void Start() {
+ // reporter.accept("Hello - private - Transformed");
+ // }
+ //
+ // private void Finish() {
+ // reporter.accept("Goodbye - private - Transformed");
+ // }
+ //
+ // public void sayHi(Runnable r) {
+ // reporter.accept("pre Start private method call - Transformed");
+ // Start();
+ // reporter.accept("post Start private method call - Transformed");
+ // r.run();
+ // reporter.accept("pre Finish private method call - Transformed");
+ // Finish();
+ // reporter.accept("post Finish private method call - Transformed");
+ // }
+ // }
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAOAoADgAfCQANACAIACELACIAIwgAJAgAJQoADQAmCAAnCwAoACkIACoKAA0AKwgA" +
+ "LAcALgcAMQEACHJlcG9ydGVyAQAdTGphdmEvdXRpbC9mdW5jdGlvbi9Db25zdW1lcjsBAAlTaWdu" +
+ "YXR1cmUBADFMamF2YS91dGlsL2Z1bmN0aW9uL0NvbnN1bWVyPExqYXZhL2xhbmcvU3RyaW5nOz47" +
+ "AQAGPGluaXQ+AQAgKExqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXI7KVYBAARDb2RlAQAPTGlu" +
+ "ZU51bWJlclRhYmxlAQA0KExqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXI8TGphdmEvbGFuZy9T" +
+ "dHJpbmc7PjspVgEABVN0YXJ0AQADKClWAQAGRmluaXNoAQAFc2F5SGkBABcoTGphdmEvbGFuZy9S" +
+ "dW5uYWJsZTspVgEAClNvdXJjZUZpbGUBAAxUZXN0OTE5LmphdmEMABMAGQwADwAQAQAdSGVsbG8g" +
+ "LSBwcml2YXRlIC0gVHJhbnNmb3JtZWQHADIMADMANAEAH0dvb2RieWUgLSBwcml2YXRlIC0gVHJh" +
+ "bnNmb3JtZWQBACtwcmUgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAAY" +
+ "ABkBACxwb3N0IFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAcANQwANgAZ" +
+ "AQAscHJlIEZpbmlzaCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQMABoAGQEALXBv" +
+ "c3QgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAcANwEAFWFydC9UZXN0" +
+ "OTE5JFRyYW5zZm9ybQEACVRyYW5zZm9ybQEADElubmVyQ2xhc3NlcwEAEGphdmEvbGFuZy9PYmpl" +
+ "Y3QBABtqYXZhL3V0aWwvZnVuY3Rpb24vQ29uc3VtZXIBAAZhY2NlcHQBABUoTGphdmEvbGFuZy9P" +
+ "YmplY3Q7KVYBABJqYXZhL2xhbmcvUnVubmFibGUBAANydW4BAAthcnQvVGVzdDkxOQAgAA0ADgAA" +
+ "AAEAAgAPABAAAQARAAAAAgASAAQAAQATABQAAgAVAAAAKgACAAIAAAAKKrcAASortQACsQAAAAEA" +
+ "FgAAAA4AAwAAAAgABAAJAAkACgARAAAAAgAXAAIAGAAZAAEAFQAAACgAAgABAAAADCq0AAISA7kA" +
+ "BAIAsQAAAAEAFgAAAAoAAgAAAA0ACwAOAAIAGgAZAAEAFQAAACgAAgABAAAADCq0AAISBbkABAIA" +
+ "sQAAAAEAFgAAAAoAAgAAABEACwASAAEAGwAcAAEAFQAAAG8AAgACAAAAOyq0AAISBrkABAIAKrcA" +
+ "Byq0AAISCLkABAIAK7kACQEAKrQAAhIKuQAEAgAqtwALKrQAAhIMuQAEAgCxAAAAAQAWAAAAIgAI" +
+ "AAAAFQALABYADwAXABoAGAAgABkAKwAaAC8AGwA6ABwAAgAdAAAAAgAeADAAAAAKAAEADQAtAC8A" +
+ "CA==");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQBeEZYBAAAAAAAAAAAAAAAAAAAAAAAAAACMBgAAcAAAAHhWNBIAAAAAAAAAAMgFAAAi" +
+ "AAAAcAAAAAkAAAD4AAAABAAAABwBAAABAAAATAEAAAcAAABUAQAAAQAAAIwBAADgBAAArAEAAKwB" +
+ "AACvAQAAsgEAALoBAAC+AQAAxAEAAMwBAADtAQAADAIAACUCAAA0AgAAWAIAAHgCAACXAgAAqwIA" +
+ "AMECAADVAgAA8wIAABIDAAAZAwAAJwMAADIDAAA1AwAAOQMAAEEDAABOAwAAVAMAAIMDAACxAwAA" +
+ "3wMAAAwEAAAWBAAAGwQAACIEAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAAEQAAABUAAAAV" +
+ "AAAACAAAAAAAAAAWAAAACAAAADQEAAAWAAAACAAAADwEAAAWAAAACAAAACwEAAAAAAcAHgAAAAAA" +
+ "AwACAAAAAAAAAAUAAAAAAAAAEgAAAAAAAgAgAAAABQAAAAIAAAAGAAAAHwAAAAcAAQAXAAAAAAAA" +
+ "AAAAAAAFAAAAAAAAABMAAACoBQAARAUAAAAAAAABKAABPAAGPGluaXQ+AAI+OwAEPjspVgAGRmlu" +
+ "aXNoAB9Hb29kYnllIC0gcHJpdmF0ZSAtIFRyYW5zZm9ybWVkAB1IZWxsbyAtIHByaXZhdGUgLSBU" +
+ "cmFuc2Zvcm1lZAAXTGFydC9UZXN0OTE5JFRyYW5zZm9ybTsADUxhcnQvVGVzdDkxOTsAIkxkYWx2" +
+ "aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNs" +
+ "YXNzOwAdTGRhbHZpay9hbm5vdGF0aW9uL1NpZ25hdHVyZTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAU" +
+ "TGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwAcTGphdmEvdXRpbC9mdW5j" +
+ "dGlvbi9Db25zdW1lcgAdTGphdmEvdXRpbC9mdW5jdGlvbi9Db25zdW1lcjsABVN0YXJ0AAxUZXN0" +
+ "OTE5LmphdmEACVRyYW5zZm9ybQABVgACVkwABmFjY2VwdAALYWNjZXNzRmxhZ3MABG5hbWUALXBv" +
+ "c3QgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAscG9zdCBTdGFydCBw" +
+ "cml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQALHByZSBGaW5pc2ggcHJpdmF0ZSBtZXRo" +
+ "b2QgY2FsbCAtIFRyYW5zZm9ybWVkACtwcmUgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRy" +
+ "YW5zZm9ybWVkAAhyZXBvcnRlcgADcnVuAAVzYXlIaQAFdmFsdWUAAAAAAQAAAAcAAAABAAAABQAA" +
+ "AAEAAAAGAAAACAEABw4BAw8BAg8AEQAHDgEIDwANAAcOAQgPABUBAAcOAQgPAQMPAQgPAQMPAQgP" +
+ "AQMPAQgPAAACAAIAAQAAAEQEAAAGAAAAcBAEAAAAWwEAAA4AAwABAAIAAABQBAAACQAAAFQgAAAb" +
+ "AQYAAAByIAYAEAAOAAAAAwABAAIAAABYBAAACQAAAFQgAAAbAQcAAAByIAYAEAAOAAAABAACAAIA" +
+ "AABgBAAAKgAAAFQgAAAbAR0AAAByIAYAEABwEAIAAgBUIAAAGwEbAAAAciAGABAAchAFAAMAVCAA" +
+ "ABsBHAAAAHIgBgAQAHAQAQACAFQgAAAbARoAAAByIAYAEAAOAAABAwEAAgCBgAT8CAECmAkBArwJ" +
+ "AwHgCQICASEYAQIDAhgECBkXFAIEASEcBBcQFwEXDxcDAgQBIRwFFwAXEBcBFw8XBAAAAAIAAABc" +
+ "BQAAYgUAAAEAAABrBQAAAQAAAHkFAACMBQAAAQAAAAEAAAAAAAAAAAAAAJgFAAAAAAAAoAUAABAA" +
+ "AAAAAAAAAQAAAAAAAAABAAAAIgAAAHAAAAACAAAACQAAAPgAAAADAAAABAAAABwBAAAEAAAAAQAA" +
+ "AEwBAAAFAAAABwAAAFQBAAAGAAAAAQAAAIwBAAACIAAAIgAAAKwBAAABEAAAAwAAACwEAAADIAAA" +
+ "BAAAAEQEAAABIAAABAAAAHwEAAAAIAAAAQAAAEQFAAAEIAAABAAAAFwFAAADEAAAAwAAAIwFAAAG" +
+ "IAAAAQAAAKgFAAAAEAAAAQAAAMgFAAA=");
+
+ // 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 static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ TestWatcher w = new TestWatcher();
+ doTest(new Transform(w), w);
+ }
+
+ public static void doTest(Transform t, TestWatcher w) {
+ Runnable do_redefinition = () -> {
+ w.accept("transforming calling function");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ };
+ // This just prints something out to show we are running the Runnable.
+ Runnable say_nothing = () -> { w.accept("Not doing anything here"); };
+
+ // Try and redefine.
+ t.sayHi(say_nothing);
+ t.sayHi(do_redefinition);
+ t.sayHi(say_nothing);
+
+ // Print output of last run.
+ System.out.print(w.getOutput());
+ }
+}
diff --git a/test/921-hello-failure/src/Main.java b/test/921-hello-failure/src/Main.java
index d9a49489f0..cfdcdc250f 100644
--- a/test/921-hello-failure/src/Main.java
+++ b/test/921-hello-failure/src/Main.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-import java.util.ArrayList;
+import art.Redefinition;
+import java.util.Arrays;
+
public class Main {
public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
-
Verification.doTest(new Transform());
NewName.doTest(new Transform());
DifferentAccess.doTest(new Transform());
@@ -37,40 +37,40 @@ public class Main {
Unmodifiable.doTest(new Transform[] { new Transform(), });
}
- // Transforms the class. This throws an exception if something goes wrong.
- public static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile) throws Exception;
-
- public static void doMultiClassRedefinition(CommonClassDefinition... defs) throws Exception {
- ArrayList<Class<?>> classes = new ArrayList<>();
- ArrayList<byte[]> class_files = new ArrayList<>();
- ArrayList<byte[]> dex_files = new ArrayList<>();
+ // TODO Replace this shim with a better re-write of this test.
+ private static Redefinition.CommonClassDefinition mapCCD(CommonClassDefinition d) {
+ return new Redefinition.CommonClassDefinition(d.target, d.class_file_bytes, d.dex_file_bytes);
+ }
- for (CommonClassDefinition d : defs) {
- classes.add(d.target);
- class_files.add(d.class_file_bytes);
- dex_files.add(d.dex_file_bytes);
- }
- doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
- class_files.toArray(new byte[0][]),
- dex_files.toArray(new byte[0][]));
+ private static Redefinition.CommonClassDefinition[] toCCDA(CommonClassDefinition[] ds) {
+ return Arrays.stream(ds).map(Main::mapCCD).toArray(Redefinition.CommonClassDefinition[]::new);
}
+ public static void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile) throws Exception {
+ Redefinition.doCommonClassRedefinition(target, classfile, dexfile);
+ }
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) throws Exception {
+ Redefinition.doMultiClassRedefinition(toCCDA(defs));
+ }
public static void addMultiTransformationResults(CommonClassDefinition... defs) throws Exception {
- for (CommonClassDefinition d : defs) {
- addCommonTransformationResult(d.target.getCanonicalName(),
- d.class_file_bytes,
- d.dex_file_bytes);
- }
+ Redefinition.addMultiTransformationResults(toCCDA(defs));
+ }
+ public static void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles) throws Exception {
+ Redefinition.doCommonMultiClassRedefinition(targets, classfiles, dexfiles);
+ }
+ public static void doCommonClassRetransformation(Class<?>... target) throws Exception {
+ Redefinition.doCommonClassRetransformation(target);
+ }
+ public static void enableCommonRetransformation(boolean enable) {
+ Redefinition.enableCommonRetransformation(enable);
+ }
+ public static void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes) {
+ Redefinition.addCommonTransformationResult(target_name, class_bytes, dex_bytes);
}
-
- public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
- byte[][] classfiles,
- byte[][] dexfiles) throws Exception;
- public static native void doCommonClassRetransformation(Class<?>... target) throws Exception;
- public static native void enableCommonRetransformation(boolean enable);
- public static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
}
diff --git a/test/921-hello-failure/src/art/Redefinition.java b/test/921-hello-failure/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/921-hello-failure/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/924-threads/expected.txt b/test/924-threads/expected.txt
index 4c0f4eaa5b..1eb2e1bd52 100644
--- a/test/924-threads/expected.txt
+++ b/test/924-threads/expected.txt
@@ -1,10 +1,10 @@
currentThread OK
-main
+TestThread
5
false
java.lang.ThreadGroup[name=main,maxpri=10]
class dalvik.system.PathClassLoader
-main
+TestThread
5
false
java.lang.ThreadGroup[name=main,maxpri=10]
@@ -33,10 +33,11 @@ class dalvik.system.PathClassLoader
e1 = ALIVE|WAITING_WITH_TIMEOUT|SLEEPING|WAITING
5 = ALIVE|RUNNABLE
2 = TERMINATED
-[Thread[FinalizerDaemon,5,system], Thread[FinalizerWatchdogDaemon,5,system], Thread[HeapTaskDaemon,5,system], Thread[ReferenceQueueDaemon,5,system], Thread[Signal Catcher,5,system], Thread[main,5,main]]
+[Thread[FinalizerDaemon,5,system], Thread[FinalizerWatchdogDaemon,5,system], Thread[HeapTaskDaemon,5,system], Thread[ReferenceQueueDaemon,5,system], Thread[TestThread,5,main], Thread[main,5,main]]
JVMTI_ERROR_THREAD_NOT_ALIVE
JVMTI_ERROR_THREAD_NOT_ALIVE
Constructed thread
-Thread(EventTestThread): start
-Thread(EventTestThread): end
+[]
+[Thread(EventTestThread): start]
+[Thread(EventTestThread): end]
Thread joined
diff --git a/test/924-threads/src/art/Test924.java b/test/924-threads/src/art/Test924.java
index 160bf8ea67..5445939cbc 100644
--- a/test/924-threads/src/art/Test924.java
+++ b/test/924-threads/src/art/Test924.java
@@ -25,17 +25,35 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
public class Test924 {
public static void run() throws Exception {
Main.bindAgentJNIForClass(Test924.class);
- doTest();
+
+ // Run the test on its own thread, so we have a known state for the "current" thread.
+ Thread t = new Thread("TestThread") {
+ @Override
+ public void run() {
+ try {
+ doTest();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ t.start();
+ t.join();
}
private static void doTest() throws Exception {
Thread t1 = Thread.currentThread();
Thread t2 = getCurrentThread();
+ // Need to adjust priority, as on-device this may be unexpected (and we prefer not
+ // to special-case this.)
+ t1.setPriority(5);
+
if (t1 != t2) {
throw new RuntimeException("Expected " + t1 + " but got " + t2);
}
@@ -188,7 +206,32 @@ public class Test924 {
}
Collections.sort(threadList, THREAD_COMP);
- System.out.println(threadList);
+
+ List<Thread> expectedList = new ArrayList<>();
+ Set<Thread> threadsFromTraces = Thread.getAllStackTraces().keySet();
+
+ expectedList.add(findThreadByName(threadsFromTraces, "FinalizerDaemon"));
+ expectedList.add(findThreadByName(threadsFromTraces, "FinalizerWatchdogDaemon"));
+ expectedList.add(findThreadByName(threadsFromTraces, "HeapTaskDaemon"));
+ expectedList.add(findThreadByName(threadsFromTraces, "ReferenceQueueDaemon"));
+ // We can't get the signal catcher through getAllStackTraces. So ignore it.
+ // expectedList.add(findThreadByName(threadsFromTraces, "Signal Catcher"));
+ expectedList.add(findThreadByName(threadsFromTraces, "TestThread"));
+ expectedList.add(findThreadByName(threadsFromTraces, "main"));
+
+ if (!threadList.containsAll(expectedList)) {
+ throw new RuntimeException("Expected " + expectedList + " as subset, got " + threadList);
+ }
+ System.out.println(expectedList);
+ }
+
+ private static Thread findThreadByName(Set<Thread> threads, String name) {
+ for (Thread t : threads) {
+ if (t.getName().equals(name)) {
+ return t;
+ }
+ }
+ throw new RuntimeException("Did not find thread " + name + ": " + threads);
}
private static void doTLSTests() throws Exception {
@@ -256,13 +299,35 @@ public class Test924 {
private static void doTestEvents() throws Exception {
enableThreadEvents(true);
- Thread t = new Thread("EventTestThread");
+ final CountDownLatch cdl1 = new CountDownLatch(1);
+ final CountDownLatch cdl2 = new CountDownLatch(1);
+
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ cdl1.countDown();
+ cdl2.await();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ Thread t = new Thread(r, "EventTestThread");
System.out.println("Constructed thread");
Thread.yield();
+ Thread.sleep(100);
+ System.out.println(Arrays.toString(getThreadEventMessages()));
t.start();
+ cdl1.await();
+
+ System.out.println(Arrays.toString(getThreadEventMessages()));
+
+ cdl2.countDown();
t.join();
+ System.out.println(Arrays.toString(getThreadEventMessages()));
System.out.println("Thread joined");
@@ -337,4 +402,5 @@ public class Test924 {
private static native void setTLS(Thread t, long l);
private static native long getTLS(Thread t);
private static native void enableThreadEvents(boolean b);
+ private static native String[] getThreadEventMessages();
}
diff --git a/test/924-threads/threads.cc b/test/924-threads/threads.cc
index 701ab1def3..e21dcc240e 100644
--- a/test/924-threads/threads.cc
+++ b/test/924-threads/threads.cc
@@ -16,6 +16,10 @@
#include <stdio.h>
+#include <mutex>
+#include <string>
+#include <vector>
+
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "jni.h"
@@ -139,17 +143,27 @@ extern "C" JNIEXPORT void JNICALL Java_art_Test924_setTLS(
JvmtiErrorToException(env, jvmti_env, result);
}
+static std::mutex gEventsMutex;
+static std::vector<std::string> gEvents;
+
static void JNICALL ThreadEvent(jvmtiEnv* jvmti_env,
JNIEnv* jni_env,
jthread thread,
bool is_start) {
jvmtiThreadInfo info;
- jvmtiError result = jvmti_env->GetThreadInfo(thread, &info);
- if (result != JVMTI_ERROR_NONE) {
- printf("Error getting thread info");
- return;
+ {
+ std::lock_guard<std::mutex> guard(gEventsMutex);
+
+ jvmtiError result = jvmti_env->GetThreadInfo(thread, &info);
+ if (result != JVMTI_ERROR_NONE) {
+ gEvents.push_back("Error getting thread info");
+ return;
+ }
+
+ gEvents.push_back(android::base::StringPrintf("Thread(%s): %s",
+ info.name,
+ is_start ? "start" : "end"));
}
- printf("Thread(%s): %s\n", info.name, is_start ? "start" : "end");
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(info.name));
jni_env->DeleteLocalRef(info.thread_group);
@@ -205,5 +219,18 @@ extern "C" JNIEXPORT void JNICALL Java_art_Test924_enableThreadEvents(
JvmtiErrorToException(env, jvmti_env, ret);
}
+extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test924_getThreadEventMessages(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+ std::lock_guard<std::mutex> guard(gEventsMutex);
+ jobjectArray ret = CreateObjectArray(env,
+ static_cast<jint>(gEvents.size()),
+ "java/lang/String",
+ [&](jint i) {
+ return env->NewStringUTF(gEvents[i].c_str());
+ });
+ gEvents.clear();
+ return ret;
+}
+
} // namespace Test924Threads
} // namespace art
diff --git a/test/926-multi-obsolescence/src/Main.java b/test/926-multi-obsolescence/src/Main.java
index 2440908c07..8e21b8f633 100644
--- a/test/926-multi-obsolescence/src/Main.java
+++ b/test/926-multi-obsolescence/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,115 +14,8 @@
* limitations under the License.
*/
-import java.util.ArrayList;
-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 CommonClassDefinition VALID_DEFINITION_T1 = new CommonClassDefinition(
- Transform.class,
- Base64.getDecoder().decode(
- "yv66vgAAADQAJAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" +
- "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
- "KVYBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkACgcAHAwAHQAeAQATSGVsbG8gLSBU" +
- "cmFuc2Zvcm1lZAcAHwwAIAAhBwAiDAAjAAoBABVHb29kYnllIC0gVHJhbnNmb3JtZWQBAAlUcmFu" +
- "c2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZh" +
- "L2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZh" +
- "L2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAABwAIAAAAAAACAAAA" +
- "CQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAAAQABAA0ADgABAAsAAAA7AAIA" +
- "AgAAABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAMACAAEAA4ABQAWAAYA" +
- "AQAPAAAAAgAQ"),
- Base64.getDecoder().decode(
- "ZGV4CjAzNQAYeAMMXgYWxoeSHAS9EWKCCtVRSAGpqZVQAwAAcAAAAHhWNBIAAAAAAAAAALACAAAR" +
- "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAMAgAARAEAAKIB" +
- "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAAB3AgAAfAIA" +
- "AIUCAACKAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" +
- "lAEAAAsAAAAGAAAAnAEAAAUAAQANAAAAAAAAAAAAAAAAAAEAEAAAAAEAAgAOAAAAAgAAAAAAAAAD" +
- "AAAADwAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAJ8CAAAAAAAAAQABAAEAAACRAgAABAAAAHAQ" +
- "AwAAAA4ABAACAAIAAACWAgAAFAAAAGIAAAAbAQIAAABuIAIAEAByEAQAAwBiAAAAGwEBAAAAbiAC" +
- "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" +
- "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" +
- "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" +
- "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00" +
- "LjEzAANvdXQAB3ByaW50bG4AA3J1bgAFc2F5SGkAAQAHDgADAQAHDoc8hwAAAAEBAICABMQCAQHc" +
- "AgAAAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAACAAAABwAAALQAAAADAAAAAwAAANAAAAAE" +
- "AAAAAQAAAPQAAAAFAAAABQAAAPwAAAAGAAAAAQAAACQBAAABIAAAAgAAAEQBAAABEAAAAgAAAJQB" +
- "AAACIAAAEQAAAKIBAAADIAAAAgAAAJECAAAAIAAAAQAAAJ8CAAAAEAAAAQAAALACAAA="));
- // class Transform2 {
- // public void sayHi(Runnable r) {
- // System.out.println("Hello 2 - Transformed");
- // r.run();
- // System.out.println("Goodbye 2 - Transformed");
- // }
- // }
- private static CommonClassDefinition VALID_DEFINITION_T2 = new CommonClassDefinition(
- Transform2.class,
- Base64.getDecoder().decode(
- "yv66vgAAADQAJAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" +
- "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
- "KVYBAApTb3VyY2VGaWxlAQAPVHJhbnNmb3JtMi5qYXZhDAAJAAoHABwMAB0AHgEAFUhlbGxvIDIg" +
- "LSBUcmFuc2Zvcm1lZAcAHwwAIAAhBwAiDAAjAAoBABdHb29kYnllIDIgLSBUcmFuc2Zvcm1lZAEA" +
- "ClRyYW5zZm9ybTIBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEA" +
- "FUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAV" +
- "KExqYXZhL2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAABwAIAAAA" +
- "AAACAAAACQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAAAQABAA0ADgABAAsA" +
- "AAA7AAIAAgAAABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAMACAAEAA4A" +
- "BQAWAAYAAQAPAAAAAgAQ"),
- Base64.getDecoder().decode(
- "ZGV4CjAzNQCee5Z6+AuFcjnPjjn7QYgZmKSmFQCO4nxUAwAAcAAAAHhWNBIAAAAAAAAAALQCAAAR" +
- "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAQAgAARAEAAKIB" +
- "AACqAQAAwwEAANoBAADoAQAA/wEAABMCAAApAgAAPQIAAFECAABiAgAAZQIAAGkCAAB9AgAAggIA" +
- "AIsCAACQAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" +
- "lAEAAAsAAAAGAAAAnAEAAAUAAQANAAAAAAAAAAAAAAAAAAEAEAAAAAEAAgAOAAAAAgAAAAAAAAAD" +
- "AAAADwAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAKUCAAAAAAAAAQABAAEAAACXAgAABAAAAHAQ" +
- "AwAAAA4ABAACAAIAAACcAgAAFAAAAGIAAAAbAQIAAABuIAIAEAByEAQAAwBiAAAAGwEBAAAAbiAC" +
- "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AF0dvb2RieWUgMiAtIFRyYW5zZm9ybWVkABVIZWxs" +
- "byAyIC0gVHJhbnNmb3JtZWQADExUcmFuc2Zvcm0yOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJM" +
- "amF2YS9sYW5nL09iamVjdDsAFExqYXZhL2xhbmcvUnVubmFibGU7ABJMamF2YS9sYW5nL1N0cmlu" +
- "ZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwAPVHJhbnNmb3JtMi5qYXZhAAFWAAJWTAASZW1pdHRlcjog" +
- "amFjay00LjIwAANvdXQAB3ByaW50bG4AA3J1bgAFc2F5SGkAAQAHDgADAQAHDoc8hwAAAAEBAICA" +
- "BMQCAQHcAgANAAAAAAAAAAEAAAAAAAAAAQAAABEAAABwAAAAAgAAAAcAAAC0AAAAAwAAAAMAAADQ" +
- "AAAABAAAAAEAAAD0AAAABQAAAAUAAAD8AAAABgAAAAEAAAAkAQAAASAAAAIAAABEAQAAARAAAAIA" +
- "AACUAQAAAiAAABEAAACiAQAAAyAAAAIAAACXAgAAACAAAAEAAAClAgAAABAAAAEAAAC0AgAA"));
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform(), new Transform2());
- }
-
- public static void doTest(final Transform t1, final Transform2 t2) {
- t1.sayHi(() -> { t2.sayHi(() -> { System.out.println("Not doing anything here"); }); });
- t1.sayHi(() -> {
- t2.sayHi(() -> {
- System.out.println("transforming calling functions");
- doMultiClassRedefinition(VALID_DEFINITION_T1, VALID_DEFINITION_T2);
- });
- });
- t1.sayHi(() -> { t2.sayHi(() -> { System.out.println("Not doing anything here"); }); });
+ public static void main(String[] args) throws Exception {
+ art.Test926.run();
}
-
- public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
- ArrayList<Class<?>> classes = new ArrayList<>();
- ArrayList<byte[]> class_files = new ArrayList<>();
- ArrayList<byte[]> dex_files = new ArrayList<>();
-
- for (CommonClassDefinition d : defs) {
- classes.add(d.target);
- class_files.add(d.class_file_bytes);
- dex_files.add(d.dex_file_bytes);
- }
- doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
- class_files.toArray(new byte[0][]),
- dex_files.toArray(new byte[0][]));
- }
-
- public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
- byte[][] classfiles,
- byte[][] dexfiles);
}
diff --git a/test/926-multi-obsolescence/src/Transform.java b/test/926-multi-obsolescence/src/Transform.java
deleted file mode 100644
index 8cda6cdf53..0000000000
--- a/test/926-multi-obsolescence/src/Transform.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class 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/926-multi-obsolescence/src/Transform2.java b/test/926-multi-obsolescence/src/Transform2.java
deleted file mode 100644
index 4877f8455b..0000000000
--- a/test/926-multi-obsolescence/src/Transform2.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform2 {
- public void sayHi(Runnable r) {
- System.out.println("hello - 2");
- r.run();
- System.out.println("goodbye - 2");
- }
-}
diff --git a/test/926-multi-obsolescence/src/art/Redefinition.java b/test/926-multi-obsolescence/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/926-multi-obsolescence/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/926-multi-obsolescence/src/art/Test926.java b/test/926-multi-obsolescence/src/art/Test926.java
new file mode 100644
index 0000000000..843d05c3fc
--- /dev/null
+++ b/test/926-multi-obsolescence/src/art/Test926.java
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import static art.Redefinition.CommonClassDefinition;
+import java.util.ArrayList;
+import java.util.Base64;
+
+public class Test926 {
+
+ static class Transform {
+ public void sayHi(Runnable r) {
+ System.out.println("hello");
+ r.run();
+ System.out.println("goodbye");
+ }
+ }
+
+ static class Transform2 {
+ public void sayHi(Runnable r) {
+ System.out.println("hello - 2");
+ r.run();
+ System.out.println("goodbye - 2");
+ }
+ }
+ // static class Transform {
+ // public void sayHi(Runnable r) {
+ // System.out.println("Hello - Transformed");
+ // r.run();
+ // System.out.println("Goodbye - Transformed");
+ // }
+ // }
+ private static CommonClassDefinition VALID_DEFINITION_T1 = new CommonClassDefinition(
+ Transform.class,
+ Base64.getDecoder().decode(
+ "yv66vgAAADQAKAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAbBwAeAQAGPGluaXQ+AQADKClW" +
+ "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
+ "KVYBAApTb3VyY2VGaWxlAQAMVGVzdDkyNi5qYXZhDAAJAAoHAB8MACAAIQEAE0hlbGxvIC0gVHJh" +
+ "bnNmb3JtZWQHACIMACMAJAcAJQwAJgAKAQAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkBwAnAQAVYXJ0" +
+ "L1Rlc3Q5MjYkVHJhbnNmb3JtAQAJVHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5n" +
+ "L09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsB" +
+ "ABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEA" +
+ "EmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgEAC2FydC9UZXN0OTI2ACAABwAIAAAAAAACAAAACQAK" +
+ "AAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAADAABAA0ADgABAAsAAAA7AAIAAgAA" +
+ "ABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAA4ACAAPAA4AEAAWABEAAgAP" +
+ "AAAAAgAQAB0AAAAKAAEABwAaABwACA=="),
+ Base64.getDecoder().decode(
+ "ZGV4CjAzNQB8m+R/AAAAAAAAAAAAAAAAAAAAAAAAAAA8BAAAcAAAAHhWNBIAAAAAAAAAAHgDAAAX" +
+ "AAAAcAAAAAoAAADMAAAAAwAAAPQAAAABAAAAGAEAAAUAAAAgAQAAAQAAAEgBAADUAgAAaAEAAGgB" +
+ "AABwAQAAhwEAAJwBAAC1AQAAxAEAAOgBAAAIAgAAHwIAADMCAABJAgAAXQIAAHECAAB/AgAAigIA" +
+ "AI0CAACRAgAAngIAAKQCAACpAgAAsgIAALcCAAC+AgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAA" +
+ "CQAAAAoAAAALAAAADgAAAA4AAAAJAAAAAAAAAA8AAAAJAAAAyAIAAA8AAAAJAAAA0AIAAAgABAAS" +
+ "AAAAAAAAAAAAAAAAAAEAFQAAAAQAAgATAAAABQAAAAAAAAAGAAAAFAAAAAAAAAAAAAAABQAAAAAA" +
+ "AAAMAAAAaAMAADwDAAAAAAAABjxpbml0PgAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkABNIZWxsbyAt" +
+ "IFRyYW5zZm9ybWVkABdMYXJ0L1Rlc3Q5MjYkVHJhbnNmb3JtOwANTGFydC9UZXN0OTI2OwAiTGRh" +
+ "bHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVy" +
+ "Q2xhc3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEv" +
+ "bGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AAxU" +
+ "ZXN0OTI2LmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vzc0ZsYWdzAARuYW1lAANvdXQAB3By" +
+ "aW50bG4AA3J1bgAFc2F5SGkABXZhbHVlAAAAAAEAAAAGAAAAAQAAAAcAAAAMAAcOAA4BAAcOAQgP" +
+ "AQMPAQgPAAEAAQABAAAA2AIAAAQAAABwEAMAAAAOAAQAAgACAAAA3QIAABQAAABiAAAAGwECAAAA" +
+ "biACABAAchAEAAMAYgAAABsBAQAAAG4gAgAQAA4AAAABAQCAgATsBQEBhAYAAAICARYYAQIDAhAE" +
+ "CBEXDQACAAAATAMAAFIDAABcAwAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAXAAAA" +
+ "cAAAAAIAAAAKAAAAzAAAAAMAAAADAAAA9AAAAAQAAAABAAAAGAEAAAUAAAAFAAAAIAEAAAYAAAAB" +
+ "AAAASAEAAAIgAAAXAAAAaAEAAAEQAAACAAAAyAIAAAMgAAACAAAA2AIAAAEgAAACAAAA7AIAAAAg" +
+ "AAABAAAAPAMAAAQgAAACAAAATAMAAAMQAAABAAAAXAMAAAYgAAABAAAAaAMAAAAQAAABAAAAeAMA" +
+ "AA=="));
+ // static class Transform2 {
+ // public void sayHi(Runnable r) {
+ // System.out.println("Hello 2 - Transformed");
+ // r.run();
+ // System.out.println("Goodbye 2 - Transformed");
+ // }
+ // }
+ private static CommonClassDefinition VALID_DEFINITION_T2 = new CommonClassDefinition(
+ Transform2.class,
+ Base64.getDecoder().decode(
+ "yv66vgAAADQAKAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAbBwAeAQAGPGluaXQ+AQADKClW" +
+ "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
+ "KVYBAApTb3VyY2VGaWxlAQAMVGVzdDkyNi5qYXZhDAAJAAoHAB8MACAAIQEAFUhlbGxvIDIgLSBU" +
+ "cmFuc2Zvcm1lZAcAIgwAIwAkBwAlDAAmAAoBABdHb29kYnllIDIgLSBUcmFuc2Zvcm1lZAcAJwEA" +
+ "FmFydC9UZXN0OTI2JFRyYW5zZm9ybTIBAApUcmFuc2Zvcm0yAQAMSW5uZXJDbGFzc2VzAQAQamF2" +
+ "YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0" +
+ "cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmlu" +
+ "ZzspVgEAEmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgEAC2FydC9UZXN0OTI2ACAABwAIAAAAAAAC" +
+ "AAAACQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAABQABAA0ADgABAAsAAAA7" +
+ "AAIAAgAAABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAcACAAIAA4ACQAW" +
+ "AAoAAgAPAAAAAgAQAB0AAAAKAAEABwAaABwACA=="),
+ Base64.getDecoder().decode(
+ "ZGV4CjAzNQBCnaUuAAAAAAAAAAAAAAAAAAAAAAAAAABABAAAcAAAAHhWNBIAAAAAAAAAAHwDAAAX" +
+ "AAAAcAAAAAoAAADMAAAAAwAAAPQAAAABAAAAGAEAAAUAAAAgAQAAAQAAAEgBAADYAgAAaAEAAGgB" +
+ "AABwAQAAiQEAAKABAAC6AQAAyQEAAO0BAAANAgAAJAIAADgCAABOAgAAYgIAAHYCAACEAgAAkAIA" +
+ "AJMCAACXAgAApAIAAKoCAACvAgAAuAIAAL0CAADEAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAA" +
+ "CQAAAAoAAAALAAAADgAAAA4AAAAJAAAAAAAAAA8AAAAJAAAAzAIAAA8AAAAJAAAA1AIAAAgABAAS" +
+ "AAAAAAAAAAAAAAAAAAEAFQAAAAQAAgATAAAABQAAAAAAAAAGAAAAFAAAAAAAAAAAAAAABQAAAAAA" +
+ "AAAMAAAAbAMAAEADAAAAAAAABjxpbml0PgAXR29vZGJ5ZSAyIC0gVHJhbnNmb3JtZWQAFUhlbGxv" +
+ "IDIgLSBUcmFuc2Zvcm1lZAAYTGFydC9UZXN0OTI2JFRyYW5zZm9ybTI7AA1MYXJ0L1Rlc3Q5MjY7" +
+ "ACJMZGFsdmlrL2Fubm90YXRpb24vRW5jbG9zaW5nQ2xhc3M7AB5MZGFsdmlrL2Fubm90YXRpb24v" +
+ "SW5uZXJDbGFzczsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABRM" +
+ "amF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5c3Rl" +
+ "bTsADFRlc3Q5MjYuamF2YQAKVHJhbnNmb3JtMgABVgACVkwAC2FjY2Vzc0ZsYWdzAARuYW1lAANv" +
+ "dXQAB3ByaW50bG4AA3J1bgAFc2F5SGkABXZhbHVlAAABAAAABgAAAAEAAAAHAAAABQAHDgAHAQAH" +
+ "DgEIDwEDDwEIDwABAAEAAQAAANwCAAAEAAAAcBADAAAADgAEAAIAAgAAAOECAAAUAAAAYgAAABsB" +
+ "AgAAAG4gAgAQAHIQBAADAGIAAAAbAQEAAABuIAIAEAAOAAAAAQEAgIAE8AUBAYgGAAACAgEWGAEC" +
+ "AwIQBAgRFw0AAgAAAFADAABWAwAAYAMAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAABAAAA" +
+ "FwAAAHAAAAACAAAACgAAAMwAAAADAAAAAwAAAPQAAAAEAAAAAQAAABgBAAAFAAAABQAAACABAAAG" +
+ "AAAAAQAAAEgBAAACIAAAFwAAAGgBAAABEAAAAgAAAMwCAAADIAAAAgAAANwCAAABIAAAAgAAAPAC" +
+ "AAAAIAAAAQAAAEADAAAEIAAAAgAAAFADAAADEAAAAQAAAGADAAAGIAAAAQAAAGwDAAAAEAAAAQAA" +
+ "AHwDAAA="));
+
+ public static void run() throws Exception {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ doTest(new Transform(), new Transform2());
+ }
+
+ public static void doTest(final Transform t1, final Transform2 t2) throws Exception {
+ t1.sayHi(() -> { t2.sayHi(() -> { System.out.println("Not doing anything here"); }); });
+ t1.sayHi(() -> {
+ t2.sayHi(() -> {
+ System.out.println("transforming calling functions");
+ Redefinition.doMultiClassRedefinition(VALID_DEFINITION_T1, VALID_DEFINITION_T2);
+ });
+ });
+ t1.sayHi(() -> { t2.sayHi(() -> { System.out.println("Not doing anything here"); }); });
+ }
+}
diff --git a/test/930-hello-retransform/src/Main.java b/test/930-hello-retransform/src/Main.java
index da59c7440b..38c1d363b6 100644
--- a/test/930-hello-retransform/src/Main.java
+++ b/test/930-hello-retransform/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,57 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
public class Main {
-
- /**
- * 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 static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test930.run();
}
-
- public static void doTest(Transform t) {
- t.sayHi();
- addCommonTransformationResult("Transform", CLASS_BYTES, DEX_BYTES);
- enableCommonRetransformation(true);
- doCommonClassRetransformation(Transform.class);
- t.sayHi();
- }
-
- // Transforms the class
- private static native void doCommonClassRetransformation(Class<?>... target);
- private static native void enableCommonRetransformation(boolean enable);
- private static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
}
diff --git a/test/930-hello-retransform/src/Transform.java b/test/930-hello-retransform/src/Transform.java
deleted file mode 100644
index 8e8af355da..0000000000
--- a/test/930-hello-retransform/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi() {
- // 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:
- // "Goodbye" < "LTransform;" < "hello".
- System.out.println("hello");
- }
-}
diff --git a/test/930-hello-retransform/src/art/Redefinition.java b/test/930-hello-retransform/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/930-hello-retransform/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/930-hello-retransform/src/art/Test930.java b/test/930-hello-retransform/src/art/Test930.java
new file mode 100644
index 0000000000..6c0fc16dad
--- /dev/null
+++ b/test/930-hello-retransform/src/art/Test930.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+public class Test930 {
+
+ static class Transform {
+ public void sayHi() {
+ System.out.println("hello");
+ }
+ }
+
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform {
+ * public void sayHi() {
+ * System.out.println("Goodbye");
+ * }
+ * }
+ */
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAIAoABgAOCQAPABAIABEKABIAEwcAFQcAGAEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAAxUZXN0OTMwLmphdmEMAAcA" +
+ "CAcAGQwAGgAbAQAHR29vZGJ5ZQcAHAwAHQAeBwAfAQAVYXJ0L1Rlc3Q5MzAkVHJhbnNmb3JtAQAJ" +
+ "VHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9T" +
+ "eXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFt" +
+ "AQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAC2FydC9UZXN0OTMwACAABQAGAAAA" +
+ "AAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAABQABAAsACAABAAkA" +
+ "AAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAHAAgACAACAAwAAAACAA0AFwAAAAoA" +
+ "AQAFABQAFgAI");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQBsgu9qAAAAAAAAAAAAAAAAAAAAAAAAAAC4AwAAcAAAAHhWNBIAAAAAAAAAAPQCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB0AgAARAEAAEQB" +
+ "AABMAQAAVQEAAG4BAAB9AQAAoQEAAMEBAADYAQAA7AEAAAACAAAUAgAAIgIAAC0CAAAwAgAANAIA" +
+ "AEECAABHAgAATAIAAFUCAABcAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABkAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA5AIAALgCAAAAAAAABjxpbml0PgAHR29vZGJ5ZQAX" +
+ "TGFydC9UZXN0OTMwJFRyYW5zZm9ybTsADUxhcnQvVGVzdDkzMDsAIkxkYWx2aWsvYW5ub3RhdGlv" +
+ "bi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEv" +
+ "aW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAS" +
+ "TGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTMwLmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vz" +
+ "c0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAQAAAAYAAAAFAAcOAAcA" +
+ "Bw4BCA8AAAAAAQABAAEAAABsAgAABAAAAHAQAwAAAA4AAwABAAIAAABxAgAACQAAAGIAAAAbAQEA" +
+ "AABuIAIAEAAOAAAAAAABAQCAgAT8BAEBlAUAAAICARMYAQIDAg4ECA8XCwACAAAAyAIAAM4CAADY" +
+ "AgAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAUAAAAcAAAAAIAAAAJAAAAwAAAAAMA" +
+ "AAACAAAA5AAAAAQAAAABAAAA/AAAAAUAAAAEAAAABAEAAAYAAAABAAAAJAEAAAIgAAAUAAAARAEA" +
+ "AAEQAAABAAAAZAIAAAMgAAACAAAAbAIAAAEgAAACAAAAfAIAAAAgAAABAAAAuAIAAAQgAAACAAAA" +
+ "yAIAAAMQAAABAAAA2AIAAAYgAAABAAAA5AIAAAAQAAABAAAA9AIAAA==");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_RETRANSFORM);
+ doTest(new Transform());
+ }
+
+ public static void doTest(Transform t) {
+ t.sayHi();
+ Redefinition.addCommonTransformationResult("art/Test930$Transform", CLASS_BYTES, DEX_BYTES);
+ Redefinition.enableCommonRetransformation(true);
+ Redefinition.doCommonClassRetransformation(Transform.class);
+ t.sayHi();
+ }
+}
diff --git a/test/932-transform-saves/src/Main.java b/test/932-transform-saves/src/Main.java
index 14e5da0d91..fba40f6828 100644
--- a/test/932-transform-saves/src/Main.java
+++ b/test/932-transform-saves/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,103 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
public class Main {
- /**
- * base64 encoded class/dex file for
- * class Transform {
- * public void sayHi() {
- * System.out.println("hello");
- * }
- * }
- */
- private static final byte[] CLASS_BYTES_A = Base64.getDecoder().decode(
- "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" +
- "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" +
- "BwAIBwAWDAAXABgBAAVoZWxsbwcAGQwAGgAbAQAJVHJhbnNmb3JtAQAQamF2YS9sYW5nL09iamVj" +
- "dAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZh" +
- "L2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgAgAAUABgAA" +
- "AAAAAgAAAAcACAABAAkAAAAdAAEAAQAAAAUqtwABsQAAAAEACgAAAAYAAQAAABEAAQALAAgAAQAJ" +
- "AAAAJQACAAEAAAAJsgACEgO2AASxAAAAAQAKAAAACgACAAAAGgAIABsAAQAMAAAAAgAN");
- private static final byte[] DEX_BYTES_A = Base64.getDecoder().decode(
- "ZGV4CjAzNQC6XWInnnDd1H4NdQ3P3inH8eCVmQI6W7LMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" +
- "AABqAQAAdwEAAI4BAACiAQAAtgEAAMoBAADaAQAA3QEAAOEBAAD1AQAA/AEAAAECAAAKAgAAAQAA" +
- "AAIAAAADAAAABAAAAAUAAAAHAAAABwAAAAUAAAAAAAAACAAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAGAAAAAAAAABwCAAAA" +
- "AAAAAQABAAEAAAARAgAABAAAAHAQAwAAAA4AAwABAAIAAAAWAgAACQAAAGIAAAAbAQoAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwAS" +
- "TGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVt" +
- "OwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTQuMjIABWhlbGxvAANvdXQA" +
- "B3ByaW50bG4ABXNheUhpABEABw4AGgAHDocAAAABAQCAgASgAgEBuAIAAA0AAAAAAAAAAQAAAAAA" +
- "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" +
- "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" +
- "AgAAABECAAAAIAAAAQAAABwCAAAAEAAAAQAAACwCAAA=");
-
- /**
- * base64 encoded class/dex file for
- * class Transform {
- * public void sayHi() {
- * System.out.println("Goodbye");
- * }
- * }
- */
- private static final byte[] CLASS_BYTES_B = Base64.getDecoder().decode(
- "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" +
- "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" +
- "BwAIBwAWDAAXABgBAAdHb29kYnllBwAZDAAaABsBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2Jq" +
- "ZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2ph" +
- "dmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABQAG" +
- "AAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAEQABAAsACAAB" +
- "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAATAAgAFAABAAwAAAACAA0=");
- private static final byte[] DEX_BYTES_B = Base64.getDecoder().decode(
- "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" +
- "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" +
- "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" +
- "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" +
- "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" +
- "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" +
- "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" +
- "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" +
- "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" +
- "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA=");
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test932.run();
}
-
- public static void doTest(Transform t) {
- // TODO We currently need to do this transform call since we don't have any way to make the
- // original-dex-file a single-class dex-file letting us restore it easily. We should use the
- // manipulation library that is being made when we store the original dex file.
- // TODO REMOVE this theoretically does nothing but it ensures the original-dex-file we have set
- // is one we can return to unaltered.
- doCommonClassRedefinition(Transform.class, CLASS_BYTES_A, DEX_BYTES_A);
- t.sayHi();
-
- // Now turn it into DEX_BYTES_B so it says 'Goodbye'
- addCommonTransformationResult("Transform", CLASS_BYTES_B, DEX_BYTES_B);
- enableCommonRetransformation(true);
- doCommonClassRetransformation(Transform.class);
- t.sayHi();
-
- // Now turn it back to normal by removing the load-hook and transforming again.
- enableCommonRetransformation(false);
- doCommonClassRetransformation(Transform.class);
- t.sayHi();
- }
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_bytes,
- byte[] dex_bytes);
- private static native void doCommonClassRetransformation(Class<?>... target);
- private static native void enableCommonRetransformation(boolean enable);
- private static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
}
diff --git a/test/932-transform-saves/src/Transform.java b/test/932-transform-saves/src/Transform.java
deleted file mode 100644
index 83f7aa4b4d..0000000000
--- a/test/932-transform-saves/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi() {
- // 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:
- // "Goodbye" < "LTransform;" < "hello".
- System.out.println("foobar");
- }
-}
diff --git a/test/932-transform-saves/src/art/Redefinition.java b/test/932-transform-saves/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/932-transform-saves/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/932-transform-saves/src/art/Test932.java b/test/932-transform-saves/src/art/Test932.java
new file mode 100644
index 0000000000..3a622322aa
--- /dev/null
+++ b/test/932-transform-saves/src/art/Test932.java
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+public class Test932 {
+
+ // This class is never used so just have it print out a bogus value so we can detect if something
+ // goes very wrong.
+ static class Transform {
+ public void sayHi() {
+ System.out.println("foobar");
+ }
+ }
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform {
+ * public void sayHi() {
+ * System.out.println("hello");
+ * }
+ * }
+ */
+ private static final byte[] CLASS_BYTES_A = Base64.getDecoder().decode(
+ "yv66vgAAADQAIAoABgAOCQAPABAIABEKABIAEwcAFQcAGAEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAAxUZXN0OTMyLmphdmEMAAcA" +
+ "CAcAGQwAGgAbAQAFaGVsbG8HABwMAB0AHgcAHwEAFWFydC9UZXN0OTMyJFRyYW5zZm9ybQEACVRy" +
+ "YW5zZm9ybQEADElubmVyQ2xhc3NlcwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lz" +
+ "dGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEA" +
+ "B3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAAthcnQvVGVzdDkzMgAgAAUABgAAAAAA" +
+ "AgAAAAcACAABAAkAAAAdAAEAAQAAAAUqtwABsQAAAAEACgAAAAYAAQAAAAUAAQALAAgAAQAJAAAA" +
+ "JQACAAEAAAAJsgACEgO2AASxAAAAAQAKAAAACgACAAAABwAIAAgAAgAMAAAAAgANABcAAAAKAAEA" +
+ "BQAUABYACA==");
+ private static final byte[] DEX_BYTES_A = Base64.getDecoder().decode(
+ "ZGV4CjAzNQAngjnzAAAAAAAAAAAAAAAAAAAAAAAAAAC4AwAAcAAAAHhWNBIAAAAAAAAAAPQCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB0AgAARAEAAEQB" +
+ "AABMAQAAZQEAAHQBAACYAQAAuAEAAM8BAADjAQAA9wEAAAsCAAAZAgAAJAIAACcCAAArAgAAOAIA" +
+ "AD8CAABFAgAASgIAAFMCAABaAgAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAALAAAA" +
+ "CwAAAAgAAAAAAAAADAAAAAgAAABkAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAJAAAA5AIAALgCAAAAAAAABjxpbml0PgAXTGFydC9UZXN0" +
+ "OTMyJFRyYW5zZm9ybTsADUxhcnQvVGVzdDkzMjsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3Np" +
+ "bmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEvaW8vUHJpbnRT" +
+ "dHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFu" +
+ "Zy9TeXN0ZW07AAxUZXN0OTMyLmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vzc0ZsYWdzAAVo" +
+ "ZWxsbwAEbmFtZQADb3V0AAdwcmludGxuAAVzYXlIaQAFdmFsdWUAAAAAAQAAAAYAAAAFAAcOAAcA" +
+ "Bw4BCA8AAAAAAQABAAEAAABsAgAABAAAAHAQAwAAAA4AAwABAAIAAABxAgAACQAAAGIAAAAbAQ4A" +
+ "AABuIAIAEAAOAAAAAAABAQCAgAT8BAEBlAUAAAICARMYAQIDAg0ECA8XCgACAAAAyAIAAM4CAADY" +
+ "AgAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAUAAAAcAAAAAIAAAAJAAAAwAAAAAMA" +
+ "AAACAAAA5AAAAAQAAAABAAAA/AAAAAUAAAAEAAAABAEAAAYAAAABAAAAJAEAAAIgAAAUAAAARAEA" +
+ "AAEQAAABAAAAZAIAAAMgAAACAAAAbAIAAAEgAAACAAAAfAIAAAAgAAABAAAAuAIAAAQgAAACAAAA" +
+ "yAIAAAMQAAABAAAA2AIAAAYgAAABAAAA5AIAAAAQAAABAAAA9AIAAA==");
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform {
+ * public void sayHi() {
+ * System.out.println("Goodbye");
+ * }
+ * }
+ */
+ private static final byte[] CLASS_BYTES_B = Base64.getDecoder().decode(
+ "yv66vgAAADQAIAoABgAOCQAPABAIABEKABIAEwcAFQcAGAEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAAxUZXN0OTMyLmphdmEMAAcA" +
+ "CAcAGQwAGgAbAQAHR29vZGJ5ZQcAHAwAHQAeBwAfAQAVYXJ0L1Rlc3Q5MzIkVHJhbnNmb3JtAQAJ" +
+ "VHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9T" +
+ "eXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFt" +
+ "AQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAC2FydC9UZXN0OTMyACAABQAGAAAA" +
+ "AAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAABQABAAsACAABAAkA" +
+ "AAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAHAAgACAACAAwAAAACAA0AFwAAAAoA" +
+ "AQAFABQAFgAI");
+ private static final byte[] DEX_BYTES_B = Base64.getDecoder().decode(
+ "ZGV4CjAzNQByglN3AAAAAAAAAAAAAAAAAAAAAAAAAAC4AwAAcAAAAHhWNBIAAAAAAAAAAPQCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB0AgAARAEAAEQB" +
+ "AABMAQAAVQEAAG4BAAB9AQAAoQEAAMEBAADYAQAA7AEAAAACAAAUAgAAIgIAAC0CAAAwAgAANAIA" +
+ "AEECAABHAgAATAIAAFUCAABcAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABkAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA5AIAALgCAAAAAAAABjxpbml0PgAHR29vZGJ5ZQAX" +
+ "TGFydC9UZXN0OTMyJFRyYW5zZm9ybTsADUxhcnQvVGVzdDkzMjsAIkxkYWx2aWsvYW5ub3RhdGlv" +
+ "bi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEv" +
+ "aW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAS" +
+ "TGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTMyLmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vz" +
+ "c0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAQAAAAYAAAAFAAcOAAcA" +
+ "Bw4BCA8AAAAAAQABAAEAAABsAgAABAAAAHAQAwAAAA4AAwABAAIAAABxAgAACQAAAGIAAAAbAQEA" +
+ "AABuIAIAEAAOAAAAAAABAQCAgAT8BAEBlAUAAAICARMYAQIDAg4ECA8XCwACAAAAyAIAAM4CAADY" +
+ "AgAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAUAAAAcAAAAAIAAAAJAAAAwAAAAAMA" +
+ "AAACAAAA5AAAAAQAAAABAAAA/AAAAAUAAAAEAAAABAEAAAYAAAABAAAAJAEAAAIgAAAUAAAARAEA" +
+ "AAEQAAABAAAAZAIAAAMgAAACAAAAbAIAAAEgAAACAAAAfAIAAAAgAAABAAAAuAIAAAQgAAACAAAA" +
+ "yAIAAAMQAAABAAAA2AIAAAYgAAABAAAA5AIAAAAQAAABAAAA9AIAAA==");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_RETRANSFORM);
+ doTest(new Transform());
+ }
+
+ public static void doTest(Transform t) {
+ // TODO We currently need to do this transform call since we don't have any way to make the
+ // original-dex-file a single-class dex-file letting us restore it easily. We should use the
+ // manipulation library that is being made when we store the original dex file.
+ // TODO REMOVE this theoretically does nothing but it ensures the original-dex-file we have set
+ // is one we can return to unaltered.
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES_A, DEX_BYTES_A);
+ t.sayHi();
+
+ // Now turn it into DEX_BYTES_B so it says 'Goodbye'
+ Redefinition.addCommonTransformationResult("art/Test932$Transform", CLASS_BYTES_B, DEX_BYTES_B);
+ Redefinition.enableCommonRetransformation(true);
+ Redefinition.doCommonClassRetransformation(Transform.class);
+ t.sayHi();
+
+ // Now turn it back to normal by removing the load-hook and transforming again.
+ Redefinition.enableCommonRetransformation(false);
+ Redefinition.doCommonClassRetransformation(Transform.class);
+ t.sayHi();
+ }
+}
diff --git a/test/934-load-transform/src/Main.java b/test/934-load-transform/src/Main.java
index 606ce78a5b..69c839fdb2 100644
--- a/test/934-load-transform/src/Main.java
+++ b/test/934-load-transform/src/Main.java
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+import static art.Redefinition.addCommonTransformationResult;
+import static art.Redefinition.enableCommonRetransformation;
+import static art.Redefinition.setPopRetransformations;
+
import java.lang.reflect.*;
import java.util.Base64;
@@ -86,11 +90,4 @@ class Main {
e.printStackTrace();
}
}
-
- private static native void setPopRetransformations(boolean should_pop);
- // Transforms the class
- private static native void enableCommonRetransformation(boolean enable);
- private static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
}
diff --git a/test/934-load-transform/src/art/Redefinition.java b/test/934-load-transform/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/934-load-transform/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/935-non-retransformable/src/Main.java b/test/935-non-retransformable/src/Main.java
index df92561784..f240224977 100644
--- a/test/935-non-retransformable/src/Main.java
+++ b/test/935-non-retransformable/src/Main.java
@@ -17,6 +17,8 @@
import java.lang.reflect.*;
import java.util.Base64;
+import art.Redefinition;
+
class Main {
public static String TEST_NAME = "935-non-retransformable";
@@ -74,10 +76,9 @@ class Main {
}
public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- setPopRetransformations(false);
- addCommonTransformationResult("Transform", CLASS_BYTES, DEX_BYTES);
- enableCommonRetransformation(true);
+ Redefinition.setPopRetransformations(false);
+ Redefinition.addCommonTransformationResult("Transform", CLASS_BYTES, DEX_BYTES);
+ Redefinition.enableCommonRetransformation(true);
try {
/* this is the "alternate" DEX/Jar file */
ClassLoader new_loader = getClassLoaderFor(System.getenv("DEX_LOCATION"));
@@ -89,23 +90,14 @@ class Main {
run_test.invoke(null);
// Remove the original transformation. It has been used by now.
- popTransformationFor("Transform");
+ Redefinition.popTransformationFor("Transform");
// Make sure we don't get called for transformation again.
- addCommonTransformationResult("Transform", new byte[0], new byte[0]);
- doCommonClassRetransformation(new_loader.loadClass("Transform"));
+ Redefinition.addCommonTransformationResult("Transform", new byte[0], new byte[0]);
+ Redefinition.doCommonClassRetransformation(new_loader.loadClass("Transform"));
run_test.invoke(null);
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
}
-
- // Transforms the class
- private static native void doCommonClassRetransformation(Class<?>... classes);
- private static native void enableCommonRetransformation(boolean enable);
- private static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
- private static native void setPopRetransformations(boolean should_pop);
- private static native void popTransformationFor(String target_name);
}
diff --git a/test/935-non-retransformable/src/art/Redefinition.java b/test/935-non-retransformable/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/935-non-retransformable/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/937-hello-retransform-package/src/Main.java b/test/937-hello-retransform-package/src/Main.java
index 866f75d5e6..eef56c2c34 100644
--- a/test/937-hello-retransform-package/src/Main.java
+++ b/test/937-hello-retransform-package/src/Main.java
@@ -17,6 +17,8 @@
import java.util.Base64;
import testing.*;
+import art.Redefinition;
+
public class Main {
/**
@@ -53,22 +55,14 @@ public class Main {
"YgEAAAMgAAACAAAAGwIAAAAgAAABAAAAJgIAAAAQAAABAAAANAIAAA==");
public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
doTest(new Transform());
}
public static void doTest(Transform t) {
t.sayHi();
- addCommonTransformationResult("testing/Transform", CLASS_BYTES, DEX_BYTES);
- enableCommonRetransformation(true);
- doCommonClassRetransformation(Transform.class);
+ Redefinition.addCommonTransformationResult("testing/Transform", CLASS_BYTES, DEX_BYTES);
+ Redefinition.enableCommonRetransformation(true);
+ Redefinition.doCommonClassRetransformation(Transform.class);
t.sayHi();
}
-
- // Transforms the class
- private static native void doCommonClassRetransformation(Class<?>... target);
- private static native void enableCommonRetransformation(boolean enable);
- private static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
}
diff --git a/test/937-hello-retransform-package/src/art/Redefinition.java b/test/937-hello-retransform-package/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/937-hello-retransform-package/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/938-load-transform-bcp/src/Main.java b/test/938-load-transform-bcp/src/Main.java
index 21b841f06a..e560942729 100644
--- a/test/938-load-transform-bcp/src/Main.java
+++ b/test/938-load-transform-bcp/src/Main.java
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import static art.Redefinition.*;
import java.lang.reflect.*;
import java.util.Base64;
@@ -114,11 +115,4 @@ class Main {
e.printStackTrace();
}
}
-
- private static native void setPopRetransformations(boolean should_pop);
- // Transforms the class
- private static native void enableCommonRetransformation(boolean enable);
- private static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
}
diff --git a/test/938-load-transform-bcp/src/art/Redefinition.java b/test/938-load-transform-bcp/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/938-load-transform-bcp/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/939-hello-transformation-bcp/src/Main.java b/test/939-hello-transformation-bcp/src/Main.java
index 0e1f845ab9..7bda667357 100644
--- a/test/939-hello-transformation-bcp/src/Main.java
+++ b/test/939-hello-transformation-bcp/src/Main.java
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import static art.Redefinition.doCommonClassRedefinition;
import java.util.Base64;
import java.util.OptionalLong;
public class Main {
@@ -110,7 +111,6 @@ public class Main {
"AABHBgAABCAAAAIAAACVBgAAACAAAAEAAACtBgAAABAAAAEAAAD4BgAA");
public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
// OptionalLong is a class that is unlikely to be used by the time this test starts and is not
// likely to be changed in any meaningful way in the future.
OptionalLong ol = OptionalLong.of(0xDEADBEEF);
@@ -119,9 +119,4 @@ public class Main {
doCommonClassRedefinition(OptionalLong.class, CLASS_BYTES, DEX_BYTES);
System.out.println("ol.toString() -> '" + ol.toString() + "'");
}
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
}
diff --git a/test/939-hello-transformation-bcp/src/art/Redefinition.java b/test/939-hello-transformation-bcp/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/939-hello-transformation-bcp/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/940-recursive-obsolete/src/Main.java b/test/940-recursive-obsolete/src/Main.java
index 724f82de27..0b0211c2c3 100644
--- a/test/940-recursive-obsolete/src/Main.java
+++ b/test/940-recursive-obsolete/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,77 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
-
public class Main {
-
- // class Transform {
- // public void sayHi(int recur, Runnable r) {
- // System.out.println("Hello" + recur + " - transformed");
- // if (recur == 1) {
- // r.run();
- // sayHi(recur - 1, r);
- // } else if (recur != 0) {
- // sayHi(recur - 1, r);
- // }
- // System.out.println("Goodbye" + recur + " - transformed");
- // }
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQANwoADwAZCQAaABsHABwKAAMAGQgAHQoAAwAeCgADAB8IACAKAAMAIQoAIgAjCwAk" +
- "ACUKAA4AJggAJwcAKAcAKQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUB" +
- "AAVzYXlIaQEAGChJTGphdmEvbGFuZy9SdW5uYWJsZTspVgEADVN0YWNrTWFwVGFibGUBAApTb3Vy" +
- "Y2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMABAAEQcAKgwAKwAsAQAXamF2YS9sYW5nL1N0cmluZ0J1" +
- "aWxkZXIBAAVIZWxsbwwALQAuDAAtAC8BAA4gLSB0cmFuc2Zvcm1lZAwAMAAxBwAyDAAzADQHADUM" +
- "ADYAEQwAFAAVAQAHR29vZGJ5ZQEACVRyYW5zZm9ybQEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZh" +
- "L2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQAGYXBwZW5kAQAtKExq" +
- "YXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAcKEkpTGphdmEvbGFu" +
- "Zy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAUKClMamF2YS9sYW5nL1N0cmluZzsBABNqYXZh" +
- "L2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEmphdmEv" +
- "bGFuZy9SdW5uYWJsZQEAA3J1bgAgAA4ADwAAAAAAAgAAABAAEQABABIAAAAdAAEAAQAAAAUqtwAB" +
- "sQAAAAEAEwAAAAYAAQAAAAEAAQAUABUAAQASAAAAnQADAAMAAABfsgACuwADWbcABBIFtgAGG7YA" +
- "BxIItgAGtgAJtgAKGwSgABQsuQALAQAqGwRkLLYADKcADxuZAAsqGwRkLLYADLIAArsAA1m3AAQS" +
- "DbYABhu2AAcSCLYABrYACbYACrEAAAACABMAAAAiAAgAAAADAB4ABAAjAAUAKQAGADQABwA4AAgA" +
- "QAAKAF4ACwAWAAAABAACNAsAAQAXAAAAAgAY");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQA3pkIgnymz2/eri+mp2dyZo3jolQmaRPKEBAAAcAAAAHhWNBIAAAAAAAAAAOQDAAAa" +
- "AAAAcAAAAAkAAADYAAAABgAAAPwAAAABAAAARAEAAAkAAABMAQAAAQAAAJQBAADQAgAAtAEAAJwC" +
- "AACsAgAAtAIAAL0CAADEAgAAxwIAAMoCAADOAgAA0gIAAN8CAAD2AgAACgMAACADAAA0AwAATwMA" +
- "AGMDAABzAwAAdgMAAHsDAAB/AwAAhwMAAJsDAACgAwAAqQMAAK4DAAC1AwAABAAAAAgAAAAJAAAA" +
- "CgAAAAsAAAAMAAAADQAAAA4AAAAQAAAABQAAAAUAAAAAAAAABgAAAAYAAACEAgAABwAAAAYAAACM" +
- "AgAAEAAAAAgAAAAAAAAAEQAAAAgAAACUAgAAEgAAAAgAAACMAgAABwACABUAAAABAAMAAQAAAAEA" +
- "BAAYAAAAAgAFABYAAAADAAMAAQAAAAQAAwAXAAAABgADAAEAAAAGAAEAEwAAAAYAAgATAAAABgAA" +
- "ABkAAAABAAAAAAAAAAMAAAAAAAAADwAAAAAAAADWAwAAAAAAAAEAAQABAAAAvwMAAAQAAABwEAMA" +
- "AAAOAAYAAwADAAAAxAMAAFQAAABiAAAAIgEGAHAQBQABABsCAwAAAG4gBwAhAAwBbiAGAEEADAEb" +
- "AgAAAABuIAcAIQAMAW4QCAABAAwBbiACABAAEhAzBCsAchAEAAUA2AAE/24wAQADBWIAAAAiAQYA" +
- "cBAFAAEAGwICAAAAbiAHACEADAFuIAYAQQAMARsCAAAAAG4gBwAhAAwBbhAIAAEADAFuIAIAEAAO" +
- "ADgE3//YAAT/bjABAAMFKNgBAAAAAAAAAAEAAAAFAAAAAgAAAAAABAAOIC0gdHJhbnNmb3JtZWQA" +
- "Bjxpbml0PgAHR29vZGJ5ZQAFSGVsbG8AAUkAAUwAAkxJAAJMTAALTFRyYW5zZm9ybTsAFUxqYXZh" +
- "L2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxl" +
- "OwASTGphdmEvbGFuZy9TdHJpbmc7ABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7ABJMamF2YS9s" +
- "YW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAANWSUwAAlZMAAZhcHBlbmQAEmVtaXR0ZXI6" +
- "IGphY2stNC4yNAADb3V0AAdwcmludGxuAANydW4ABXNheUhpAAh0b1N0cmluZwABAAcOAAMCAAAH" +
- "DgEgDzw8XQEgDxktAAAAAQEAgIAEtAMBAcwDDQAAAAAAAAABAAAAAAAAAAEAAAAaAAAAcAAAAAIA" +
- "AAAJAAAA2AAAAAMAAAAGAAAA/AAAAAQAAAABAAAARAEAAAUAAAAJAAAATAEAAAYAAAABAAAAlAEA" +
- "AAEgAAACAAAAtAEAAAEQAAADAAAAhAIAAAIgAAAaAAAAnAIAAAMgAAACAAAAvwMAAAAgAAABAAAA" +
- "1gMAAAAQAAABAAAA5AMAAA==");
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test940.run();
}
-
- public static void doTest(Transform t) {
- t.sayHi(2, () -> { System.out.println("Not doing anything here"); });
- t.sayHi(2, () -> {
- System.out.println("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- });
- t.sayHi(2, () -> { 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/940-recursive-obsolete/src/Transform.java b/test/940-recursive-obsolete/src/Transform.java
deleted file mode 100644
index 97522cddf6..0000000000
--- a/test/940-recursive-obsolete/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi(int recur, Runnable r) {
- System.out.println("hello" + recur);
- if (recur == 1) {
- r.run();
- sayHi(recur - 1, r);
- } else if (recur != 0) {
- sayHi(recur - 1, r);
- }
- System.out.println("goodbye" + recur);
- }
-}
diff --git a/test/940-recursive-obsolete/src/art/Redefinition.java b/test/940-recursive-obsolete/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/940-recursive-obsolete/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/940-recursive-obsolete/src/art/Test940.java b/test/940-recursive-obsolete/src/art/Test940.java
new file mode 100644
index 0000000000..d67d7726da
--- /dev/null
+++ b/test/940-recursive-obsolete/src/art/Test940.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Test940 {
+
+ static class Transform {
+ public void sayHi(int recur, Runnable r) {
+ System.out.println("hello" + recur);
+ if (recur == 1) {
+ r.run();
+ sayHi(recur - 1, r);
+ } else if (recur != 0) {
+ sayHi(recur - 1, r);
+ }
+ System.out.println("goodbye" + recur);
+ }
+ }
+
+
+ // static class Transform {
+ // public void sayHi(int recur, Runnable r) {
+ // System.out.println("Hello" + recur + " - transformed");
+ // if (recur == 1) {
+ // r.run();
+ // sayHi(recur - 1, r);
+ // } else if (recur != 0) {
+ // sayHi(recur - 1, r);
+ // }
+ // System.out.println("Goodbye" + recur + " - transformed");
+ // }
+ // }
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAOwoADwAZCQAaABsHABwKAAMAGQgAHQoAAwAeCgADAB8IACAKAAMAIQoAIgAjCwAk" +
+ "ACUKAA4AJggAJwcAKQcALAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUB" +
+ "AAVzYXlIaQEAGChJTGphdmEvbGFuZy9SdW5uYWJsZTspVgEADVN0YWNrTWFwVGFibGUBAApTb3Vy" +
+ "Y2VGaWxlAQAMVGVzdDk0MC5qYXZhDAAQABEHAC0MAC4ALwEAF2phdmEvbGFuZy9TdHJpbmdCdWls" +
+ "ZGVyAQAFSGVsbG8MADAAMQwAMAAyAQAOIC0gdHJhbnNmb3JtZWQMADMANAcANQwANgA3BwA4DAA5" +
+ "ABEMABQAFQEAB0dvb2RieWUHADoBABVhcnQvVGVzdDk0MCRUcmFuc2Zvcm0BAAlUcmFuc2Zvcm0B" +
+ "AAxJbm5lckNsYXNzZXMBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291" +
+ "dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEABmFwcGVuZAEALShMamF2YS9sYW5nL1N0cmluZzsp" +
+ "TGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEAHChJKUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsB" +
+ "AAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQATamF2YS9pby9QcmludFN0cmVhbQEA" +
+ "B3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABJqYXZhL2xhbmcvUnVubmFibGUBAANy" +
+ "dW4BAAthcnQvVGVzdDk0MAAgAA4ADwAAAAAAAgAAABAAEQABABIAAAAdAAEAAQAAAAUqtwABsQAA" +
+ "AAEAEwAAAAYAAQAAAAUAAQAUABUAAQASAAAAnQADAAMAAABfsgACuwADWbcABBIFtgAGG7YABxII" +
+ "tgAGtgAJtgAKGwSgABQsuQALAQAqGwRkLLYADKcADxuZAAsqGwRkLLYADLIAArsAA1m3AAQSDbYA" +
+ "Bhu2AAcSCLYABrYACbYACrEAAAACABMAAAAiAAgAAAAHAB4ACAAjAAkAKQAKADQACwA4AAwAQAAO" +
+ "AF4ADwAWAAAABAACNAsAAgAXAAAAAgAYACsAAAAKAAEADgAoACoACA==");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQDQv3jgAAAAAAAAAAAAAAAAAAAAAAAAAAB8BQAAcAAAAHhWNBIAAAAAAAAAALgEAAAg" +
+ "AAAAcAAAAAwAAADwAAAABgAAACABAAABAAAAaAEAAAkAAABwAQAAAQAAALgBAACkAwAA2AEAANgB" +
+ "AADoAQAA8AEAAPkBAAAAAgAAAwIAAAYCAAAKAgAADgIAACcCAAA2AgAAWgIAAHoCAACRAgAApQIA" +
+ "ALsCAADPAgAA6gIAAP4CAAAMAwAAFwMAABoDAAAfAwAAIwMAADADAAA4AwAAPgMAAEMDAABMAwAA" +
+ "UQMAAFgDAABiAwAABAAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAAU" +
+ "AAAABQAAAAgAAAAAAAAABgAAAAkAAAB8AwAABwAAAAkAAAB0AwAAFAAAAAsAAAAAAAAAFQAAAAsA" +
+ "AABsAwAAFgAAAAsAAAB0AwAACgAFABoAAAABAAMAAQAAAAEABAAdAAAABQAFABsAAAAGAAMAAQAA" +
+ "AAcAAwAcAAAACQADAAEAAAAJAAEAGAAAAAkAAgAYAAAACQAAAB4AAAABAAAAAAAAAAYAAAAAAAAA" +
+ "EgAAAKgEAAB8BAAAAAAAAA4gLSB0cmFuc2Zvcm1lZAAGPGluaXQ+AAdHb29kYnllAAVIZWxsbwAB" +
+ "SQABTAACTEkAAkxMABdMYXJ0L1Rlc3Q5NDAkVHJhbnNmb3JtOwANTGFydC9UZXN0OTQwOwAiTGRh" +
+ "bHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVy" +
+ "Q2xhc3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEv" +
+ "bGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwAZTGphdmEvbGFuZy9TdHJpbmdCdWls" +
+ "ZGVyOwASTGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTQwLmphdmEACVRyYW5zZm9ybQABVgADVklM" +
+ "AAJWTAALYWNjZXNzRmxhZ3MABmFwcGVuZAAEbmFtZQADb3V0AAdwcmludGxuAANydW4ABXNheUhp" +
+ "AAh0b1N0cmluZwAFdmFsdWUAAAAAAgAAAAAABwABAAAACAAAAAEAAAAAAAAABQAHDgAHAgAABw4B" +
+ "IA8BAw8BAw8BBRIBIA8BAQoBAg8AAAAAAQABAAEAAACEAwAABAAAAHAQAwAAAA4ABgADAAMAAACJ" +
+ "AwAAVQAAAGIAAAAiAQkAcBAFAAEAGwIDAAAAbiAHACEADAFuIAYAQQAMARsCAAAAAG4gBwAhAAwB" +
+ "bhAIAAEADAFuIAIAEAASEDMEKwByEAQABQDYAAT/bjABAAMFYgAAACIBCQBwEAUAAQAbAgIAAABu" +
+ "IAcAIQAMAW4gBgBBAAwBGwIAAAAAbiAHACEADAFuEAgAAQAMAW4gAgAQAA4AOATf/9gABP9uMAEA" +
+ "AwUpANj/AAAAAAEBAICABKgHAQHABwAAAgMBHxgCAgQCFwQIGRcTAAIAAACMBAAAkgQAAJwEAAAA" +
+ "AAAAAAAAAAAAAAAQAAAAAAAAAAEAAAAAAAAAAQAAACAAAABwAAAAAgAAAAwAAADwAAAAAwAAAAYA" +
+ "AAAgAQAABAAAAAEAAABoAQAABQAAAAkAAABwAQAABgAAAAEAAAC4AQAAAiAAACAAAADYAQAAARAA" +
+ "AAMAAABsAwAAAyAAAAIAAACEAwAAASAAAAIAAACoAwAAACAAAAEAAAB8BAAABCAAAAIAAACMBAAA" +
+ "AxAAAAEAAACcBAAABiAAAAEAAACoBAAAABAAAAEAAAC4BAAA");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ doTest(new Transform());
+ }
+
+ public static void doTest(Transform t) {
+ t.sayHi(2, () -> { System.out.println("Not doing anything here"); });
+ t.sayHi(2, () -> {
+ System.out.println("transforming calling function");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ });
+ t.sayHi(2, () -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/941-recurive-obsolete-jit/src/Main.java b/test/941-recurive-obsolete-jit/src/Main.java
index d88bb9b722..1c391a4db5 100644
--- a/test/941-recurive-obsolete-jit/src/Main.java
+++ b/test/941-recurive-obsolete-jit/src/Main.java
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+import static art.Redefinition.doCommonClassRedefinition;
+
import java.util.Base64;
import java.util.function.Consumer;
import java.lang.reflect.Method;
@@ -148,9 +150,4 @@ public class Main {
private static native boolean isInterpretedFunction(Method m, boolean require_deoptimizable);
private static native void ensureJitCompiled(Class c, String name);
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
}
diff --git a/test/941-recurive-obsolete-jit/src/art/Redefinition.java b/test/941-recurive-obsolete-jit/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/941-recurive-obsolete-jit/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/942-private-recursive/src/Main.java b/test/942-private-recursive/src/Main.java
index cac75c02f8..8a1f7c6e04 100644
--- a/test/942-private-recursive/src/Main.java
+++ b/test/942-private-recursive/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,82 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
-
public class Main {
-
- // class Transform {
- // public void sayHi(int recur, Runnable r) {
- // privateSayHi(recur, r);
- // }
- // private void privateSayHi(int recur, Runnable r) {
- // System.out.println("Hello" + recur + " - transformed");
- // if (recur == 1) {
- // r.run();
- // privateSayHi(recur - 1, r);
- // } else if (recur != 0) {
- // privateSayHi(recur - 1, r);
- // }
- // System.out.println("Goodbye" + recur + " - transformed");
- // }
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQAOAoADwAaCgAOABsJABwAHQcAHgoABAAaCAAfCgAEACAKAAQAIQgAIgoABAAjCgAk" +
- "ACULACYAJwgAKAcAKQcAKgEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUB" +
- "AAVzYXlIaQEAGChJTGphdmEvbGFuZy9SdW5uYWJsZTspVgEADHByaXZhdGVTYXlIaQEADVN0YWNr" +
- "TWFwVGFibGUBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMABAAEQwAFgAVBwArDAAsAC0B" +
- "ABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgEABUhlbGxvDAAuAC8MAC4AMAEADiAtIHRyYW5zZm9y" +
- "bWVkDAAxADIHADMMADQANQcANgwANwARAQAHR29vZGJ5ZQEACVRyYW5zZm9ybQEAEGphdmEvbGFu" +
- "Zy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07" +
- "AQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7" +
- "AQAcKEkpTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEACHRvU3RyaW5nAQAUKClMamF2YS9sYW5n" +
- "L1N0cmluZzsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0" +
- "cmluZzspVgEAEmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgAgAA4ADwAAAAAAAwAAABAAEQABABIA" +
- "AAAdAAEAAQAAAAUqtwABsQAAAAEAEwAAAAYAAQAAAAEAAQAUABUAAQASAAAAIwADAAMAAAAHKhss" +
- "twACsQAAAAEAEwAAAAoAAgAAAAMABgAEAAIAFgAVAAEAEgAAAJ0AAwADAAAAX7IAA7sABFm3AAUS" +
- "BrYABxu2AAgSCbYAB7YACrYACxsEoAAULLkADAEAKhsEZCy3AAKnAA8bmQALKhsEZCy3AAKyAAO7" +
- "AARZtwAFEg22AAcbtgAIEgm2AAe2AAq2AAuxAAAAAgATAAAAIgAIAAAABgAeAAcAIwAIACkACQA0" +
- "AAoAOAALAEAADQBeAA4AFwAAAAQAAjQLAAEAGAAAAAIAGQ==");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQBQqwVIiZvIuS8j1HDurKbXZEV62Mnug5PEBAAAcAAAAHhWNBIAAAAAAAAAACQEAAAb" +
- "AAAAcAAAAAkAAADcAAAABgAAAAABAAABAAAASAEAAAoAAABQAQAAAQAAAKABAAAEAwAAwAEAAMAC" +
- "AADQAgAA2AIAAOECAADoAgAA6wIAAO4CAADyAgAA9gIAAAMDAAAaAwAALgMAAEQDAABYAwAAcwMA" +
- "AIcDAACXAwAAmgMAAJ8DAACjAwAAqwMAAL8DAADEAwAAzQMAANsDAADgAwAA5wMAAAQAAAAIAAAA" +
- "CQAAAAoAAAALAAAADAAAAA0AAAAOAAAAEAAAAAUAAAAFAAAAAAAAAAYAAAAGAAAAqAIAAAcAAAAG" +
- "AAAAsAIAABAAAAAIAAAAAAAAABEAAAAIAAAAuAIAABIAAAAIAAAAsAIAAAcAAgAVAAAAAQADAAEA" +
- "AAABAAQAFwAAAAEABAAZAAAAAgAFABYAAAADAAMAAQAAAAQAAwAYAAAABgADAAEAAAAGAAEAEwAA" +
- "AAYAAgATAAAABgAAABoAAAABAAAAAAAAAAMAAAAAAAAADwAAAAAAAAAQBAAAAAAAAAEAAQABAAAA" +
- "8QMAAAQAAABwEAQAAAAOAAYAAwADAAAA9gMAAFQAAABiAAAAIgEGAHAQBgABABsCAwAAAG4gCAAh" +
- "AAwBbiAHAEEADAEbAgAAAABuIAgAIQAMAW4QCQABAAwBbiADABAAEhAzBCsAchAFAAUA2AAE/3Aw" +
- "AQADBWIAAAAiAQYAcBAGAAEAGwICAAAAbiAIACEADAFuIAcAQQAMARsCAAAAAG4gCAAhAAwBbhAJ" +
- "AAEADAFuIAMAEAAOADgE3//YAAT/cDABAAMFKNgDAAMAAwAAAAgEAAAEAAAAcDABABACDgABAAAA" +
- "AAAAAAEAAAAFAAAAAgAAAAAABAAOIC0gdHJhbnNmb3JtZWQABjxpbml0PgAHR29vZGJ5ZQAFSGVs" +
- "bG8AAUkAAUwAAkxJAAJMTAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGph" +
- "dmEvbGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7" +
- "ABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7ABJMamF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9y" +
- "bS5qYXZhAAFWAANWSUwAAlZMAAZhcHBlbmQAEmVtaXR0ZXI6IGphY2stNC4yNAADb3V0AAdwcmlu" +
- "dGxuAAxwcml2YXRlU2F5SGkAA3J1bgAFc2F5SGkACHRvU3RyaW5nAAEABw4ABgIAAAcOASAPPDxd" +
- "ASAPGS0AAwIAAAcOPAAAAAIBAICABMADAQLYAwIBkAUAAA0AAAAAAAAAAQAAAAAAAAABAAAAGwAA" +
- "AHAAAAACAAAACQAAANwAAAADAAAABgAAAAABAAAEAAAAAQAAAEgBAAAFAAAACgAAAFABAAAGAAAA" +
- "AQAAAKABAAABIAAAAwAAAMABAAABEAAAAwAAAKgCAAACIAAAGwAAAMACAAADIAAAAwAAAPEDAAAA" +
- "IAAAAQAAABAEAAAAEAAAAQAAACQEAAA=");
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test942.run();
}
-
- public static void doTest(Transform t) {
- t.sayHi(2, () -> { System.out.println("Not doing anything here"); });
- t.sayHi(2, () -> {
- System.out.println("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- });
- t.sayHi(2, () -> { 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/942-private-recursive/src/art/Redefinition.java b/test/942-private-recursive/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/942-private-recursive/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/942-private-recursive/src/art/Test942.java b/test/942-private-recursive/src/art/Test942.java
new file mode 100644
index 0000000000..cccc2fd9e0
--- /dev/null
+++ b/test/942-private-recursive/src/art/Test942.java
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Test942 {
+
+ static class Transform {
+ private void privateSayHi(int recur, Runnable r) {
+ System.out.println("hello" + recur);
+ if (recur == 1) {
+ r.run();
+ privateSayHi(recur - 1, r);
+ } else if (recur != 0) {
+ privateSayHi(recur - 1, r);
+ }
+ System.out.println("goodbye" + recur);
+ }
+
+ public void sayHi(int recur, Runnable r) {
+ privateSayHi(recur, r);
+ }
+ }
+
+
+ // static class Transform {
+ // public void sayHi(int recur, Runnable r) {
+ // privateSayHi(recur, r);
+ // }
+ // private void privateSayHi(int recur, Runnable r) {
+ // System.out.println("Hello" + recur + " - transformed");
+ // if (recur == 1) {
+ // r.run();
+ // privateSayHi(recur - 1, r);
+ // } else if (recur != 0) {
+ // privateSayHi(recur - 1, r);
+ // }
+ // System.out.println("Goodbye" + recur + " - transformed");
+ // }
+ // }
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAPAoADwAaCgAOABsJABwAHQcAHgoABAAaCAAfCgAEACAKAAQAIQgAIgoABAAjCgAk" +
+ "ACULACYAJwgAKAcAKgcALQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUB" +
+ "AAVzYXlIaQEAGChJTGphdmEvbGFuZy9SdW5uYWJsZTspVgEADHByaXZhdGVTYXlIaQEADVN0YWNr" +
+ "TWFwVGFibGUBAApTb3VyY2VGaWxlAQAMVGVzdDk0Mi5qYXZhDAAQABEMABYAFQcALgwALwAwAQAX" +
+ "amF2YS9sYW5nL1N0cmluZ0J1aWxkZXIBAAVIZWxsbwwAMQAyDAAxADMBAA4gLSB0cmFuc2Zvcm1l" +
+ "ZAwANAA1BwA2DAA3ADgHADkMADoAEQEAB0dvb2RieWUHADsBABVhcnQvVGVzdDk0MiRUcmFuc2Zv" +
+ "cm0BAAlUcmFuc2Zvcm0BAAxJbm5lckNsYXNzZXMBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9s" +
+ "YW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEABmFwcGVuZAEALShMamF2" +
+ "YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWlsZGVyOwEAHChJKUxqYXZhL2xhbmcv" +
+ "U3RyaW5nQnVpbGRlcjsBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQATamF2YS9p" +
+ "by9QcmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABJqYXZhL2xh" +
+ "bmcvUnVubmFibGUBAANydW4BAAthcnQvVGVzdDk0MgAgAA4ADwAAAAAAAwAAABAAEQABABIAAAAd" +
+ "AAEAAQAAAAUqtwABsQAAAAEAEwAAAAYAAQAAAAUAAQAUABUAAQASAAAAIwADAAMAAAAHKhsstwAC" +
+ "sQAAAAEAEwAAAAoAAgAAAAcABgAIAAIAFgAVAAEAEgAAAJ0AAwADAAAAX7IAA7sABFm3AAUSBrYA" +
+ "Bxu2AAgSCbYAB7YACrYACxsEoAAULLkADAEAKhsEZCy3AAKnAA8bmQALKhsEZCy3AAKyAAO7AARZ" +
+ "twAFEg22AAcbtgAIEgm2AAe2AAq2AAuxAAAAAgATAAAAIgAIAAAACgAeAAsAIwAMACkADQA0AA4A" +
+ "OAAPAEAAEQBeABIAFwAAAAQAAjQLAAIAGAAAAAIAGQAsAAAACgABAA4AKQArAAg=");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQDiy6hGAAAAAAAAAAAAAAAAAAAAAAAAAAC4BQAAcAAAAHhWNBIAAAAAAAAAAPQEAAAh" +
+ "AAAAcAAAAAwAAAD0AAAABgAAACQBAAABAAAAbAEAAAoAAAB0AQAAAQAAAMQBAADUAwAA5AEAAOQB" +
+ "AAD0AQAA/AEAAAUCAAAMAgAADwIAABICAAAWAgAAGgIAADMCAABCAgAAZgIAAIYCAACdAgAAsQIA" +
+ "AMcCAADbAgAA9gIAAAoDAAAYAwAAIwMAACYDAAArAwAALwMAADwDAABEAwAASgMAAE8DAABYAwAA" +
+ "ZgMAAGsDAAByAwAAfAMAAAQAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAAR" +
+ "AAAAFAAAAAUAAAAIAAAAAAAAAAYAAAAJAAAAlAMAAAcAAAAJAAAAjAMAABQAAAALAAAAAAAAABUA" +
+ "AAALAAAAhAMAABYAAAALAAAAjAMAAAoABQAaAAAAAQADAAEAAAABAAQAHAAAAAEABAAeAAAABQAF" +
+ "ABsAAAAGAAMAAQAAAAcAAwAdAAAACQADAAEAAAAJAAEAGAAAAAkAAgAYAAAACQAAAB8AAAABAAAA" +
+ "AAAAAAYAAAAAAAAAEgAAAOQEAAC0BAAAAAAAAA4gLSB0cmFuc2Zvcm1lZAAGPGluaXQ+AAdHb29k" +
+ "YnllAAVIZWxsbwABSQABTAACTEkAAkxMABdMYXJ0L1Rlc3Q5NDIkVHJhbnNmb3JtOwANTGFydC9U" +
+ "ZXN0OTQyOwAiTGRhbHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5v" +
+ "dGF0aW9uL0lubmVyQ2xhc3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2Jq" +
+ "ZWN0OwAUTGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwAZTGphdmEvbGFu" +
+ "Zy9TdHJpbmdCdWlsZGVyOwASTGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTQyLmphdmEACVRyYW5z" +
+ "Zm9ybQABVgADVklMAAJWTAALYWNjZXNzRmxhZ3MABmFwcGVuZAAEbmFtZQADb3V0AAdwcmludGxu" +
+ "AAxwcml2YXRlU2F5SGkAA3J1bgAFc2F5SGkACHRvU3RyaW5nAAV2YWx1ZQAAAgAAAAAABwABAAAA" +
+ "CAAAAAEAAAAAAAAABQAHDgAKAgAABw4BIA8BAw8BAw8BBRIBIA8BAQoBAg8ABwIAAAcOAQMPAAAB" +
+ "AAEAAQAAAJwDAAAEAAAAcBAEAAAADgAGAAMAAwAAAKEDAABVAAAAYgAAACIBCQBwEAYAAQAbAgMA" +
+ "AABuIAgAIQAMAW4gBwBBAAwBGwIAAAAAbiAIACEADAFuEAkAAQAMAW4gAwAQABIQMwQrAHIQBQAF" +
+ "ANgABP9wMAEAAwViAAAAIgEJAHAQBgABABsCAgAAAG4gCAAhAAwBbiAHAEEADAEbAgAAAABuIAgA" +
+ "IQAMAW4QCQABAAwBbiADABAADgA4BN//2AAE/3AwAQADBSkA2P8AAAMAAwADAAAAvQMAAAQAAABw" +
+ "MAEAEAIOAAAAAgEAgIAEyAcBAuAHAgGcCQAAAgMBIBgCAgQCFwQIGRcTAAIAAADIBAAAzgQAANgE" +
+ "AAAAAAAAAAAAAAAAAAAQAAAAAAAAAAEAAAAAAAAAAQAAACEAAABwAAAAAgAAAAwAAAD0AAAAAwAA" +
+ "AAYAAAAkAQAABAAAAAEAAABsAQAABQAAAAoAAAB0AQAABgAAAAEAAADEAQAAAiAAACEAAADkAQAA" +
+ "ARAAAAMAAACEAwAAAyAAAAMAAACcAwAAASAAAAMAAADIAwAAACAAAAEAAAC0BAAABCAAAAIAAADI" +
+ "BAAAAxAAAAEAAADYBAAABiAAAAEAAADkBAAAABAAAAEAAAD0BAAA");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ doTest(new Transform());
+ }
+
+ public static void doTest(Transform t) {
+ t.sayHi(2, () -> { System.out.println("Not doing anything here"); });
+ t.sayHi(2, () -> {
+ System.out.println("transforming calling function");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ });
+ t.sayHi(2, () -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/943-private-recursive-jit/src/Main.java b/test/943-private-recursive-jit/src/Main.java
index f380c062d1..01760ad0c1 100644
--- a/test/943-private-recursive-jit/src/Main.java
+++ b/test/943-private-recursive-jit/src/Main.java
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+import static art.Redefinition.doCommonClassRedefinition;
+
import java.util.Base64;
import java.util.function.Consumer;
import java.lang.reflect.Method;
@@ -164,9 +166,4 @@ public class Main {
private static native boolean isInterpretedFunction(Method m, boolean require_deoptimizable);
private static native void ensureJitCompiled(Class c, String name);
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
}
diff --git a/test/943-private-recursive-jit/src/art/Redefinition.java b/test/943-private-recursive-jit/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/943-private-recursive-jit/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/944-transform-classloaders/classloader.cc b/test/944-transform-classloaders/classloader.cc
deleted file mode 100644
index 698e023771..0000000000
--- a/test/944-transform-classloaders/classloader.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#include "android-base/macros.h"
-#include "jni.h"
-#include "jvmti.h"
-#include "mirror/class-inl.h"
-#include "scoped_local_ref.h"
-
-// Test infrastructure
-#include "test_env.h"
-
-namespace art {
-namespace Test944TransformClassloaders {
-
-extern "C" JNIEXPORT jlong JNICALL Java_Main_getDexFilePointer(JNIEnv* env, jclass, jclass klass) {
- if (Runtime::Current() == nullptr) {
- env->ThrowNew(env->FindClass("java/lang/Exception"),
- "We do not seem to be running in ART! Unable to get dex file.");
- return 0;
- }
- ScopedObjectAccess soa(env);
- // This sequence of casts must be the same as those done in
- // runtime/native/dalvik_system_DexFile.cc in order to ensure that we get the same results.
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(
- &soa.Decode<mirror::Class>(klass)->GetDexFile()));
-}
-
-} // namespace Test944TransformClassloaders
-} // namespace art
diff --git a/test/944-transform-classloaders/src/Main.java b/test/944-transform-classloaders/src/Main.java
index b558660cfd..3d76d237ea 100644
--- a/test/944-transform-classloaders/src/Main.java
+++ b/test/944-transform-classloaders/src/Main.java
@@ -14,254 +14,8 @@
* limitations under the License.
*/
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.lang.reflect.*;
public class Main {
-
- /**
- * base64 encoded class/dex file for
- * class Transform {
- * public void sayHi() {
- * System.out.println("Goodbye");
- * }
- * }
- */
- private static CommonClassDefinition TRANSFORM_DEFINITION = new CommonClassDefinition(
- Transform.class,
- Base64.getDecoder().decode(
- "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" +
- "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA5UcmFuc2Zvcm0uamF2YQwA" +
- "BwAIBwAWDAAXABgBAAdHb29kYnllBwAZDAAaABsBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2Jq" +
- "ZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2ph" +
- "dmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABQAG" +
- "AAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAEQABAAsACAAB" +
- "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAATAAgAFAABAAwAAAACAA0="),
- Base64.getDecoder().decode(
- "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" +
- "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" +
- "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" +
- "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" +
- "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" +
- "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" +
- "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" +
- "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" +
- "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" +
- "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA="));
-
- /**
- * base64 encoded class/dex file for
- * class Transform2 {
- * public void sayHi() {
- * System.out.println("Goodbye2");
- * }
- * }
- */
- private static CommonClassDefinition TRANSFORM2_DEFINITION = new CommonClassDefinition(
- Transform2.class,
- Base64.getDecoder().decode(
- "yv66vgAAADQAHAoABgAOCQAPABAIABEKABIAEwcAFAcAFQEABjxpbml0PgEAAygpVgEABENvZGUB" +
- "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA9UcmFuc2Zvcm0yLmphdmEM" +
- "AAcACAcAFgwAFwAYAQAIR29vZGJ5ZTIHABkMABoAGwEAClRyYW5zZm9ybTIBABBqYXZhL2xhbmcv" +
- "T2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEA" +
- "E2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAA" +
- "BQAGAAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAAAQABAAsA" +
- "CAABAAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAADAAgABAABAAwAAAACAA0="),
- Base64.getDecoder().decode(
- "ZGV4CjAzNQABX6vL8OT7aGLjbzFBEfCM9Aaz+zzGzVnQAgAAcAAAAHhWNBIAAAAAAAAAADACAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACwAQAAIAEAAGIB" +
- "AABqAQAAdAEAAIIBAACZAQAArQEAAMEBAADVAQAA5gEAAOkBAADtAQAAAQIAAAYCAAAPAgAAAgAA" +
- "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAACECAAAA" +
- "AAAAAQABAAEAAAAWAgAABAAAAHAQAwAAAA4AAwABAAIAAAAbAgAACQAAAGIAAAAbAQEAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgAIR29vZGJ5ZTIADExUcmFuc2Zvcm0yOwAVTGphdmEvaW8vUHJp" +
- "bnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEv" +
- "bGFuZy9TeXN0ZW07AA9UcmFuc2Zvcm0yLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTQuMjQA" +
- "A291dAAHcHJpbnRsbgAFc2F5SGkAAQAHDgADAAcOhwAAAAEBAICABKACAQG4AgANAAAAAAAAAAEA" +
- "AAAAAAAAAQAAAA4AAABwAAAAAgAAAAYAAACoAAAAAwAAAAIAAADAAAAABAAAAAEAAADYAAAABQAA" +
- "AAQAAADgAAAABgAAAAEAAAAAAQAAASAAAAIAAAAgAQAAARAAAAEAAABcAQAAAiAAAA4AAABiAQAA" +
- "AyAAAAIAAAAWAgAAACAAAAEAAAAhAgAAABAAAAEAAAAwAgAA"));
-
public static void main(String[] args) throws Exception {
- doTest();
- System.out.println("Passed");
- }
-
- private static void checkIsInstance(Class<?> klass, Object o) throws Exception {
- if (!klass.isInstance(o)) {
- throw new Exception(klass + " is not the class of " + o);
- }
- }
-
- private static boolean arrayContains(long[] arr, long value) {
- if (arr == null) {
- return false;
- }
- for (int i = 0; i < arr.length; i++) {
- if (arr[i] == value) {
- return true;
- }
- }
- return false;
+ art.Test944.run();
}
-
- /**
- * Checks that we can find the dex-file for the given class in its classloader.
- *
- * Throws if it fails.
- */
- private static void checkDexFileInClassLoader(Class<?> klass) throws Exception {
- // If all the android BCP classes were availible when compiling this test and access checks
- // weren't a thing this function would be written as follows:
- //
- // long dexFilePtr = getDexFilePointer(klass);
- // dalvik.system.BaseDexClassLoader loader =
- // (dalvik.system.BaseDexClassLoader)klass.getClassLoader();
- // dalvik.system.DexPathList pathListValue = loader.pathList;
- // dalvik.system.DexPathList.Element[] elementArrayValue = pathListValue.dexElements;
- // int array_length = elementArrayValue.length;
- // for (int i = 0; i < array_length; i++) {
- // dalvik.system.DexPathList.Element curElement = elementArrayValue[i];
- // dalvik.system.DexFile curDexFile = curElement.dexFile;
- // if (curDexFile == null) {
- // continue;
- // }
- // long[] curCookie = (long[])curDexFile.mCookie;
- // long[] curInternalCookie = (long[])curDexFile.mInternalCookie;
- // if (arrayContains(curCookie, dexFilePtr) || arrayContains(curInternalCookie, dexFilePtr)) {
- // return;
- // }
- // }
- // throw new Exception(
- // "Unable to find dex file pointer " + dexFilePtr + " in class loader for " + klass);
-
- // Get all the fields and classes we need by reflection.
- Class<?> baseDexClassLoaderClass = Class.forName("dalvik.system.BaseDexClassLoader");
- Field pathListField = baseDexClassLoaderClass.getDeclaredField("pathList");
-
- Class<?> dexPathListClass = Class.forName("dalvik.system.DexPathList");
- Field elementArrayField = dexPathListClass.getDeclaredField("dexElements");
-
- Class<?> dexPathListElementClass = Class.forName("dalvik.system.DexPathList$Element");
- Field dexFileField = dexPathListElementClass.getDeclaredField("dexFile");
-
- Class<?> dexFileClass = Class.forName("dalvik.system.DexFile");
- Field dexFileCookieField = dexFileClass.getDeclaredField("mCookie");
- Field dexFileInternalCookieField = dexFileClass.getDeclaredField("mInternalCookie");
-
- // Make all the fields accessible
- AccessibleObject.setAccessible(new AccessibleObject[] { pathListField,
- elementArrayField,
- dexFileField,
- dexFileCookieField,
- dexFileInternalCookieField }, true);
-
- long dexFilePtr = getDexFilePointer(klass);
-
- ClassLoader loader = klass.getClassLoader();
- checkIsInstance(baseDexClassLoaderClass, loader);
- // DexPathList pathListValue = ((BaseDexClassLoader) loader).pathList;
- Object pathListValue = pathListField.get(loader);
-
- checkIsInstance(dexPathListClass, pathListValue);
-
- // DexPathList.Element[] elementArrayValue = pathListValue.dexElements;
- Object elementArrayValue = elementArrayField.get(pathListValue);
- if (!elementArrayValue.getClass().isArray() ||
- elementArrayValue.getClass().getComponentType() != dexPathListElementClass) {
- throw new Exception("elementArrayValue is not an " + dexPathListElementClass + " array!");
- }
- // int array_length = elementArrayValue.length;
- int array_length = Array.getLength(elementArrayValue);
- for (int i = 0; i < array_length; i++) {
- // DexPathList.Element curElement = elementArrayValue[i];
- Object curElement = Array.get(elementArrayValue, i);
- checkIsInstance(dexPathListElementClass, curElement);
-
- // DexFile curDexFile = curElement.dexFile;
- Object curDexFile = dexFileField.get(curElement);
- if (curDexFile == null) {
- continue;
- }
- checkIsInstance(dexFileClass, curDexFile);
-
- // long[] curCookie = (long[])curDexFile.mCookie;
- long[] curCookie = (long[])dexFileCookieField.get(curDexFile);
- // long[] curInternalCookie = (long[])curDexFile.mInternalCookie;
- long[] curInternalCookie = (long[])dexFileInternalCookieField.get(curDexFile);
-
- if (arrayContains(curCookie, dexFilePtr) || arrayContains(curInternalCookie, dexFilePtr)) {
- return;
- }
- }
- throw new Exception(
- "Unable to find dex file pointer " + dexFilePtr + " in class loader for " + klass);
- }
-
- private static void doTest() throws Exception {
- art.Main.bindAgentJNIForClass(Main.class);
-
- Transform t = new Transform();
- Transform2 t2 = new Transform2();
-
- long initial_t1_dex = getDexFilePointer(Transform.class);
- long initial_t2_dex = getDexFilePointer(Transform2.class);
- if (initial_t2_dex != initial_t1_dex) {
- throw new Exception("The classes " + Transform.class + " and " + Transform2.class + " " +
- "have different initial dex files!");
- }
- checkDexFileInClassLoader(Transform.class);
- checkDexFileInClassLoader(Transform2.class);
-
- // Make sure they are loaded
- t.sayHi();
- t2.sayHi();
- // Redefine both of the classes.
- doMultiClassRedefinition(TRANSFORM_DEFINITION, TRANSFORM2_DEFINITION);
- // Make sure we actually transformed them!
- t.sayHi();
- t2.sayHi();
-
- long final_t1_dex = getDexFilePointer(Transform.class);
- long final_t2_dex = getDexFilePointer(Transform2.class);
- if (final_t2_dex == final_t1_dex) {
- throw new Exception("The classes " + Transform.class + " and " + Transform2.class + " " +
- "have the same initial dex files!");
- } else if (final_t1_dex == initial_t1_dex) {
- throw new Exception("The class " + Transform.class + " did not get a new dex file!");
- } else if (final_t2_dex == initial_t2_dex) {
- throw new Exception("The class " + Transform2.class + " did not get a new dex file!");
- }
- // Check to make sure the new dex files are in the class loader.
- checkDexFileInClassLoader(Transform.class);
- checkDexFileInClassLoader(Transform2.class);
- }
-
- private static void doMultiClassRedefinition(CommonClassDefinition... defs) {
- ArrayList<Class<?>> classes = new ArrayList<>();
- ArrayList<byte[]> class_files = new ArrayList<>();
- ArrayList<byte[]> dex_files = new ArrayList<>();
-
- for (CommonClassDefinition d : defs) {
- classes.add(d.target);
- class_files.add(d.class_file_bytes);
- dex_files.add(d.dex_file_bytes);
- }
- doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
- class_files.toArray(new byte[0][]),
- dex_files.toArray(new byte[0][]));
- }
-
- // Gets the 'long' (really a native pointer) that is stored in the ClassLoader representing the
- // DexFile a class is loaded from. This is converted from the DexFile* in the same way it is done
- // in runtime/native/dalvik_system_DexFile.cc
- private static native long getDexFilePointer(Class<?> target);
- // Transforms the classes
- private static native void doCommonMultiClassRedefinition(Class<?>[] targets,
- byte[][] classfiles,
- byte[][] dexfiles);
}
diff --git a/test/944-transform-classloaders/src/Transform.java b/test/944-transform-classloaders/src/Transform.java
deleted file mode 100644
index 8e8af355da..0000000000
--- a/test/944-transform-classloaders/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi() {
- // 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:
- // "Goodbye" < "LTransform;" < "hello".
- System.out.println("hello");
- }
-}
diff --git a/test/944-transform-classloaders/src/Transform2.java b/test/944-transform-classloaders/src/Transform2.java
deleted file mode 100644
index eb22842184..0000000000
--- a/test/944-transform-classloaders/src/Transform2.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform2 {
- public void sayHi() {
- System.out.println("hello2");
- }
-}
diff --git a/test/944-transform-classloaders/src/art/Redefinition.java b/test/944-transform-classloaders/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/944-transform-classloaders/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/944-transform-classloaders/src/art/Test944.java b/test/944-transform-classloaders/src/art/Test944.java
new file mode 100644
index 0000000000..fe1c024ec4
--- /dev/null
+++ b/test/944-transform-classloaders/src/art/Test944.java
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import static art.Redefinition.CommonClassDefinition;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.lang.reflect.*;
+public class Test944 {
+
+ static class Transform {
+ public void sayHi() {
+ System.out.println("hello");
+ }
+ }
+
+ static class Transform2 {
+ public void sayHi() {
+ System.out.println("hello2");
+ }
+ }
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform {
+ * public void sayHi() {
+ * System.out.println("Goodbye");
+ * }
+ * }
+ */
+ private static CommonClassDefinition TRANSFORM_DEFINITION = new CommonClassDefinition(
+ Transform.class,
+ Base64.getDecoder().decode(
+ "yv66vgAAADQAIAoABgAOCQAPABAIABEKABIAEwcAFQcAGAEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAAxUZXN0OTQ0LmphdmEMAAcA" +
+ "CAcAGQwAGgAbAQAHR29vZGJ5ZQcAHAwAHQAeBwAfAQAVYXJ0L1Rlc3Q5NDQkVHJhbnNmb3JtAQAJ" +
+ "VHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9T" +
+ "eXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFt" +
+ "AQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAC2FydC9UZXN0OTQ0ACAABQAGAAAA" +
+ "AAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAACgABAAsACAABAAkA" +
+ "AAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAMAAgADQACAAwAAAACAA0AFwAAAAoA" +
+ "AQAFABQAFgAI"),
+ Base64.getDecoder().decode(
+ "ZGV4CjAzNQCFgsuWAAAAAAAAAAAAAAAAAAAAAAAAAAC4AwAAcAAAAHhWNBIAAAAAAAAAAPQCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB0AgAARAEAAEQB" +
+ "AABMAQAAVQEAAG4BAAB9AQAAoQEAAMEBAADYAQAA7AEAAAACAAAUAgAAIgIAAC0CAAAwAgAANAIA" +
+ "AEECAABHAgAATAIAAFUCAABcAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABkAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA5AIAALgCAAAAAAAABjxpbml0PgAHR29vZGJ5ZQAX" +
+ "TGFydC9UZXN0OTQ0JFRyYW5zZm9ybTsADUxhcnQvVGVzdDk0NDsAIkxkYWx2aWsvYW5ub3RhdGlv" +
+ "bi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEv" +
+ "aW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAS" +
+ "TGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTQ0LmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vz" +
+ "c0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAQAAAAYAAAAKAAcOAAwA" +
+ "Bw4BCA8AAAAAAQABAAEAAABsAgAABAAAAHAQAwAAAA4AAwABAAIAAABxAgAACQAAAGIAAAAbAQEA" +
+ "AABuIAIAEAAOAAAAAAABAQCAgAT8BAEBlAUAAAICARMYAQIDAg4ECA8XCwACAAAAyAIAAM4CAADY" +
+ "AgAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAUAAAAcAAAAAIAAAAJAAAAwAAAAAMA" +
+ "AAACAAAA5AAAAAQAAAABAAAA/AAAAAUAAAAEAAAABAEAAAYAAAABAAAAJAEAAAIgAAAUAAAARAEA" +
+ "AAEQAAABAAAAZAIAAAMgAAACAAAAbAIAAAEgAAACAAAAfAIAAAAgAAABAAAAuAIAAAQgAAACAAAA" +
+ "yAIAAAMQAAABAAAA2AIAAAYgAAABAAAA5AIAAAAQAAABAAAA9AIAAA=="));
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform2 {
+ * public void sayHi() {
+ * System.out.println("Goodbye2");
+ * }
+ * }
+ */
+ private static CommonClassDefinition TRANSFORM2_DEFINITION = new CommonClassDefinition(
+ Transform2.class,
+ Base64.getDecoder().decode(
+ "yv66vgAAADQAIAoABgAOCQAPABAIABEKABIAEwcAFQcAGAEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAAxUZXN0OTQ0LmphdmEMAAcA" +
+ "CAcAGQwAGgAbAQAIR29vZGJ5ZTIHABwMAB0AHgcAHwEAFmFydC9UZXN0OTQ0JFRyYW5zZm9ybTIB" +
+ "AApUcmFuc2Zvcm0yAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFu" +
+ "Zy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3Ry" +
+ "ZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAC2FydC9UZXN0OTQ0ACAABQAG" +
+ "AAAAAAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAABQABAAsACAAB" +
+ "AAkAAAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAHAAgACAACAAwAAAACAA0AFwAA" +
+ "AAoAAQAFABQAFgAI"),
+ Base64.getDecoder().decode(
+ "ZGV4CjAzNQAUg8BCAAAAAAAAAAAAAAAAAAAAAAAAAAC8AwAAcAAAAHhWNBIAAAAAAAAAAPgCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB4AgAARAEAAEQB" +
+ "AABMAQAAVgEAAHABAAB/AQAAowEAAMMBAADaAQAA7gEAAAICAAAWAgAAJAIAADACAAAzAgAANwIA" +
+ "AEQCAABKAgAATwIAAFgCAABfAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABoAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA6AIAALwCAAAAAAAABjxpbml0PgAIR29vZGJ5ZTIA" +
+ "GExhcnQvVGVzdDk0NCRUcmFuc2Zvcm0yOwANTGFydC9UZXN0OTQ0OwAiTGRhbHZpay9hbm5vdGF0" +
+ "aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xhc3M7ABVMamF2" +
+ "YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7" +
+ "ABJMamF2YS9sYW5nL1N5c3RlbTsADFRlc3Q5NDQuamF2YQAKVHJhbnNmb3JtMgABVgACVkwAC2Fj" +
+ "Y2Vzc0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAAEAAAAGAAAABQAH" +
+ "DgAHAAcOAQgPAAAAAAEAAQABAAAAcAIAAAQAAABwEAMAAAAOAAMAAQACAAAAdQIAAAkAAABiAAAA" +
+ "GwEBAAAAbiACABAADgAAAAAAAQEAgIAEgAUBAZgFAAACAgETGAECAwIOBAgPFwsAAgAAAMwCAADS" +
+ "AgAA3AIAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAABAAAAFAAAAHAAAAACAAAACQAAAMAA" +
+ "AAADAAAAAgAAAOQAAAAEAAAAAQAAAPwAAAAFAAAABAAAAAQBAAAGAAAAAQAAACQBAAACIAAAFAAA" +
+ "AEQBAAABEAAAAQAAAGgCAAADIAAAAgAAAHACAAABIAAAAgAAAIACAAAAIAAAAQAAALwCAAAEIAAA" +
+ "AgAAAMwCAAADEAAAAQAAANwCAAAGIAAAAQAAAOgCAAAAEAAAAQAAAPgCAAA="));
+
+ public static void run() throws Exception {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ doTest();
+ System.out.println("Passed");
+ }
+
+ private static void checkIsInstance(Class<?> klass, Object o) throws Exception {
+ if (!klass.isInstance(o)) {
+ throw new Exception(klass + " is not the class of " + o);
+ }
+ }
+
+ private static boolean arrayContains(long[] arr, long value) {
+ if (arr == null) {
+ return false;
+ }
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i] == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks that we can find the dex-file for the given class in its classloader.
+ *
+ * Throws if it fails.
+ */
+ private static void checkDexFileInClassLoader(Class<?> klass) throws Exception {
+ // If all the android BCP classes were availible when compiling this test and access checks
+ // weren't a thing this function would be written as follows:
+ //
+ // long dexFilePtr = getDexFilePointer(klass);
+ // dalvik.system.BaseDexClassLoader loader =
+ // (dalvik.system.BaseDexClassLoader)klass.getClassLoader();
+ // dalvik.system.DexPathList pathListValue = loader.pathList;
+ // dalvik.system.DexPathList.Element[] elementArrayValue = pathListValue.dexElements;
+ // int array_length = elementArrayValue.length;
+ // for (int i = 0; i < array_length; i++) {
+ // dalvik.system.DexPathList.Element curElement = elementArrayValue[i];
+ // dalvik.system.DexFile curDexFile = curElement.dexFile;
+ // if (curDexFile == null) {
+ // continue;
+ // }
+ // long[] curCookie = (long[])curDexFile.mCookie;
+ // long[] curInternalCookie = (long[])curDexFile.mInternalCookie;
+ // if (arrayContains(curCookie, dexFilePtr) || arrayContains(curInternalCookie, dexFilePtr)) {
+ // return;
+ // }
+ // }
+ // throw new Exception(
+ // "Unable to find dex file pointer " + dexFilePtr + " in class loader for " + klass);
+
+ // Get all the fields and classes we need by reflection.
+ Class<?> baseDexClassLoaderClass = Class.forName("dalvik.system.BaseDexClassLoader");
+ Field pathListField = baseDexClassLoaderClass.getDeclaredField("pathList");
+
+ Class<?> dexPathListClass = Class.forName("dalvik.system.DexPathList");
+ Field elementArrayField = dexPathListClass.getDeclaredField("dexElements");
+
+ Class<?> dexPathListElementClass = Class.forName("dalvik.system.DexPathList$Element");
+ Field dexFileField = dexPathListElementClass.getDeclaredField("dexFile");
+
+ Class<?> dexFileClass = Class.forName("dalvik.system.DexFile");
+ Field dexFileCookieField = dexFileClass.getDeclaredField("mCookie");
+ Field dexFileInternalCookieField = dexFileClass.getDeclaredField("mInternalCookie");
+
+ // Make all the fields accessible
+ AccessibleObject.setAccessible(new AccessibleObject[] { pathListField,
+ elementArrayField,
+ dexFileField,
+ dexFileCookieField,
+ dexFileInternalCookieField }, true);
+
+ long dexFilePtr = getDexFilePointer(klass);
+
+ ClassLoader loader = klass.getClassLoader();
+ checkIsInstance(baseDexClassLoaderClass, loader);
+ // DexPathList pathListValue = ((BaseDexClassLoader) loader).pathList;
+ Object pathListValue = pathListField.get(loader);
+
+ checkIsInstance(dexPathListClass, pathListValue);
+
+ // DexPathList.Element[] elementArrayValue = pathListValue.dexElements;
+ Object elementArrayValue = elementArrayField.get(pathListValue);
+ if (!elementArrayValue.getClass().isArray() ||
+ elementArrayValue.getClass().getComponentType() != dexPathListElementClass) {
+ throw new Exception("elementArrayValue is not an " + dexPathListElementClass + " array!");
+ }
+ // int array_length = elementArrayValue.length;
+ int array_length = Array.getLength(elementArrayValue);
+ for (int i = 0; i < array_length; i++) {
+ // DexPathList.Element curElement = elementArrayValue[i];
+ Object curElement = Array.get(elementArrayValue, i);
+ checkIsInstance(dexPathListElementClass, curElement);
+
+ // DexFile curDexFile = curElement.dexFile;
+ Object curDexFile = dexFileField.get(curElement);
+ if (curDexFile == null) {
+ continue;
+ }
+ checkIsInstance(dexFileClass, curDexFile);
+
+ // long[] curCookie = (long[])curDexFile.mCookie;
+ long[] curCookie = (long[])dexFileCookieField.get(curDexFile);
+ // long[] curInternalCookie = (long[])curDexFile.mInternalCookie;
+ long[] curInternalCookie = (long[])dexFileInternalCookieField.get(curDexFile);
+
+ if (arrayContains(curCookie, dexFilePtr) || arrayContains(curInternalCookie, dexFilePtr)) {
+ return;
+ }
+ }
+ throw new Exception(
+ "Unable to find dex file pointer " + dexFilePtr + " in class loader for " + klass);
+ }
+
+ private static void doTest() throws Exception {
+ Transform t = new Transform();
+ Transform2 t2 = new Transform2();
+
+ long initial_t1_dex = getDexFilePointer(Transform.class);
+ long initial_t2_dex = getDexFilePointer(Transform2.class);
+ if (initial_t2_dex != initial_t1_dex) {
+ throw new Exception("The classes " + Transform.class + " and " + Transform2.class + " " +
+ "have different initial dex files!");
+ }
+ checkDexFileInClassLoader(Transform.class);
+ checkDexFileInClassLoader(Transform2.class);
+
+ // Make sure they are loaded
+ t.sayHi();
+ t2.sayHi();
+ // Redefine both of the classes.
+ Redefinition.doMultiClassRedefinition(TRANSFORM_DEFINITION, TRANSFORM2_DEFINITION);
+ // Make sure we actually transformed them!
+ t.sayHi();
+ t2.sayHi();
+
+ long final_t1_dex = getDexFilePointer(Transform.class);
+ long final_t2_dex = getDexFilePointer(Transform2.class);
+ if (final_t2_dex == final_t1_dex) {
+ throw new Exception("The classes " + Transform.class + " and " + Transform2.class + " " +
+ "have the same initial dex files!");
+ } else if (final_t1_dex == initial_t1_dex) {
+ throw new Exception("The class " + Transform.class + " did not get a new dex file!");
+ } else if (final_t2_dex == initial_t2_dex) {
+ throw new Exception("The class " + Transform2.class + " did not get a new dex file!");
+ }
+ // Check to make sure the new dex files are in the class loader.
+ checkDexFileInClassLoader(Transform.class);
+ checkDexFileInClassLoader(Transform2.class);
+ }
+
+ // Gets the 'long' (really a native pointer) that is stored in the ClassLoader representing the
+ // DexFile a class is loaded from. This is plucked out of the internal DexCache object associated
+ // with the class.
+ private static long getDexFilePointer(Class<?> target) throws Exception {
+ // If all the android BCP classes were available when compiling this test and access checks
+ // weren't a thing this function would be written as follows:
+ //
+ // java.lang.DexCache dexCacheObject = target.dexCache;
+ // if (dexCacheObject == null) {
+ // return 0;
+ // }
+ // return dexCacheObject.dexFile;
+ Field dexCacheField = Class.class.getDeclaredField("dexCache");
+
+ Class<?> dexCacheClass = Class.forName("java.lang.DexCache");
+ Field dexFileField = dexCacheClass.getDeclaredField("dexFile");
+
+ AccessibleObject.setAccessible(new AccessibleObject[] { dexCacheField, dexFileField }, true);
+
+ Object dexCacheObject = dexCacheField.get(target);
+ if (dexCacheObject == null) {
+ return 0;
+ }
+ checkIsInstance(dexCacheClass, dexCacheObject);
+ return dexFileField.getLong(dexCacheObject);
+ }
+}
diff --git a/test/945-obsolete-native/obsolete_native.cc b/test/945-obsolete-native/obsolete_native.cc
index ee653a4a12..e3090f5906 100644
--- a/test/945-obsolete-native/obsolete_native.cc
+++ b/test/945-obsolete-native/obsolete_native.cc
@@ -19,31 +19,20 @@
#include <stdio.h>
#include "android-base/stringprintf.h"
-
-#include "android-base/stringprintf.h"
-#include "base/logging.h"
-#include "base/macros.h"
#include "jni.h"
#include "jvmti.h"
-#include "scoped_local_ref.h"
// Test infrastructure
#include "jni_binder.h"
#include "test_env.h"
+#include "scoped_local_ref.h"
namespace art {
namespace Test945ObsoleteNative {
-extern "C" JNIEXPORT void JNICALL Java_Main_bindTest945ObsoleteNative(
- JNIEnv* env, jclass klass ATTRIBUTE_UNUSED) {
- BindFunctions(jvmti_env, env, "Transform");
-}
-
-extern "C" JNIEXPORT void JNICALL Java_Transform_doExecute(JNIEnv* env,
- jclass klass ATTRIBUTE_UNUSED,
- jobject runnable) {
+extern "C" JNIEXPORT void JNICALL Java_art_Test945_00024Transform_doExecute(
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jobject runnable) {
jclass runnable_klass = env->FindClass("java/lang/Runnable");
- DCHECK(runnable_klass != nullptr);
jmethodID run_method = env->GetMethodID(runnable_klass, "run", "()V");
env->CallVoidMethod(runnable, run_method);
}
diff --git a/test/945-obsolete-native/src/Main.java b/test/945-obsolete-native/src/Main.java
index a7901cd2bb..c94bc2206c 100644
--- a/test/945-obsolete-native/src/Main.java
+++ b/test/945-obsolete-native/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,65 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
-
public class Main {
- // class Transform {
- // public void sayHi(Runnable r) {
- // System.out.println("Hello - Transformed");
- // doExecute(r);
- // System.out.println("Goodbye - Transformed");
- // }
- //
- // private static native void doExecute(Runnable r);
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQAIgoACAASCQATABQIABUKABYAFwoABwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" +
- "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
- "KVYBAAlkb0V4ZWN1dGUBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkACgcAHAwAHQAe" +
- "AQATSGVsbG8gLSBUcmFuc2Zvcm1lZAcAHwwAIAAhDAAPAA4BABVHb29kYnllIC0gVHJhbnNmb3Jt" +
- "ZWQBAAlUcmFuc2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291" +
- "dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxu" +
- "AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWACAABwAIAAAAAAADAAAACQAKAAEACwAAAB0AAQABAAAA" +
- "BSq3AAGxAAAAAQAMAAAABgABAAAAEQABAA0ADgABAAsAAAA5AAIAAgAAABWyAAISA7YABCu4AAWy" +
- "AAISBrYABLEAAAABAAwAAAASAAQAAAATAAgAFAAMABUAFAAWAQoADwAOAAAAAQAQAAAAAgAR");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQB1fZcJR/opPuXacK8mIla5shH0LSg72qJYAwAAcAAAAHhWNBIAAAAAAAAAALgCAAAR" +
- "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAUAgAARAEAAKIB" +
- "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAABuAgAAggIA" +
- "AIcCAACQAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" +
- "lAEAAAsAAAAGAAAAnAEAAAUAAQAOAAAAAAAAAAAAAAAAAAEADAAAAAAAAQAQAAAAAQACAA8AAAAC" +
- "AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAKUCAAAAAAAAAQABAAEAAACXAgAABAAAAHAQ" +
- "BAAAAA4ABAACAAIAAACcAgAAFAAAAGIAAAAbAQIAAABuIAMAEABxEAEAAwBiAAAAGwEBAAAAbiAD" +
- "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" +
- "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" +
- "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" +
- "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAAJZG9FeGVjdXRlABJlbWl0" +
- "dGVyOiBqYWNrLTQuMjUAA291dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAQAHDoc8hwAAAAIBAICA" +
- "BMQCAYoCAAIB3AIADQAAAAAAAAABAAAAAAAAAAEAAAARAAAAcAAAAAIAAAAHAAAAtAAAAAMAAAAD" +
- "AAAA0AAAAAQAAAABAAAA9AAAAAUAAAAFAAAA/AAAAAYAAAABAAAAJAEAAAEgAAACAAAARAEAAAEQ" +
- "AAACAAAAlAEAAAIgAAARAAAAogEAAAMgAAACAAAAlwIAAAAgAAABAAAApQIAAAAQAAABAAAAuAIA" +
- "AA==");
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- bindTest945ObsoleteNative();
- 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"); });
+ public static void main(String[] args) throws Exception {
+ art.Test945.run();
}
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
-
- private static native void bindTest945ObsoleteNative();
}
diff --git a/test/945-obsolete-native/src/Transform.java b/test/945-obsolete-native/src/Transform.java
deleted file mode 100644
index 2b7cc1b3a1..0000000000
--- a/test/945-obsolete-native/src/Transform.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi(Runnable r) {
- System.out.println("hello");
- doExecute(r);
- System.out.println("goodbye");
- }
-
- private static native void doExecute(Runnable r);
-}
diff --git a/test/945-obsolete-native/src/art/Redefinition.java b/test/945-obsolete-native/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/945-obsolete-native/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/945-obsolete-native/src/art/Test945.java b/test/945-obsolete-native/src/art/Test945.java
new file mode 100644
index 0000000000..6cf31f6d05
--- /dev/null
+++ b/test/945-obsolete-native/src/art/Test945.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Test945 {
+
+ static class Transform {
+ static {
+ art.Main.bindAgentJNIForClass(Transform.class);
+ }
+
+ public void sayHi(Runnable r) {
+ System.out.println("hello");
+ doExecute(r);
+ System.out.println("goodbye");
+ }
+
+ private static native void doExecute(Runnable r);
+ }
+
+ // static class Transform {
+ // static { }
+ // public void sayHi(Runnable r) {
+ // System.out.println("Hello - Transformed");
+ // doExecute(r);
+ // System.out.println("Goodbye - Transformed");
+ // }
+ //
+ // private static native void doExecute(Runnable r);
+ // }
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAJwoACAATCQAUABUIABYKABcAGAoABwAZCAAaBwAcBwAfAQAGPGluaXQ+AQADKClW" +
+ "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
+ "KVYBAAlkb0V4ZWN1dGUBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAxUZXN0OTQ1LmphdmEMAAkA" +
+ "CgcAIAwAIQAiAQATSGVsbG8gLSBUcmFuc2Zvcm1lZAcAIwwAJAAlDAAPAA4BABVHb29kYnllIC0g" +
+ "VHJhbnNmb3JtZWQHACYBABVhcnQvVGVzdDk0NSRUcmFuc2Zvcm0BAAlUcmFuc2Zvcm0BAAxJbm5l" +
+ "ckNsYXNzZXMBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxq" +
+ "YXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExq" +
+ "YXZhL2xhbmcvU3RyaW5nOylWAQALYXJ0L1Rlc3Q5NDUAIAAHAAgAAAAAAAQAAAAJAAoAAQALAAAA" +
+ "HQABAAEAAAAFKrcAAbEAAAABAAwAAAAGAAEAAAAFAAEADQAOAAEACwAAADkAAgACAAAAFbIAAhID" +
+ "tgAEK7gABbIAAhIGtgAEsQAAAAEADAAAABIABAAAAAgACAAJAAwACgAUAAsBCgAPAA4AAAAIABAA" +
+ "CgABAAsAAAAZAAAAAAAAAAGxAAAAAQAMAAAABgABAAAABgACABEAAAACABIAHgAAAAoAAQAHABsA" +
+ "HQAI");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQAFqcJFAAAAAAAAAAAAAAAAAAAAAAAAAAB8BAAAcAAAAHhWNBIAAAAAAAAAALgDAAAY" +
+ "AAAAcAAAAAoAAADQAAAAAwAAAPgAAAABAAAAHAEAAAYAAAAkAQAAAQAAAFQBAAAIAwAAdAEAAHQB" +
+ "AAB+AQAAhgEAAJ0BAACyAQAAywEAANoBAAD+AQAAHgIAADUCAABJAgAAXwIAAHMCAACHAgAAlQIA" +
+ "AKACAACjAgAApwIAALQCAAC/AgAAxQIAAMoCAADTAgAA2gIAAAQAAAAFAAAABgAAAAcAAAAIAAAA" +
+ "CQAAAAoAAAALAAAADAAAAA8AAAAPAAAACQAAAAAAAAAQAAAACQAAAOQCAAAQAAAACQAAAOwCAAAI" +
+ "AAQAFAAAAAAAAAAAAAAAAAAAAAEAAAAAAAEAEgAAAAAAAQAWAAAABAACABUAAAAFAAAAAQAAAAAA" +
+ "AAAAAAAABQAAAAAAAAANAAAAqAMAAHQDAAAAAAAACDxjbGluaXQ+AAY8aW5pdD4AFUdvb2RieWUg" +
+ "LSBUcmFuc2Zvcm1lZAATSGVsbG8gLSBUcmFuc2Zvcm1lZAAXTGFydC9UZXN0OTQ1JFRyYW5zZm9y" +
+ "bTsADUxhcnQvVGVzdDk0NTsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxk" +
+ "YWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2" +
+ "YS9sYW5nL09iamVjdDsAFExqYXZhL2xhbmcvUnVubmFibGU7ABJMamF2YS9sYW5nL1N0cmluZzsA" +
+ "EkxqYXZhL2xhbmcvU3lzdGVtOwAMVGVzdDk0NS5qYXZhAAlUcmFuc2Zvcm0AAVYAAlZMAAthY2Nl" +
+ "c3NGbGFncwAJZG9FeGVjdXRlAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAAAB" +
+ "AAAABgAAAAEAAAAHAAAABQAHDgAFAAcOAAgBAAcOAQgPAQMPAQgPAAAAAAAAAAAAAAAA9AIAAAEA" +
+ "AAAOAAAAAQABAAEAAAD5AgAABAAAAHAQBQAAAA4ABAACAAIAAAD+AgAAFAAAAGIAAAAbAQMAAABu" +
+ "IAQAEABxEAIAAwBiAAAAGwECAAAAbiAEABAADgAAAAMBAIiABJAGAYCABKQGAYoCAAMBvAYCAgEX" +
+ "GAECAwIRBAgTFw4AAgAAAIwDAACSAwAAnAMAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAAB" +
+ "AAAAGAAAAHAAAAACAAAACgAAANAAAAADAAAAAwAAAPgAAAAEAAAAAQAAABwBAAAFAAAABgAAACQB" +
+ "AAAGAAAAAQAAAFQBAAACIAAAGAAAAHQBAAABEAAAAgAAAOQCAAADIAAAAwAAAPQCAAABIAAAAwAA" +
+ "ABADAAAAIAAAAQAAAHQDAAAEIAAAAgAAAIwDAAADEAAAAQAAAJwDAAAGIAAAAQAAAKgDAAAAEAAA" +
+ "AQAAALgDAAA=");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ 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");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ });
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/946-obsolete-throw/expected.txt b/test/946-obsolete-throw/expected.txt
index 71d5182100..edf796eb96 100644
--- a/test/946-obsolete-throw/expected.txt
+++ b/test/946-obsolete-throw/expected.txt
@@ -5,10 +5,11 @@ hello
transforming calling function
Received error : java.lang.Error: Throwing exception into an obsolete method!
java.lang.Error: Throwing exception into an obsolete method!
- at Main$DoRedefinitionClass.run(Main.java:65)
- at Transform.sayHi(Transform.java:27)
- at Main.doTest(Main.java:72)
- at Main.main(Main.java:57)
+ at art.Test946$DoRedefinitionClass.run(Test946.java:81)
+ at art.Test946$Transform.sayHi(Test946.java:26)
+ at art.Test946.doTest(Test946.java:88)
+ at art.Test946.run(Test946.java:73)
+ at Main.main(Main.java:19)
Hello - Transformed
Not doing anything here
Goodbye - Transformed
diff --git a/test/946-obsolete-throw/src/Main.java b/test/946-obsolete-throw/src/Main.java
index 077ad72acd..0b1f78dc4a 100644
--- a/test/946-obsolete-throw/src/Main.java
+++ b/test/946-obsolete-throw/src/Main.java
@@ -14,71 +14,8 @@
* 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) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
- }
-
- static class DoRedefinitionClass implements Runnable {
- @Override
- public void run() {
- System.out.println("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- throw new Error("Throwing exception into an obsolete method!");
- }
+ public static void main(String[] args) throws Exception {
+ art.Test946.run();
}
-
- public static void doTest(Transform t) {
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
- try {
- t.sayHi(new DoRedefinitionClass());
- } catch (Throwable e) {
- System.out.println("Received error : " + e);
- e.printStackTrace(System.out);
- }
- 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/946-obsolete-throw/src/Transform.java b/test/946-obsolete-throw/src/Transform.java
deleted file mode 100644
index 4f43086d32..0000000000
--- a/test/946-obsolete-throw/src/Transform.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-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/946-obsolete-throw/src/art/Redefinition.java b/test/946-obsolete-throw/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/946-obsolete-throw/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/946-obsolete-throw/src/art/Test946.java b/test/946-obsolete-throw/src/art/Test946.java
new file mode 100644
index 0000000000..9f0e57c333
--- /dev/null
+++ b/test/946-obsolete-throw/src/art/Test946.java
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Test946 {
+
+ static class Transform {
+ public void sayHi(Runnable r) {
+ System.out.println("hello");
+ r.run();
+ System.out.println("goodbye");
+ }
+ }
+
+ // static 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(
+ "yv66vgAAADQAKAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAbBwAeAQAGPGluaXQ+AQADKClW" +
+ "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
+ "KVYBAApTb3VyY2VGaWxlAQAMVGVzdDk0Ni5qYXZhDAAJAAoHAB8MACAAIQEAE0hlbGxvIC0gVHJh" +
+ "bnNmb3JtZWQHACIMACMAJAcAJQwAJgAKAQAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkBwAnAQAVYXJ0" +
+ "L1Rlc3Q5NDYkVHJhbnNmb3JtAQAJVHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5n" +
+ "L09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsB" +
+ "ABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEA" +
+ "EmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgEAC2FydC9UZXN0OTQ2ACAABwAIAAAAAAACAAAACQAK" +
+ "AAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAABQABAA0ADgABAAsAAAA7AAIAAgAA" +
+ "ABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAcACAAIAA4ACQAWAAoAAgAP" +
+ "AAAAAgAQAB0AAAAKAAEABwAaABwACA==");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQB0mzt6AAAAAAAAAAAAAAAAAAAAAAAAAAA8BAAAcAAAAHhWNBIAAAAAAAAAAHgDAAAX" +
+ "AAAAcAAAAAoAAADMAAAAAwAAAPQAAAABAAAAGAEAAAUAAAAgAQAAAQAAAEgBAADUAgAAaAEAAGgB" +
+ "AABwAQAAhwEAAJwBAAC1AQAAxAEAAOgBAAAIAgAAHwIAADMCAABJAgAAXQIAAHECAAB/AgAAigIA" +
+ "AI0CAACRAgAAngIAAKQCAACpAgAAsgIAALcCAAC+AgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAA" +
+ "CQAAAAoAAAALAAAADgAAAA4AAAAJAAAAAAAAAA8AAAAJAAAAyAIAAA8AAAAJAAAA0AIAAAgABAAS" +
+ "AAAAAAAAAAAAAAAAAAEAFQAAAAQAAgATAAAABQAAAAAAAAAGAAAAFAAAAAAAAAAAAAAABQAAAAAA" +
+ "AAAMAAAAaAMAADwDAAAAAAAABjxpbml0PgAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkABNIZWxsbyAt" +
+ "IFRyYW5zZm9ybWVkABdMYXJ0L1Rlc3Q5NDYkVHJhbnNmb3JtOwANTGFydC9UZXN0OTQ2OwAiTGRh" +
+ "bHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVy" +
+ "Q2xhc3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEv" +
+ "bGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AAxU" +
+ "ZXN0OTQ2LmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vzc0ZsYWdzAARuYW1lAANvdXQAB3By" +
+ "aW50bG4AA3J1bgAFc2F5SGkABXZhbHVlAAAAAAEAAAAGAAAAAQAAAAcAAAAFAAcOAAcBAAcOAQgP" +
+ "AQMPAQgPAAEAAQABAAAA2AIAAAQAAABwEAMAAAAOAAQAAgACAAAA3QIAABQAAABiAAAAGwECAAAA" +
+ "biACABAAchAEAAMAYgAAABsBAQAAAG4gAgAQAA4AAAABAQCAgATsBQEBhAYAAAICARYYAQIDAhAE" +
+ "CBEXDQACAAAATAMAAFIDAABcAwAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAXAAAA" +
+ "cAAAAAIAAAAKAAAAzAAAAAMAAAADAAAA9AAAAAQAAAABAAAAGAEAAAUAAAAFAAAAIAEAAAYAAAAB" +
+ "AAAASAEAAAIgAAAXAAAAaAEAAAEQAAACAAAAyAIAAAMgAAACAAAA2AIAAAEgAAACAAAA7AIAAAAg" +
+ "AAABAAAAPAMAAAQgAAACAAAATAMAAAMQAAABAAAAXAMAAAYgAAABAAAAaAMAAAAQAAABAAAAeAMA" +
+ "AA==");
+
+ public static void run() {
+ doTest(new Transform());
+ }
+
+ static class DoRedefinitionClass implements Runnable {
+ @Override
+ public void run() {
+ System.out.println("transforming calling function");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ throw new Error("Throwing exception into an obsolete method!");
+ }
+ }
+
+ public static void doTest(Transform t) {
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ try {
+ t.sayHi(new DoRedefinitionClass());
+ } catch (Throwable e) {
+ System.out.println("Received error : " + e);
+ e.printStackTrace(System.out);
+ }
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/947-reflect-method/src/Main.java b/test/947-reflect-method/src/Main.java
index da746ac4db..bc3f4b2cf4 100644
--- a/test/947-reflect-method/src/Main.java
+++ b/test/947-reflect-method/src/Main.java
@@ -14,60 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
-import java.lang.reflect.Method;
-
public class Main {
-
- /**
- * 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 static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
+ public static void main(String[] args) throws Exception {
+ art.Test947.run();
}
-
- public static void doTest(Transform t) {
- try {
- Method say_hi_method = t.getClass().getDeclaredMethod("sayHi");
- say_hi_method.invoke(t);
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- say_hi_method.invoke(t);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
}
diff --git a/test/947-reflect-method/src/Transform.java b/test/947-reflect-method/src/Transform.java
deleted file mode 100644
index b8fe34aef3..0000000000
--- a/test/947-reflect-method/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-class Transform {
- public void sayHi() {
- // 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:
- // "Goodbye" < "LTransform;" < "hello".
- System.out.println("hello");
- }
-}
diff --git a/test/947-reflect-method/src/art/Redefinition.java b/test/947-reflect-method/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/947-reflect-method/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/947-reflect-method/src/art/Test947.java b/test/947-reflect-method/src/art/Test947.java
new file mode 100644
index 0000000000..8cb515e492
--- /dev/null
+++ b/test/947-reflect-method/src/art/Test947.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+import java.lang.reflect.Method;
+
+public class Test947 {
+
+ static class Transform {
+ public void sayHi() {
+ System.out.println("hello");
+ }
+ }
+
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform {
+ * public void sayHi() {
+ * System.out.println("Goodbye");
+ * }
+ * }
+ */
+ private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+ "yv66vgAAADQAIAoABgAOCQAPABAIABEKABIAEwcAFQcAGAEABjxpbml0PgEAAygpVgEABENvZGUB" +
+ "AA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAAxUZXN0OTQ3LmphdmEMAAcA" +
+ "CAcAGQwAGgAbAQAHR29vZGJ5ZQcAHAwAHQAeBwAfAQAVYXJ0L1Rlc3Q5NDckVHJhbnNmb3JtAQAJ" +
+ "VHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5nL09iamVjdAEAEGphdmEvbGFuZy9T" +
+ "eXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFt" +
+ "AQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAC2FydC9UZXN0OTQ3ACAABQAGAAAA" +
+ "AAACAAAABwAIAAEACQAAAB0AAQABAAAABSq3AAGxAAAAAQAKAAAABgABAAAABQABAAsACAABAAkA" +
+ "AAAlAAIAAQAAAAmyAAISA7YABLEAAAABAAoAAAAKAAIAAAAHAAgACAACAAwAAAACAA0AFwAAAAoA" +
+ "AQAFABQAFgAI");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQCEgoKcAAAAAAAAAAAAAAAAAAAAAAAAAAC4AwAAcAAAAHhWNBIAAAAAAAAAAPQCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB0AgAARAEAAEQB" +
+ "AABMAQAAVQEAAG4BAAB9AQAAoQEAAMEBAADYAQAA7AEAAAACAAAUAgAAIgIAAC0CAAAwAgAANAIA" +
+ "AEECAABHAgAATAIAAFUCAABcAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABkAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA5AIAALgCAAAAAAAABjxpbml0PgAHR29vZGJ5ZQAX" +
+ "TGFydC9UZXN0OTQ3JFRyYW5zZm9ybTsADUxhcnQvVGVzdDk0NzsAIkxkYWx2aWsvYW5ub3RhdGlv" +
+ "bi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEv" +
+ "aW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAS" +
+ "TGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTQ3LmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vz" +
+ "c0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAQAAAAYAAAAFAAcOAAcA" +
+ "Bw4BCA8AAAAAAQABAAEAAABsAgAABAAAAHAQAwAAAA4AAwABAAIAAABxAgAACQAAAGIAAAAbAQEA" +
+ "AABuIAIAEAAOAAAAAAABAQCAgAT8BAEBlAUAAAICARMYAQIDAg4ECA8XCwACAAAAyAIAAM4CAADY" +
+ "AgAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAUAAAAcAAAAAIAAAAJAAAAwAAAAAMA" +
+ "AAACAAAA5AAAAAQAAAABAAAA/AAAAAUAAAAEAAAABAEAAAYAAAABAAAAJAEAAAIgAAAUAAAARAEA" +
+ "AAEQAAABAAAAZAIAAAMgAAACAAAAbAIAAAEgAAACAAAAfAIAAAAgAAABAAAAuAIAAAQgAAACAAAA" +
+ "yAIAAAMQAAABAAAA2AIAAAYgAAABAAAA5AIAAAAQAAABAAAA9AIAAA==");
+
+ public static void run() {
+ doTest(new Transform());
+ }
+
+ public static void doTest(Transform t) {
+ try {
+ Method say_hi_method = t.getClass().getDeclaredMethod("sayHi");
+ say_hi_method.invoke(t);
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ say_hi_method.invoke(t);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/test/948-change-annotations/src/Main.java b/test/948-change-annotations/src/Main.java
index a290396ebf..5d3406dacc 100644
--- a/test/948-change-annotations/src/Main.java
+++ b/test/948-change-annotations/src/Main.java
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import art.Redefinition;
import java.util.Arrays;
import java.util.Base64;
import java.util.Comparator;
@@ -85,7 +86,9 @@ public class Main {
}
// Transforms the class
- public static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
+ public static void doCommonClassRedefinition(Class<?> target,
+ byte[] class_file,
+ byte[] dex_file) {
+ Redefinition.doCommonClassRedefinition(target, class_file, dex_file);
+ }
}
diff --git a/test/948-change-annotations/src/art/Redefinition.java b/test/948-change-annotations/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/948-change-annotations/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/949-in-memory-transform/src/Main.java b/test/949-in-memory-transform/src/Main.java
index 1a6b224a37..b49a93f67b 100644
--- a/test/949-in-memory-transform/src/Main.java
+++ b/test/949-in-memory-transform/src/Main.java
@@ -14,112 +14,8 @@
* 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 {
- art.Main.bindAgentJNIForClass(Main.class);
- 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);
+ art.Test949.run();
}
-
- 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/949-in-memory-transform/src/art/Redefinition.java b/test/949-in-memory-transform/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/949-in-memory-transform/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/949-in-memory-transform/src/art/Test949.java b/test/949-in-memory-transform/src/art/Test949.java
new file mode 100644
index 0000000000..cd733b9f2d
--- /dev/null
+++ b/test/949-in-memory-transform/src/art/Test949.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import static art.Redefinition.doCommonClassRedefinition;
+
+import java.util.Base64;
+import java.lang.reflect.*;
+import java.nio.ByteBuffer;
+
+public class Test949 {
+ /**
+ * 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 run() 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);
+ }
+}
diff --git a/test/950-redefine-intrinsic/src/Main.java b/test/950-redefine-intrinsic/src/Main.java
index 2578d6e278..369a8f417e 100644
--- a/test/950-redefine-intrinsic/src/Main.java
+++ b/test/950-redefine-intrinsic/src/Main.java
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import static art.Redefinition.doCommonClassRedefinition;
import java.util.Base64;
import java.util.Random;
import java.util.function.*;
@@ -464,9 +465,4 @@ public class Main {
}
System.out.println("Finished!");
}
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
}
diff --git a/test/950-redefine-intrinsic/src/art/Redefinition.java b/test/950-redefine-intrinsic/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/950-redefine-intrinsic/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/951-threaded-obsolete/src/Main.java b/test/951-threaded-obsolete/src/Main.java
index a82090e736..d245aa9ec8 100644
--- a/test/951-threaded-obsolete/src/Main.java
+++ b/test/951-threaded-obsolete/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,84 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
-import java.util.concurrent.Semaphore;
-
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) {
- art.Main.bindAgentJNIForClass(Main.class);
- // Semaphores to let each thread know where the other is. We could use barriers but semaphores
- // mean we don't need to have the worker thread be waiting around.
- final Semaphore sem_redefine_start = new Semaphore(0);
- final Semaphore sem_redefine_end = new Semaphore(0);
- // Create a thread to do the actual redefinition. We will just communicate through an
- // atomic-integer.
- new Thread(() -> {
- try {
- // Wait for the other thread to ask for redefinition.
- sem_redefine_start.acquire();
- // Do the redefinition.
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- // Allow the other thread to wake up if it is waiting.
- sem_redefine_end.release();
- } catch (InterruptedException e) {
- throw new Error("unable to do redefinition", e);
- }
- }).start();
-
- Transform t = new Transform();
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
- t.sayHi(() -> {
- try {
- System.out.println("transforming calling function");
- // Wake up the waiting thread.
- sem_redefine_start.release();
- // Wait for the other thread to finish with redefinition.
- sem_redefine_end.acquire();
- } catch (InterruptedException e) {
- throw new Error("unable to do redefinition", e);
- }
- });
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ public static void main(String[] args) throws Exception {
+ art.Test951.run();
}
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
}
diff --git a/test/951-threaded-obsolete/src/Transform.java b/test/951-threaded-obsolete/src/Transform.java
deleted file mode 100644
index 8cda6cdf53..0000000000
--- a/test/951-threaded-obsolete/src/Transform.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class 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/951-threaded-obsolete/src/art/Redefinition.java b/test/951-threaded-obsolete/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/951-threaded-obsolete/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/951-threaded-obsolete/src/art/Test951.java b/test/951-threaded-obsolete/src/art/Test951.java
new file mode 100644
index 0000000000..3628f4f9db
--- /dev/null
+++ b/test/951-threaded-obsolete/src/art/Test951.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+import java.util.concurrent.Semaphore;
+
+public class Test951 {
+
+ static class Transform {
+ public void sayHi(Runnable r) {
+ System.out.println("hello");
+ r.run();
+ System.out.println("goodbye");
+ }
+ }
+
+ // static 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(
+ "yv66vgAAADQAKAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAbBwAeAQAGPGluaXQ+AQADKClW" +
+ "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
+ "KVYBAApTb3VyY2VGaWxlAQAMVGVzdDk1MS5qYXZhDAAJAAoHAB8MACAAIQEAE0hlbGxvIC0gVHJh" +
+ "bnNmb3JtZWQHACIMACMAJAcAJQwAJgAKAQAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkBwAnAQAVYXJ0" +
+ "L1Rlc3Q5NTEkVHJhbnNmb3JtAQAJVHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5n" +
+ "L09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsB" +
+ "ABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEA" +
+ "EmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgEAC2FydC9UZXN0OTUxACAABwAIAAAAAAACAAAACQAK" +
+ "AAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAABQABAA0ADgABAAsAAAA7AAIAAgAA" +
+ "ABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAcACAAIAA4ACQAWAAoAAgAP" +
+ "AAAAAgAQAB0AAAAKAAEABwAaABwACA==");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQBom/JeAAAAAAAAAAAAAAAAAAAAAAAAAAA8BAAAcAAAAHhWNBIAAAAAAAAAAHgDAAAX" +
+ "AAAAcAAAAAoAAADMAAAAAwAAAPQAAAABAAAAGAEAAAUAAAAgAQAAAQAAAEgBAADUAgAAaAEAAGgB" +
+ "AABwAQAAhwEAAJwBAAC1AQAAxAEAAOgBAAAIAgAAHwIAADMCAABJAgAAXQIAAHECAAB/AgAAigIA" +
+ "AI0CAACRAgAAngIAAKQCAACpAgAAsgIAALcCAAC+AgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAA" +
+ "CQAAAAoAAAALAAAADgAAAA4AAAAJAAAAAAAAAA8AAAAJAAAAyAIAAA8AAAAJAAAA0AIAAAgABAAS" +
+ "AAAAAAAAAAAAAAAAAAEAFQAAAAQAAgATAAAABQAAAAAAAAAGAAAAFAAAAAAAAAAAAAAABQAAAAAA" +
+ "AAAMAAAAaAMAADwDAAAAAAAABjxpbml0PgAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkABNIZWxsbyAt" +
+ "IFRyYW5zZm9ybWVkABdMYXJ0L1Rlc3Q5NTEkVHJhbnNmb3JtOwANTGFydC9UZXN0OTUxOwAiTGRh" +
+ "bHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVy" +
+ "Q2xhc3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEv" +
+ "bGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AAxU" +
+ "ZXN0OTUxLmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vzc0ZsYWdzAARuYW1lAANvdXQAB3By" +
+ "aW50bG4AA3J1bgAFc2F5SGkABXZhbHVlAAAAAAEAAAAGAAAAAQAAAAcAAAAFAAcOAAcBAAcOAQgP" +
+ "AQMPAQgPAAEAAQABAAAA2AIAAAQAAABwEAMAAAAOAAQAAgACAAAA3QIAABQAAABiAAAAGwECAAAA" +
+ "biACABAAchAEAAMAYgAAABsBAQAAAG4gAgAQAA4AAAABAQCAgATsBQEBhAYAAAICARYYAQIDAhAE" +
+ "CBEXDQACAAAATAMAAFIDAABcAwAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAXAAAA" +
+ "cAAAAAIAAAAKAAAAzAAAAAMAAAADAAAA9AAAAAQAAAABAAAAGAEAAAUAAAAFAAAAIAEAAAYAAAAB" +
+ "AAAASAEAAAIgAAAXAAAAaAEAAAEQAAACAAAAyAIAAAMgAAACAAAA2AIAAAEgAAACAAAA7AIAAAAg" +
+ "AAABAAAAPAMAAAQgAAACAAAATAMAAAMQAAABAAAAXAMAAAYgAAABAAAAaAMAAAAQAAABAAAAeAMA" +
+ "AA==");
+
+ public static void run() {
+ // Semaphores to let each thread know where the other is. We could use barriers but semaphores
+ // mean we don't need to have the worker thread be waiting around.
+ final Semaphore sem_redefine_start = new Semaphore(0);
+ final Semaphore sem_redefine_end = new Semaphore(0);
+ // Create a thread to do the actual redefinition. We will just communicate through an
+ // atomic-integer.
+ new Thread(() -> {
+ try {
+ // Wait for the other thread to ask for redefinition.
+ sem_redefine_start.acquire();
+ // Do the redefinition.
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ // Allow the other thread to wake up if it is waiting.
+ sem_redefine_end.release();
+ } catch (InterruptedException e) {
+ throw new Error("unable to do redefinition", e);
+ }
+ }).start();
+
+ Transform t = new Transform();
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ t.sayHi(() -> {
+ try {
+ System.out.println("transforming calling function");
+ // Wake up the waiting thread.
+ sem_redefine_start.release();
+ // Wait for the other thread to finish with redefinition.
+ sem_redefine_end.acquire();
+ } catch (InterruptedException e) {
+ throw new Error("unable to do redefinition", e);
+ }
+ });
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/959-invoke-polymorphic-accessors/src/Main.java b/test/959-invoke-polymorphic-accessors/src/Main.java
index b7ecf8e818..59db8076b2 100644
--- a/test/959-invoke-polymorphic-accessors/src/Main.java
+++ b/test/959-invoke-polymorphic-accessors/src/Main.java
@@ -794,6 +794,7 @@ public class Main {
ValueHolder valueHolder = new ValueHolder();
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle h0 = lookup.findSetter(ValueHolder.class, "m_f", float.class);
+ MethodHandle s0 = lookup.findSetter(ValueHolder.class, "m_s", short.class);
h0.invoke(valueHolder, 0.22f);
h0.invoke(valueHolder, new Float(1.11f));
Number floatNumber = getFloatAsNumber();
@@ -807,6 +808,11 @@ public class Main {
unreachable();
} catch (NullPointerException e) {}
+ // Test that type conversion checks work on small field types.
+ short temp = (short)s0.invoke(valueHolder, new Byte((byte)45));
+ assertTrue(temp == 0);
+ assertTrue(valueHolder.m_s == 45);
+
h0.invoke(valueHolder, (byte)1);
h0.invoke(valueHolder, (short)2);
h0.invoke(valueHolder, 3);
@@ -848,6 +854,7 @@ public class Main {
private static void testStaticSetter() throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodHandle s0 = lookup.findStaticSetter(ValueHolder.class, "s_s", short.class);
MethodHandle h0 = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class);
h0.invoke(0.22f);
h0.invoke(new Float(1.11f));
@@ -860,6 +867,11 @@ public class Main {
unreachable();
} catch (NullPointerException e) {}
+ // Test that type conversion checks work on small field types.
+ short temp = (short)s0.invoke(new Byte((byte)45));
+ assertTrue(temp == 0);
+ assertTrue(ValueHolder.s_s == 45);
+
h0.invoke((byte)1);
h0.invoke((short)2);
h0.invoke(3);
diff --git a/test/980-redefine-object/check b/test/980-redefine-object/check
index 987066fe15..07b21b3176 100755
--- a/test/980-redefine-object/check
+++ b/test/980-redefine-object/check
@@ -17,4 +17,4 @@
# The number of paused background threads (and therefore InterruptedExceptions)
# can change so we will just delete their lines from the log.
-sed "/Object allocated of type 'Ljava\/lang\/InterruptedException;'/d" "$2" | diff --strip-trailing-cr -q "$1" - >/dev/null
+sed "/Object allocated of type 'java\.lang\.InterruptedException'/d" "$2" | diff --strip-trailing-cr -q "$1" - >/dev/null
diff --git a/test/980-redefine-object/expected.txt b/test/980-redefine-object/expected.txt
index 6e9bce027a..4c294bc870 100644
--- a/test/980-redefine-object/expected.txt
+++ b/test/980-redefine-object/expected.txt
@@ -2,51 +2,31 @@
Allocating an j.l.Object before redefining Object class
Allocating a Transform before redefining Object class
Redefining the Object class to add a hook into the <init> method
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
Allocating an j.l.Object after redefining Object class
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
+Object allocated of type 'java.lang.Object'
Allocating a Transform after redefining Object class
-Object allocated of type 'LTransform;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
+Object allocated of type 'Transform'
Allocating an int[] after redefining Object class
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
Allocating an array list
-Object allocated of type 'Ljava/util/ArrayList;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
+Object allocated of type 'java.util.ArrayList'
Adding a bunch of stuff to the array list
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'LTransform;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
+Object allocated of type 'java.lang.Object'
+Object allocated of type 'java.lang.Object'
+Object allocated of type 'Transform'
Allocating a linked list
-Object allocated of type 'Ljava/util/LinkedList;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
+Object allocated of type 'java.util.LinkedList'
Adding a bunch of stuff to the linked list
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/lang/Object;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'LTransform;'
-Object allocated of type 'Ljava/util/LinkedList$Node;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
+Object allocated of type 'java.lang.Object'
+Object allocated of type 'java.util.LinkedList$Node'
+Object allocated of type 'java.lang.Object'
+Object allocated of type 'java.util.LinkedList$Node'
+Object allocated of type 'java.util.LinkedList$Node'
+Object allocated of type 'java.util.LinkedList$Node'
+Object allocated of type 'java.util.LinkedList$Node'
+Object allocated of type 'java.util.LinkedList$Node'
+Object allocated of type 'Transform'
+Object allocated of type 'java.util.LinkedList$Node'
Throwing from down 4 stack frames
-Object allocated of type 'Ljava/lang/Exception;'
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
+Object allocated of type 'java.lang.Exception'
Exception caught.
-Object allocated of type 'Ljava/lang/StringBuilder;'
-Object allocated of type 'Ljava/nio/HeapCharBuffer;'
Finishing test!
diff --git a/test/980-redefine-object/redefine_object.cc b/test/980-redefine-object/redefine_object.cc
deleted file mode 100644
index 1faf1a16a7..0000000000
--- a/test/980-redefine-object/redefine_object.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.
- */
-
-#include <inttypes.h>
-#include <iostream>
-
-#include "android-base/stringprintf.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "jni.h"
-#include "jvmti.h"
-#include "scoped_utf_chars.h"
-
-// Test infrastructure
-#include "jni_binder.h"
-#include "jvmti_helper.h"
-#include "test_env.h"
-
-namespace art {
-namespace Test980RedefineObjects {
-
-extern "C" JNIEXPORT void JNICALL Java_Main_bindFunctionsForClass(
- JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass target) {
- BindFunctionsOnClass(jvmti_env, env, target);
-}
-
-extern "C" JNIEXPORT void JNICALL Java_art_test_TestWatcher_NotifyConstructed(
- JNIEnv* env, jclass TestWatcherClass ATTRIBUTE_UNUSED, jobject constructed) {
- char* sig = nullptr;
- char* generic_sig = nullptr;
- if (JvmtiErrorToException(env,
- jvmti_env,
- jvmti_env->GetClassSignature(env->GetObjectClass(constructed),
- &sig,
- &generic_sig))) {
- // Exception.
- return;
- }
- std::cout << "Object allocated of type '" << sig << "'" << std::endl;
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(sig));
- jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(generic_sig));
-}
-
-} // namespace Test980RedefineObjects
-} // namespace art
diff --git a/test/980-redefine-object/src-ex/TestWatcher.java b/test/980-redefine-object/src-ex/TestWatcher.java
index d15e68871c..c38e07bfe9 100644
--- a/test/980-redefine-object/src-ex/TestWatcher.java
+++ b/test/980-redefine-object/src-ex/TestWatcher.java
@@ -16,10 +16,60 @@
package art.test;
+import java.util.concurrent.locks.ReentrantLock;
+
public class TestWatcher {
- // NB This function is native since it is called in the Object.<init> method and so cannot cause
- // any java allocations at all. The normal System.out.print* functions will cause allocations to
- // occur so we cannot use them. This means the easiest way to report the object as being created
- // is to go into native code and do it there.
- public static native void NotifyConstructed(Object o);
+ // Lock to synchronize access to the static state of this class.
+ private static final ReentrantLock lock = new ReentrantLock();
+ private static volatile boolean criticalFailure = false;
+ private static boolean reportingEnabled = true;
+ private static boolean doingReport = false;
+
+ private static void MonitorEnter() {
+ lock.lock();
+ }
+
+ private static void MonitorExit() {
+ // Need to do this manually since we need to notify critical failure but would deadlock if
+ // waited for the unlock.
+ if (!lock.isHeldByCurrentThread()) {
+ NotifyCriticalFailure();
+ throw new IllegalMonitorStateException("Locking error!");
+ } else {
+ lock.unlock();
+ }
+ }
+
+ // Stops reporting. Must be paired with an EnableReporting call.
+ public static void DisableReporting() {
+ MonitorEnter();
+ reportingEnabled = false;
+ }
+
+ // Stops reporting. Must be paired with a DisableReporting call.
+ public static void EnableReporting() {
+ reportingEnabled = true;
+ MonitorExit();
+ }
+
+ public static void NotifyCriticalFailure() {
+ criticalFailure = true;
+ }
+
+ public static void NotifyConstructed(Object o) {
+ if (criticalFailure) {
+ // Something went very wrong. We are probably trying to report it so don't get in the way.
+ return;
+ }
+ MonitorEnter();
+ // We could enter an infinite loop if println allocates (which it does) so we disable
+ // reporting while we are doing a report. Since we are synchronized we won't miss any
+ // allocations.
+ if (reportingEnabled && !doingReport) {
+ doingReport = true;
+ System.out.println("Object allocated of type '" + o.getClass().getName() + "'");
+ doingReport = false;
+ }
+ MonitorExit();
+ }
}
diff --git a/test/980-redefine-object/src/Main.java b/test/980-redefine-object/src/Main.java
index a50215e1ad..63c0cab95e 100644
--- a/test/980-redefine-object/src/Main.java
+++ b/test/980-redefine-object/src/Main.java
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+import static art.Redefinition.doCommonClassRedefinition;
+
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Base64;
import java.util.LinkedList;
@@ -287,6 +290,31 @@ public class Main {
private static final String LISTENER_LOCATION =
System.getenv("DEX_LOCATION") + "/980-redefine-object-ex.jar";
+ private static Method doEnableReporting;
+ private static Method doDisableReporting;
+
+ private static void DisableReporting() {
+ if (doDisableReporting == null) {
+ return;
+ }
+ try {
+ doDisableReporting.invoke(null);
+ } catch (Exception e) {
+ throw new Error("Unable to disable reporting!");
+ }
+ }
+
+ private static void EnableReporting() {
+ if (doEnableReporting == null) {
+ return;
+ }
+ try {
+ doEnableReporting.invoke(null);
+ } catch (Exception e) {
+ throw new Error("Unable to enable reporting!");
+ }
+ }
+
public static void main(String[] args) {
art.Main.bindAgentJNIForClass(Main.class);
doTest();
@@ -298,8 +326,8 @@ public class Main {
addToBootClassLoader(LISTENER_LOCATION);
// Load TestWatcher from the bootclassloader and make sure it is initialized.
Class<?> testwatcher_class = Class.forName("art.test.TestWatcher", true, null);
- // Bind the native functions of testwatcher_class.
- bindFunctionsForClass(testwatcher_class);
+ doEnableReporting = testwatcher_class.getDeclaredMethod("EnableReporting");
+ doDisableReporting = testwatcher_class.getDeclaredMethod("DisableReporting");
} catch (Exception e) {
throw new Error("Exception while making testwatcher", e);
}
@@ -308,9 +336,9 @@ public class Main {
// NB This function will cause 2 objects of type "Ljava/nio/HeapCharBuffer;" and
// "Ljava/nio/HeapCharBuffer;" to be allocated each time it is called.
private static void safePrintln(Object o) {
- System.out.flush();
- System.out.print("\t" + o + "\n");
- System.out.flush();
+ DisableReporting();
+ System.out.println("\t" + o);
+ EnableReporting();
}
private static void throwFrom(int depth) throws Exception {
@@ -381,11 +409,4 @@ public class Main {
}
private static native void addToBootClassLoader(String s);
-
- private static native void bindFunctionsForClass(Class<?> target);
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
}
diff --git a/test/980-redefine-object/src/art/Redefinition.java b/test/980-redefine-object/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/980-redefine-object/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/981-dedup-original-dex/src/Main.java b/test/981-dedup-original-dex/src/Main.java
index 288f7ce4e0..f90c15ce8a 100644
--- a/test/981-dedup-original-dex/src/Main.java
+++ b/test/981-dedup-original-dex/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,190 +14,8 @@
* limitations under the License.
*/
-import java.lang.reflect.Field;
-import java.util.Base64;
-import java.nio.ByteBuffer;
-
-import dalvik.system.ClassExt;
-import dalvik.system.InMemoryDexClassLoader;
-
public class Main {
-
- /**
- * base64 encoded class/dex file for
- * class Transform {
- * public void sayHi() {
- * System.out.println("Goodbye");
- * }
- * }
- */
- private static final byte[] DEX_BYTES_1 = Base64.getDecoder().decode(
- "ZGV4CjAzNQCLXSBQ5FiS3f16krSYZFF8xYZtFVp0GRXMAgAAcAAAAHhWNBIAAAAAAAAAACwCAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACsAQAAIAEAAGIB" +
- "AABqAQAAcwEAAIABAACXAQAAqwEAAL8BAADTAQAA4wEAAOYBAADqAQAA/gEAAAMCAAAMAgAAAgAA" +
- "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAAB4CAAAA" +
- "AAAAAQABAAEAAAATAgAABAAAAHAQAwAAAA4AAwABAAIAAAAYAgAACQAAAGIAAAAbAQEAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgAHR29vZGJ5ZQALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50" +
- "U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xh" +
- "bmcvU3lzdGVtOwAOVHJhbnNmb3JtLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTMuMzYAA291" +
- "dAAHcHJpbnRsbgAFc2F5SGkAEQAHDgATAAcOhQAAAAEBAICABKACAQG4Ag0AAAAAAAAAAQAAAAAA" +
- "AAABAAAADgAAAHAAAAACAAAABgAAAKgAAAADAAAAAgAAAMAAAAAEAAAAAQAAANgAAAAFAAAABAAA" +
- "AOAAAAAGAAAAAQAAAAABAAABIAAAAgAAACABAAABEAAAAQAAAFwBAAACIAAADgAAAGIBAAADIAAA" +
- "AgAAABMCAAAAIAAAAQAAAB4CAAAAEAAAAQAAACwCAAA=");
-
- /**
- * base64 encoded class/dex file for
- * class Transform2 {
- * public void sayHi() {
- * System.out.println("Goodbye2");
- * }
- * }
- */
- private static final byte[] DEX_BYTES_2 = Base64.getDecoder().decode(
- "ZGV4CjAzNQAjXDED2iflQ3NXbPtBRVjQVMqoDU9nDz/QAgAAcAAAAHhWNBIAAAAAAAAAADACAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACwAQAAIAEAAGIB" +
- "AABqAQAAdAEAAIIBAACZAQAArQEAAMEBAADVAQAA5gEAAOkBAADtAQAAAQIAAAYCAAAPAgAAAgAA" +
- "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAACECAAAA" +
- "AAAAAQABAAEAAAAWAgAABAAAAHAQAwAAAA4AAwABAAIAAAAbAgAACQAAAGIAAAAbAQEAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgAIR29vZGJ5ZTIADExUcmFuc2Zvcm0yOwAVTGphdmEvaW8vUHJp" +
- "bnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEv" +
- "bGFuZy9TeXN0ZW07AA9UcmFuc2Zvcm0yLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTQuMzAA" +
- "A291dAAHcHJpbnRsbgAFc2F5SGkAAQAHDgADAAcOhwAAAAEBAICABKACAQG4AgANAAAAAAAAAAEA" +
- "AAAAAAAAAQAAAA4AAABwAAAAAgAAAAYAAACoAAAAAwAAAAIAAADAAAAABAAAAAEAAADYAAAABQAA" +
- "AAQAAADgAAAABgAAAAEAAAAAAQAAASAAAAIAAAAgAQAAARAAAAEAAABcAQAAAiAAAA4AAABiAQAA" +
- "AyAAAAIAAAAWAgAAACAAAAEAAAAhAgAAABAAAAEAAAAwAgAA");
-
-
- /**
- * base64 encoded class/dex file for
- * class Transform3 {
- * public void sayHi() {
- * System.out.println("hello3");
- * }
- * }
- */
- private static final byte[] DEX_BYTES_3_INITIAL = Base64.getDecoder().decode(
- "ZGV4CjAzNQC2W2fBsAeLNAwWYlG8FVigzfsV7nBWITzQAgAAcAAAAHhWNBIAAAAAAAAAADACAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACwAQAAIAEAAGIB" +
- "AABqAQAAeAEAAI8BAACjAQAAtwEAAMsBAADcAQAA3wEAAOMBAAD3AQAA/wEAAAQCAAANAgAAAQAA" +
- "AAIAAAADAAAABAAAAAUAAAAHAAAABwAAAAUAAAAAAAAACAAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAGAAAAAAAAAB8CAAAA" +
- "AAAAAQABAAEAAAAUAgAABAAAAHAQAwAAAA4AAwABAAIAAAAZAgAACQAAAGIAAAAbAQoAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgAMTFRyYW5zZm9ybTM7ABVMamF2YS9pby9QcmludFN0cmVhbTsA" +
- "EkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5c3Rl" +
- "bTsAD1RyYW5zZm9ybTMuamF2YQABVgACVkwAEmVtaXR0ZXI6IGphY2stNC4zMAAGaGVsbG8zAANv" +
- "dXQAB3ByaW50bG4ABXNheUhpAAIABw4ABAAHDocAAAABAQCAgASgAgEBuAIAAAANAAAAAAAAAAEA" +
- "AAAAAAAAAQAAAA4AAABwAAAAAgAAAAYAAACoAAAAAwAAAAIAAADAAAAABAAAAAEAAADYAAAABQAA" +
- "AAQAAADgAAAABgAAAAEAAAAAAQAAASAAAAIAAAAgAQAAARAAAAEAAABcAQAAAiAAAA4AAABiAQAA" +
- "AyAAAAIAAAAUAgAAACAAAAEAAAAfAgAAABAAAAEAAAAwAgAA");
-
- /**
- * base64 encoded class/dex file for
- * class Transform3 {
- * public void sayHi() {
- * System.out.println("Goodbye3");
- * }
- * }
- */
- private static final byte[] DEX_BYTES_3_FINAL = Base64.getDecoder().decode(
- "ZGV4CjAzNQBAXE5GthgMydaFBuinf+ZBfXcBYIw2UlXQAgAAcAAAAHhWNBIAAAAAAAAAADACAAAO" +
- "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACwAQAAIAEAAGIB" +
- "AABqAQAAdAEAAIIBAACZAQAArQEAAMEBAADVAQAA5gEAAOkBAADtAQAAAQIAAAYCAAAPAgAAAgAA" +
- "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
- "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAACECAAAA" +
- "AAAAAQABAAEAAAAWAgAABAAAAHAQAwAAAA4AAwABAAIAAAAbAgAACQAAAGIAAAAbAQEAAABuIAIA" +
- "EAAOAAAAAQAAAAMABjxpbml0PgAIR29vZGJ5ZTMADExUcmFuc2Zvcm0zOwAVTGphdmEvaW8vUHJp" +
- "bnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEv" +
- "bGFuZy9TeXN0ZW07AA9UcmFuc2Zvcm0zLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTQuMzAA" +
- "A291dAAHcHJpbnRsbgAFc2F5SGkAAgAHDgAEAAcOhwAAAAEBAICABKACAQG4AgANAAAAAAAAAAEA" +
- "AAAAAAAAAQAAAA4AAABwAAAAAgAAAAYAAACoAAAAAwAAAAIAAADAAAAABAAAAAEAAADYAAAABQAA" +
- "AAQAAADgAAAABgAAAAEAAAAAAQAAASAAAAIAAAAgAQAAARAAAAEAAABcAQAAAiAAAA4AAABiAQAA" +
- "AyAAAAIAAAAWAgAAACAAAAEAAAAhAgAAABAAAAEAAAAwAgAA");
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- try {
- doTest();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private static void assertSame(Object a, Object b) throws Exception {
- if (a != b) {
- throw new AssertionError("'" + (a != null ? a.toString() : "null") + "' is not the same as " +
- "'" + (b != null ? b.toString() : "null") + "'");
- }
- }
-
- private static Object getObjectField(Object o, String name) throws Exception {
- return getObjectField(o, o.getClass(), name);
- }
-
- private static Object getObjectField(Object o, Class<?> type, String name) throws Exception {
- Field f = type.getDeclaredField(name);
- f.setAccessible(true);
- return f.get(o);
- }
-
- private static Object getOriginalDexFile(Class<?> k) throws Exception {
- ClassExt ext_data_object = (ClassExt) getObjectField(k, "extData");
- if (ext_data_object == null) {
- return null;
- }
-
- return getObjectField(ext_data_object, "originalDexFile");
+ public static void main(String[] args) throws Exception {
+ art.Test981.run();
}
-
- public static void doTest() throws Exception {
- // Make sure both of these are loaded prior to transformations being added so they have the same
- // original dex files.
- Transform t1 = new Transform();
- Transform2 t2 = new Transform2();
-
- assertSame(null, getOriginalDexFile(t1.getClass()));
- assertSame(null, getOriginalDexFile(t2.getClass()));
- assertSame(null, getOriginalDexFile(Main.class));
-
- addCommonTransformationResult("Transform", new byte[0], DEX_BYTES_1);
- addCommonTransformationResult("Transform2", new byte[0], DEX_BYTES_2);
- enableCommonRetransformation(true);
- doCommonClassRetransformation(Transform.class, Transform2.class);
-
- assertSame(getOriginalDexFile(t1.getClass()), getOriginalDexFile(t2.getClass()));
- assertSame(null, getOriginalDexFile(Main.class));
- // Make sure that the original dex file is a DexCache object.
- assertSame(getOriginalDexFile(t1.getClass()).getClass(), Class.forName("java.lang.DexCache"));
-
- // Check that we end up with a byte[] if we do a direct RedefineClasses
- enableCommonRetransformation(false);
- doCommonClassRedefinition(Transform.class, new byte[0], DEX_BYTES_1);
- assertSame((new byte[0]).getClass(), getOriginalDexFile(t1.getClass()).getClass());
-
- // Check we don't have anything if we don't have any originalDexFile if the onload
- // transformation doesn't do anything.
- enableCommonRetransformation(true);
- Class<?> transform3Class = new InMemoryDexClassLoader(
- ByteBuffer.wrap(DEX_BYTES_3_INITIAL), Main.class.getClassLoader()).loadClass("Transform3");
- assertSame(null, getOriginalDexFile(transform3Class));
-
- // Check that we end up with a java.lang.Long pointer if we do an 'on-load' redefinition.
- addCommonTransformationResult("Transform3", new byte[0], DEX_BYTES_3_FINAL);
- enableCommonRetransformation(true);
- Class<?> transform3ClassTransformed = new InMemoryDexClassLoader(
- ByteBuffer.wrap(DEX_BYTES_3_INITIAL), Main.class.getClassLoader()).loadClass("Transform3");
- assertSame(Long.class, getOriginalDexFile(transform3ClassTransformed).getClass());
- }
-
- // Transforms the class
- private static native void doCommonClassRetransformation(Class<?>... target);
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] class_file,
- byte[] dex_file);
- private static native void enableCommonRetransformation(boolean enable);
- private static native void addCommonTransformationResult(String target_name,
- byte[] class_bytes,
- byte[] dex_bytes);
}
diff --git a/test/981-dedup-original-dex/src/Transform.java b/test/981-dedup-original-dex/src/Transform.java
deleted file mode 100644
index 3c97907ddc..0000000000
--- a/test/981-dedup-original-dex/src/Transform.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi() {
- System.out.println("hello");
- }
-}
diff --git a/test/981-dedup-original-dex/src/Transform2.java b/test/981-dedup-original-dex/src/Transform2.java
deleted file mode 100644
index eb22842184..0000000000
--- a/test/981-dedup-original-dex/src/Transform2.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform2 {
- public void sayHi() {
- System.out.println("hello2");
- }
-}
diff --git a/test/981-dedup-original-dex/src/art/Redefinition.java b/test/981-dedup-original-dex/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/981-dedup-original-dex/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/981-dedup-original-dex/src/art/Test981.java b/test/981-dedup-original-dex/src/art/Test981.java
new file mode 100644
index 0000000000..3a97268ef9
--- /dev/null
+++ b/test/981-dedup-original-dex/src/art/Test981.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.
+ */
+
+package art;
+
+import java.lang.reflect.Field;
+import java.util.Base64;
+import java.nio.ByteBuffer;
+
+import dalvik.system.ClassExt;
+import dalvik.system.InMemoryDexClassLoader;
+
+public class Test981 {
+
+ static class Transform {
+ public void sayHi() {
+ System.out.println("hello");
+ }
+ }
+
+ static class Transform2 {
+ public void sayHi() {
+ System.out.println("hello2");
+ }
+ }
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform {
+ * public void sayHi() {
+ * System.out.println("Goodbye");
+ * }
+ * }
+ */
+ private static final byte[] DEX_BYTES_1 = Base64.getDecoder().decode(
+ "ZGV4CjAzNQB+giqQAAAAAAAAAAAAAAAAAAAAAAAAAAC4AwAAcAAAAHhWNBIAAAAAAAAAAPQCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB0AgAARAEAAEQB" +
+ "AABMAQAAVQEAAG4BAAB9AQAAoQEAAMEBAADYAQAA7AEAAAACAAAUAgAAIgIAAC0CAAAwAgAANAIA" +
+ "AEECAABHAgAATAIAAFUCAABcAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABkAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA5AIAALgCAAAAAAAABjxpbml0PgAHR29vZGJ5ZQAX" +
+ "TGFydC9UZXN0OTgxJFRyYW5zZm9ybTsADUxhcnQvVGVzdDk4MTsAIkxkYWx2aWsvYW5ub3RhdGlv" +
+ "bi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAVTGphdmEv" +
+ "aW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAS" +
+ "TGphdmEvbGFuZy9TeXN0ZW07AAxUZXN0OTgxLmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vz" +
+ "c0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAQAAAAYAAAAFAAcOAAcA" +
+ "Bw4BCA8AAAAAAQABAAEAAABsAgAABAAAAHAQAwAAAA4AAwABAAIAAABxAgAACQAAAGIAAAAbAQEA" +
+ "AABuIAIAEAAOAAAAAAABAQCAgAT8BAEBlAUAAAICARMYAQIDAg4ECA8XCwACAAAAyAIAAM4CAADY" +
+ "AgAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAUAAAAcAAAAAIAAAAJAAAAwAAAAAMA" +
+ "AAACAAAA5AAAAAQAAAABAAAA/AAAAAUAAAAEAAAABAEAAAYAAAABAAAAJAEAAAIgAAAUAAAARAEA" +
+ "AAEQAAABAAAAZAIAAAMgAAACAAAAbAIAAAEgAAACAAAAfAIAAAAgAAABAAAAuAIAAAQgAAACAAAA" +
+ "yAIAAAMQAAABAAAA2AIAAAYgAAABAAAA5AIAAAAQAAABAAAA9AIAAA==");
+
+ /**
+ * base64 encoded class/dex file for
+ * static class Transform2 {
+ * public void sayHi() {
+ * System.out.println("Goodbye2");
+ * }
+ * }
+ */
+ private static final byte[] DEX_BYTES_2 = Base64.getDecoder().decode(
+ "ZGV4CjAzNQAhg+RVAAAAAAAAAAAAAAAAAAAAAAAAAAC8AwAAcAAAAHhWNBIAAAAAAAAAAPgCAAAU" +
+ "AAAAcAAAAAkAAADAAAAAAgAAAOQAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAB4AgAARAEAAEQB" +
+ "AABMAQAAVgEAAHABAAB/AQAAowEAAMMBAADaAQAA7gEAAAICAAAWAgAAJAIAADACAAAzAgAANwIA" +
+ "AEQCAABKAgAATwIAAFgCAABfAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAA" +
+ "DAAAAAgAAAAAAAAADQAAAAgAAABoAgAABwAEABAAAAAAAAAAAAAAAAAAAAASAAAABAABABEAAAAF" +
+ "AAAAAAAAAAAAAAAAAAAABQAAAAAAAAAKAAAA6AIAALwCAAAAAAAABjxpbml0PgAIR29vZGJ5ZTIA" +
+ "GExhcnQvVGVzdDk4MSRUcmFuc2Zvcm0yOwANTGFydC9UZXN0OTgxOwAiTGRhbHZpay9hbm5vdGF0" +
+ "aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xhc3M7ABVMamF2" +
+ "YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7" +
+ "ABJMamF2YS9sYW5nL1N5c3RlbTsADFRlc3Q5ODEuamF2YQAKVHJhbnNmb3JtMgABVgACVkwAC2Fj" +
+ "Y2Vzc0ZsYWdzAARuYW1lAANvdXQAB3ByaW50bG4ABXNheUhpAAV2YWx1ZQAAAAEAAAAGAAAACgAH" +
+ "DgAMAAcOAQgPAAAAAAEAAQABAAAAcAIAAAQAAABwEAMAAAAOAAMAAQACAAAAdQIAAAkAAABiAAAA" +
+ "GwEBAAAAbiACABAADgAAAAAAAQEAgIAEgAUBAZgFAAACAgETGAECAwIOBAgPFwsAAgAAAMwCAADS" +
+ "AgAA3AIAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAABAAAAFAAAAHAAAAACAAAACQAAAMAA" +
+ "AAADAAAAAgAAAOQAAAAEAAAAAQAAAPwAAAAFAAAABAAAAAQBAAAGAAAAAQAAACQBAAACIAAAFAAA" +
+ "AEQBAAABEAAAAQAAAGgCAAADIAAAAgAAAHACAAABIAAAAgAAAIACAAAAIAAAAQAAALwCAAAEIAAA" +
+ "AgAAAMwCAAADEAAAAQAAANwCAAAGIAAAAQAAAOgCAAAAEAAAAQAAAPgCAAA=");
+
+ /**
+ * base64 encoded class/dex file for
+ * class Transform3 {
+ * public void sayHi() {
+ * System.out.println("hello3");
+ * }
+ * }
+ */
+ private static final byte[] DEX_BYTES_3_INITIAL = Base64.getDecoder().decode(
+ "ZGV4CjAzNQC2W2fBsAeLNAwWYlG8FVigzfsV7nBWITzQAgAAcAAAAHhWNBIAAAAAAAAAADACAAAO" +
+ "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACwAQAAIAEAAGIB" +
+ "AABqAQAAeAEAAI8BAACjAQAAtwEAAMsBAADcAQAA3wEAAOMBAAD3AQAA/wEAAAQCAAANAgAAAQAA" +
+ "AAIAAAADAAAABAAAAAUAAAAHAAAABwAAAAUAAAAAAAAACAAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
+ "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAGAAAAAAAAAB8CAAAA" +
+ "AAAAAQABAAEAAAAUAgAABAAAAHAQAwAAAA4AAwABAAIAAAAZAgAACQAAAGIAAAAbAQoAAABuIAIA" +
+ "EAAOAAAAAQAAAAMABjxpbml0PgAMTFRyYW5zZm9ybTM7ABVMamF2YS9pby9QcmludFN0cmVhbTsA" +
+ "EkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5c3Rl" +
+ "bTsAD1RyYW5zZm9ybTMuamF2YQABVgACVkwAEmVtaXR0ZXI6IGphY2stNC4zMAAGaGVsbG8zAANv" +
+ "dXQAB3ByaW50bG4ABXNheUhpAAIABw4ABAAHDocAAAABAQCAgASgAgEBuAIAAAANAAAAAAAAAAEA" +
+ "AAAAAAAAAQAAAA4AAABwAAAAAgAAAAYAAACoAAAAAwAAAAIAAADAAAAABAAAAAEAAADYAAAABQAA" +
+ "AAQAAADgAAAABgAAAAEAAAAAAQAAASAAAAIAAAAgAQAAARAAAAEAAABcAQAAAiAAAA4AAABiAQAA" +
+ "AyAAAAIAAAAUAgAAACAAAAEAAAAfAgAAABAAAAEAAAAwAgAA");
+
+ /**
+ * base64 encoded class/dex file for
+ * class Transform3 {
+ * public void sayHi() {
+ * System.out.println("Goodbye3");
+ * }
+ * }
+ */
+ private static final byte[] DEX_BYTES_3_FINAL = Base64.getDecoder().decode(
+ "ZGV4CjAzNQBAXE5GthgMydaFBuinf+ZBfXcBYIw2UlXQAgAAcAAAAHhWNBIAAAAAAAAAADACAAAO" +
+ "AAAAcAAAAAYAAACoAAAAAgAAAMAAAAABAAAA2AAAAAQAAADgAAAAAQAAAAABAACwAQAAIAEAAGIB" +
+ "AABqAQAAdAEAAIIBAACZAQAArQEAAMEBAADVAQAA5gEAAOkBAADtAQAAAQIAAAYCAAAPAgAAAgAA" +
+ "AAMAAAAEAAAABQAAAAYAAAAIAAAACAAAAAUAAAAAAAAACQAAAAUAAABcAQAABAABAAsAAAAAAAAA" +
+ "AAAAAAAAAAANAAAAAQABAAwAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAHAAAAAAAAACECAAAA" +
+ "AAAAAQABAAEAAAAWAgAABAAAAHAQAwAAAA4AAwABAAIAAAAbAgAACQAAAGIAAAAbAQEAAABuIAIA" +
+ "EAAOAAAAAQAAAAMABjxpbml0PgAIR29vZGJ5ZTMADExUcmFuc2Zvcm0zOwAVTGphdmEvaW8vUHJp" +
+ "bnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEv" +
+ "bGFuZy9TeXN0ZW07AA9UcmFuc2Zvcm0zLmphdmEAAVYAAlZMABJlbWl0dGVyOiBqYWNrLTQuMzAA" +
+ "A291dAAHcHJpbnRsbgAFc2F5SGkAAgAHDgAEAAcOhwAAAAEBAICABKACAQG4AgANAAAAAAAAAAEA" +
+ "AAAAAAAAAQAAAA4AAABwAAAAAgAAAAYAAACoAAAAAwAAAAIAAADAAAAABAAAAAEAAADYAAAABQAA" +
+ "AAQAAADgAAAABgAAAAEAAAAAAQAAASAAAAIAAAAgAQAAARAAAAEAAABcAQAAAiAAAA4AAABiAQAA" +
+ "AyAAAAIAAAAWAgAAACAAAAEAAAAhAgAAABAAAAEAAAAwAgAA");
+
+ public static void run() throws Exception {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_RETRANSFORM);
+ doTest();
+ }
+
+ private static void assertSame(Object a, Object b) throws Exception {
+ if (a != b) {
+ throw new AssertionError("'" + (a != null ? a.toString() : "null") + "' is not the same as " +
+ "'" + (b != null ? b.toString() : "null") + "'");
+ }
+ }
+
+ private static Object getObjectField(Object o, String name) throws Exception {
+ return getObjectField(o, o.getClass(), name);
+ }
+
+ private static Object getObjectField(Object o, Class<?> type, String name) throws Exception {
+ Field f = type.getDeclaredField(name);
+ f.setAccessible(true);
+ return f.get(o);
+ }
+
+ private static Object getOriginalDexFile(Class<?> k) throws Exception {
+ ClassExt ext_data_object = (ClassExt) getObjectField(k, "extData");
+ if (ext_data_object == null) {
+ return null;
+ }
+
+ return getObjectField(ext_data_object, "originalDexFile");
+ }
+
+ public static void doTest() throws Exception {
+ // Make sure both of these are loaded prior to transformations being added so they have the same
+ // original dex files.
+ Transform t1 = new Transform();
+ Transform2 t2 = new Transform2();
+
+ assertSame(null, getOriginalDexFile(t1.getClass()));
+ assertSame(null, getOriginalDexFile(t2.getClass()));
+ assertSame(null, getOriginalDexFile(Test981.class));
+
+ Redefinition.addCommonTransformationResult("art/Test981$Transform", new byte[0], DEX_BYTES_1);
+ Redefinition.addCommonTransformationResult("art/Test981$Transform2", new byte[0], DEX_BYTES_2);
+ Redefinition.enableCommonRetransformation(true);
+ Redefinition.doCommonClassRetransformation(Transform.class, Transform2.class);
+
+ assertSame(getOriginalDexFile(t1.getClass()), getOriginalDexFile(t2.getClass()));
+ assertSame(null, getOriginalDexFile(Test981.class));
+ // Make sure that the original dex file is a DexCache object.
+ assertSame(getOriginalDexFile(t1.getClass()).getClass(), Class.forName("java.lang.DexCache"));
+
+ // Check that we end up with a byte[] if we do a direct RedefineClasses
+ Redefinition.enableCommonRetransformation(false);
+ Redefinition.doCommonClassRedefinition(Transform.class, new byte[0], DEX_BYTES_1);
+ assertSame((new byte[0]).getClass(), getOriginalDexFile(t1.getClass()).getClass());
+
+ // Check we don't have anything if we don't have any originalDexFile if the onload
+ // transformation doesn't do anything.
+ Redefinition.enableCommonRetransformation(true);
+ Class<?> transform3Class = new InMemoryDexClassLoader(
+ ByteBuffer.wrap(DEX_BYTES_3_INITIAL), Test981.class.getClassLoader()).loadClass("Transform3");
+ assertSame(null, getOriginalDexFile(transform3Class));
+
+ // Check that we end up with a java.lang.Long pointer if we do an 'on-load' redefinition.
+ Redefinition.addCommonTransformationResult("Transform3", new byte[0], DEX_BYTES_3_FINAL);
+ Redefinition.enableCommonRetransformation(true);
+ Class<?> transform3ClassTransformed = new InMemoryDexClassLoader(
+ ByteBuffer.wrap(DEX_BYTES_3_INITIAL), Test981.class.getClassLoader()).loadClass("Transform3");
+ assertSame(Long.class, getOriginalDexFile(transform3ClassTransformed).getClass());
+ }
+}
diff --git a/test/982-ok-no-retransform/src/Main.java b/test/982-ok-no-retransform/src/Main.java
index 33e50d77ba..bd73e81da6 100644
--- a/test/982-ok-no-retransform/src/Main.java
+++ b/test/982-ok-no-retransform/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,22 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
public class Main {
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest(new Transform());
- }
-
- public static void doTest(Transform t) {
- t.sayHi();
- enableCommonRetransformation(true);
- doCommonClassRetransformation(Transform.class);
- t.sayHi();
+ public static void main(String[] args) throws Exception {
+ art.Test982.run();
}
-
- // Transforms the class
- private static native void doCommonClassRetransformation(Class<?>... target);
- private static native void enableCommonRetransformation(boolean enable);
}
diff --git a/test/982-ok-no-retransform/src/Transform.java b/test/982-ok-no-retransform/src/Transform.java
deleted file mode 100644
index 8e8af355da..0000000000
--- a/test/982-ok-no-retransform/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi() {
- // 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:
- // "Goodbye" < "LTransform;" < "hello".
- System.out.println("hello");
- }
-}
diff --git a/test/982-ok-no-retransform/src/art/Redefinition.java b/test/982-ok-no-retransform/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/982-ok-no-retransform/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/942-private-recursive/src/Transform.java b/test/982-ok-no-retransform/src/art/Test982.java
index 7714326066..080d47facc 100644
--- a/test/942-private-recursive/src/Transform.java
+++ b/test/982-ok-no-retransform/src/art/Test982.java
@@ -14,19 +14,26 @@
* limitations under the License.
*/
-class Transform {
- private void privateSayHi(int recur, Runnable r) {
- System.out.println("hello" + recur);
- if (recur == 1) {
- r.run();
- privateSayHi(recur - 1, r);
- } else if (recur != 0) {
- privateSayHi(recur - 1, r);
+package art;
+
+import java.util.Base64;
+public class Test982 {
+
+ static class Transform {
+ public void sayHi() {
+ System.out.println("hello");
}
- System.out.println("goodbye" + recur);
}
- public void sayHi(int recur, Runnable r) {
- privateSayHi(recur, r);
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_RETRANSFORM);
+ doTest(new Transform());
+ }
+
+ public static void doTest(Transform t) {
+ t.sayHi();
+ Redefinition.enableCommonRetransformation(true);
+ Redefinition.doCommonClassRetransformation(Transform.class);
+ t.sayHi();
}
}
diff --git a/test/983-source-transform-verify/expected.txt b/test/983-source-transform-verify/expected.txt
index 0a94212ad2..abcdf3a868 100644
--- a/test/983-source-transform-verify/expected.txt
+++ b/test/983-source-transform-verify/expected.txt
@@ -1,2 +1,2 @@
-Dex file hook for Transform
+Dex file hook for art/Test983$Transform
Dex file hook for java/lang/Object
diff --git a/test/983-source-transform-verify/src/Main.java b/test/983-source-transform-verify/src/Main.java
index ad081a2006..e1d20f6678 100644
--- a/test/983-source-transform-verify/src/Main.java
+++ b/test/983-source-transform-verify/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,23 +14,8 @@
* limitations under the License.
*/
-import java.util.Base64;
public class Main {
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest();
- }
-
- public static void doTest() {
- Transform abc = new Transform();
- enableCommonRetransformation(true);
- doCommonClassRetransformation(Transform.class);
- doCommonClassRetransformation(Object.class);
- enableCommonRetransformation(false);
+ public static void main(String[] args) throws Exception {
+ art.Test983.run();
}
-
- // Transforms the class
- private static native void doCommonClassRetransformation(Class<?>... target);
- private static native void enableCommonRetransformation(boolean enable);
}
diff --git a/test/983-source-transform-verify/src/Transform.java b/test/983-source-transform-verify/src/Transform.java
deleted file mode 100644
index 8e8af355da..0000000000
--- a/test/983-source-transform-verify/src/Transform.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- public void sayHi() {
- // 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:
- // "Goodbye" < "LTransform;" < "hello".
- System.out.println("hello");
- }
-}
diff --git a/test/983-source-transform-verify/src/art/Redefinition.java b/test/983-source-transform-verify/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/983-source-transform-verify/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/915-obsolete-2/src/Transform.java b/test/983-source-transform-verify/src/art/Test983.java
index e914e29479..b81e7f4df3 100644
--- a/test/915-obsolete-2/src/Transform.java
+++ b/test/983-source-transform-verify/src/art/Test983.java
@@ -14,22 +14,25 @@
* limitations under the License.
*/
-class Transform {
- private void Start() {
- System.out.println("hello - private");
+package art;
+
+import java.util.Base64;
+public class Test983 {
+ static class Transform {
+ public void sayHi() {
+ System.out.println("hello");
+ }
}
- private void Finish() {
- System.out.println("goodbye - private");
+ public static void run() {
+ doTest();
}
- 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");
+ public static void doTest() {
+ Transform abc = new Transform();
+ Redefinition.enableCommonRetransformation(true);
+ Redefinition.doCommonClassRetransformation(Transform.class);
+ Redefinition.doCommonClassRetransformation(Object.class);
+ Redefinition.enableCommonRetransformation(false);
}
}
diff --git a/test/984-obsolete-invoke/obsolete_invoke.cc b/test/984-obsolete-invoke/obsolete_invoke.cc
index 27e36ba509..ab2499aa62 100644
--- a/test/984-obsolete-invoke/obsolete_invoke.cc
+++ b/test/984-obsolete-invoke/obsolete_invoke.cc
@@ -17,20 +17,20 @@
#include "android-base/macros.h"
#include "jni.h"
#include "jvmti.h"
-#include "mirror/class-inl.h"
-#include "scoped_local_ref.h"
// Test infrastructure
#include "test_env.h"
#include "jvmti_helper.h"
+#include "scoped_local_ref.h"
namespace art {
namespace Test984ObsoleteInvoke {
static constexpr size_t kNumFrames = 30;
-extern "C" JNIEXPORT jobject JNICALL Java_Main_getFirstObsoleteMethod984(JNIEnv* env, jclass) {
+extern "C" JNIEXPORT jobject JNICALL Java_art_Test984_getFirstObsoleteMethod984(JNIEnv* env,
+ jclass) {
jthread cur;
jint frame_count;
jvmtiFrameInfo frames[kNumFrames];
diff --git a/test/984-obsolete-invoke/src/Main.java b/test/984-obsolete-invoke/src/Main.java
index 418d64d906..04a368dcd4 100644
--- a/test/984-obsolete-invoke/src/Main.java
+++ b/test/984-obsolete-invoke/src/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,96 +14,8 @@
* limitations under the License.
*/
-import java.lang.reflect.Method;
-import java.util.Base64;
-
public class Main {
- // class Transform {
- // public static 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" +
- "CQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAAAQAJAA0ADgABAAsAAAA7AAIA" +
- "AQAAABeyAAISA7YABCq5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAMACAAEAA4ABQAWAAYA" +
- "AQAPAAAAAgAQ");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQCMekj2NPwzrEp/v+2yzzSg8xZvBtU1bC1QAwAAcAAAAHhWNBIAAAAAAAAAALACAAAR" +
- "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAMAgAARAEAAKIB" +
- "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAAB3AgAAfAIA" +
- "AIUCAACKAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" +
- "lAEAAAsAAAAGAAAAnAEAAAUAAQANAAAAAAAAAAAAAAAAAAEAEAAAAAEAAgAOAAAAAgAAAAAAAAAD" +
- "AAAADwAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAJ8CAAAAAAAAAQABAAEAAACRAgAABAAAAHAQ" +
- "AwAAAA4AAwABAAIAAACWAgAAFAAAAGIAAAAbAQIAAABuIAIAEAByEAQAAgBiAAAAGwEBAAAAbiAC" +
- "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" +
- "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" +
- "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" +
- "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00" +
- "LjMxAANvdXQAB3ByaW50bG4AA3J1bgAFc2F5SGkAAQAHDgADAQAHDoc8hwAAAAIAAICABMQCAQnc" +
- "AgAAAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAACAAAABwAAALQAAAADAAAAAwAAANAAAAAE" +
- "AAAAAQAAAPQAAAAFAAAABQAAAPwAAAAGAAAAAQAAACQBAAABIAAAAgAAAEQBAAABEAAAAgAAAJQB" +
- "AAACIAAAEQAAAKIBAAADIAAAAgAAAJECAAAAIAAAAQAAAJ8CAAAAEAAAAQAAALACAAA=");
-
- public static void main(String[] args) {
- art.Main.bindAgentJNIForClass(Main.class);
- doTest();
+ public static void main(String[] args) throws Exception {
+ art.Test984.run();
}
-
- // The Method that holds an obsolete method pointer. We will fill it in by getting a jmethodID
- // from a stack with an obsolete method in it. There should be no other ways to obtain an obsolete
- // jmethodID in ART without unsafe casts.
- public static Method obsolete_method = null;
-
- public static void doTest() {
- // Capture the obsolete method.
- //
- // NB The obsolete method must be direct so that we will not look in the receiver type to get
- // the actual method.
- Transform.sayHi(() -> {
- System.out.println("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- System.out.println("Retrieving obsolete method from current stack");
- // This should get the obsolete sayHi method (as the only obsolete method on the current
- // threads stack).
- Main.obsolete_method = getFirstObsoleteMethod984();
- });
-
- // Prove we did actually redefine something.
- System.out.println("Invoking redefined version of method.");
- Transform.sayHi(() -> { System.out.println("Not doing anything here"); });
-
- System.out.println("invoking obsolete method");
- try {
- obsolete_method.invoke(null, (Runnable)() -> {
- throw new Error("Unexpected code running from invoke of obsolete method!");
- });
- throw new Error("Running obsolete method did not throw exception");
- } catch (Throwable e) {
- if (e instanceof InternalError || e.getCause() instanceof InternalError) {
- System.out.println("Caught expected error from attempting to invoke an obsolete method.");
- } else {
- System.out.println("Unexpected error type for calling obsolete method! Expected either "
- + "an InternalError or something that is caused by an InternalError.");
- throw new Error("Unexpected error caught: ", e);
- }
- }
- }
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
-
- // Gets the first obsolete method on the current threads stack (NB only looks through the first 30
- // stack frames).
- private static native Method getFirstObsoleteMethod984();
}
diff --git a/test/984-obsolete-invoke/src/Transform.java b/test/984-obsolete-invoke/src/Transform.java
deleted file mode 100644
index 536de84c46..0000000000
--- a/test/984-obsolete-invoke/src/Transform.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-class Transform {
- // This method must be 'static' so that when we try to invoke it through a j.l.r.Method we will
- // simply use the jmethodID directly and not do any lookup in any receiver object.
- public static void sayHi(Runnable r) {
- System.out.println("hello");
- r.run();
- System.out.println("goodbye");
- }
-}
diff --git a/test/984-obsolete-invoke/src/art/Redefinition.java b/test/984-obsolete-invoke/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/984-obsolete-invoke/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/984-obsolete-invoke/src/art/Test984.java b/test/984-obsolete-invoke/src/art/Test984.java
new file mode 100644
index 0000000000..3fe66f68bf
--- /dev/null
+++ b/test/984-obsolete-invoke/src/art/Test984.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.lang.reflect.Method;
+import java.util.Base64;
+
+public class Test984 {
+
+ static class Transform {
+ // This method must be 'static' so that when we try to invoke it through a j.l.r.Method we will
+ // simply use the jmethodID directly and not do any lookup in any receiver object.
+ public static void sayHi(Runnable r) {
+ System.out.println("hello");
+ r.run();
+ System.out.println("goodbye");
+ }
+ }
+ // static class Transform {
+ // public static 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(
+ "yv66vgAAADQAKAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAbBwAeAQAGPGluaXQ+AQADKClW" +
+ "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
+ "KVYBAApTb3VyY2VGaWxlAQAMVGVzdDk4NC5qYXZhDAAJAAoHAB8MACAAIQEAE0hlbGxvIC0gVHJh" +
+ "bnNmb3JtZWQHACIMACMAJAcAJQwAJgAKAQAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkBwAnAQAVYXJ0" +
+ "L1Rlc3Q5ODQkVHJhbnNmb3JtAQAJVHJhbnNmb3JtAQAMSW5uZXJDbGFzc2VzAQAQamF2YS9sYW5n" +
+ "L09iamVjdAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsB" +
+ "ABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEA" +
+ "EmphdmEvbGFuZy9SdW5uYWJsZQEAA3J1bgEAC2FydC9UZXN0OTg0ACAABwAIAAAAAAACAAAACQAK" +
+ "AAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAABQAJAA0ADgABAAsAAAA7AAIAAQAA" +
+ "ABeyAAISA7YABCq5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAcACAAIAA4ACQAWAAoAAgAP" +
+ "AAAAAgAQAB0AAAAKAAEABwAaABwACA==");
+ private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+ "ZGV4CjAzNQB/mxSMAAAAAAAAAAAAAAAAAAAAAAAAAAA8BAAAcAAAAHhWNBIAAAAAAAAAAHgDAAAX" +
+ "AAAAcAAAAAoAAADMAAAAAwAAAPQAAAABAAAAGAEAAAUAAAAgAQAAAQAAAEgBAADUAgAAaAEAAGgB" +
+ "AABwAQAAhwEAAJwBAAC1AQAAxAEAAOgBAAAIAgAAHwIAADMCAABJAgAAXQIAAHECAAB/AgAAigIA" +
+ "AI0CAACRAgAAngIAAKQCAACpAgAAsgIAALcCAAC+AgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAA" +
+ "CQAAAAoAAAALAAAADgAAAA4AAAAJAAAAAAAAAA8AAAAJAAAAyAIAAA8AAAAJAAAA0AIAAAgABAAS" +
+ "AAAAAAAAAAAAAAAAAAEAFQAAAAQAAgATAAAABQAAAAAAAAAGAAAAFAAAAAAAAAAAAAAABQAAAAAA" +
+ "AAAMAAAAaAMAADwDAAAAAAAABjxpbml0PgAVR29vZGJ5ZSAtIFRyYW5zZm9ybWVkABNIZWxsbyAt" +
+ "IFRyYW5zZm9ybWVkABdMYXJ0L1Rlc3Q5ODQkVHJhbnNmb3JtOwANTGFydC9UZXN0OTg0OwAiTGRh" +
+ "bHZpay9hbm5vdGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVy" +
+ "Q2xhc3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEv" +
+ "bGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AAxU" +
+ "ZXN0OTg0LmphdmEACVRyYW5zZm9ybQABVgACVkwAC2FjY2Vzc0ZsYWdzAARuYW1lAANvdXQAB3By" +
+ "aW50bG4AA3J1bgAFc2F5SGkABXZhbHVlAAAAAAEAAAAGAAAAAQAAAAcAAAAFAAcOAAcBAAcOAQgP" +
+ "AQMPAQgPAAEAAQABAAAA2AIAAAQAAABwEAMAAAAOAAMAAQACAAAA3QIAABQAAABiAAAAGwECAAAA" +
+ "biACABAAchAEAAIAYgAAABsBAQAAAG4gAgAQAA4AAAACAACAgATsBQEJhAYAAAICARYYAQIDAhAE" +
+ "CBEXDQACAAAATAMAAFIDAABcAwAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAAAAEAAAAXAAAA" +
+ "cAAAAAIAAAAKAAAAzAAAAAMAAAADAAAA9AAAAAQAAAABAAAAGAEAAAUAAAAFAAAAIAEAAAYAAAAB" +
+ "AAAASAEAAAIgAAAXAAAAaAEAAAEQAAACAAAAyAIAAAMgAAACAAAA2AIAAAEgAAACAAAA7AIAAAAg" +
+ "AAABAAAAPAMAAAQgAAACAAAATAMAAAMQAAABAAAAXAMAAAYgAAABAAAAaAMAAAAQAAABAAAAeAMA" +
+ "AA==");
+
+ public static void run() {
+ art.Main.bindAgentJNIForClass(Test984.class);
+ doTest();
+ }
+
+ // The Method that holds an obsolete method pointer. We will fill it in by getting a jmethodID
+ // from a stack with an obsolete method in it. There should be no other ways to obtain an obsolete
+ // jmethodID in ART without unsafe casts.
+ public static Method obsolete_method = null;
+
+ public static void doTest() {
+ // Capture the obsolete method.
+ //
+ // NB The obsolete method must be direct so that we will not look in the receiver type to get
+ // the actual method.
+ Transform.sayHi(() -> {
+ System.out.println("transforming calling function");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+ System.out.println("Retrieving obsolete method from current stack");
+ // This should get the obsolete sayHi method (as the only obsolete method on the current
+ // threads stack).
+ Test984.obsolete_method = getFirstObsoleteMethod984();
+ });
+
+ // Prove we did actually redefine something.
+ System.out.println("Invoking redefined version of method.");
+ Transform.sayHi(() -> { System.out.println("Not doing anything here"); });
+
+ System.out.println("invoking obsolete method");
+ try {
+ obsolete_method.invoke(null, (Runnable)() -> {
+ throw new Error("Unexpected code running from invoke of obsolete method!");
+ });
+ throw new Error("Running obsolete method did not throw exception");
+ } catch (Throwable e) {
+ if (e instanceof InternalError || e.getCause() instanceof InternalError) {
+ System.out.println("Caught expected error from attempting to invoke an obsolete method.");
+ } else {
+ System.out.println("Unexpected error type for calling obsolete method! Expected either "
+ + "an InternalError or something that is caused by an InternalError.");
+ throw new Error("Unexpected error caught: ", e);
+ }
+ }
+ }
+
+ // Gets the first obsolete method on the current threads stack (NB only looks through the first 30
+ // stack frames).
+ private static native Method getFirstObsoleteMethod984();
+}
diff --git a/test/985-re-obsolete/expected.txt b/test/985-re-obsolete/expected.txt
new file mode 100644
index 0000000000..5159a00f43
--- /dev/null
+++ b/test/985-re-obsolete/expected.txt
@@ -0,0 +1,35 @@
+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
+Pre Start private method call - Transformed
+Hello - private - Transformed
+Post Start private method call - Transformed
+transforming calling function
+Pre Finish private method call - Transformed
+second - Goodbye - private - Transformed
+Post Finish private method call - Transformed
+second - Pre Start private method call - Transformed
+second - Hello - private - Transformed
+second - Post Start private method call - Transformed
+Not doing anything here
+second - Pre Finish private method call - Transformed
+second - Goodbye - private - Transformed
+second - Post Finish private method call - Transformed
diff --git a/test/985-re-obsolete/info.txt b/test/985-re-obsolete/info.txt
new file mode 100644
index 0000000000..c8eafdc723
--- /dev/null
+++ b/test/985-re-obsolete/info.txt
@@ -0,0 +1,4 @@
+Tests basic obsolete method support
+
+Regression test for b/37475600 which was caused by incorrectly checking for
+differences in the obsolete methods map.
diff --git a/test/985-re-obsolete/run b/test/985-re-obsolete/run
new file mode 100755
index 0000000000..e92b873956
--- /dev/null
+++ b/test/985-re-obsolete/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/912-classes/src-ex/A.java b/test/985-re-obsolete/src/Main.java
index 2c43cfbd79..d78d591f47 100644
--- a/test/912-classes/src-ex/A.java
+++ b/test/985-re-obsolete/src/Main.java
@@ -14,5 +14,8 @@
* limitations under the License.
*/
-public class A {
+public class Main {
+ public static void main(String[] args) throws Exception {
+ art.Test985.run();
+ }
}
diff --git a/test/926-multi-obsolescence/src/CommonClassDefinition.java b/test/985-re-obsolete/src/art/Main.java
index 62602a02e9..8b01920638 100644
--- a/test/926-multi-obsolescence/src/CommonClassDefinition.java
+++ b/test/985-re-obsolete/src/art/Main.java
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-class CommonClassDefinition {
- public final Class<?> target;
- public final byte[] class_file_bytes;
- public final byte[] dex_file_bytes;
+package art;
- CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
- this.target = target;
- this.class_file_bytes = class_file_bytes;
- this.dex_file_bytes = dex_file_bytes;
- }
+// Binder class so the agent's C code has something that can be bound and exposed to tests.
+// In a package to separate cleanly and work around CTS reference issues (though this class
+// should be replaced in the CTS version).
+public class Main {
+ // Load the given class with the given classloader, and bind all native methods to corresponding
+ // C methods in the agent. Will abort if any of the steps fail.
+ public static native void bindAgentJNI(String className, ClassLoader classLoader);
+ // Same as above, giving the class directly.
+ public static native void bindAgentJNIForClass(Class<?> klass);
}
diff --git a/test/985-re-obsolete/src/art/Redefinition.java b/test/985-re-obsolete/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/985-re-obsolete/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/985-re-obsolete/src/art/Test985.java b/test/985-re-obsolete/src/art/Test985.java
new file mode 100644
index 0000000000..405abd5d14
--- /dev/null
+++ b/test/985-re-obsolete/src/art/Test985.java
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.Base64;
+
+public class Test985 {
+
+ static 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");
+ }
+ }
+
+ // static 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_1 = Base64.getDecoder().decode(
+ "yv66vgAAADQANgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" +
+ "JwcAKQcALAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" +
+ "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAM" +
+ "VGVzdDk4NS5qYXZhDAAPABAHAC0MAC4ALwEAHUhlbGxvIC0gcHJpdmF0ZSAtIFRyYW5zZm9ybWVk" +
+ "BwAwDAAxADIBAB9Hb29kYnllIC0gcHJpdmF0ZSAtIFRyYW5zZm9ybWVkAQArUHJlIFN0YXJ0IHBy" +
+ "aXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAwAEwAQAQAsUG9zdCBTdGFydCBwcml2YXRl" +
+ "IG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQHADMMADQAEAEALFByZSBGaW5pc2ggcHJpdmF0ZSBt" +
+ "ZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAAUABABAC1Qb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhv" +
+ "ZCBjYWxsIC0gVHJhbnNmb3JtZWQHADUBABVhcnQvVGVzdDk4NSRUcmFuc2Zvcm0BAAlUcmFuc2Zv" +
+ "cm0BAAxJbm5lckNsYXNzZXMBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEA" +
+ "A291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmlu" +
+ "dGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuAQAL" +
+ "YXJ0L1Rlc3Q5ODUAIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAABABIA" +
+ "AAAGAAEAAAAEAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAAAAYA" +
+ "CAAHAAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAkACAAKAAEA" +
+ "FQAWAAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQqtwAL" +
+ "sgACEgy2AASxAAAAAQASAAAAIgAIAAAADAAIAA0ADAAOABQADwAaABAAIgARACYAEgAuABMAAgAX" +
+ "AAAAAgAYACsAAAAKAAEADQAoACoACA==");
+ private static final byte[] DEX_BYTES_1 = Base64.getDecoder().decode(
+ "ZGV4CjAzNQAh+CJbAAAAAAAAAAAAAAAAAAAAAAAAAADUBQAAcAAAAHhWNBIAAAAAAAAAABAFAAAd" +
+ "AAAAcAAAAAoAAADkAAAAAwAAAAwBAAABAAAAMAEAAAcAAAA4AQAAAQAAAHABAABEBAAAkAEAAJAB" +
+ "AACYAQAAoAEAAMEBAADgAQAA+QEAAAgCAAAsAgAATAIAAGMCAAB3AgAAjQIAAKECAAC1AgAA5AIA" +
+ "ABIDAABAAwAAbQMAAHQDAACCAwAAjQMAAJADAACUAwAAoQMAAKcDAACsAwAAtQMAALoDAADBAwAA" +
+ "BAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAAFAAAABQAAAAJAAAAAAAAABUAAAAJ" +
+ "AAAA0AMAABUAAAAJAAAAyAMAAAgABAAYAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAARAAAAAAABABsA" +
+ "AAAEAAIAGQAAAAUAAAAAAAAABgAAABoAAAAAAAAAAAAAAAUAAAAAAAAAEgAAAAAFAADMBAAAAAAA" +
+ "AAY8aW5pdD4ABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVsbG8g" +
+ "LSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAF0xhcnQvVGVzdDk4NSRUcmFuc2Zvcm07AA1MYXJ0L1Rl" +
+ "c3Q5ODU7ACJMZGFsdmlrL2Fubm90YXRpb24vRW5jbG9zaW5nQ2xhc3M7AB5MZGFsdmlrL2Fubm90" +
+ "YXRpb24vSW5uZXJDbGFzczsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmpl" +
+ "Y3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5n" +
+ "L1N5c3RlbTsALVBvc3QgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAs" +
+ "UG9zdCBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQALFByZSBGaW5pc2gg" +
+ "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkACtQcmUgU3RhcnQgcHJpdmF0ZSBtZXRo" +
+ "b2QgY2FsbCAtIFRyYW5zZm9ybWVkAAVTdGFydAAMVGVzdDk4NS5qYXZhAAlUcmFuc2Zvcm0AAVYA" +
+ "AlZMAAthY2Nlc3NGbGFncwAEbmFtZQADb3V0AAdwcmludGxuAANydW4ABXNheUhpAAV2YWx1ZQAB" +
+ "AAAABwAAAAEAAAAGAAAABAAHDgAJAAcOAQgPAAYABw4BCA8ADAEABw4BCA8BAw8BCA8BAw8BCA8B" +
+ "Aw8BCA8AAQABAAEAAADYAwAABAAAAHAQBQAAAA4AAwABAAIAAADdAwAACQAAAGIAAAAbAQIAAABu" +
+ "IAQAEAAOAAAAAwABAAIAAADlAwAACQAAAGIAAAAbAQMAAABuIAQAEAAOAAAABAACAAIAAADtAwAA" +
+ "KgAAAGIAAAAbARAAAABuIAQAEABwEAIAAgBiAAAAGwEOAAAAbiAEABAAchAGAAMAYgAAABsBDwAA" +
+ "AG4gBAAQAHAQAQACAGIAAAAbAQ0AAABuIAQAEAAOAAAAAwEAgIAEiAgBAqAIAQLECAMB6AgAAAIC" +
+ "ARwYAQIDAhYECBcXEwACAAAA5AQAAOoEAAD0BAAAAAAAAAAAAAAAAAAAEAAAAAAAAAABAAAAAAAA" +
+ "AAEAAAAdAAAAcAAAAAIAAAAKAAAA5AAAAAMAAAADAAAADAEAAAQAAAABAAAAMAEAAAUAAAAHAAAA" +
+ "OAEAAAYAAAABAAAAcAEAAAIgAAAdAAAAkAEAAAEQAAACAAAAyAMAAAMgAAAEAAAA2AMAAAEgAAAE" +
+ "AAAACAQAAAAgAAABAAAAzAQAAAQgAAACAAAA5AQAAAMQAAABAAAA9AQAAAYgAAABAAAAAAUAAAAQ" +
+ "AAABAAAAEAUAAA==");
+
+ // static class Transform {
+ // private void Start() {
+ // System.out.println("second - Hello - private - Transformed");
+ // }
+ //
+ // private void Finish() {
+ // System.out.println("second - Goodbye - private - Transformed");
+ // }
+ //
+ // public void sayHi(Runnable r) {
+ // System.out.println("second - Pre Start private method call - Transformed");
+ // Start();
+ // System.out.println("second - Post Start private method call - Transformed");
+ // r.run();
+ // System.out.println("second - Pre Finish private method call - Transformed");
+ // Finish();
+ // System.out.println("second - Post Finish private method call - Transformed");
+ // }
+ // }
+ private static final byte[] CLASS_BYTES_2 = Base64.getDecoder().decode(
+ "yv66vgAAADQANgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" +
+ "JwcAKQcALAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" +
+ "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAM" +
+ "VGVzdDk4NS5qYXZhDAAPABAHAC0MAC4ALwEAJnNlY29uZCAtIEhlbGxvIC0gcHJpdmF0ZSAtIFRy" +
+ "YW5zZm9ybWVkBwAwDAAxADIBAChzZWNvbmQgLSBHb29kYnllIC0gcHJpdmF0ZSAtIFRyYW5zZm9y" +
+ "bWVkAQA0c2Vjb25kIC0gUHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1l" +
+ "ZAwAEwAQAQA1c2Vjb25kIC0gUG9zdCBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNm" +
+ "b3JtZWQHADMMADQAEAEANXNlY29uZCAtIFByZSBGaW5pc2ggcHJpdmF0ZSBtZXRob2QgY2FsbCAt" +
+ "IFRyYW5zZm9ybWVkDAAUABABADZzZWNvbmQgLSBQb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhvZCBj" +
+ "YWxsIC0gVHJhbnNmb3JtZWQHADUBABVhcnQvVGVzdDk4NSRUcmFuc2Zvcm0BAAlUcmFuc2Zvcm0B" +
+ "AAxJbm5lckNsYXNzZXMBABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291" +
+ "dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxu" +
+ "AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuAQALYXJ0" +
+ "L1Rlc3Q5ODUAIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAABABIAAAAG" +
+ "AAEAAAAEAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAAAAYACAAH" +
+ "AAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAkACAAKAAEAFQAW" +
+ "AAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQqtwALsgAC" +
+ "Egy2AASxAAAAAQASAAAAIgAIAAAADAAIAA0ADAAOABQADwAaABAAIgARACYAEgAuABMAAgAXAAAA" +
+ "AgAYACsAAAAKAAEADQAoACoACA==");
+ private static final byte[] DEX_BYTES_2 = Base64.getDecoder().decode(
+ "ZGV4CjAzNQBw/x+UAAAAAAAAAAAAAAAAAAAAAAAAAAAMBgAAcAAAAHhWNBIAAAAAAAAAAEgFAAAd" +
+ "AAAAcAAAAAoAAADkAAAAAwAAAAwBAAABAAAAMAEAAAcAAAA4AQAAAQAAAHABAAB8BAAAkAEAAJAB" +
+ "AACYAQAAoAEAALkBAADIAQAA7AEAAAwCAAAjAgAANwIAAE0CAABhAgAAdQIAAHwCAACKAgAAlQIA" +
+ "AJgCAACcAgAAqQIAAK8CAAC0AgAAvQIAAMICAADJAgAA8wIAABsDAABTAwAAigMAAMEDAAD3AwAA" +
+ "AgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAADgAAAA4AAAAJAAAAAAAAAA8AAAAJ" +
+ "AAAACAQAAA8AAAAJAAAAAAQAAAgABAASAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAALAAAAAAABABUA" +
+ "AAAEAAIAEwAAAAUAAAAAAAAABgAAABQAAAAAAAAAAAAAAAUAAAAAAAAADAAAADgFAAAEBQAAAAAA" +
+ "AAY8aW5pdD4ABkZpbmlzaAAXTGFydC9UZXN0OTg1JFRyYW5zZm9ybTsADUxhcnQvVGVzdDk4NTsA" +
+ "IkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9J" +
+ "bm5lckNsYXNzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAFExq" +
+ "YXZhL2xhbmcvUnVubmFibGU7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVt" +
+ "OwAFU3RhcnQADFRlc3Q5ODUuamF2YQAJVHJhbnNmb3JtAAFWAAJWTAALYWNjZXNzRmxhZ3MABG5h" +
+ "bWUAA291dAAHcHJpbnRsbgADcnVuAAVzYXlIaQAoc2Vjb25kIC0gR29vZGJ5ZSAtIHByaXZhdGUg" +
+ "LSBUcmFuc2Zvcm1lZAAmc2Vjb25kIC0gSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQANnNl" +
+ "Y29uZCAtIFBvc3QgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAA1c2Vj" +
+ "b25kIC0gUG9zdCBTdGFydCBwcml2YXRlIG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQANXNlY29u" +
+ "ZCAtIFByZSBGaW5pc2ggcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkADRzZWNvbmQg" +
+ "LSBQcmUgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkAAV2YWx1ZQAAAAEA" +
+ "AAAHAAAAAQAAAAYAAAAEAAcOAAkABw4BCA8ABgAHDgEIDwAMAQAHDgEIDwEDDwEIDwEDDwEIDwED" +
+ "DwEIDwABAAEAAQAAABAEAAAEAAAAcBAFAAAADgADAAEAAgAAABUEAAAJAAAAYgAAABsBFgAAAG4g" +
+ "BAAQAA4AAAADAAEAAgAAAB0EAAAJAAAAYgAAABsBFwAAAG4gBAAQAA4AAAAEAAIAAgAAACUEAAAq" +
+ "AAAAYgAAABsBGwAAAG4gBAAQAHAQAgACAGIAAAAbARkAAABuIAQAEAByEAYAAwBiAAAAGwEaAAAA" +
+ "biAEABAAcBABAAIAYgAAABsBGAAAAG4gBAAQAA4AAAADAQCAgATACAEC2AgBAvwIAwGgCQAAAgIB" +
+ "HBgBAgMCEAQIERcNAAIAAAAcBQAAIgUAACwFAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAEAAAAAAAAA" +
+ "AQAAAB0AAABwAAAAAgAAAAoAAADkAAAAAwAAAAMAAAAMAQAABAAAAAEAAAAwAQAABQAAAAcAAAA4" +
+ "AQAABgAAAAEAAABwAQAAAiAAAB0AAACQAQAAARAAAAIAAAAABAAAAyAAAAQAAAAQBAAAASAAAAQA" +
+ "AABABAAAACAAAAEAAAAEBQAABCAAAAIAAAAcBQAAAxAAAAEAAAAsBQAABiAAAAEAAAA4BQAAABAA" +
+ "AAEAAABIBQAA");
+
+ public static void run() {
+ Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+ 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");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES_1, DEX_BYTES_1);
+ });
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ t.sayHi(() -> {
+ System.out.println("transforming calling function");
+ Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES_2, DEX_BYTES_2);
+ });
+ t.sayHi(() -> { System.out.println("Not doing anything here"); });
+ }
+}
diff --git a/test/986-native-method-bind/expected.txt b/test/986-native-method-bind/expected.txt
new file mode 100644
index 0000000000..189217d761
--- /dev/null
+++ b/test/986-native-method-bind/expected.txt
@@ -0,0 +1,8 @@
+private static native void art.Test986$Transform.sayHi() = Java_art_Test986_00024Transform_sayHi -> Java_art_Test986_00024Transform_sayHi
+Hello
+private static native void art.Test986$Transform.sayHi() = Java_art_Test986_00024Transform_sayHi -> NoReallySayGoodbye
+Bye
+public static native void art.Main.bindAgentJNI(java.lang.String,java.lang.ClassLoader) = Java_art_Main_bindAgentJNI -> Java_art_Main_bindAgentJNI
+public static native void art.Main.bindAgentJNIForClass(java.lang.Class) = Java_art_Main_bindAgentJNIForClass -> Java_art_Main_bindAgentJNIForClass
+private static native void art.Test986.setNativeBindNotify(boolean) = Java_art_Test986_setNativeBindNotify -> Java_art_Test986_setNativeBindNotify
+private static native void art.Test986.setupNativeBindNotify() = Java_art_Test986_setupNativeBindNotify -> Java_art_Test986_setupNativeBindNotify
diff --git a/test/986-native-method-bind/info.txt b/test/986-native-method-bind/info.txt
new file mode 100644
index 0000000000..1939936ca9
--- /dev/null
+++ b/test/986-native-method-bind/info.txt
@@ -0,0 +1 @@
+Tests native-method-bind callback and native method replacement.
diff --git a/test/986-native-method-bind/native_bind.cc b/test/986-native-method-bind/native_bind.cc
new file mode 100644
index 0000000000..4f93f87dfe
--- /dev/null
+++ b/test/986-native-method-bind/native_bind.cc
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#include <inttypes.h>
+#include <memory>
+#include <stdio.h>
+#include <dlfcn.h>
+
+#include "android-base/stringprintf.h"
+#include "jni.h"
+#include "jvmti.h"
+
+// Test infrastructure
+#include "jni_binder.h"
+#include "jvmti_helper.h"
+#include "test_env.h"
+#include "scoped_local_ref.h"
+
+namespace art {
+namespace Test986NativeBind {
+
+static void doUpPrintCall(JNIEnv* env, const char* function) {
+ ScopedLocalRef<jclass> klass(env, env->FindClass("art/Test986"));
+ jmethodID targetMethod = env->GetStaticMethodID(klass.get(), function, "()V");
+ env->CallStaticVoidMethod(klass.get(), targetMethod);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test986_00024Transform_sayHi(
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED) {
+ doUpPrintCall(env, "doSayHi");
+}
+
+extern "C" JNIEXPORT void JNICALL NoReallySayGoodbye(JNIEnv* env, jclass klass ATTRIBUTE_UNUSED) {
+ doUpPrintCall(env, "doSayBye");
+}
+
+static void doJvmtiMethodBind(jvmtiEnv* jvmtienv ATTRIBUTE_UNUSED,
+ JNIEnv* env,
+ jthread thread ATTRIBUTE_UNUSED,
+ jmethodID m,
+ void* address,
+ /*out*/void** out_address) {
+ ScopedLocalRef<jclass> method_class(env, env->FindClass("java/lang/reflect/Method"));
+ ScopedLocalRef<jobject> method_obj(env, env->ToReflectedMethod(method_class.get(), m, false));
+ Dl_info addr_info;
+ if (dladdr(address, &addr_info) == 0 || addr_info.dli_sname == nullptr) {
+ ScopedLocalRef<jclass> exception_class(env, env->FindClass("java/lang/Exception"));
+ env->ThrowNew(exception_class.get(), "dladdr failure!");
+ return;
+ }
+ ScopedLocalRef<jstring> sym_name(env, env->NewStringUTF(addr_info.dli_sname));
+ ScopedLocalRef<jclass> klass(env, env->FindClass("art/Test986"));
+ jmethodID upcallMethod = env->GetStaticMethodID(
+ klass.get(),
+ "doNativeMethodBind",
+ "(Ljava/lang/reflect/Method;Ljava/lang/String;)Ljava/lang/String;");
+ if (env->ExceptionCheck()) {
+ return;
+ }
+ ScopedLocalRef<jstring> new_symbol(env,
+ reinterpret_cast<jstring>(
+ env->CallStaticObjectMethod(klass.get(),
+ upcallMethod,
+ method_obj.get(),
+ sym_name.get())));
+ const char* new_symbol_chars = env->GetStringUTFChars(new_symbol.get(), nullptr);
+ if (strcmp(new_symbol_chars, addr_info.dli_sname) != 0) {
+ *out_address = dlsym(RTLD_DEFAULT, new_symbol_chars);
+ if (*out_address == nullptr) {
+ ScopedLocalRef<jclass> exception_class(env, env->FindClass("java/lang/Exception"));
+ env->ThrowNew(exception_class.get(), "dlsym failure!");
+ return;
+ }
+ }
+ env->ReleaseStringUTFChars(new_symbol.get(), new_symbol_chars);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test986_setupNativeBindNotify(
+ JNIEnv* env ATTRIBUTE_UNUSED, jclass klass ATTRIBUTE_UNUSED) {
+ jvmtiEventCallbacks cb;
+ memset(&cb, 0, sizeof(cb));
+ cb.NativeMethodBind = doJvmtiMethodBind;
+ jvmti_env->SetEventCallbacks(&cb, sizeof(cb));
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test986_setNativeBindNotify(
+ JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jboolean enable) {
+ jvmtiError res = jvmti_env->SetEventNotificationMode(enable ? JVMTI_ENABLE : JVMTI_DISABLE,
+ JVMTI_EVENT_NATIVE_METHOD_BIND,
+ nullptr);
+ if (res != JVMTI_ERROR_NONE) {
+ JvmtiErrorToException(env, jvmti_env, res);
+ }
+}
+
+} // namespace Test986NativeBind
+} // namespace art
diff --git a/test/986-native-method-bind/run b/test/986-native-method-bind/run
new file mode 100755
index 0000000000..e92b873956
--- /dev/null
+++ b/test/986-native-method-bind/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/912-classes/src-ex/C.java b/test/986-native-method-bind/src/Main.java
index 97f8021486..fac9d8e2a9 100644
--- a/test/912-classes/src-ex/C.java
+++ b/test/986-native-method-bind/src/Main.java
@@ -14,5 +14,8 @@
* limitations under the License.
*/
-public class C extends A {
+public class Main {
+ public static void main(String[] args) throws Exception {
+ art.Test986.run();
+ }
}
diff --git a/test/944-transform-classloaders/src/CommonClassDefinition.java b/test/986-native-method-bind/src/art/Main.java
index 62602a02e9..8b01920638 100644
--- a/test/944-transform-classloaders/src/CommonClassDefinition.java
+++ b/test/986-native-method-bind/src/art/Main.java
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-class CommonClassDefinition {
- public final Class<?> target;
- public final byte[] class_file_bytes;
- public final byte[] dex_file_bytes;
+package art;
- CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
- this.target = target;
- this.class_file_bytes = class_file_bytes;
- this.dex_file_bytes = dex_file_bytes;
- }
+// Binder class so the agent's C code has something that can be bound and exposed to tests.
+// In a package to separate cleanly and work around CTS reference issues (though this class
+// should be replaced in the CTS version).
+public class Main {
+ // Load the given class with the given classloader, and bind all native methods to corresponding
+ // C methods in the agent. Will abort if any of the steps fail.
+ public static native void bindAgentJNI(String className, ClassLoader classLoader);
+ // Same as above, giving the class directly.
+ public static native void bindAgentJNIForClass(Class<?> klass);
}
diff --git a/test/986-native-method-bind/src/art/Redefinition.java b/test/986-native-method-bind/src/art/Redefinition.java
new file mode 100644
index 0000000000..0350ab42ad
--- /dev/null
+++ b/test/986-native-method-bind/src/art/Redefinition.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+ // Bind native functions.
+ static {
+ Main.bindAgentJNIForClass(Redefinition.class);
+ }
+
+ public static final class CommonClassDefinition {
+ public final Class<?> target;
+ public final byte[] class_file_bytes;
+ public final byte[] dex_file_bytes;
+
+ public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+ this.target = target;
+ this.class_file_bytes = class_file_bytes;
+ this.dex_file_bytes = dex_file_bytes;
+ }
+ }
+
+ // A set of possible test configurations. Test should set this if they need to.
+ // This must be kept in sync with the defines in ti-agent/common_helper.cc
+ public static enum Config {
+ COMMON_REDEFINE(0),
+ COMMON_RETRANSFORM(1),
+ COMMON_TRANSFORM(2);
+
+ private final int val;
+ private Config(int val) {
+ this.val = val;
+ }
+ }
+
+ public static void setTestConfiguration(Config type) {
+ nativeSetTestConfiguration(type.val);
+ }
+
+ private static native void nativeSetTestConfiguration(int type);
+
+ // Transforms the class
+ public static native void doCommonClassRedefinition(Class<?> target,
+ byte[] classfile,
+ byte[] dexfile);
+
+ public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+ ArrayList<Class<?>> classes = new ArrayList<>();
+ ArrayList<byte[]> class_files = new ArrayList<>();
+ ArrayList<byte[]> dex_files = new ArrayList<>();
+
+ for (CommonClassDefinition d : defs) {
+ classes.add(d.target);
+ class_files.add(d.class_file_bytes);
+ dex_files.add(d.dex_file_bytes);
+ }
+ doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+ class_files.toArray(new byte[0][]),
+ dex_files.toArray(new byte[0][]));
+ }
+
+ public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+ for (CommonClassDefinition d : defs) {
+ addCommonTransformationResult(d.target.getCanonicalName(),
+ d.class_file_bytes,
+ d.dex_file_bytes);
+ }
+ }
+
+ public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+ byte[][] classfiles,
+ byte[][] dexfiles);
+ public static native void doCommonClassRetransformation(Class<?>... target);
+ public static native void setPopRetransformations(boolean pop);
+ public static native void popTransformationFor(String name);
+ public static native void enableCommonRetransformation(boolean enable);
+ public static native void addCommonTransformationResult(String target_name,
+ byte[] class_bytes,
+ byte[] dex_bytes);
+}
diff --git a/test/986-native-method-bind/src/art/Test986.java b/test/986-native-method-bind/src/art/Test986.java
new file mode 100644
index 0000000000..edd2e9d79f
--- /dev/null
+++ b/test/986-native-method-bind/src/art/Test986.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package art;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+public class Test986 {
+ static {
+ // NB This is called before any setup is done so we don't need to worry about getting bind
+ // events.
+ Main.bindAgentJNIForClass(Test986.class);
+ }
+
+
+ private static final HashMap<Method, String> SymbolMap = new HashMap<>();
+
+ // A class with a native method we can play with.
+ static class Transform {
+ private static native void sayHi();
+ }
+
+ public static void run() throws Exception {
+ setupNativeBindNotify();
+ setNativeBindNotify(true);
+ doTest();
+ }
+
+ private static void setNativeTransform(Method method, String dest) {
+ SymbolMap.put(method, dest);
+ }
+
+ /**
+ * Notifies java that a native method bind has occurred and requests the new symbol to bind to.
+ */
+ public static String doNativeMethodBind(Method method, String nativeSym) {
+ // Disable native bind notify for now to avoid infinite loops.
+ setNativeBindNotify(false);
+ String transSym = SymbolMap.getOrDefault(method, nativeSym);
+ System.out.println(method + " = " + nativeSym + " -> " + transSym);
+ setNativeBindNotify(true);
+ return transSym;
+ }
+
+ public static void doTest() throws Exception {
+ Method say_hi_method = Transform.class.getDeclaredMethod("sayHi");
+ // TODO We should test auto-binding but due to the way this is run that will be annoying.
+ Main.bindAgentJNIForClass(Transform.class);
+ Transform.sayHi();
+ setNativeTransform(say_hi_method, "NoReallySayGoodbye");
+ Main.bindAgentJNIForClass(Transform.class);
+ Transform.sayHi();
+ Main.bindAgentJNIForClass(Main.class);
+ Main.bindAgentJNIForClass(Test986.class);
+ }
+
+ // Functions called from native code.
+ public static void doSayHi() {
+ System.out.println("Hello");
+ }
+
+ public static void doSayBye() {
+ System.out.println("Bye");
+ }
+
+ private static native void setNativeBindNotify(boolean enable);
+ private static native void setupNativeBindNotify();
+}
diff --git a/test/Android.bp b/test/Android.bp
index 9a8e1742ef..d8a3f0eeed 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -250,6 +250,7 @@ art_cc_defaults {
"ti-agent/jni_binder.cc",
"ti-agent/jvmti_helper.cc",
"ti-agent/test_env.cc",
+ "ti-agent/common_helper.cc",
// This is the list of non-special OnLoad things and excludes BCI and anything that depends
// on ART internals.
"903-hello-tagging/tagging.cc",
@@ -260,6 +261,8 @@ art_cc_defaults {
"908-gc-start-finish/gc_callbacks.cc",
"910-methods/methods.cc",
"911-get-stack-trace/stack_trace.cc",
+ "912-classes/classes.cc",
+ "913-heaps/heaps.cc",
"918-fields/fields.cc",
"920-objects/objects.cc",
"922-properties/properties.cc",
@@ -271,6 +274,9 @@ art_cc_defaults {
"929-search/search.cc",
"931-agent-thread/agent_thread.cc",
"933-misc-events/misc_events.cc",
+ "945-obsolete-native/obsolete_native.cc",
+ "984-obsolete-invoke/obsolete_invoke.cc",
+ "986-native-method-bind/native_bind.cc",
],
shared_libs: [
"libbase",
@@ -286,20 +292,14 @@ art_cc_defaults {
// This is to get the IsInterpreted native method.
"common/stack_inspect.cc",
"common/runtime_state.cc",
+ "ti-agent/common_load.cc",
// This includes the remaining test functions. We should try to refactor things to
// make this list smaller.
- "ti-agent/common_helper.cc",
- "ti-agent/common_load.cc",
"901-hello-ti-agent/basics.cc",
"909-attach-agent/attach.cc",
- "912-classes/classes.cc",
- "913-heaps/heaps.cc",
+ "912-classes/classes_art.cc",
"936-search-onload/search_onload.cc",
- "944-transform-classloaders/classloader.cc",
- "945-obsolete-native/obsolete_native.cc",
- "980-redefine-object/redefine_object.cc",
"983-source-transform-verify/source_transform.cc",
- "984-obsolete-invoke/obsolete_invoke.cc",
],
}
@@ -318,6 +318,33 @@ art_cc_test_library {
shared_libs: ["libartd"],
}
+art_cc_defaults {
+ name: "libtistress-defaults",
+ defaults: ["libartagent-defaults"],
+ srcs: [
+ "ti-stress/stress.cc",
+ ],
+ shared_libs: [
+ "libbase",
+ ],
+ header_libs: ["libopenjdkjvmti_headers"],
+}
+
+art_cc_test_library {
+ name: "libtistress",
+ defaults: [ "libtistress-defaults"],
+ shared_libs: ["libart"],
+}
+
+art_cc_test_library {
+ name: "libtistressd",
+ defaults: [
+ "libtistress-defaults",
+ "art_debug_defaults",
+ ],
+ shared_libs: ["libartd"],
+}
+
art_cc_test_library {
name: "libctstiagent",
defaults: ["libtiagent-base-defaults"],
diff --git a/test/Android.run-test-jvmti-java-library.mk b/test/Android.run-test-jvmti-java-library.mk
index b6da92b942..70ee693a60 100644
--- a/test/Android.run-test-jvmti-java-library.mk
+++ b/test/Android.run-test-jvmti-java-library.mk
@@ -18,13 +18,17 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-# Main shim classes. We use one that exposes the tagging common functionality.
-LOCAL_MAIN_SHIM := 903-hello-tagging/src/art/Main.java
-LOCAL_SRC_FILES := $(LOCAL_MAIN_SHIM)
+# shim classes. We use one that exposes the common functionality.
+LOCAL_SHIM_CLASSES := \
+ 902-hello-transformation/src/art/Redefinition.java \
+ 903-hello-tagging/src/art/Main.java \
+
+LOCAL_SRC_FILES := $(LOCAL_SHIM_CLASSES)
# Actual test classes.
LOCAL_SRC_FILES += \
901-hello-ti-agent/src/art/Test901.java \
+ 902-hello-transformation/src/art/Test902.java \
903-hello-tagging/src/art/Test903.java \
904-object-allocation/src/art/Test904.java \
905-object-free/src/art/Test905.java \
@@ -41,20 +45,39 @@ LOCAL_SRC_FILES += \
911-get-stack-trace/src/art/Recurse.java \
911-get-stack-trace/src/art/SameThread.java \
911-get-stack-trace/src/art/ThreadListTraces.java \
+ 912-classes/src/art/Test912.java \
+ 912-classes/src/art/DexData.java \
913-heaps/src/art/Test913.java \
+ 914-hello-obsolescence/src/art/Test914.java \
+ 915-obsolete-2/src/art/Test915.java \
+ 917-fields-transformation/src/art/Test917.java \
918-fields/src/art/Test918.java \
+ 919-obsolete-fields/src/art/Test919.java \
920-objects/src/art/Test920.java \
922-properties/src/art/Test922.java \
923-monitors/src/art/Test923.java \
924-threads/src/art/Test924.java \
925-threadgroups/src/art/Test925.java \
+ 926-multi-obsolescence/src/art/Test926.java \
927-timers/src/art/Test927.java \
928-jni-table/src/art/Test928.java \
+ 930-hello-retransform/src/art/Test930.java \
931-agent-thread/src/art/Test931.java \
+ 932-transform-saves/src/art/Test932.java \
933-misc-events/src/art/Test933.java \
+ 940-recursive-obsolete/src/art/Test940.java \
+ 942-private-recursive/src/art/Test942.java \
+ 944-transform-classloaders/src/art/Test944.java \
+ 945-obsolete-native/src/art/Test945.java \
+ 947-reflect-method/src/art/Test947.java \
+ 951-threaded-obsolete/src/art/Test951.java \
+ 981-dedup-original-dex/src/art/Test981.java \
+ 982-ok-no-retransform/src/art/Test982.java \
+ 984-obsolete-invoke/src/art/Test984.java \
JVMTI_RUN_TEST_GENERATED_NUMBERS := \
901 \
+ 902 \
903 \
904 \
905 \
@@ -63,17 +86,34 @@ JVMTI_RUN_TEST_GENERATED_NUMBERS := \
908 \
910 \
911 \
+ 912 \
913 \
+ 914 \
+ 915 \
+ 917 \
918 \
+ 919 \
920 \
922 \
923 \
924 \
925 \
+ 926 \
927 \
928 \
+ 930 \
931 \
+ 932 \
933 \
+ 940 \
+ 942 \
+ 944 \
+ 945 \
+ 947 \
+ 951 \
+ 981 \
+ 982 \
+ 984 \
# Try to enforce that the directories correspond to the Java files we pull in.
JVMTI_RUN_TEST_DIR_CHECK := $(sort $(foreach DIR,$(JVMTI_RUN_TEST_GENERATED_NUMBERS), \
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index f9e3213398..afd914432e 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -50,6 +50,14 @@ TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_2ND_ARCH
TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_2ND_ARCH)_libtiagentd)
endif
+# Also need libtistress.
+TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_ARCH)_libtistress)
+TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_ARCH)_libtistressd)
+ifdef TARGET_2ND_ARCH
+TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_2ND_ARCH)_libtistress)
+TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_2ND_ARCH)_libtistressd)
+endif
+
# Also need libarttest.
TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_ARCH)_libarttest)
TEST_ART_TARGET_SYNC_DEPS += $(OUT_DIR)/$(ART_TEST_LIST_device_$(TARGET_ARCH)_libarttestd)
@@ -81,6 +89,8 @@ ART_TEST_HOST_RUN_TEST_DEPENDENCIES := \
$(HOST_OUT_EXECUTABLES)/hprof-conv \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(ART_HOST_ARCH)_libtiagent) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(ART_HOST_ARCH)_libtiagentd) \
+ $(OUT_DIR)/$(ART_TEST_LIST_host_$(ART_HOST_ARCH)_libtistress) \
+ $(OUT_DIR)/$(ART_TEST_LIST_host_$(ART_HOST_ARCH)_libtistressd) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(ART_HOST_ARCH)_libartagent) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(ART_HOST_ARCH)_libartagentd) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(ART_HOST_ARCH)_libarttest) \
@@ -96,6 +106,8 @@ ifneq ($(HOST_PREFER_32_BIT),true)
ART_TEST_HOST_RUN_TEST_DEPENDENCIES += \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(2ND_ART_HOST_ARCH)_libtiagent) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(2ND_ART_HOST_ARCH)_libtiagentd) \
+ $(OUT_DIR)/$(ART_TEST_LIST_host_$(2ND_ART_HOST_ARCH)_libtistress) \
+ $(OUT_DIR)/$(ART_TEST_LIST_host_$(2ND_ART_HOST_ARCH)_libtistressd) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(2ND_ART_HOST_ARCH)_libartagent) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(2ND_ART_HOST_ARCH)_libartagentd) \
$(OUT_DIR)/$(ART_TEST_LIST_host_$(2ND_ART_HOST_ARCH)_libarttest) \
diff --git a/test/common/stack_inspect.cc b/test/common/stack_inspect.cc
index df7fa20226..ceb4ba241b 100644
--- a/test/common/stack_inspect.cc
+++ b/test/common/stack_inspect.cc
@@ -144,22 +144,11 @@ extern "C" JNIEXPORT void JNICALL Java_Main_assertIsInterpreted(JNIEnv* env, jcl
}
}
-static jboolean IsManaged(JNIEnv* env, jclass cls, size_t level) {
+static jboolean IsManaged(JNIEnv* env, jclass, size_t level) {
ScopedObjectAccess soa(env);
-
- ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls);
- const DexFile& dex_file = klass->GetDexFile();
- const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
- if (oat_dex_file == nullptr) {
- // No oat file, this must be a test configuration that doesn't compile at all. Ignore that the
- // result will be that we're running the interpreter.
- return JNI_FALSE;
- }
-
NthCallerVisitor caller(soa.Self(), level, false);
caller.WalkStack();
CHECK(caller.caller != nullptr);
-
return caller.GetCurrentShadowFrame() != nullptr ? JNI_FALSE : JNI_TRUE;
}
diff --git a/test/etc/default-build b/test/etc/default-build
index d74b24d985..744c38bb6d 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -91,7 +91,7 @@ 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"
# We need to leave javac at default 1.7 so that dx will continue to work
-JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.7 -target 1.7"
+JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.8 -target 1.8"
JAVAC_EXPERIMENTAL_ARGS["agents"]="-source 1.8 -target 1.8"
while true; do
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index f1b6132e94..56cfd244e6 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -62,6 +62,7 @@ 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"
+JVMTI_STRESS="n"
VDEX_FILTER=""
PROFILE="n"
RANDOM_PROFILE="n"
@@ -145,6 +146,11 @@ while true; do
elif [ "x$1" = "x--prebuild" ]; then
PREBUILD="y"
shift
+ elif [ "x$1" = "x--jvmti-stress" ]; then
+ # APP_IMAGE doesn't really work with jvmti-torture
+ APP_IMAGE="n"
+ JVMTI_STRESS="y"
+ shift
elif [ "x$1" = "x--no-app-image" ]; then
APP_IMAGE="n"
shift
@@ -365,6 +371,28 @@ if [ "$IS_JVMTI_TEST" = "y" ]; then
fi
fi
+if [[ "$JVMTI_STRESS" = "y" ]]; then
+ if [[ "$USE_JVM" = "n" ]]; then
+ plugin=libopenjdkjvmtid.so
+ agent=libtistressd.so
+ if [[ "$TEST_IS_NDEBUG" = "y" ]]; then
+ agent=libtistress.so
+ plugin=libopenjdkjvmti.so
+ fi
+
+ file_1=$(mktemp --tmpdir=${DEX_LOCATION})
+ file_2=$(mktemp --tmpdir=${DEX_LOCATION})
+ # TODO Remove need for DEXTER_BINARY!
+ FLAGS="${FLAGS} -agentpath:${agent}=${DEXTER_BINARY},${file_1},${file_2}"
+ if [ "$IS_JVMTI_TEST" = "n" ]; then
+ FLAGS="${FLAGS} -Xplugin:${plugin}"
+ FLAGS="${FLAGS} -Xcompiler-option --debuggable"
+ # Always make the compilation be debuggable.
+ COMPILE_FLAGS="${COMPILE_FLAGS} --debuggable"
+ fi
+ fi
+fi
+
if [ "$USE_JVM" = "y" ]; then
export LD_LIBRARY_PATH=${ANDROID_HOST_OUT}/lib64
# Xmx is necessary since we don't pass down the ART flags to JVM.
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 7891d4c19f..0e42a29bf6 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -220,7 +220,6 @@
"tests": ["604-hot-static-interface",
"612-jit-dex-cache",
"613-inlining-dex-cache",
- "616-cha",
"626-set-resolved-string"],
"variant": "trace | stream",
"description": ["These tests expect JIT compilation, which is",
@@ -330,14 +329,8 @@
"variant": "interpreter | optimizing | regalloc_gc | jit"
},
{
- "tests": ["912-classes",
- "616-cha",
- "616-cha-abstract",
- "616-cha-interface",
- "616-cha-interface-default",
- "616-cha-miranda",
- "616-cha-proxy-method-inline"],
- "bug": "http://b/36344364 http://b/36344221",
+ "tests": ["912-classes"],
+ "bug": "http://b/36344364",
"variant": "no-dex2oat | relocate-npatchoat"
},
{
@@ -366,5 +359,248 @@
"634-vdex-duplicate"],
"description": ["Profile driven dexlayout does not work with vdex or dex verifier."],
"variant": "speed-profile"
+ },
+ {
+ "tests": [
+ "004-checker-UnsafeTest18",
+ "127-checker-secondarydex",
+ "441-checker-inliner",
+ "442-checker-constant-folding",
+ "444-checker-nce",
+ "445-checker-licm",
+ "446-checker-inliner2",
+ "447-checker-inliner3",
+ "449-checker-bce",
+ "450-checker-types",
+ "455-checker-gvn",
+ "458-checker-instruct-simplification",
+ "462-checker-inlining-dex-files",
+ "463-checker-boolean-simplifier",
+ "464-checker-inline-sharpen-calls",
+ "465-checker-clinit-gvn",
+ "468-checker-bool-simplif-regression",
+ "473-checker-inliner-constants",
+ "474-checker-boolean-input",
+ "476-checker-ctor-memory-barrier",
+ "477-checker-bound-type",
+ "478-checker-clinit-check-pruning",
+ "478-checker-inline-noreturn",
+ "478-checker-inliner-nested-loop",
+ "480-checker-dead-blocks",
+ "482-checker-loop-back-edge-use",
+ "484-checker-register-hints",
+ "485-checker-dce-loop-update",
+ "485-checker-dce-switch",
+ "486-checker-must-do-null-check",
+ "487-checker-inline-calls",
+ "488-checker-inline-recursive-calls",
+ "490-checker-inline",
+ "492-checker-inline-invoke-interface",
+ "493-checker-inline-invoke-interface",
+ "494-checker-instanceof-tests",
+ "495-checker-checkcast-tests",
+ "496-checker-inlining-class-loader",
+ "508-checker-disassembly",
+ "510-checker-try-catch",
+ "517-checker-builder-fallthrough",
+ "521-checker-array-set-null",
+ "522-checker-regression-monitor-exit",
+ "523-checker-can-throw-regression",
+ "525-checker-arrays-fields1",
+ "525-checker-arrays-fields2",
+ "526-checker-caller-callee-regs",
+ "527-checker-array-access-split",
+ "529-checker-unresolved",
+ "530-checker-loops1",
+ "530-checker-loops2",
+ "530-checker-loops3",
+ "530-checker-loops4",
+ "530-checker-loops5",
+ "530-checker-lse",
+ "530-checker-lse2",
+ "530-checker-regression-reftyp-final",
+ "532-checker-nonnull-arrayset",
+ "534-checker-bce-deoptimization",
+ "536-checker-intrinsic-optimization",
+ "536-checker-needs-access-check",
+ "537-checker-arraycopy",
+ "537-checker-debuggable",
+ "537-checker-inline-and-unverified",
+ "537-checker-jump-over-jump",
+ "538-checker-embed-constants",
+ "540-checker-rtp-bug",
+ "543-checker-dce-trycatch",
+ "548-checker-inlining-and-dce",
+ "549-checker-types-merge",
+ "550-checker-multiply-accumulate",
+ "550-checker-regression-wide-store",
+ "551-checker-clinit",
+ "551-checker-shifter-operand",
+ "552-checker-primitive-typeprop",
+ "552-checker-sharpening",
+ "554-checker-rtp-checkcast",
+ "557-checker-instruct-simplifier-ror",
+ "557-checker-ref-equivalent",
+ "559-checker-irreducible-loop",
+ "559-checker-rtp-ifnotnull",
+ "562-checker-no-intermediate",
+ "563-checker-fakestring",
+ "563-checker-invoke-super",
+ "564-checker-bitcount",
+ "564-checker-inline-loop",
+ "564-checker-irreducible-loop",
+ "564-checker-negbitwise",
+ "565-checker-condition-liveness",
+ "565-checker-doublenegbitwise",
+ "565-checker-irreducible-loop",
+ "565-checker-rotate",
+ "566-checker-codegen-select",
+ "566-checker-signum",
+ "567-checker-compare",
+ "568-checker-onebit",
+ "569-checker-pattern-replacement",
+ "570-checker-osr",
+ "570-checker-select",
+ "572-checker-array-get-regression",
+ "573-checker-checkcast-regression",
+ "575-checker-isnan",
+ "575-checker-string-init-alias",
+ "577-checker-fp2int",
+ "580-checker-round",
+ "580-checker-string-fact-intrinsics",
+ "582-checker-bce-length",
+ "583-checker-zero",
+ "584-checker-div-bool",
+ "586-checker-null-array-get",
+ "588-checker-irreducib-lifetime-hole",
+ "590-checker-arr-set-null-regression",
+ "591-checker-regression-dead-loop",
+ "592-checker-regression-bool-input",
+ "593-checker-boolean-2-integral-conv",
+ "593-checker-long-2-float-regression",
+ "593-checker-shift-and-simplifier",
+ "594-checker-array-alias",
+ "594-checker-irreducible-linorder",
+ "596-checker-dead-phi",
+ "598-checker-irreducible-dominance",
+ "599-checker-irreducible-loop",
+ "603-checker-instanceof",
+ "608-checker-unresolved-lse",
+ "609-checker-inline-interface",
+ "609-checker-x86-bounds-check",
+ "611-checker-simplify-if",
+ "614-checker-dump-constant-location",
+ "615-checker-arm64-store-zero",
+ "618-checker-induction",
+ "619-checker-current-method",
+ "620-checker-bce-intrinsics",
+ "622-checker-bce-regressions",
+ "623-checker-loop-regressions",
+ "624-checker-stringops",
+ "625-checker-licm-regressions",
+ "626-checker-arm64-scratch-register",
+ "627-checker-unroll",
+ "631-checker-fp-abs",
+ "631-checker-get-class",
+ "632-checker-char-at-bounds",
+ "633-checker-rtp-getclass",
+ "635-checker-arm64-volatile-load-cc",
+ "637-checker-throw-inline",
+ "638-checker-inline-caches",
+ "639-checker-code-sinking",
+ "640-checker-boolean-simd",
+ "640-checker-byte-simd",
+ "640-checker-char-simd",
+ "640-checker-double-simd",
+ "640-checker-float-simd",
+ "640-checker-integer-valueof",
+ "640-checker-int-simd",
+ "640-checker-long-simd",
+ "640-checker-short-simd",
+ "641-checker-arraycopy",
+ "643-checker-bogus-ic",
+ "644-checker-deopt",
+ "645-checker-abs-simd",
+ "706-checker-scheduler"],
+ "description": ["Checker tests are not compatible with jvmti."],
+ "variant": "jvmti-stress"
+ },
+ {
+ "tests": [
+ "961-default-iface-resolution-gen",
+ "964-default-iface-init-gen"
+ ],
+ "description": ["Tests that just take too long with jvmti-stress"],
+ "variant": "jvmti-stress"
+ },
+ {
+ "tests": [
+ "950-redefine-intrinsic",
+ "951-threaded-obsolete",
+ "952-invoke-custom",
+ "953-invoke-polymorphic-compiler",
+ "954-invoke-polymorphic-verifier",
+ "955-methodhandles-smali",
+ "956-methodhandles",
+ "957-methodhandle-transforms",
+ "958-methodhandle-stackframe",
+ "959-invoke-polymorphic-accessors"
+ ],
+ "description": [
+ "Tests that use dex version 38 which is not yet supported by",
+ "dexter/slicer."
+ ],
+ "bug": "b/37272822",
+ "variant": "jvmti-stress"
+ },
+ {
+ "tests": [
+ "137-cfi",
+ "595-profile-saving",
+ "900-hello-plugin",
+ "909-attach-agent",
+ "981-dedup-original-dex"
+ ],
+ "description": ["Tests that require exact knowledge of the number of plugins and agents."],
+ "variant": "jvmti-stress"
+ },
+ {
+ "tests": [
+ "097-duplicate-method",
+ "138-duplicate-classes-check2",
+ "804-class-extends-itself",
+ "921-hello-failure"
+ ],
+ "description": [
+ "Tests that use illegal dex files or otherwise break dexter assumptions"
+ ],
+ "variant": "jvmti-stress"
+ },
+ {
+ "tests": [
+ "018-stack-overflow",
+ "068-classloader",
+ "086-null-super",
+ "087-gc-after-link",
+ "626-const-class-linking",
+ "629-vdex-speed",
+ "944-transform-classloaders"
+ ],
+ "description": [
+ "Tests that use custom class loaders or other features not supported ",
+ "by our JVMTI implementation"
+ ],
+ "variant": "jvmti-stress"
+ },
+ {
+ "tests": [
+ "031-class-attributes",
+ "911-get-stack-trace"
+ ],
+ "description": [
+ "Tests that use annotations and debug data that is not kept around by dexter."
+ ],
+ "bug": "b/37239009",
+ "variant": "jvmti-stress"
}
]
diff --git a/test/run-test b/test/run-test
index e46099d2e2..f60f766751 100755
--- a/test/run-test
+++ b/test/run-test
@@ -137,6 +137,7 @@ trace_stream="false"
basic_verify="false"
gc_verify="false"
gc_stress="false"
+jvmti_stress="false"
strace="false"
always_clean="no"
never_clean="no"
@@ -233,6 +234,9 @@ while true; do
basic_verify="true"
gc_stress="true"
shift
+ elif [ "x$1" = "x--jvmti-stress" ]; then
+ jvmti_stress="true"
+ shift
elif [ "x$1" = "x--suspend-timeout" ]; then
shift
suspend_timeout="$1"
@@ -443,6 +447,9 @@ fi
if [ "$gc_stress" = "true" ]; then
run_args="${run_args} --gc-stress --runtime-option -Xgc:gcstress --runtime-option -Xms2m --runtime-option -Xmx16m"
fi
+if [ "$jvmti_stress" = "true" ]; then
+ run_args="${run_args} --no-app-image --jvmti-stress"
+fi
if [ "$trace" = "true" ]; then
run_args="${run_args} --runtime-option -Xmethod-trace --runtime-option -Xmethod-trace-file-size:2000000"
if [ "$trace_stream" = "true" ]; then
@@ -651,6 +658,7 @@ if [ "$usage" = "yes" ]; then
echo " --stream Run method tracing in streaming mode (requires --trace)"
echo " --gcstress Run with gc stress testing"
echo " --gcverify Run with gc verification"
+ echo " --jvmti-stress Run with jvmti stress testing"
echo " --always-clean Delete the test files even if the test fails."
echo " --never-clean Keep the test files even if the test succeeds."
echo " --android-root [path] The path on target for the android root. (/system by default)."
diff --git a/test/testrunner/env.py b/test/testrunner/env.py
index f5e2a61685..7d9297ff89 100644
--- a/test/testrunner/env.py
+++ b/test/testrunner/env.py
@@ -202,6 +202,9 @@ TARGET_ARCH = _get_build_var('TARGET_ARCH')
# Note: ART_2ND_PHONY_TEST_TARGET_SUFFIX is 2ND_ART_PHONY_TEST_TARGET_SUFFIX in .mk files
# Note: ART_2ND_PHONY_TEST_HOST_SUFFIX is 2ND_ART_PHONY_HOST_TARGET_SUFFIX in .mk files
# Python does not let us have variable names starting with a digit, so it has differ.
+
+ART_TEST_RUN_TEST_JVMTI_STRESS = _getEnvBoolean('ART_TEST_RUN_TEST_JVMTI_STRESS', ART_TEST_FULL)
+
if TARGET_2ND_ARCH:
if "64" in TARGET_ARCH:
ART_PHONY_TEST_TARGET_SUFFIX = "64"
diff --git a/test/testrunner/target_config.py b/test/testrunner/target_config.py
index 95ab2e7875..6e47c5eb7a 100644
--- a/test/testrunner/target_config.py
+++ b/test/testrunner/target_config.py
@@ -26,7 +26,7 @@ target_config = {
'make' : 'test-art-host-gtest',
'run-test' : [],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false'
+ 'ART_USE_READ_BARRIER' : 'true'
}
},
@@ -45,19 +45,19 @@ target_config = {
'art-interpreter' : {
'run-test' : ['--interpreter'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false'
+ 'ART_USE_READ_BARRIER' : 'true'
}
},
'art-interpreter-access-checks' : {
'run-test' : ['--interp-ac'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false'
+ 'ART_USE_READ_BARRIER' : 'true'
}
},
'art-jit' : {
'run-test' : ['--jit'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false'
+ 'ART_USE_READ_BARRIER' : 'true'
}
},
'art-gcstress-gcverify': {
@@ -167,51 +167,51 @@ target_config = {
'art-tracing' : {
'run-test' : ['--trace'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false'
+ 'ART_USE_READ_BARRIER' : 'true'
}
},
'art-interpreter-tracing' : {
'run-test' : ['--interpreter',
'--trace'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false',
+ 'ART_USE_READ_BARRIER' : 'true',
}
},
'art-forcecopy' : {
'run-test' : ['--forcecopy'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false',
+ 'ART_USE_READ_BARRIER' : 'true',
}
},
'art-no-prebuild' : {
'run-test' : ['--no-prebuild'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false',
+ 'ART_USE_READ_BARRIER' : 'true',
}
},
'art-no-image' : {
'run-test' : ['--no-image'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false',
+ 'ART_USE_READ_BARRIER' : 'true',
}
},
'art-interpreter-no-image' : {
'run-test' : ['--interpreter',
'--no-image'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false',
+ 'ART_USE_READ_BARRIER' : 'true',
}
},
'art-relocate-no-patchoat' : {
'run-test' : ['--relocate-npatchoat'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false',
+ 'ART_USE_READ_BARRIER' : 'true',
}
},
'art-no-dex2oat' : {
'run-test' : ['--no-dex2oat'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false',
+ 'ART_USE_READ_BARRIER' : 'true',
}
},
'art-heap-poisoning' : {
@@ -231,7 +231,7 @@ target_config = {
'--relocate',
'--jit'],
'env' : {
- 'ART_USE_READ_BARRIER' : 'false'
+ 'ART_USE_READ_BARRIER' : 'true'
}
},
diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py
index 5d3687e293..8072631e8e 100755
--- a/test/testrunner/testrunner.py
+++ b/test/testrunner/testrunner.py
@@ -73,6 +73,7 @@ PICTEST_TYPES = set()
DEBUGGABLE_TYPES = set()
ADDRESS_SIZES = set()
OPTIMIZING_COMPILER_TYPES = set()
+JVMTI_TYPES = set()
ADDRESS_SIZES_TARGET = {'host': set(), 'target': set()}
# timeout for individual tests.
# TODO: make it adjustable per tests and for buildbots
@@ -146,6 +147,7 @@ def gather_test_info():
VARIANT_TYPE_DICT['relocate'] = {'relocate-npatchoat', 'relocate', 'no-relocate'}
VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'}
VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
+ VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress'}
VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'optimizing',
'regalloc_gc', 'speed-profile'}
@@ -195,6 +197,10 @@ def setup_test_env():
if env.ART_TEST_SPEED_PROFILE:
COMPILER_TYPES.add('speed-profile')
+ # By default only run without jvmti
+ if not JVMTI_TYPES:
+ JVMTI_TYPES.add('no-jvmti')
+
# By default we run all 'compiler' variants.
if not COMPILER_TYPES:
COMPILER_TYPES.add('optimizing')
@@ -310,6 +316,7 @@ def run_tests(tests):
total_test_count *= len(PICTEST_TYPES)
total_test_count *= len(DEBUGGABLE_TYPES)
total_test_count *= len(COMPILER_TYPES)
+ total_test_count *= len(JVMTI_TYPES)
target_address_combinations = 0
for target in TARGET_TYPES:
for address_size in ADDRESS_SIZES_TARGET[target]:
@@ -336,10 +343,10 @@ def run_tests(tests):
config = itertools.product(tests, TARGET_TYPES, RUN_TYPES, PREBUILD_TYPES,
COMPILER_TYPES, RELOCATE_TYPES, TRACE_TYPES,
GC_TYPES, JNI_TYPES, IMAGE_TYPES, PICTEST_TYPES,
- DEBUGGABLE_TYPES)
+ DEBUGGABLE_TYPES, JVMTI_TYPES)
for test, target, run, prebuild, compiler, relocate, trace, gc, \
- jni, image, pictest, debuggable in config:
+ jni, image, pictest, debuggable, jvmti in config:
for address_size in ADDRESS_SIZES_TARGET[target]:
if stop_testrunner:
# When ART_TEST_KEEP_GOING is set to false, then as soon as a test
@@ -361,11 +368,12 @@ def run_tests(tests):
test_name += image + '-'
test_name += pictest + '-'
test_name += debuggable + '-'
+ test_name += jvmti + '-'
test_name += test
test_name += address_size
variant_set = {target, run, prebuild, compiler, relocate, trace, gc, jni,
- image, pictest, debuggable, address_size}
+ image, pictest, debuggable, jvmti, address_size}
options_test = options_all
@@ -428,6 +436,9 @@ def run_tests(tests):
if debuggable == 'debuggable':
options_test += ' --debuggable'
+ if jvmti == 'jvmti-stress':
+ options_test += ' --jvmti-stress'
+
if address_size == '64':
options_test += ' --64'
@@ -762,6 +773,7 @@ def parse_test_name(test_name):
regex += '(' + '|'.join(VARIANT_TYPE_DICT['image']) + ')-'
regex += '(' + '|'.join(VARIANT_TYPE_DICT['pictest']) + ')-'
regex += '(' + '|'.join(VARIANT_TYPE_DICT['debuggable']) + ')-'
+ regex += '(' + '|'.join(VARIANT_TYPE_DICT['jvmti']) + ')-'
regex += '(' + '|'.join(RUN_TEST_SET) + ')'
regex += '(' + '|'.join(VARIANT_TYPE_DICT['address_sizes']) + ')$'
match = re.match(regex, test_name)
@@ -777,8 +789,9 @@ def parse_test_name(test_name):
IMAGE_TYPES.add(match.group(9))
PICTEST_TYPES.add(match.group(10))
DEBUGGABLE_TYPES.add(match.group(11))
- ADDRESS_SIZES.add(match.group(13))
- return {match.group(12)}
+ JVMTI_TYPES.add(match.group(12))
+ ADDRESS_SIZES.add(match.group(14))
+ return {match.group(13)}
raise ValueError(test_name + " is not a valid test")
@@ -918,6 +931,10 @@ def parse_option():
GC_TYPES.add('cms')
if options['multipicimage']:
IMAGE_TYPES.add('multipicimage')
+ if options['jvmti_stress']:
+ JVMTI_TYPES.add('jvmti-stress')
+ if options['no_jvmti']:
+ JVMTI_TYPES.add('no-jvmti')
if options['verbose']:
verbose = True
if options['n_thread']:
diff --git a/test/ti-agent/common_helper.cc b/test/ti-agent/common_helper.cc
index ab5dbcc0db..bfd4d254f4 100644
--- a/test/ti-agent/common_helper.cc
+++ b/test/ti-agent/common_helper.cc
@@ -17,18 +17,15 @@
#include "common_helper.h"
#include <dlfcn.h>
+#include <map>
#include <stdio.h>
#include <sstream>
#include <deque>
+#include <vector>
#include "android-base/stringprintf.h"
-#include "art_method.h"
#include "jni.h"
-#include "jni_internal.h"
#include "jvmti.h"
-#include "scoped_thread_state_change-inl.h"
-#include "stack.h"
-#include "utils.h"
#include "jni_binder.h"
#include "jvmti_helper.h"
@@ -37,6 +34,10 @@
namespace art {
+static void SetupCommonRetransform();
+static void SetupCommonRedefine();
+static void SetupCommonTransform();
+
template <bool is_redefine>
static void throwCommonRedefinitionError(jvmtiEnv* jvmti,
JNIEnv* env,
@@ -108,18 +109,15 @@ static void DoClassRedefine(jvmtiEnv* jvmti_env,
// Magic JNI export that classes can use for redefining classes.
// To use classes should declare this as a native function with signature (Ljava/lang/Class;[B[B)V
-extern "C" JNIEXPORT void JNICALL Java_Main_doCommonClassRedefinition(JNIEnv* env,
- jclass,
- jclass target,
- jbyteArray class_file_bytes,
- jbyteArray dex_file_bytes) {
+extern "C" JNIEXPORT void JNICALL Java_art_Redefinition_doCommonClassRedefinition(
+ JNIEnv* env, jclass, jclass target, jbyteArray class_file_bytes, jbyteArray dex_file_bytes) {
DoClassRedefine(jvmti_env, env, target, class_file_bytes, dex_file_bytes);
}
// Magic JNI export that classes can use for redefining classes.
// To use classes should declare this as a native function with signature
// ([Ljava/lang/Class;[[B[[B)V
-extern "C" JNIEXPORT void JNICALL Java_Main_doCommonMultiClassRedefinition(
+extern "C" JNIEXPORT void JNICALL Java_art_Redefinition_doCommonMultiClassRedefinition(
JNIEnv* env,
jclass,
jobjectArray targets,
@@ -155,11 +153,7 @@ jint OnLoad(JavaVM* vm,
printf("Unable to get jvmti env!\n");
return 1;
}
- jvmtiCapabilities caps;
- jvmti_env->GetPotentialCapabilities(&caps);
- caps.can_retransform_classes = 0;
- caps.can_retransform_any_class = 0;
- jvmti_env->AddCapabilities(&caps);
+ SetupCommonRedefine();
return 0;
}
@@ -183,11 +177,8 @@ struct CommonTransformationResult {
std::map<std::string, std::deque<CommonTransformationResult>> gTransformations;
bool gPopTransformations = true;
-extern "C" JNIEXPORT void JNICALL Java_Main_addCommonTransformationResult(JNIEnv* env,
- jclass,
- jstring class_name,
- jbyteArray class_array,
- jbyteArray dex_array) {
+extern "C" JNIEXPORT void JNICALL Java_art_Redefinition_addCommonTransformationResult(
+ JNIEnv* env, jclass, jstring class_name, jbyteArray class_array, jbyteArray dex_array) {
const char* name_chrs = env->GetStringUTFChars(class_name, nullptr);
std::string name_str(name_chrs);
env->ReleaseStringUTFChars(class_name, name_chrs);
@@ -244,15 +235,15 @@ void JNICALL CommonClassFileLoadHookRetransformable(jvmtiEnv* jvmti_env,
}
}
-extern "C" JNIEXPORT void Java_Main_setPopRetransformations(JNIEnv*,
- jclass,
- jboolean enable) {
+extern "C" JNIEXPORT void Java_art_Redefinition_setPopRetransformations(JNIEnv*,
+ jclass,
+ jboolean enable) {
gPopTransformations = enable;
}
-extern "C" JNIEXPORT void Java_Main_popTransformationFor(JNIEnv* env,
- jclass,
- jstring class_name) {
+extern "C" JNIEXPORT void Java_art_Redefinition_popTransformationFor(JNIEnv* env,
+ jclass,
+ jstring class_name) {
const char* name_chrs = env->GetStringUTFChars(class_name, nullptr);
std::string name_str(name_chrs);
env->ReleaseStringUTFChars(class_name, name_chrs);
@@ -267,9 +258,9 @@ extern "C" JNIEXPORT void Java_Main_popTransformationFor(JNIEnv* env,
}
}
-extern "C" JNIEXPORT void Java_Main_enableCommonRetransformation(JNIEnv* env,
- jclass,
- jboolean enable) {
+extern "C" JNIEXPORT void Java_art_Redefinition_enableCommonRetransformation(JNIEnv* env,
+ jclass,
+ jboolean enable) {
jvmtiError res = jvmti_env->SetEventNotificationMode(enable ? JVMTI_ENABLE : JVMTI_DISABLE,
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
nullptr);
@@ -298,9 +289,8 @@ static void DoClassRetransformation(jvmtiEnv* jvmti_env, JNIEnv* env, jobjectArr
}
}
-extern "C" JNIEXPORT void JNICALL Java_Main_doCommonClassRetransformation(JNIEnv* env,
- jclass,
- jobjectArray targets) {
+extern "C" JNIEXPORT void JNICALL Java_art_Redefinition_doCommonClassRetransformation(
+ JNIEnv* env, jclass, jobjectArray targets) {
jvmtiCapabilities caps;
jvmtiError caps_err = jvmti_env->GetCapabilities(&caps);
if (caps_err != JVMTI_ERROR_NONE) {
@@ -338,14 +328,7 @@ jint OnLoad(JavaVM* vm,
printf("Unable to get jvmti env!\n");
return 1;
}
- SetAllCapabilities(jvmti_env);
- jvmtiEventCallbacks cb;
- memset(&cb, 0, sizeof(cb));
- cb.ClassFileLoadHook = CommonClassFileLoadHookRetransformable;
- if (jvmti_env->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
- printf("Unable to set class file load hook cb!\n");
- return 1;
- }
+ SetupCommonRetransform();
return 0;
}
@@ -353,8 +336,6 @@ jint OnLoad(JavaVM* vm,
namespace common_transform {
-using art::common_retransform::CommonClassFileLoadHookRetransformable;
-
// Get all capabilities except those related to retransformation.
jint OnLoad(JavaVM* vm,
char* options ATTRIBUTE_UNUSED,
@@ -363,6 +344,35 @@ jint OnLoad(JavaVM* vm,
printf("Unable to get jvmti env!\n");
return 1;
}
+ SetupCommonTransform();
+ return 0;
+}
+
+} // namespace common_transform
+
+#define CONFIGURATION_COMMON_REDEFINE 0
+#define CONFIGURATION_COMMON_RETRANSFORM 1
+#define CONFIGURATION_COMMON_TRANSFORM 2
+
+static void SetupCommonRedefine() {
+ jvmtiCapabilities caps;
+ jvmti_env->GetPotentialCapabilities(&caps);
+ caps.can_retransform_classes = 0;
+ caps.can_retransform_any_class = 0;
+ jvmti_env->AddCapabilities(&caps);
+}
+
+static void SetupCommonRetransform() {
+ SetAllCapabilities(jvmti_env);
+ jvmtiEventCallbacks cb;
+ memset(&cb, 0, sizeof(cb));
+ cb.ClassFileLoadHook = common_retransform::CommonClassFileLoadHookRetransformable;
+ jvmtiError res = jvmti_env->SetEventCallbacks(&cb, sizeof(cb));
+ CHECK_EQ(res, JVMTI_ERROR_NONE);
+ common_retransform::gTransformations.clear();
+}
+
+static void SetupCommonTransform() {
// Don't set the retransform caps
jvmtiCapabilities caps;
jvmti_env->GetPotentialCapabilities(&caps);
@@ -373,14 +383,31 @@ jint OnLoad(JavaVM* vm,
// Use the same callback as the retransform test.
jvmtiEventCallbacks cb;
memset(&cb, 0, sizeof(cb));
- cb.ClassFileLoadHook = CommonClassFileLoadHookRetransformable;
- if (jvmti_env->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
- printf("Unable to set class file load hook cb!\n");
- return 1;
- }
- return 0;
+ cb.ClassFileLoadHook = common_retransform::CommonClassFileLoadHookRetransformable;
+ jvmtiError res = jvmti_env->SetEventCallbacks(&cb, sizeof(cb));
+ CHECK_EQ(res, JVMTI_ERROR_NONE);
+ common_retransform::gTransformations.clear();
}
-} // namespace common_transform
-
+extern "C" JNIEXPORT void JNICALL Java_art_Redefinition_nativeSetTestConfiguration(JNIEnv*,
+ jclass,
+ jint type) {
+ switch (type) {
+ case CONFIGURATION_COMMON_REDEFINE: {
+ SetupCommonRedefine();
+ return;
+ }
+ case CONFIGURATION_COMMON_RETRANSFORM: {
+ SetupCommonRetransform();
+ return;
+ }
+ case CONFIGURATION_COMMON_TRANSFORM: {
+ SetupCommonTransform();
+ return;
+ }
+ default: {
+ LOG(FATAL) << "Unknown test configuration: " << type;
+ }
+ }
+}
} // namespace art
diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc
index 9e7b75daf2..3455409b2d 100644
--- a/test/ti-agent/common_load.cc
+++ b/test/ti-agent/common_load.cc
@@ -60,31 +60,17 @@ static jint MinimalOnLoad(JavaVM* vm,
// MinimalOnLoad.
static AgentLib agents[] = {
{ "901-hello-ti-agent", Test901HelloTi::OnLoad, nullptr },
- { "902-hello-transformation", common_redefine::OnLoad, nullptr },
{ "909-attach-agent", nullptr, Test909AttachAgent::OnAttach },
- { "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 },
- { "919-obsolete-fields", common_redefine::OnLoad, nullptr },
{ "921-hello-failure", common_retransform::OnLoad, nullptr },
- { "926-multi-obsolescence", common_redefine::OnLoad, nullptr },
- { "930-hello-retransform", common_retransform::OnLoad, nullptr },
- { "932-transform-saves", common_retransform::OnLoad, nullptr },
{ "934-load-transform", common_retransform::OnLoad, nullptr },
{ "935-non-retransformable", common_transform::OnLoad, nullptr },
{ "936-search-onload", Test936SearchOnload::OnLoad, nullptr },
{ "937-hello-retransform-package", common_retransform::OnLoad, nullptr },
{ "938-load-transform-bcp", common_retransform::OnLoad, nullptr },
{ "939-hello-transformation-bcp", common_redefine::OnLoad, nullptr },
- { "940-recursive-obsolete", common_redefine::OnLoad, nullptr },
{ "941-recursive-obsolete-jit", common_redefine::OnLoad, nullptr },
- { "942-private-recursive", common_redefine::OnLoad, nullptr },
{ "943-private-recursive-jit", common_redefine::OnLoad, nullptr },
- { "944-transform-classloaders", common_redefine::OnLoad, nullptr },
- { "945-obsolete-native", common_redefine::OnLoad, nullptr },
- { "981-dedup-original-dex", common_retransform::OnLoad, nullptr },
- { "982-ok-no-retransform", common_retransform::OnLoad, nullptr },
{ "983-source-transform-verify", Test983SourceTransformVerify::OnLoad, nullptr },
};
diff --git a/test/ti-agent/scoped_local_ref.h b/test/ti-agent/scoped_local_ref.h
index daa1583457..ba9725fdff 100644
--- a/test/ti-agent/scoped_local_ref.h
+++ b/test/ti-agent/scoped_local_ref.h
@@ -44,7 +44,7 @@ class ScopedLocalRef {
}
}
- T release() __attribute__((warn_unused_result)) {
+ T release() WARN_UNUSED {
T localRef = mLocalRef;
mLocalRef = nullptr;
return localRef;
diff --git a/test/ti-stress/stress.cc b/test/ti-stress/stress.cc
new file mode 100644
index 0000000000..fa49a35a8e
--- /dev/null
+++ b/test/ti-stress/stress.cc
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+#include <sstream>
+
+#include "jvmti.h"
+#include "exec_utils.h"
+#include "utils.h"
+
+namespace art {
+
+// Should we do a 'full_rewrite' with this test?
+static constexpr bool kDoFullRewrite = true;
+
+struct StressData {
+ std::string dexter_cmd;
+ std::string out_temp_dex;
+ std::string in_temp_dex;
+ bool vm_class_loader_initialized;
+};
+
+static void WriteToFile(const std::string& fname, jint data_len, const unsigned char* data) {
+ std::ofstream file(fname, std::ios::binary | std::ios::out | std::ios::trunc);
+ file.write(reinterpret_cast<const char*>(data), data_len);
+ file.flush();
+}
+
+static bool ReadIntoBuffer(const std::string& fname, /*out*/std::vector<unsigned char>* data) {
+ std::ifstream file(fname, std::ios::binary | std::ios::in);
+ file.seekg(0, std::ios::end);
+ size_t len = file.tellg();
+ data->resize(len);
+ file.seekg(0);
+ file.read(reinterpret_cast<char*>(data->data()), len);
+ return len != 0;
+}
+
+// TODO rewrite later.
+static bool DoExtractClassFromData(StressData* data,
+ const std::string& class_name,
+ jint in_len,
+ const unsigned char* in_data,
+ /*out*/std::vector<unsigned char>* dex) {
+ // Write the dex file into a temporary file.
+ WriteToFile(data->in_temp_dex, in_len, in_data);
+ // Clear out file so even if something suppresses the exit value we will still detect dexter
+ // failure.
+ WriteToFile(data->out_temp_dex, 0, nullptr);
+ // Have dexter do the extraction.
+ std::vector<std::string> args;
+ args.push_back(data->dexter_cmd);
+ if (kDoFullRewrite) {
+ args.push_back("-x");
+ args.push_back("full_rewrite");
+ }
+ args.push_back("-e");
+ args.push_back(class_name);
+ args.push_back("-o");
+ args.push_back(data->out_temp_dex);
+ args.push_back(data->in_temp_dex);
+ std::string error;
+ if (ExecAndReturnCode(args, &error) != 0) {
+ LOG(ERROR) << "unable to execute dexter: " << error;
+ return false;
+ }
+ return ReadIntoBuffer(data->out_temp_dex, dex);
+}
+
+// The hook we are using.
+void JNICALL ClassFileLoadHookSecretNoOp(jvmtiEnv* jvmti,
+ JNIEnv* jni_env ATTRIBUTE_UNUSED,
+ jclass class_being_redefined ATTRIBUTE_UNUSED,
+ jobject loader ATTRIBUTE_UNUSED,
+ const char* name,
+ jobject protection_domain ATTRIBUTE_UNUSED,
+ jint class_data_len,
+ const unsigned char* class_data,
+ jint* new_class_data_len,
+ unsigned char** new_class_data) {
+ std::vector<unsigned char> out;
+ std::string name_str(name);
+ // Make the jvmti semi-descriptor into the java style descriptor (though with $ for inner
+ // classes).
+ std::replace(name_str.begin(), name_str.end(), '/', '.');
+ StressData* data = nullptr;
+ CHECK_EQ(jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)),
+ JVMTI_ERROR_NONE);
+ if (!data->vm_class_loader_initialized) {
+ LOG(WARNING) << "Ignoring load of class " << name << " because VMClassLoader is not yet "
+ << "initialized. Transforming this class could cause spurious test failures.";
+ return;
+ } else if (DoExtractClassFromData(data, name_str, class_data_len, class_data, /*out*/ &out)) {
+ LOG(INFO) << "Extracted class: " << name;
+ unsigned char* new_data;
+ CHECK_EQ(JVMTI_ERROR_NONE, jvmti->Allocate(out.size(), &new_data));
+ memcpy(new_data, out.data(), out.size());
+ *new_class_data_len = static_cast<jint>(out.size());
+ *new_class_data = new_data;
+ } else {
+ std::cerr << "Unable to extract class " << name_str << std::endl;
+ *new_class_data_len = 0;
+ *new_class_data = nullptr;
+ }
+}
+
+// Options are ${DEXTER_BINARY},${TEMP_FILE_1},${TEMP_FILE_2}
+static void ReadOptions(StressData* data, char* options) {
+ std::string ops(options);
+ data->dexter_cmd = ops.substr(0, ops.find(','));
+ ops = ops.substr(ops.find(',') + 1);
+ data->in_temp_dex = ops.substr(0, ops.find(','));
+ ops = ops.substr(ops.find(',') + 1);
+ data->out_temp_dex = ops;
+}
+
+// We need to make sure that VMClassLoader is initialized before we start redefining anything since
+// it can give (non-fatal) error messages if it's initialized after we've redefined BCP classes.
+// These error messages are expected and no problem but they will mess up our testing
+// infrastructure.
+static void JNICALL EnsureVMClassloaderInitializedCB(jvmtiEnv *jvmti_env,
+ JNIEnv* jni_env,
+ jthread thread ATTRIBUTE_UNUSED) {
+ // Load the VMClassLoader class. We will get a ClassNotFound exception because we don't have
+ // visibility but the class will be loaded behind the scenes.
+ LOG(INFO) << "manual load & initialization of class java/lang/VMClassLoader!";
+ jclass klass = jni_env->FindClass("java/lang/VMClassLoader");
+ if (klass == nullptr) {
+ LOG(ERROR) << "Unable to find VMClassLoader class!";
+ } else {
+ // GetMethodID is spec'd to cause the class to be initialized.
+ jni_env->GetMethodID(klass, "hashCode", "()I");
+ jni_env->DeleteLocalRef(klass);
+ StressData* data = nullptr;
+ CHECK_EQ(jvmti_env->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)),
+ JVMTI_ERROR_NONE);
+ data->vm_class_loader_initialized = true;
+ }
+}
+
+extern "C" JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm,
+ char* options,
+ void* reserved ATTRIBUTE_UNUSED) {
+ jvmtiEnv* jvmti = nullptr;
+ if (vm->GetEnv(reinterpret_cast<void**>(&jvmti), JVMTI_VERSION_1_0)) {
+ LOG(ERROR) << "Unable to get jvmti env.";
+ return 1;
+ }
+ StressData* data = nullptr;
+ if (JVMTI_ERROR_NONE != jvmti->Allocate(sizeof(StressData),
+ reinterpret_cast<unsigned char**>(&data))) {
+ LOG(ERROR) << "Unable to allocate data for stress test.";
+ return 1;
+ }
+ memset(data, 0, sizeof(StressData));
+ // Read the options into the static variables that hold them.
+ ReadOptions(data, options);
+ // Save the data
+ if (JVMTI_ERROR_NONE != jvmti->SetEnvironmentLocalStorage(data)) {
+ LOG(ERROR) << "Unable to save stress test data.";
+ return 1;
+ }
+
+ // Just get all capabilities.
+ jvmtiCapabilities caps;
+ jvmti->GetPotentialCapabilities(&caps);
+ jvmti->AddCapabilities(&caps);
+
+ // Set callbacks.
+ jvmtiEventCallbacks cb;
+ memset(&cb, 0, sizeof(cb));
+ cb.ClassFileLoadHook = ClassFileLoadHookSecretNoOp;
+ cb.VMInit = EnsureVMClassloaderInitializedCB;
+ if (jvmti->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
+ LOG(ERROR) << "Unable to set class file load hook cb!";
+ return 1;
+ }
+ if (jvmti->SetEventNotificationMode(JVMTI_ENABLE,
+ JVMTI_EVENT_VM_INIT,
+ nullptr) != JVMTI_ERROR_NONE) {
+ LOG(ERROR) << "Unable to enable JVMTI_EVENT_VM_INIT event!";
+ return 1;
+ }
+ if (jvmti->SetEventNotificationMode(JVMTI_ENABLE,
+ JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
+ nullptr) != JVMTI_ERROR_NONE) {
+ LOG(ERROR) << "Unable to enable CLASS_FILE_LOAD_HOOK event!";
+ return 1;
+ }
+ return 0;
+}
+
+} // namespace art