[pypy-commit] stmgc card-marking: add stmcb_should_use_cards

Raemi noreply at buildbot.pypy.org
Fri May 23 14:17:29 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: card-marking
Changeset: r1244:1d1ac9cd4297
Date: 2014-05-23 14:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/1d1ac9cd4297/

Log:	add stmcb_should_use_cards

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -579,9 +579,16 @@
                 || card_index == last_card_index)) {  /* this is the last card */
             /* do the copying: */
             uintptr_t copy_size;
+            uintptr_t next_card_offset;
+            uintptr_t next_card = card_index;
 
-            uintptr_t next_card_offset = stmcb_index_to_byte_offset(
-                realobj, get_card_index_to_index(card_index + 1));
+            if (card_value == CARD_MARKED_OLD) {
+                /* card_index is the last card of the object, but we need
+                   to go one further to get the right offset */
+                next_card++;
+            }
+            next_card_offset = stmcb_index_to_byte_offset(
+                realobj, get_card_index_to_index(next_card));
 
             if (next_card_offset > obj_size)
                 next_card_offset = obj_size;
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -111,7 +111,7 @@
     return addr;
 }
 
-object_t *_stm_allocate_old(ssize_t size_rounded_up)
+object_t *_stm_allocate_old(ssize_t size_rounded_up, long use_cards)
 {
     /* only for tests xxx but stm_setup_prebuilt() uses this now too */
     char *p = allocate_outside_nursery_large(size_rounded_up);
@@ -119,7 +119,7 @@
 
     object_t *o = (object_t *)(p - stm_object_pages);
     o->stm_flags = GCFLAG_WRITE_BARRIER;
-    if (size_rounded_up > CARD_SIZE)
+    if (use_cards && size_rounded_up > CARD_SIZE)
         o->stm_flags |= GCFLAG_HAS_CARDS;
 
     if (testing_prebuilt_objs == NULL)
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -65,6 +65,8 @@
     object_t *obj = *pobj;
     object_t *nobj;
     uintptr_t nobj_sync_now;
+    char *realobj;
+    size_t size;
 
     if (obj == NULL)
         return;
@@ -75,8 +77,6 @@
            to GCWORD_MOVED.  In that case, the forwarding location, i.e.
            where the object moved to, is stored in the second word in 'obj'. */
         object_t *TLPREFIX *pforwarded_array = (object_t *TLPREFIX *)obj;
-        char *realobj;
-        size_t size;
 
         if (obj->stm_flags & GCFLAG_HAS_SHADOW) {
             /* ^^ the single check above detects both already-moved objects
@@ -114,7 +114,7 @@
          copy_large_object:;
             char *realnobj = REAL_ADDRESS(STM_SEGMENT->segment_base, nobj);
             memcpy(realnobj, realobj, size);
-            if (size > CARD_SIZE)
+            if (size > CARD_SIZE && stmcb_should_use_cards((struct object_s*)realnobj))
                 nobj->stm_flags |= GCFLAG_HAS_CARDS;
 
             nobj_sync_now = ((uintptr_t)nobj) | FLAG_SYNC_LARGE;
@@ -141,6 +141,11 @@
         nobj = obj;
         tree_delete_item(STM_PSEGMENT->young_outside_nursery, (uintptr_t)nobj);
         nobj_sync_now = ((uintptr_t)nobj) | FLAG_SYNC_LARGE;
+
+        realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
+        size = stmcb_size_rounded_up((struct object_s *)realobj);
+        if (size > CARD_SIZE && stmcb_should_use_cards((struct object_s*)realobj))
+            nobj->stm_flags |= GCFLAG_HAS_CARDS;
     }
 
     /* Set the overflow_number if nedeed */
@@ -655,9 +660,6 @@
     char *result = allocate_outside_nursery_large(size_rounded_up);
     object_t *o = (object_t *)(result - stm_object_pages);
 
-    if (size_rounded_up > CARD_SIZE)
-        o->stm_flags |= GCFLAG_HAS_CARDS;
-
     tree_insert(STM_PSEGMENT->young_outside_nursery, (uintptr_t)o, 0);
 
     memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up);
@@ -759,8 +761,6 @@
     memcpy(realnobj, realobj, size);
 
     obj->stm_flags |= GCFLAG_HAS_SHADOW;
-    if (size > CARD_SIZE)             /* probably not necessary */
-        nobj->stm_flags |= GCFLAG_HAS_CARDS;
 
     tree_insert(STM_PSEGMENT->nursery_objects_shadows,
                 (uintptr_t)obj, (uintptr_t)nobj);
diff --git a/c7/stm/prebuilt.c b/c7/stm/prebuilt.c
--- a/c7/stm/prebuilt.c
+++ b/c7/stm/prebuilt.c
@@ -29,7 +29,7 @@
     /* We need to make a copy of this object.  The extra "long" is for
        the prebuilt hash. */
     size_t size = stmcb_size_rounded_up(obj);
-    object_t *nobj = _stm_allocate_old(size + sizeof(long));
+    object_t *nobj = _stm_allocate_old(size + sizeof(long), 0);
 
     /* Copy the object */
     char *realnobj = REAL_ADDRESS(stm_object_pages, nobj);
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -116,7 +116,7 @@
 void _stm_collectable_safe_point(void);
 
 /* for tests, but also used in duhton: */
-object_t *_stm_allocate_old(ssize_t size_rounded_up);
+object_t *_stm_allocate_old(ssize_t size_rounded_up, long use_cards);
 char *_stm_real_address(object_t *o);
 #ifdef STM_TESTS
 #include <stdbool.h>
@@ -256,6 +256,7 @@
    object's size then) */
 extern uintptr_t stmcb_index_to_byte_offset(struct object_s *,
                                             uintptr_t index);
+extern long stmcb_should_use_cards(struct object_s *);
 extern void stmcb_commit_soon(void);
 
 
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -41,7 +41,7 @@
 /*void stm_write(object_t *obj); use _checked_stm_write() instead */
 object_t *stm_allocate(ssize_t size_rounded_up);
 object_t *stm_allocate_weakref(ssize_t size_rounded_up);
-object_t *_stm_allocate_old(ssize_t size_rounded_up);
+object_t *_stm_allocate_old(ssize_t size_rounded_up, long use_cards);
 
 /*void stm_write_card(); use _checked_stm_write_card() instead */
 
@@ -321,12 +321,21 @@
 {
     struct myobj_s *myobj = (struct myobj_s*)obj;
     if (myobj->type_id < 421420) {
-        /* basic case: no references */
-        return sizeof(struct myobj_s) + index;
+        abort(); // works, but we want to test otherwise
+        /* basic case: index=byteoffset */
+        return index;
     }
     return sizeof(struct myobj_s) + index * sizeof(object_t*);
 }
 
+long stmcb_should_use_cards(struct object_s *obj)
+{
+    struct myobj_s *myobj = (struct myobj_s*)obj;
+    if (myobj->type_id < 421420)
+        return 0; /*no refs*/
+    return 1;
+}
+
 void stm_push_marker(stm_thread_local_t *tl, uintptr_t onum, object_t *ob)
 {
     STM_PUSH_MARKER(*tl, onum, ob);
@@ -378,13 +387,13 @@
     return lib.stm_can_move(o)
 
 def stm_allocate_old(size):
-    o = lib._stm_allocate_old(size)
+    o = lib._stm_allocate_old(size, False)
     tid = 42 + size
     lib._set_type_id(o, tid)
     return o
 
 def stm_allocate_old_refs(n):
-    o = lib._stm_allocate_old(HDR + n * WORD)
+    o = lib._stm_allocate_old(HDR + n * WORD, True)
     tid = 421420 + n
     lib._set_type_id(o, tid)
     return o
diff --git a/c7/test/test_card_marking.py b/c7/test/test_card_marking.py
--- a/c7/test/test_card_marking.py
+++ b/c7/test/test_card_marking.py
@@ -17,14 +17,14 @@
             self.switch(0)
 
     def test_simple(self):
-        o = stm_allocate_old(1024)
+        o = stm_allocate_old_refs(1024)
         self.start_transaction()
         stm_read(o)
         stm_write(o)
         self.commit_transaction()
 
     def test_simple2(self):
-        o = stm_allocate_old(1024)
+        o = stm_allocate_old_refs(1024)
         self.start_transaction()
         stm_write_card(o, 5)
         assert not stm_was_written(o) # don't remove GCFLAG_WRITE_BARRIER
@@ -34,7 +34,7 @@
     @py.test.mark.parametrize("k", range(3))
     def test_overflow(self, k):
         self.start_transaction()
-        o = stm_allocate(1024)
+        o = stm_allocate_refs(1024)
 
         self.push_root(o)
         self._collect(k)
diff --git a/c7/test/test_random.py b/c7/test/test_random.py
--- a/c7/test/test_random.py
+++ b/c7/test/test_random.py
@@ -380,7 +380,7 @@
     thread_state.register_root(r)
 
 def op_allocate_ref(ex, global_state, thread_state):
-    num = str(global_state.rnd.randrange(1, 100))
+    num = str(global_state.rnd.randrange(1, 1000))
     r = global_state.get_new_root_name(True, num)
     thread_state.push_roots(ex)
     ex.do('%s = stm_allocate_refs(%s)' % (r, num))
@@ -415,7 +415,7 @@
     r = thread_state.get_random_root()
     trs = thread_state.transaction_state
     is_ref = global_state.has_ref_type(r)
-    try_cards = global_state.rnd.randrange(1, 100) > 5
+    try_cards = global_state.rnd.randrange(1, 100) > 5# and False
     #
     # check for possible write-write conflict:
     was_written = False


More information about the pypy-commit mailing list