[pypy-commit] stmgc card-marking: move clearing of modified_old_objects to where they get pushed or reset

Raemi noreply at buildbot.pypy.org
Thu May 22 10:30:52 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: card-marking
Changeset: r1227:5e3ed01df505
Date: 2014-05-22 09:59 +0200
http://bitbucket.org/pypy/stmgc/changeset/5e3ed01df505/

Log:	move clearing of modified_old_objects to where they get pushed or
	reset

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -424,7 +424,7 @@
     }
 }
 
-static void synchronize_object_now(object_t *obj)
+static void synchronize_object_now(object_t *obj, bool ignore_cards)
 {
     /* Copy around the version of 'obj' that lives in our own segment.
        It is first copied into the shared pages, and then into other
@@ -502,6 +502,8 @@
             start = (start + 4096) & ~4095;
         }
     }
+
+    _cards_cleared_in_object(get_priv_segment(STM_SEGMENT->segment_num), obj);
 }
 
 static void push_overflow_objects_from_privatized_pages(void)
@@ -511,7 +513,7 @@
 
     acquire_privatization_lock();
     LIST_FOREACH_R(STM_PSEGMENT->large_overflow_objects, object_t *,
-                   synchronize_object_now(item));
+                   synchronize_object_now(item, true /*ignore_cards*/));
     release_privatization_lock();
 }
 
@@ -533,9 +535,13 @@
                minor_collection() */
             assert((item->stm_flags & GCFLAG_WRITE_BARRIER) != 0);
 
+            if (item->stm_flags & GCFLAG_HAS_CARDS)
+                _reset_object_cards(get_priv_segment(STM_SEGMENT->segment_num),
+                                    item, CARD_CLEAR, false);
+
             /* copy the object to the shared page, and to the other
                private pages as needed */
-            synchronize_object_now(item);
+            synchronize_object_now(item, false); /* don't ignore_cards */
         }));
     release_privatization_lock();
 
@@ -605,6 +611,7 @@
 
     /* synchronize modified old objects to other threads */
     push_modified_to_other_segments();
+    _verify_cards_cleared_in_all_lists(get_priv_segment(STM_SEGMENT->segment_num));
 
     /* update 'overflow_number' if needed */
     if (STM_PSEGMENT->overflow_number_has_been_used) {
@@ -664,6 +671,9 @@
             ssize_t size = stmcb_size_rounded_up((struct object_s *)src);
             memcpy(dst, src, size);
 
+            if (item->stm_flags & GCFLAG_HAS_CARDS)
+                _reset_object_cards(pseg, item, CARD_CLEAR, false);
+
             /* objects in 'modified_old_objects' usually have the
                WRITE_BARRIER flag, unless they have been modified
                recently.  Ignore the old flag; after copying from the
@@ -725,6 +735,7 @@
 
     /* reset all the modified objects (incl. re-adding GCFLAG_WRITE_BARRIER) */
     reset_modified_from_other_segments(segment_num);
+    _verify_cards_cleared_in_all_lists(pseg);
 
     /* reset the tl->shadowstack and thread_local_obj to their original
        value before the transaction start */
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -288,7 +288,7 @@
 }
 
 static void copy_object_to_shared(object_t *obj, int source_segment_num);
-static void synchronize_object_now(object_t *obj);
+static void synchronize_object_now(object_t *obj, bool ignore_cards);
 
 static inline void acquire_privatization_lock(void)
 {
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -469,8 +469,8 @@
                     OPT_ASSERT(!(realobj->stm_flags & GCFLAG_CARDS_SET));
 
                     realobj->stm_flags |= GCFLAG_WRITE_BARRIER;
-                    /* XXX: this will be necessary when only synchronising cards */
 
+                    /* logic corresponds to _collect_now() in nursery.c */
                     if (realobj->stm_flags & GCFLAG_HAS_CARDS) {
                         /* We called a normal WB on these objs. If we wrote
                            a value to some place in them, we need to
@@ -493,7 +493,7 @@
                     OPT_ASSERT(realobj->stm_flags & GCFLAG_CARDS_SET);
                     OPT_ASSERT(realobj->stm_flags & GCFLAG_WRITE_BARRIER);
 
-                    /* XXX: this will be necessary when only synchronising cards */
+                    /* logic corresponds to _trace_card_object() in nursery.c */
                     uint8_t mark_value = IS_OVERFLOW_OBJ(pseg, realobj) ?
                         CARD_CLEAR : CARD_MARKED_OLD;
                     _reset_object_cards(pseg, item, mark_value, false);
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -390,7 +390,7 @@
             struct stm_priv_segment_info_s *pseg = get_priv_segment(STM_SEGMENT->segment_num);
             if (STM_PSEGMENT->minor_collect_will_commit_now) {
                 acquire_privatization_lock();
-                synchronize_object_now(obj);
+                synchronize_object_now(obj, true); /* ignore cards! */
                 release_privatization_lock();
             } else {
                 LIST_APPEND(STM_PSEGMENT->large_overflow_objects, obj);
@@ -480,21 +480,11 @@
     tree_clear(pseg->nursery_objects_shadows);
 
 
-    /* nearly all objs in old_objects_with_cards are also in modified_old_objects,
-       so we don't need to go through both lists: */
-    LIST_FOREACH_R(pseg->modified_old_objects, object_t * /*item*/,
-        {
-            struct object_s *realobj = (struct object_s *)
-                REAL_ADDRESS(pseg->pub.segment_base, item);
-
-            if (realobj->stm_flags & GCFLAG_HAS_CARDS) {
-                /* clear all possibly used cards in this transaction */
-                _reset_object_cards(pseg, item, CARD_CLEAR, false);
-            }
-        });
-    /* overflow objects with cards are not in modified_old_objects */
+    /* modified_old_objects' cards get cleared in push_modified_to_other_segments
+       or reset_modified_from_other_segments. Objs in old_objs_with_cards but not
+       in modified_old_objs are overflow objects and handled here: */
     if (pseg->large_overflow_objects != NULL) {
-        /* some overflow objects may have cards, clear them too */
+        /* some overflow objects may have cards when aborting, clear them too */
         LIST_FOREACH_R(pseg->large_overflow_objects, object_t * /*item*/,
             {
                 struct object_s *realobj = (struct object_s *)
@@ -508,8 +498,6 @@
             });
     }
 
-    _verify_cards_cleared_in_all_lists(pseg);
-
     return nursery_used;
 #pragma pop_macro("STM_SEGMENT")
 #pragma pop_macro("STM_PSEGMENT")


More information about the pypy-commit mailing list