summaryrefslogtreecommitdiffstats
path: root/vm/alloc/CardTable.c
diff options
context:
space:
mode:
authorCarl Shapiro <cshapiro@google.com>2010-09-29 01:09:11 -0700
committerCarl Shapiro <cshapiro@google.com>2010-09-29 01:42:06 -0700
commit71ce7a90945d1c26deea1eff84554b180a031afd (patch)
tree197a7989f4034e4d27f553a96eb4c2a3a5a53722 /vm/alloc/CardTable.c
parentb36ea7918612c81cb42ff2021443358a9f109a6d (diff)
downloadandroid_dalvik-71ce7a90945d1c26deea1eff84554b180a031afd.tar.gz
android_dalvik-71ce7a90945d1c26deea1eff84554b180a031afd.tar.bz2
android_dalvik-71ce7a90945d1c26deea1eff84554b180a031afd.zip
Update the card table scanning for header-only card marks.
Previously, the card table accessors assumed that objects had either their header marked or would be marked exactly. As such, after reckoning a marked card the scan would back up until it found an object header and then move forward blackening each object within the address range of the marked card. Following a recent change we exclusively mark headers. The scan only has to move forward until the end of a card. This saves scanning time as dlmalloc's binning may leave large segments of the heap unused. It is not uncommon for hundreds of cards to be spanned when backing up to the first live object below a marked card. In addition, this change fixes the card table verifier to search the mark stack for gray objects. It is permissible for roots to point to white objects on unmarked cards. This was incorrectly treated as an error. Change-Id: Ia6b6ee2012e381d644b8b3f38b39d746749ea47a
Diffstat (limited to 'vm/alloc/CardTable.c')
-rw-r--r--vm/alloc/CardTable.c63
1 files changed, 28 insertions, 35 deletions
diff --git a/vm/alloc/CardTable.c b/vm/alloc/CardTable.c
index 06512ed8f..cc344a800 100644
--- a/vm/alloc/CardTable.c
+++ b/vm/alloc/CardTable.c
@@ -138,42 +138,14 @@ void dvmMarkCard(const void *addr)
}
/*
- * Handles the complexity of object arrays for isObjectDirty. Array
- * objects are exactly marked so all spanned cards are examined.
- */
-static bool isObjectArrayDirty(const Object *obj)
-{
- u1 *ptr, *limit;
- size_t size;
-
- assert(obj != NULL);
- assert(dvmIsValidObject(obj));
- assert(IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISOBJECTARRAY));
- size = dvmArrayObjectSize((const ArrayObject *)obj);
- ptr = dvmCardFromAddr(obj);
- limit = dvmCardFromAddr((u1 *)obj + size - 1) + 1;
- assert(ptr != limit);
- for (; ptr != limit; ++ptr) {
- if (*ptr == GC_CARD_DIRTY) {
- return true;
- }
- }
- return false;
-}
-
-/*
* Returns true if the object is on a dirty card.
*/
static bool isObjectDirty(const Object *obj)
{
assert(obj != NULL);
assert(dvmIsValidObject(obj));
- if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISOBJECTARRAY)) {
- return isObjectArrayDirty(obj);
- } else {
- u1 *card = dvmCardFromAddr(obj);
- return *card == GC_CARD_DIRTY;
- }
+ u1 *card = dvmCardFromAddr(obj);
+ return *card == GC_CARD_DIRTY;
}
/*
@@ -239,10 +211,29 @@ static bool isWeakInternedString(const Object *obj)
}
/*
- * Callback applied to marked objects. If the object is found to be
- * gray a message is written to the log. By virtue of where the card
- * table verification occurs weak references have yet to be blackened
- * and so their containing objects are permitted to be gray.
+ * Returns true if the given object has been pushed on the mark stack
+ * by root marking.
+ */
+static bool isPushedOnMarkStack(const Object *obj)
+{
+ GcMarkContext *ctx = &gDvm.gcHeap->markContext;
+ const Object **ptr;
+
+ for (ptr = ctx->stack.top; ptr != ctx->stack.base; ++ptr) {
+ if (*ptr == obj) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Callback applied to marked objects. If the object is gray and on
+ * an unmarked card an error is logged and the VM is aborted. Card
+ * table verification occurs between root marking and weak reference
+ * processing. We treat objects marked from the roots and weak
+ * references specially as it is permissible for these objects to be
+ * gray and on an unmarked card.
*/
static void verifyCardTableCallback(void *ptr, void *arg)
{
@@ -258,8 +249,10 @@ static void verifyCardTableCallback(void *ptr, void *arg)
return;
} else if (isWeakInternedString(obj)) {
return;
+ } else if (isPushedOnMarkStack(obj)) {
+ return;
} else {
- LOGE("Verify failed, object %p is gray", obj);
+ LOGE("Verify failed, object %p is gray and on an unmarked card", obj);
dvmDumpObject(obj);
dvmAbort();
}