summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJohannes Carlsson <johannes.carlsson.x@sonyericsson.com>2011-02-03 15:12:46 +0100
committerJohan Redestig <johan.redestig@sonymobile.com>2012-06-05 10:55:49 +0200
commite0e29754397bc0447d77d8cc82009d83ffb01208 (patch)
treecb63ff88c02d55a67629c84429e09125f0fb79f5 /tests
parent07901d5e8d0be0130d92b626f0b92d177ba8f460 (diff)
downloadandroid_dalvik-e0e29754397bc0447d77d8cc82009d83ffb01208.tar.gz
android_dalvik-e0e29754397bc0447d77d8cc82009d83ffb01208.tar.bz2
android_dalvik-e0e29754397bc0447d77d8cc82009d83ffb01208.zip
Add test cases for concurrent gc and System.arraycopy
When System.arraycopy runs at the same time as a concurrent gc the phone will sometimes crash since System.arraycopy was implemented using memmove and memcpy. In current implementation of mememove bytes are copied one at a time. If for instance only 3 out of 4 bytes to an object reference were copied when the thread switch to the gc thread occurred and the gc was scanning the marked objects the gc read an invalid address. The parameters to dvmWriteBarrierArray in one case was also corrected (they are currently not used). The fix itself for this crash is made elsewhere, this commit just adds test cases to verify that this works. Change-Id: I0a8cfd43561b3d5de4bba818993bcf8b40413045
Diffstat (limited to 'tests')
-rw-r--r--tests/096-array-copy-concurrent-gc/expected.txt3
-rw-r--r--tests/096-array-copy-concurrent-gc/info.txt2
-rw-r--r--tests/096-array-copy-concurrent-gc/src/Main.java86
3 files changed, 91 insertions, 0 deletions
diff --git a/tests/096-array-copy-concurrent-gc/expected.txt b/tests/096-array-copy-concurrent-gc/expected.txt
new file mode 100644
index 000000000..23b9dab6b
--- /dev/null
+++ b/tests/096-array-copy-concurrent-gc/expected.txt
@@ -0,0 +1,3 @@
+Initializing...
+Starting the test
+Test OK
diff --git a/tests/096-array-copy-concurrent-gc/info.txt b/tests/096-array-copy-concurrent-gc/info.txt
new file mode 100644
index 000000000..37dd8be9b
--- /dev/null
+++ b/tests/096-array-copy-concurrent-gc/info.txt
@@ -0,0 +1,2 @@
+This is a test to verify that System.arraycopy works nice together with
+the concurrent gc.
diff --git a/tests/096-array-copy-concurrent-gc/src/Main.java b/tests/096-array-copy-concurrent-gc/src/Main.java
new file mode 100644
index 000000000..c8e538b5e
--- /dev/null
+++ b/tests/096-array-copy-concurrent-gc/src/Main.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/**
+ * Running concurrent gc and doing some System.arraycopy
+ * Several threads is created in order to increase the probability
+ * of thread switches at critical points. Without creating several
+ * threads the test case usually passed even when there were bugs.
+ * Size of array and amount of garbage created is based on experimental
+ * numbers and is a tradeoff between time that the test takes when
+ * it succeeds and the probability that the test discovers a problem.
+ */
+public class Main {
+ public static void main(String args[]) {
+ new ObjectCreatorThread(true).start();
+ new ObjectCreatorThread(false).start();
+ new ObjectCreatorThread(false).start();
+ }
+
+ static class ObjectCreatorThread extends Thread {
+ boolean mDoLog;
+ public ObjectCreatorThread(boolean doLog) {
+ mDoLog = doLog;
+ }
+
+ @Override
+ public void run() {
+ new Main().stressArray(mDoLog);
+ }
+ }
+
+ Object [] array = new Object[10000];
+
+ void stressArray(boolean doLog) {
+ // We want many references in the array
+ // We also want elements close to each other to have large
+ // diff in address so lets skip every 2:nd address so it is null
+ if (doLog) {
+ System.out.println("Initializing...");
+ }
+ for (int i = 0; i < array.length; i+=2) {
+ array[i] = new String("Creating some garbage" + i);
+ }
+
+ if (doLog) {
+ System.out.println("Starting the test");
+ }
+
+ for (int j = 0; j < array.length; j++) {
+ Object obj = array[array.length - 1];
+ System.arraycopy(array, 0, array, 1, array.length - 1);
+ array[0] = obj;
+ new String("Creating some garbage" + Math.random());
+ new String("Creating some garbage" + Math.random());
+ new String("Creating some garbage" + Math.random());
+ new String("Creating some garbage" + Math.random());
+ }
+
+ for (int j = 0; j < array.length; j++) {
+ Object obj = array[0];
+ System.arraycopy(array, 1, array, 0, array.length - 1);
+ array[array.length - 1] = obj;
+ new String("Creating some garbage" + Math.random());
+ new String("Creating some garbage" + Math.random());
+ new String("Creating some garbage" + Math.random());
+ new String("Creating some garbage" + Math.random());
+ }
+
+ if (doLog) {
+ System.out.println("Test OK");
+ }
+ }
+}