summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hans Boehm <hboehm@google.com> 2022-05-07 15:36:01 +0000
committer Hans Boehm <hboehm@google.com> 2022-05-07 15:36:01 +0000
commitbcf7ef1253691af61dab4062a358a2b903704d45 (patch)
tree52aa4530982f707ed2dc46a22fa5bea8a6435fa6
parente7b9d1c5cfaba4dfb498c4f54a35f142f95db5fa (diff)
Revert "Add reference processor tests"
This reverts commit e7b9d1c5cfaba4dfb498c4f54a35f142f95db5fa. Reason for revert: Times out with poisoning and occasional WeakReference failures. Change-Id: I0e36729fb4758ef6864490db10fcdd05e931145e
-rw-r--r--TEST_MAPPING12
-rw-r--r--test/2042-reference-processing/Android.bp40
-rw-r--r--test/2042-reference-processing/expected-stderr.txt0
-rw-r--r--test/2042-reference-processing/expected-stdout.txt2
-rw-r--r--test/2042-reference-processing/info.txt6
-rw-r--r--test/2042-reference-processing/src/Main.java311
-rw-r--r--test/2043-reference-pauses/Android.bp40
-rw-r--r--test/2043-reference-pauses/expected-stderr.txt0
-rw-r--r--test/2043-reference-pauses/expected-stdout.txt2
-rw-r--r--test/2043-reference-pauses/info.txt5
-rw-r--r--test/2043-reference-pauses/src/Main.java289
-rw-r--r--test/knownfailures.json4
12 files changed, 2 insertions, 709 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING
index f4384849c8..d606d7ca85 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -401,12 +401,6 @@
"name": "art-run-test-2042-checker-dce-always-throw[com.google.android.art.apex]"
},
{
- "name": "art-run-test-2042-reference-processing[com.google.android.art.apex]"
- },
- {
- "name": "art-run-test-2043-reference-pauses[com.google.android.art.apex]"
- },
- {
"name": "art-run-test-2231-checker-heap-poisoning[com.google.android.art.apex]"
},
{
@@ -1705,12 +1699,6 @@
"name": "art-run-test-2042-checker-dce-always-throw"
},
{
- "name": "art-run-test-2042-reference-processing"
- },
- {
- "name": "art-run-test-2043-reference-pauses"
- },
- {
"name": "art-run-test-2231-checker-heap-poisoning"
},
{
diff --git a/test/2042-reference-processing/Android.bp b/test/2042-reference-processing/Android.bp
deleted file mode 100644
index a73b8d0bd0..0000000000
--- a/test/2042-reference-processing/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Generated by `regen-test-files`. Do not edit manually.
-
-// Build rules for ART run-test `2042-reference-processing`.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "art_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["art_license"],
-}
-
-// Test's Dex code.
-java_test {
- name: "art-run-test-2042-reference-processing",
- defaults: ["art-run-test-defaults"],
- test_config_template: ":art-run-test-target-template",
- srcs: ["src/**/*.java"],
- data: [
- ":art-run-test-2042-reference-processing-expected-stdout",
- ":art-run-test-2042-reference-processing-expected-stderr",
- ],
-}
-
-// Test's expected standard output.
-genrule {
- name: "art-run-test-2042-reference-processing-expected-stdout",
- out: ["art-run-test-2042-reference-processing-expected-stdout.txt"],
- srcs: ["expected-stdout.txt"],
- cmd: "cp -f $(in) $(out)",
-}
-
-// Test's expected standard error.
-genrule {
- name: "art-run-test-2042-reference-processing-expected-stderr",
- out: ["art-run-test-2042-reference-processing-expected-stderr.txt"],
- srcs: ["expected-stderr.txt"],
- cmd: "cp -f $(in) $(out)",
-}
diff --git a/test/2042-reference-processing/expected-stderr.txt b/test/2042-reference-processing/expected-stderr.txt
deleted file mode 100644
index e69de29bb2..0000000000
--- a/test/2042-reference-processing/expected-stderr.txt
+++ /dev/null
diff --git a/test/2042-reference-processing/expected-stdout.txt b/test/2042-reference-processing/expected-stdout.txt
deleted file mode 100644
index 8b3e832833..0000000000
--- a/test/2042-reference-processing/expected-stdout.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Starting
-Finished
diff --git a/test/2042-reference-processing/info.txt b/test/2042-reference-processing/info.txt
deleted file mode 100644
index e2d7a99436..0000000000
--- a/test/2042-reference-processing/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-A test for reference processing correctness.
-
-The emphasis here is on fundamental properties. In particular, references to
-unreachable referents should be enqueued, and this should ensure that uncleared
-References don't point to objects for which References were enqueued. We also
-check various other ordering properties for java.lang.ref.References.
diff --git a/test/2042-reference-processing/src/Main.java b/test/2042-reference-processing/src/Main.java
deleted file mode 100644
index ed670523ea..0000000000
--- a/test/2042-reference-processing/src/Main.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.math.BigInteger;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.HashMap;
-import java.util.TreeMap;
-
-/**
- * Test that objects get finalized and their references cleared in the right order.
- *
- * We maintain a list of nominally MAX_LIVE_OBJS numbered finalizable objects.
- * We then alternately drop the last 50, and add 50 more. When we see an object finalized
- * or its reference cleared, we make sure that the preceding objects in its group of 50
- * have also had their references cleared. We also perform a number of other more
- * straightforward checks, such as ensuring that all references are eventually cleared,
- * and all objects are finalized.
- */
-public class Main {
- // TODO(b/216481630) Enable CHECK_PHANTOM_REFS. This currently occasionally reports a few
- // PhantomReferences as not enqueued. If this report is correct, this needs to be tracked
- // down and fixed.
- static final boolean CHECK_PHANTOM_REFS = false;
-
- static final int MAX_LIVE_OBJS = 150;
- static final int DROP_OBJS = 50; // Number of linked objects dropped in each batch.
- static final int MIN_LIVE_OBJS = MAX_LIVE_OBJS - DROP_OBJS;
- static final int TOTAL_OBJS = 200_000; // Allocate this many finalizable objects in total.
- static final boolean REPORT_DROPS = false;
- static volatile boolean pleaseStop;
-
- AtomicInteger totalFinalized = new AtomicInteger(0);
- Object phantomRefsLock = new Object();
- int maxDropped = 0;
- int liveObjects = 0;
-
- // Number of next finalizable object to be allocated.
- int nextAllocated = 0;
-
- // List of finalizable objects in descending order. We add to the front and drop
- // from the rear.
- FinalizableObject listHead;
-
- // A possibly incomplete list of FinalizableObject indices that were finalized, but
- // have yet to be checked for consistency with reference processing.
- ArrayBlockingQueue<Integer> finalized = new ArrayBlockingQueue<>(20_000);
-
- // Maps from object number to Reference; Cleared references are deleted when queues are
- // processed.
- TreeMap<Integer, MyWeakReference> weakRefs = new TreeMap<>();
- HashMap<Integer, MyPhantomReference> phantomRefs = new HashMap<>();
-
- class FinalizableObject {
- int n;
- FinalizableObject next;
- FinalizableObject(int num, FinalizableObject nextObj) {
- n = num;
- next = nextObj;
- }
- protected void finalize() {
- if (!inPhantomRefs(n)) {
- System.out.println("PhantomRef enqueued before finalizer ran");
- }
- totalFinalized.incrementAndGet();
- if (!finalized.offer(n) && REPORT_DROPS) {
- System.out.println("Dropped finalization of " + n);
- }
- }
- }
- ReferenceQueue<FinalizableObject> refQueue = new ReferenceQueue<>();
- class MyWeakReference extends WeakReference<FinalizableObject> {
- int n;
- MyWeakReference(FinalizableObject obj) {
- super(obj, refQueue);
- n = obj.n;
- }
- };
- class MyPhantomReference extends PhantomReference<FinalizableObject> {
- int n;
- MyPhantomReference(FinalizableObject obj) {
- super(obj, refQueue);
- n = obj.n;
- }
- }
- boolean inPhantomRefs(int n) {
- synchronized(phantomRefsLock) {
- MyPhantomReference ref = phantomRefs.get(n);
- if (ref == null) {
- return false;
- }
- if (ref.n != n) {
- System.out.println("phantomRef retrieval failed");
- }
- return true;
- }
- }
-
- void CheckOKToClearWeak(int num) {
- if (num > maxDropped) {
- System.out.println("WeakRef to live object " + num + " was cleared/enqueued.");
- }
- int batchEnd = (num / DROP_OBJS + 1) * DROP_OBJS;
- for (MyWeakReference wr : weakRefs.subMap(num + 1, batchEnd).values()) {
- if (wr.n <= num || wr.n / DROP_OBJS != num / DROP_OBJS) {
- throw new AssertionError("MyWeakReference logic error!");
- }
- // wr referent was dropped in same batch and precedes it in list.
- if (wr.get() != null) {
- // This violates the WeakReference spec, and can result in strong references
- // to objects that have been cleaned.
- System.out.println("WeakReference to " + wr.n
- + " was erroneously cleared after " + num);
- }
- }
- }
-
- void CheckOKToClearPhantom(int num) {
- if (num > maxDropped) {
- System.out.println("PhantomRef to live object " + num + " was enqueued.");
- }
- MyWeakReference wr = weakRefs.get(num);
- if (wr != null && wr.get() != null) {
- System.out.println("PhantomRef cleared before WeakRef for " + num);
- }
- }
-
- void emptyAndCheckQueues() {
- // Check recently finalized objects for consistency with cleared references.
- while (true) {
- Integer num = finalized.poll();
- if (num == null) {
- break;
- }
- MyWeakReference wr = weakRefs.get(num);
- if (wr != null) {
- if (wr.n != num) {
- System.out.println("Finalization logic error!");
- }
- if (wr.get() != null) {
- System.out.println("Finalizing object with uncleared reference");
- }
- }
- CheckOKToClearWeak(num);
- }
- // Check recently enqueued references for consistency.
- while (true) {
- Reference<FinalizableObject> ref = (Reference<FinalizableObject>) refQueue.poll();
- if (ref == null) {
- break;
- }
- if (ref instanceof MyWeakReference) {
- MyWeakReference wr = (MyWeakReference) ref;
- if (wr.get() != null) {
- System.out.println("WeakRef " + wr.n + " enqueued but not cleared");
- }
- CheckOKToClearWeak(wr.n);
- if (weakRefs.remove(Integer.valueOf(wr.n)) != ref) {
- System.out.println("Missing WeakReference: " + wr.n);
- }
- } else if (ref instanceof MyPhantomReference) {
- MyPhantomReference pr = (MyPhantomReference) ref;
- CheckOKToClearPhantom(pr.n);
- if (phantomRefs.remove(Integer.valueOf(pr.n)) != ref) {
- System.out.println("Missing PhantomReference: " + pr.n);
- }
- } else {
- System.out.println("Found unrecognized reference in queue");
- }
- }
- }
-
-
- /**
- * Add n objects to the head of the list. These will be assigned the next n consecutive
- * numbers after the current head of the list.
- */
- void addObjects(int n) {
- for (int i = 0; i < n; ++i) {
- int me = nextAllocated++;
- listHead = new FinalizableObject(me, listHead);
- weakRefs.put(me, new MyWeakReference(listHead));
- synchronized(phantomRefsLock) {
- phantomRefs.put(me, new MyPhantomReference(listHead));
- }
- }
- liveObjects += n;
- }
-
- /**
- * Drop n finalizable objects from the tail of the list. These are the lowest-numbered objects
- * in the list.
- */
- void dropObjects(int n) {
- FinalizableObject list = listHead;
- FinalizableObject last = null;
- if (n > liveObjects) {
- System.out.println("Removing too many elements");
- }
- if (liveObjects == n) {
- maxDropped = list.n;
- listHead = null;
- } else {
- final int skip = liveObjects - n;
- for (int i = 0; i < skip; ++i) {
- last = list;
- list = list.next;
- }
- int expected = nextAllocated - skip - 1;
- if (list.n != expected) {
- System.out.println("dropObjects found " + list.n + " but expected " + expected);
- }
- maxDropped = expected;
- last.next = null;
- }
- liveObjects -= n;
- }
-
- void testLoop() {
- System.out.println("Starting");
- addObjects(MIN_LIVE_OBJS);
- final int ITERS = (TOTAL_OBJS - MIN_LIVE_OBJS) / DROP_OBJS;
- for (int i = 0; i < ITERS; ++i) {
- addObjects(DROP_OBJS);
- if (liveObjects != MAX_LIVE_OBJS) {
- System.out.println("Unexpected live object count");
- }
- dropObjects(DROP_OBJS);
- emptyAndCheckQueues();
- }
- dropObjects(MIN_LIVE_OBJS);
- if (liveObjects != 0 || listHead != null) {
- System.out.println("Unexpected live objecs at end");
- }
- if (maxDropped != TOTAL_OBJS - 1) {
- System.out.println("Unexpected dropped object count: " + maxDropped);
- }
- for (int i = 0; i < 2; ++i) {
- Runtime.getRuntime().gc();
- System.runFinalization();
- emptyAndCheckQueues();
- }
- if (!weakRefs.isEmpty()) {
- System.out.println("Weak Reference map nonempty size = " + weakRefs.size());
- }
- if (CHECK_PHANTOM_REFS && !phantomRefs.isEmpty()) {
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- System.out.println("Unexpected interrupt");
- }
- if (!phantomRefs.isEmpty()) {
- System.out.println("Phantom Reference map nonempty size = " + phantomRefs.size());
- System.out.print("First elements:");
- int i = 0;
- for (MyPhantomReference pr : phantomRefs.values()) {
- System.out.print(" " + pr.n);
- if (++i > 10) {
- break;
- }
- }
- System.out.println("");
- }
- }
- if (totalFinalized.get() != TOTAL_OBJS) {
- System.out.println("Finalized only " + totalFinalized + " objects");
- }
- }
-
- static Runnable causeGCs = new Runnable() {
- public void run() {
- // Allocate a lot.
- BigInteger counter = BigInteger.ZERO;
- while (!pleaseStop) {
- counter = counter.add(BigInteger.TEN);
- }
- // Look at counter to reduce chance of optimizing out the allocation.
- if (counter.longValue() % 10 != 0) {
- System.out.println("Bad causeGCs counter value: " + counter);
- }
- }
- };
-
- public static void main(String[] args) throws Exception {
- Main theTest = new Main();
- Thread gcThread = new Thread(causeGCs);
- gcThread.setDaemon(true); // Terminate if main thread dies.
- gcThread.start();
- theTest.testLoop();
- pleaseStop = true;
- gcThread.join();
- System.out.println("Finished");
- }
-}
diff --git a/test/2043-reference-pauses/Android.bp b/test/2043-reference-pauses/Android.bp
deleted file mode 100644
index a84aea25e8..0000000000
--- a/test/2043-reference-pauses/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Generated by `regen-test-files`. Do not edit manually.
-
-// Build rules for ART run-test `2043-reference-pauses`.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "art_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["art_license"],
-}
-
-// Test's Dex code.
-java_test {
- name: "art-run-test-2043-reference-pauses",
- defaults: ["art-run-test-defaults"],
- test_config_template: ":art-run-test-target-template",
- srcs: ["src/**/*.java"],
- data: [
- ":art-run-test-2043-reference-pauses-expected-stdout",
- ":art-run-test-2043-reference-pauses-expected-stderr",
- ],
-}
-
-// Test's expected standard output.
-genrule {
- name: "art-run-test-2043-reference-pauses-expected-stdout",
- out: ["art-run-test-2043-reference-pauses-expected-stdout.txt"],
- srcs: ["expected-stdout.txt"],
- cmd: "cp -f $(in) $(out)",
-}
-
-// Test's expected standard error.
-genrule {
- name: "art-run-test-2043-reference-pauses-expected-stderr",
- out: ["art-run-test-2043-reference-pauses-expected-stderr.txt"],
- srcs: ["expected-stderr.txt"],
- cmd: "cp -f $(in) $(out)",
-}
diff --git a/test/2043-reference-pauses/expected-stderr.txt b/test/2043-reference-pauses/expected-stderr.txt
deleted file mode 100644
index e69de29bb2..0000000000
--- a/test/2043-reference-pauses/expected-stderr.txt
+++ /dev/null
diff --git a/test/2043-reference-pauses/expected-stdout.txt b/test/2043-reference-pauses/expected-stdout.txt
deleted file mode 100644
index 8b3e832833..0000000000
--- a/test/2043-reference-pauses/expected-stdout.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Starting
-Finished
diff --git a/test/2043-reference-pauses/info.txt b/test/2043-reference-pauses/info.txt
deleted file mode 100644
index f76fa328cc..0000000000
--- a/test/2043-reference-pauses/info.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Tests WeakReference processing and retention of objects needed by finalizers.
-
-Can be used as Reference.get() blocking benchmark by setting PRINT_TIMES to
-true. This will print maximum observed latencies for Reference.get() when
-significant memory is only reachable from SoftReferences and Finalizers.
diff --git a/test/2043-reference-pauses/src/Main.java b/test/2043-reference-pauses/src/Main.java
deleted file mode 100644
index 3cd60b7950..0000000000
--- a/test/2043-reference-pauses/src/Main.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.lang.ref.SoftReference;
-import java.math.BigInteger;
-import java.util.ArrayList;
-
-/**
- * Basic test of WeakReferences with large amounts of memory that's only reachable through
- * finalizers. Also makes sure that finalizer-reachable data is not collected.
- * Can easily be modified to time Reference.get() blocking.
- */
-public class Main {
- static final boolean PRINT_TIMES = false; // true will cause benchmark failure.
- // Data structures repeatedly allocated in background to trigger GC.
- // Size of finalizer reachable trees.
- static final int TREE_HEIGHT = 15; // Trees contain 2^TREE_HEIGHT -1 allocated objects.
- // Number of finalizable tree-owning objects that exist at one point.
- static final int N_RESURRECTING_OBJECTS = 10;
- // Number of short-lived, not finalizer-reachable, objects allocated between trees.
- static final int N_PLAIN_OBJECTS = 20_000;
- // Number of SoftReferences to CBTs we allocate.
- static final int N_SOFTREFS = 10;
-
- static final boolean BACKGROUND_GC_THREAD = true;
- static final int NBATCHES = 10;
- static final int NREFS = PRINT_TIMES ? 1_000_000 : 300_000; // Multiple of NBATCHES.
- static final int REFS_PER_BATCH = NREFS / NBATCHES;
-
- static volatile boolean pleaseStop = false;
-
- // Large array of WeakReferences filled and accessed by tests below.
- ArrayList<WeakReference<Integer>> weakRefs = new ArrayList<>(NREFS);
-
- /**
- * Complete binary tree data structure. make(n) takes O(2^n) space.
- */
- static class CBT {
- CBT left;
- CBT right;
- CBT(CBT l, CBT r) {
- left = l;
- right = r;
- }
- static CBT make(int n) {
- if (n == 0) {
- return null;
- }
- return new CBT(make(n - 1), make(n - 1));
- }
- /**
- * Check that path described by bit-vector path has the correct length.
- */
- void check(int n, int path) {
- CBT current = this;
- for (int i = 0; i < n; i++, path = path >>> 1) {
- // Unexpectedly short paths result in NPE.
- if ((path & 1) == 0) {
- current = current.left;
- } else {
- current = current.right;
- }
- }
- if (current != null) {
- System.out.println("Complete binary tree path too long");
- }
- }
- }
-
-
- /**
- * A finalizable object that refers to O(2^TREE_HEIGHT) otherwise unreachable memory.
- * When finalized, it creates a new identical object, making sure that one always stays
- * around.
- */
- static class ResurrectingObject {
- CBT stuff;
- ResurrectingObject() {
- stuff = CBT.make(TREE_HEIGHT);
- }
- static ResurrectingObject a[] = new ResurrectingObject[2];
- static int i = 0;
- static synchronized void allocOne() {
- a[(++i) % 2] = new ResurrectingObject();
- // Check the previous one to make it hard to optimize anything out.
- if (i > 1) {
- a[(i + 1) % 2].stuff.check(TREE_HEIGHT, i /* weirdly interpreted as path */);
- }
- }
- protected void finalize() {
- stuff.check(TREE_HEIGHT, 42 /* Some path descriptor */);
- // Allocate a new one to replace this one.
- allocOne();
- }
- }
-
- void fillWeakRefs() {
- for (int i = 0; i < NREFS; ++i) {
- weakRefs.add(null);
- }
- }
-
- /*
- * Return maximum observed time in nanos to dereference a WeakReference to an unreachable
- * object. weakRefs is presumed to be pre-filled to have the correct size.
- */
- long timeUnreachable() {
- long maxNanos = 0;
- // Fill weakRefs with WeakReferences to unreachable integers, a batch at a time.
- // Then time and test .get() calls on carefully sampled array entries, some of which
- // will have been cleared.
- for (int i = 0; i < NBATCHES; ++i) {
- for (int j = 0; j < REFS_PER_BATCH; ++j) {
- weakRefs.set(i * REFS_PER_BATCH + j,
- new WeakReference(new Integer(i * REFS_PER_BATCH + j)));
- }
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
- System.out.println("Unexpected exception");
- }
- // Iterate over the filled-in section of weakRefs, but look only at a subset of the
- // elements, making sure the subsets for different top-level iterations are disjoint.
- // Otherwise the get() calls here will extend the lifetimes of the referents, and we
- // may never see any cleared WeakReferences.
- for (int j = (i + 1) * REFS_PER_BATCH - i - 1; j >= 0; j -= NBATCHES) {
- WeakReference<Integer> wr = weakRefs.get(j);
- if (wr != null) {
- long startNanos = System.nanoTime();
- Integer referent = wr.get();
- long totalNanos = System.nanoTime() - startNanos;
- if (referent == null) {
- // Optimization to reduce max space use and scanning time.
- weakRefs.set(j, null);
- }
- maxNanos = Math.max(maxNanos, totalNanos);
- if (referent != null && referent.intValue() != j) {
- System.out.println("Unexpected referent; expected " + j + " got "
- + referent.intValue());
- }
- }
- }
- }
- Runtime.getRuntime().gc();
- System.runFinalization(); // Presumed to wait for reference clearing.
- for (int i = 0; i < NREFS; ++i) {
- if (weakRefs.get(i) != null && weakRefs.get(i).get() != null) {
- System.out.println("WeakReference to " + i + " wasn't cleared");
- }
- }
- return maxNanos;
- }
-
- /**
- * Return maximum observed time in nanos to dereference a WeakReference to a reachable
- * object. Overwrites weakRefs, which is presumed to have NREFS entries already.
- */
- long timeReachable() {
- long maxNanos = 0;
- // Similar to the above, but we use WeakReferences to otherwise reachable objects,
- // which should thus not get cleared.
- Integer[] strongRefs = new Integer[NREFS];
- for (int i = 0; i < NBATCHES; ++i) {
- for (int j = i * REFS_PER_BATCH; j < (i + 1) * NREFS / NBATCHES; ++j) {
- Integer newObj = new Integer(j);
- strongRefs[j] = newObj;
- weakRefs.set(j, new WeakReference(newObj));
- }
- for (int j = (i + 1) * REFS_PER_BATCH - 1; j >= 0; --j) {
- WeakReference<Integer> wr = weakRefs.get(j);
- long startNanos = System.nanoTime();
- Integer referent = wr.get();
- long totalNanos = System.nanoTime() - startNanos;
- maxNanos = Math.max(maxNanos, totalNanos);
- if (referent == null) {
- System.out.println("Unexpectedly cleared referent at " + j);
- } else if (referent.intValue() != j) {
- System.out.println("Unexpected reachable referent; expected " + j + " got "
- + referent.intValue());
- }
- }
- }
- Reference.reachabilityFence(strongRefs);
- return maxNanos;
- }
-
- void runTest() {
- System.out.println("Starting");
- fillWeakRefs();
- long unreachableNanos = timeUnreachable();
- if (PRINT_TIMES) {
- System.out.println("Finished timeUnrechable()");
- }
- long reachableNanos = timeReachable();
- String unreachableMillis =
- String. format("%,.3f", ((double) unreachableNanos) / 1_000_000);
- String reachableMillis =
- String. format("%,.3f", ((double) reachableNanos) / 1_000_000);
- if (PRINT_TIMES) {
- System.out.println(
- "Max time for WeakReference.get (unreachable): " + unreachableMillis);
- System.out.println(
- "Max time for WeakReference.get (reachable): " + reachableMillis);
- }
- // Only report extremely egregious pauses to avoid spurious failures.
- if (unreachableNanos > 10_000_000_000L) {
- System.out.println("WeakReference.get (unreachable) time unreasonably long");
- }
- if (reachableNanos > 10_000_000_000L) {
- System.out.println("WeakReference.get (reachable) time unreasonably long");
- }
- }
-
- /**
- * Allocate and GC a lot, while keeping significant amounts of finalizer and
- * SoftReference-reachable memory around.
- */
- static Runnable allocFinalizable = new Runnable() {
- public void run() {
- // Allocate and drop some finalizable objects that take a long time
- // to mark. Designed to be hard to optimize away. Each of these objects will
- // build a new one in its finalizer before really going away.
- ArrayList<SoftReference<CBT>> softRefs = new ArrayList<>(N_SOFTREFS);
- for (int i = 0; i < N_SOFTREFS; ++i) {
- // These should not normally get reclaimed, since we shouldn't run out of
- // memory. They do increase tracing time.
- softRefs.add(new SoftReference(CBT.make(TREE_HEIGHT)));
- }
- for (int i = 0; i < N_RESURRECTING_OBJECTS; ++i) {
- ResurrectingObject.allocOne();
- }
- BigInteger counter = BigInteger.ZERO;
- for (int i = 1; !pleaseStop; ++i) {
- // Allocate a lot of short-lived objects, using BigIntegers to minimize the chance
- // of the allocation getting optimized out. This makes things slightly more
- // realistic, since not all objects will be finalizer reachable.
- for (int j = 0; j < N_PLAIN_OBJECTS / 2; ++j) {
- counter = counter.add(BigInteger.TEN);
- }
- // Look at counter to reduce chance of optimizing out the allocation.
- if (counter.longValue() % 10 != 0) {
- System.out.println("Bad allocFinalizable counter value: " + counter);
- }
- // Explicitly collect here, mostly to prevent heap growth. Otherwise we get
- // ahead of the GC and eventually block on it.
- Runtime.getRuntime().gc();
- if (PRINT_TIMES && i % 100 == 0) {
- System.out.println("Collected " + i + " times");
- }
- }
- // To be safe, access softRefs.
- final CBT sample = softRefs.get(N_SOFTREFS / 2).get();
- if (sample != null) {
- sample.check(TREE_HEIGHT, 47 /* some path descriptor */);
- }
- }
- };
-
- public static void main(String[] args) throws Exception {
- Main theTest = new Main();
- Thread allocThread = null;
- if (BACKGROUND_GC_THREAD) {
- allocThread = new Thread(allocFinalizable);
- allocThread.setDaemon(true); // Terminate if main thread dies.
- allocThread.start();
- }
- theTest.runTest();
- if (BACKGROUND_GC_THREAD) {
- pleaseStop = true;
- allocThread.join();
- }
- System.out.println("Finished");
- }
-}
diff --git a/test/knownfailures.json b/test/knownfailures.json
index de51d99c7d..3e485f6daf 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1358,9 +1358,9 @@
"description": "Interpreting BigInteger.add() is too slow (timeouts)"
},
{
- "tests": ["2029-contended-monitors", "2042-reference-processing", "2043-reference-pauses"],
+ "tests": ["2029-contended-monitors"],
"variant": "interpreter | interp-ac | gcstress | trace",
- "description": ["Slow tests. Prone to timeouts."]
+ "description": ["Slow test. Prone to timeouts."]
},
{
"tests": ["096-array-copy-concurrent-gc"],