[pypy-commit] stmgc c8-card-marking: Write down the stm_write_card() version I'm talking about.

arigo noreply at buildbot.pypy.org
Sun Mar 1 19:28:34 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: c8-card-marking
Changeset: r1686:0b71086399c8
Date: 2015-03-01 19:29 +0100
http://bitbucket.org/pypy/stmgc/changeset/0b71086399c8/

Log:	Write down the stm_write_card() version I'm talking about. I think
	the PyPy JIT should be modified to do exactly that.

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -933,6 +933,7 @@
     bool mark_card = obj_should_use_cards(STM_SEGMENT->segment_base, obj);
     write_slowpath_common(obj, mark_card);
     return mark_card;
+    /* XXX likely, this whole function can be removed now */
 }
 
 
@@ -975,22 +976,19 @@
     /* Write into the card's lock.  This is used by the next minor
        collection to know what parts of the big object may have changed.
        We already own the object here or it is an overflow obj. */
-    struct stm_read_marker_s *cards = get_read_marker(STM_SEGMENT->segment_base,
-                                                      (uintptr_t)obj);
-    uintptr_t card_index = get_index_to_card_index(index);
-    if (cards[card_index].rm == CARD_MARKED)
-        return;
+    stm_read_marker_t *card = (stm_read_marker_t *)(((uintptr_t)obj) >> 4);
+    card += get_index_to_card_index(index);
 
     if (!IS_OVERFLOW_OBJ(STM_PSEGMENT, obj)
-        && !(cards[card_index].rm == CARD_MARKED
-             || cards[card_index].rm == STM_SEGMENT->transaction_read_version)) {
+        && !(card->rm == CARD_MARKED
+             || card->rm == STM_SEGMENT->transaction_read_version)) {
         /* need to do the backup slice of the card */
         make_bk_slices(obj,
                        false,       /* first_call */
                        index,       /* index: only 1 card */
                        false);      /* do_missing_cards */
     }
-    cards[card_index].rm = CARD_MARKED;
+    card->rm = CARD_MARKED;
 
     dprintf(("mark %p index %lu, card:%lu with %d\n",
              obj, index, get_index_to_card_index(index), CARD_MARKED));
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -202,8 +202,27 @@
 __attribute__((always_inline))
 static inline void stm_write_card(object_t *obj, uintptr_t index)
 {
-    if (UNLIKELY((obj->stm_flags & _STM_GCFLAG_WRITE_BARRIER) != 0))
-        _stm_write_slowpath_card(obj, index);
+    /* if GCFLAG_WRITE_BARRIER is set, then don't do anything more. */
+    if (UNLIKELY((obj->stm_flags & _STM_GCFLAG_WRITE_BARRIER) != 0)) {
+
+        /* GCFLAG_WRITE_BARRIER is not set.  This might be because
+           it's the first time we see a given small array; or it might
+           be because it's a big array with card marking.  In the
+           latter case we will always reach this point, even if we
+           already marked the correct card.  Based on the idea that it
+           is actually the most common case, check it here.  If the
+           array doesn't actually use card marking, the following read
+           is a bit nonsensical, but in a way that should never return
+           CARD_MARKED by mistake.
+        */
+        stm_read_marker_t *card = (stm_read_marker_t *)(((uintptr_t)obj) >> 4);
+        card += (index / _STM_CARD_SIZE) + 1;  /* get_index_to_card_index() */
+        if (card->rm != _STM_CARD_MARKED) {
+
+            /* slow path. */
+            _stm_write_slowpath_card(obj, index);
+        }
+    }
 }
 
 


More information about the pypy-commit mailing list