summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Shapiro <cshapiro@google.com>2011-01-11 17:16:48 -0800
committerCarl Shapiro <cshapiro@google.com>2011-01-12 10:44:06 -0800
commit4d7dd56902150ab8db4c20a191bad112928839e9 (patch)
tree83cfa9b49e350b56839338c018a59664d3c51778
parent6159ef4520073ae8e7ce7b7d1f7648b161a33302 (diff)
downloaddalvik-4d7dd56902150ab8db4c20a191bad112928839e9.tar.gz
Handle the case of referent clearing during tracing.
Reference objects with non-null referent fields are collected during tracing for processing after the trace has completed. Before the trace was made concurrent there was no way for a reference with a non-null referent field to have its referent become null by any action of the garbage collector after it was discovered. Assertions were placed in the reference processing code to check this invariant. After the trace was made concurrent it became possible for a user to clear the referent field of an already discovered reference. This violates the assertions in the reference processing code. This change replaces the assertions in the reference processing code with logic to deal with null referent fields. The assert in the SoftReference preservation code has been converted to a continue that short circuits the preservation logic. The assert in the white reference clearing code short circuits the clearing and enqueueing. Bug: 3342757 Change-Id: I967b011485e2691b2752500a3488fbcb54f129d3
-rw-r--r--vm/alloc/MarkSweep.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/vm/alloc/MarkSweep.c b/vm/alloc/MarkSweep.c
index bde1b49e8..62a4ccc9f 100644
--- a/vm/alloc/MarkSweep.c
+++ b/vm/alloc/MarkSweep.c
@@ -722,7 +722,10 @@ void dvmHandleSoftRefs(Object **list)
while (*list != NULL) {
ref = dequeuePendingReference(list);
referent = dvmGetFieldObject(ref, referentOffset);
- assert(referent != NULL);
+ if (referent == NULL) {
+ /* Referent was cleared by the user during marking. */
+ continue;
+ }
marked = isMarked(referent, ctx);
if (!marked && ((++counter) & 1)) {
/* Referent is white and biased toward saving, mark it. */
@@ -760,8 +763,7 @@ void dvmClearWhiteRefs(Object **list)
while (*list != NULL) {
ref = dequeuePendingReference(list);
referent = dvmGetFieldObject(ref, referentOffset);
- assert(referent != NULL);
- if (!isMarked(referent, ctx)) {
+ if (referent != NULL && !isMarked(referent, ctx)) {
/* Referent is white, clear it. */
clearReference(ref);
if (isEnqueuable(ref)) {