Author: Remi Meier <[email protected]>
Branch: card-marking
Changeset: r1213:aeafbbe2bb03
Date: 2014-05-19 16:45 +0200
http://bitbucket.org/pypy/stmgc/changeset/aeafbbe2bb03/

Log:    wip

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -40,6 +40,39 @@
 #endif
 }
 
+static bool _stm_write_slowpath_overflow_objs(object_t *obj, uintptr_t offset)
+{
+    /* is this an object from the same transaction, outside the nursery? */
+    if ((obj->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0)
+        == STM_PSEGMENT->overflow_number) {
+
+        assert(STM_PSEGMENT->objects_pointing_to_nursery != NULL);
+        dprintf_test(("write_slowpath %p -> ovf obj_to_nurs\n", obj));
+
+        if (!offset) {
+            /* no card to be marked */
+            obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
+            LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+        } else {
+            /* don't remove GCFLAG_WRITE_BARRIER because we need to be
+               here for every card to mark */
+            if (!(obj->stm_flags & GCFLAG_CARDS_SET)) {
+                /* not yet in the list */
+                LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+                obj->stm_flags |= GCFLAG_CARDS_SET;
+            }
+
+            /* just acquire the corresponding lock for the next 
minor_collection
+               to know what may have changed. only we know about this object: 
*/
+            uintptr_t lock_idx = get_write_lock_idx((uintptr_t)obj + offset);
+            assert(!write_locks[lock_idx]);
+            write_locks[lock_idx] = STM_PSEGMENT->write_lock_num;
+        }
+        return true;
+    }
+    return false;
+}
+
 void _stm_write_slowpath(object_t *obj, uintptr_t offset)
 {
     assert(IMPLY(!(obj->stm_flags & GCFLAG_HAS_CARDS),
@@ -49,16 +82,8 @@
     assert(!_is_young(obj));
     assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
 
-    /* is this an object from the same transaction, outside the nursery? */
-    if ((obj->stm_flags & -GCFLAG_OVERFLOW_NUMBER_bit0) ==
-            STM_PSEGMENT->overflow_number) {
-
-        dprintf_test(("write_slowpath %p -> ovf obj_to_nurs\n", obj));
-        obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
-        assert(STM_PSEGMENT->objects_pointing_to_nursery != NULL);
-        LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, obj);
+    if (_stm_write_slowpath_overflow_objs(obj, offset))
         return;
-    }
 
     /* do a read-barrier now.  Note that this must occur before the
        safepoints that may be issued in write_write_contention_management(). */
@@ -71,7 +96,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 lock_idx = get_write_lock_idx(obj);
+    uintptr_t lock_idx = get_write_lock_idx((uintptr_t)obj);
     uint8_t lock_num = STM_PSEGMENT->write_lock_num;
     assert(lock_idx < sizeof(write_locks));
  retry:
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -58,6 +58,8 @@
 
     /* Set on objects after allocation that may use card marking */
     GCFLAG_HAS_CARDS = _STM_GCFLAG_HAS_CARDS,
+    /* Set on objects that have at least one card marked */
+    GCFLAG_CARDS_SET = _STM_GCFLAG_CARDS_SET,
 
     /* All remaining bits of the 32-bit 'stm_flags' field are taken by
        the "overflow number".  This is a number that identifies the
@@ -66,7 +68,7 @@
        current transaction that have been flushed out of the nursery,
        which occurs if the same transaction allocates too many objects.
     */
-    GCFLAG_OVERFLOW_NUMBER_bit0 = 0x10   /* must be last */
+    GCFLAG_OVERFLOW_NUMBER_bit0 = 0x20   /* must be last */
 };
 
 
@@ -220,8 +222,8 @@
 
 #define REAL_ADDRESS(segment_base, src)   ((segment_base) + (uintptr_t)(src))
 
-static inline uintptr_t get_write_lock_idx(object_t *obj) {
-    return (((uintptr_t)obj) >> 4) - WRITELOCK_START;
+static inline uintptr_t get_write_lock_idx(uintptr_t obj) {
+    return (obj >> 4) - WRITELOCK_START;
 }
 
 static inline char *get_segment_base(long segment_num) {
diff --git a/c7/stm/misc.c b/c7/stm/misc.c
--- a/c7/stm/misc.c
+++ b/c7/stm/misc.c
@@ -47,9 +47,9 @@
         STM_SEGMENT->transaction_read_version);
 }
 
-bool _stm_was_written_card(object_t *obj, uintptr_t offset)
+bool _stm_was_written_card(object_t *obj)
 {
-    return write_locks[get_write_lock_idx((object_t*)((uintptr_t)obj + 
offset))];
+    return obj->stm_flags & _STM_GCFLAG_CARDS_SET;
 }
 
 #ifdef STM_TESTS
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -84,6 +84,7 @@
     /* Check that some values are acceptable */
     assert(NB_SEGMENTS <= NB_SEGMENTS_MAX);
     assert(CARD_SIZE > 0 && CARD_SIZE % 16 == 0);
+    assert(CARD_SIZE == 16);    /* actually, it is hardcoded in some places 
right now.. */
     assert(4096 <= ((uintptr_t)STM_SEGMENT));
     assert((uintptr_t)STM_SEGMENT == (uintptr_t)STM_PSEGMENT);
     assert(((uintptr_t)STM_PSEGMENT) + sizeof(*STM_PSEGMENT) <= 8192);
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -121,7 +121,7 @@
 bool _stm_was_read(object_t *obj);
 bool _stm_was_written(object_t *obj);
 bool _stm_was_read_card(object_t *obj, uintptr_t offset);
-bool _stm_was_written_card(object_t *obj, uintptr_t offset);
+bool _stm_was_written_card(object_t *obj);
 uintptr_t _stm_get_private_page(uintptr_t pagenum);
 bool _stm_in_transaction(stm_thread_local_t *tl);
 char *_stm_get_segment_base(long index);
@@ -146,6 +146,7 @@
 
 #define _STM_GCFLAG_WRITE_BARRIER      0x01
 #define _STM_GCFLAG_HAS_CARDS          0x08
+#define _STM_GCFLAG_CARDS_SET          0x10
 #define _STM_CARD_SIZE                 16 /* modulo 16 == 0! */
 #define _STM_NSE_SIGNAL_MAX     _STM_TIME_N
 #define _STM_FAST_ALLOC           (66*1024)
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -60,7 +60,7 @@
 bool _stm_was_read(object_t *obj);
 bool _stm_was_read_card(object_t *obj, uintptr_t offset);
 bool _stm_was_written(object_t *obj);
-bool _stm_was_written_card(object_t *obj, uintptr_t offset);
+bool _stm_was_written_card(object_t *obj);
 char *_stm_real_address(object_t *obj);
 char *_stm_get_segment_base(long index);
 bool _stm_in_transaction(stm_thread_local_t *tl);
@@ -443,8 +443,8 @@
 def stm_was_read_card(o, offset):
     return lib._stm_was_read_card(o, offset)
 
-def stm_was_written_card(o, offset):
-    return lib._stm_was_written_card(o, offset)
+def stm_was_written_card(o):
+    return lib._stm_was_written_card(o)
 
 
 def stm_start_safe_point():
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to