[pypy-commit] stmgc card-marking: some clarifications and adding the second fastpath to stm_write_card()

Raemi noreply at buildbot.pypy.org
Fri May 23 09:54:31 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: card-marking
Changeset: r1242:008b3c48e38b
Date: 2014-05-23 09:55 +0200
http://bitbucket.org/pypy/stmgc/changeset/008b3c48e38b/

Log:	some clarifications and adding the second fastpath to
	stm_write_card()

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -40,7 +40,7 @@
 #endif
 }
 
-static void _stm_mark_card(object_t *obj, uintptr_t card_index)
+void _stm_mark_card(object_t *obj, uintptr_t card_index)
 {
     assert(card_index > 0);
 
@@ -115,12 +115,27 @@
     assert(_seems_to_be_running_transaction());
     assert(!_is_young(obj));
     assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
+    assert(IMPLY(card_index, (card_index - 1) * CARD_SIZE < stmcb_size_rounded_up(
+                     (struct object_s*)REAL_ADDRESS(STM_SEGMENT->segment_base, obj))));
+
+    uintptr_t base_lock_idx = get_write_lock_idx((uintptr_t)obj);
+    uint8_t lock_num = STM_PSEGMENT->write_lock_num;
+    assert(base_lock_idx < sizeof(write_locks));
 
     if (!(obj->stm_flags & GCFLAG_HAS_CARDS))
         card_index = 0;         /* assume no cards */
 
-    assert(IMPLY(card_index, (card_index - 1) * CARD_SIZE < stmcb_size_rounded_up(
-                (struct object_s*)REAL_ADDRESS(STM_SEGMENT->segment_base, obj))));
+    /* if card_index and obj->stm_flags & CARDS_SET:
+           directly mark the card of obj at card_index
+           return (no STM part needed)
+       -> see stmgc.h */
+    /* if CARDS_SET, we entered here at least once, so we own the write_lock
+       OR this is an overflow object and the write_lock is not owned */
+    OPT_ASSERT(
+        IMPLY(obj->stm_flags & GCFLAG_CARDS_SET,
+              (!IS_OVERFLOW_OBJ(STM_PSEGMENT, obj) && write_locks[base_lock_idx] == lock_num)
+              || (IS_OVERFLOW_OBJ(STM_PSEGMENT, obj) && write_locks[base_lock_idx] == 0)
+              ));
 
     if (_stm_write_slowpath_overflow_objs(obj, card_index))
         return;
@@ -136,9 +151,7 @@
        'modified_old_objects' (but, because it had GCFLAG_WRITE_BARRIER,
        not in 'objects_pointing_to_nursery').  We'll detect this case
        by finding that we already own the write-lock. */
-    uintptr_t base_lock_idx = get_write_lock_idx((uintptr_t)obj);
-    uint8_t lock_num = STM_PSEGMENT->write_lock_num;
-    assert(base_lock_idx < sizeof(write_locks));
+
  retry:
     if (write_locks[base_lock_idx] == 0) {
         /* A lock to prevent reading garbage from
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -233,8 +233,8 @@
 
 #define REAL_ADDRESS(segment_base, src)   ((segment_base) + (uintptr_t)(src))
 
-#define IS_OVERFLOW_OBJ(pseg, obj) ((obj->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0) \
-                                    == pseg->overflow_number)
+#define IS_OVERFLOW_OBJ(pseg, obj) (((obj)->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0) \
+                                    == (pseg)->overflow_number)
 
 static inline uintptr_t get_card_index(uintptr_t byte_offset) {
     return (byte_offset / CARD_SIZE) + 1;
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -108,6 +108,7 @@
    but it's not exposed to C code so far */
 void _stm_write_slowpath(object_t *);
 void _stm_write_slowpath_card(object_t *, uintptr_t);
+void _stm_mark_card(object_t *obj, uintptr_t card_index);
 object_t *_stm_allocate_slowpath(ssize_t);
 object_t *_stm_allocate_external(ssize_t);
 void _stm_become_inevitable(const char*);
@@ -221,16 +222,23 @@
 }
 
 /* The following is a GC-optimized barrier that works on the granularity
-   of CARD_SIZE. It can only be used on objects one called stm_use_cards()
-   on. It has the same purpose as stm_write() for TM.
+   of CARD_SIZE. It can only be used on objects one any object, but only
+   helps with those that were internally marked with GCFLAG_HAS_CARDS
+   It has the same purpose as stm_write() for TM.
    'index' is the byte-offset into the object divided by _STM_CARD_SIZE
    plus 1: (offset // CARD_SIZE) + 1
 */
 __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 (UNLIKELY((obj->stm_flags & _STM_GCFLAG_WRITE_BARRIER) != 0)) {
+        if (LIKELY((obj->stm_flags & _STM_GCFLAG_CARDS_SET) != 0)) {
+            /* XXX: check how well clang optimizes this */
+            _stm_mark_card(obj, index);
+        } else {
+            _stm_write_slowpath_card(obj, index);
+        }
+    }
 }
 
 /* Must be provided by the user of this library.


More information about the pypy-commit mailing list