Author: Remi Meier
Branch: c7-weakref
Changeset: r986:510710368671
Date: 2014-03-12 17:21 +0100
http://bitbucket.org/pypy/stmgc/changeset/510710368671/

Log:    consider major collections

diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -111,11 +111,12 @@
     struct tree_s *nursery_objects_shadows;
 
     /* List of all young weakrefs to check in minor collections. These
-       are the only weakrefs that may point to young objects. */
+       are the only weakrefs that may point to young objects and never
+       contain NULL. */
     struct list_s *young_weakrefs;
 
     /* List of all old weakrefs to check in major collections. These
-       weakrefs never point to young objects */
+       weakrefs never point to young objects and never contain NULL. */
     struct list_s *old_weakrefs;
 
     /* Tree of 'key->callback' associations from stm_call_on_abort() */
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -450,7 +450,11 @@
         /* 'objects_pointing_to_nursery' should be empty, but isn't
            necessarily because it also lists objects that have been
            written to but don't actually point to the nursery.  Clear
-           it up and set GCFLAG_WRITE_BARRIER again on the objects. */
+           it up and set GCFLAG_WRITE_BARRIER again on the objects.
+           This is the case for transactions where
+               MINOR_NOTHING_TO_DO() == false
+           but they still did write-barriers on objects
+        */
         lst = pseg->objects_pointing_to_nursery;
         if (lst != NULL) {
             LIST_FOREACH_R(lst, uintptr_t /*item*/,
@@ -537,6 +541,9 @@
     mark_visit_from_roots();
     LIST_FREE(mark_objects_to_trace);
 
+    /* weakrefs: */
+    stm_visit_old_weakrefs();
+
     /* cleanup */
     clean_up_segment_lists();
 
diff --git a/c7/stm/weakref.c b/c7/stm/weakref.c
--- a/c7/stm/weakref.c
+++ b/c7/stm/weakref.c
@@ -86,141 +86,38 @@
 
 /***** Major collection *****/
 
-/* static _Bool is_partially_visited(gcptr obj) */
-/* { */
-/*     /\* Based on gcpage.c:visit_public().  Check the code here if we change 
*/
-/*        visit_public().  Returns True or False depending on whether we find 
any */
-/*        version of 'obj' to be MARKED or not. */
-/*     *\/ */
-/*     assert(IMPLIES(obj->h_tid & GCFLAG_VISITED, */
-/*                    obj->h_tid & GCFLAG_MARKED)); */
-/*     if (obj->h_tid & GCFLAG_MARKED) */
-/*         return 1; */
 
-/*     /\* if (!(obj->h_tid & GCFLAG_PUBLIC)) *\/ */
-/*     /\*     return 0; *\/ */
-/*     assert(!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)); */
-/*     if (obj->h_original != 0) { */
-/*         gcptr original = (gcptr)obj->h_original; */
-/*         assert(IMPLIES(original->h_tid & GCFLAG_VISITED, */
-/*                        original->h_tid & GCFLAG_MARKED)); */
-/*         if (original->h_tid & GCFLAG_MARKED) */
-/*             return 1; */
-/*     } */
-/*     return 0; */
-/* } */
+void stm_visit_old_weakrefs(void)
+{
+    long i;
+    for (i = 0; i < NB_SEGMENTS; i++) {
+        struct stm_priv_segment_info_s *pseg = get_priv_segment(i);
+        struct list_s *lst;
 
-/* static void update_old_weakrefs_list(struct tx_public_descriptor *gcp) */
-/* { */
-/*     long i, size = gcp->old_weakrefs.size; */
-/*     gcptr *items = gcp->old_weakrefs.items; */
+        lst = pseg->old_weakrefs;
+        uintptr_t n = list_count(lst);
+        while (n > 0) {
+            object_t *weakref = (object_t *)list_item(lst, --n);
+            if (!mark_visited_test(weakref)) {
+                /* weakref dies */
+                list_set_item(lst, n, list_pop_item(lst));
+                continue;
+            }
 
-/*     for (i = 0; i < size; i++) { */
-/*         gcptr weakref = items[i]; */
+            char *realobj = REAL_ADDRESS(pseg->pub.segment_base, weakref);
+            ssize_t size = stmcb_size_rounded_up((struct object_s *)realobj);
+            object_t *pointing_to = *WEAKREF_PTR(weakref, size);
+            assert(pointing_to != NULL);
+            if (!mark_visited_test(pointing_to)) {
+                *WEAKREF_PTR(weakref, size) = NULL;
 
-/*         /\* if a weakref moved, update its position in the list *\/ */
-/*         if (weakref->h_tid & GCFLAG_MOVED) { */
-/*             items[i] = (gcptr)weakref->h_original; */
-/*         } */
-/*     } */
-/* } */
-
-/* static void visit_old_weakrefs(struct tx_public_descriptor *gcp) */
-/* { */
-/*     /\* Note: it's possible that a weakref points to a public stub to a */
-/*        protected object, and only the protected object was marked as */
-/*        VISITED so far.  In this case, this function needs to mark the */
-/*        public stub as VISITED too. */
-/*     *\/ */
-/*     long i, size = gcp->old_weakrefs.size; */
-/*     gcptr *items = gcp->old_weakrefs.items; */
-
-/*     for (i = 0; i < size; i++) { */
-/*         gcptr weakref = items[i]; */
-
-/*         if (!(weakref->h_tid & GCFLAG_VISITED)) { */
-/*             /\* the weakref itself dies *\/ */
-/*         } */
-/*         else { */
-/*             /\* the weakref belongs to our thread, therefore we should */
-/*                always see the most current revision here: *\/ */
-/*             assert(weakref->h_revision & 1); */
-
-/*             size_t size = stmgc_size(weakref); */
-/*             gcptr pointing_to = *WEAKREF_PTR(weakref, size); */
-/*             assert(pointing_to != NULL); */
-/*             if (is_partially_visited(pointing_to)) { */
-/*                 pointing_to = stmgcpage_visit(pointing_to); */
-/*                 dprintf(("mweakref ptr moved %p->%p\n", */
-/*                          *WEAKREF_PTR(weakref, size), */
-/*                          pointing_to)); */
-
-/*                 assert(pointing_to->h_tid & GCFLAG_VISITED); */
-/*                 *WEAKREF_PTR(weakref, size) = pointing_to; */
-/*             } */
-/*             else { */
-/*                 /\* the weakref appears to be pointing to a dying object, */
-/*                    but we don't know for sure now.  Clearing it is left */
-/*                    to clean_old_weakrefs(). *\/ */
-/*             } */
-/*         } */
-/*     } */
-/* } */
-
-/* static void clean_old_weakrefs(struct tx_public_descriptor *gcp) */
-/* { */
-/*     long i, size = gcp->old_weakrefs.size; */
-/*     gcptr *items = gcp->old_weakrefs.items; */
-
-/*     for (i = size - 1; i >= 0; i--) { */
-/*         gcptr weakref = items[i]; */
-/*         assert(weakref->h_revision & 1); */
-/*         if (weakref->h_tid & GCFLAG_VISITED) { */
-/*             size_t size = stmgc_size(weakref); */
-/*             gcptr pointing_to = *WEAKREF_PTR(weakref, size); */
-/*             if (pointing_to->h_tid & GCFLAG_VISITED) { */
-/*                 continue;   /\* the target stays alive, the weakref remains 
*\/ */
-/*             } */
-/*             dprintf(("mweakref lost ptr %p\n", *WEAKREF_PTR(weakref, 
size))); */
-/*             *WEAKREF_PTR(weakref, size) = NULL;  /\* the target dies *\/ */
-/*         } */
-/*         /\* remove this weakref from the list *\/ */
-/*         items[i] = items[--gcp->old_weakrefs.size]; */
-/*     } */
-/*     gcptrlist_compress(&gcp->old_weakrefs); */
-/* } */
-
-/* static void for_each_public_descriptor( */
-/*                                   void visit(struct tx_public_descriptor 
*)) { */
-/*     struct tx_descriptor *d; */
-/*     for (d = stm_tx_head; d; d = d->tx_next) */
-/*         visit(d->public_descriptor); */
-
-/*     struct tx_public_descriptor *gcp; */
-/*     revision_t index = -1; */
-/*     while ((gcp = stm_get_free_public_descriptor(&index)) != NULL) */
-/*         visit(gcp); */
-/* } */
-
-/* void stm_update_old_weakrefs_lists(void) */
-/* { */
-/*     /\* go over old weakrefs lists and update the list with possibly */
-/*        new pointers because of copy_over_original *\/ */
-/*     for_each_public_descriptor(update_old_weakrefs_list); */
-/* } */
-
-
-/* void stm_visit_old_weakrefs(void) */
-/* { */
-/*     /\* Figure out which weakrefs survive, which possibly */
-/*        adds more objects to 'objects_to_trace'. */
-/*     *\/ */
-/*     for_each_public_descriptor(visit_old_weakrefs); */
-/* } */
-
-/* void stm_clean_old_weakrefs(void) */
-/* { */
-/*     /\* Clean up the non-surviving weakrefs */
-/*      *\/ */
-/*     for_each_public_descriptor(clean_old_weakrefs); */
-/* } */
+                /* we don't need it in this list anymore */
+                list_set_item(lst, n, list_pop_item(lst));
+                continue;
+            }
+            else {
+                /* it survives! */
+            }
+        }
+    }
+}
diff --git a/c7/stm/weakref.h b/c7/stm/weakref.h
--- a/c7/stm/weakref.h
+++ b/c7/stm/weakref.h
@@ -5,9 +5,7 @@
 #define WEAKREF_PTR(wr, sz)  ((object_t * TLPREFIX *)(((stm_char *)(wr)) + 
(sz) - sizeof(void*)))
 
 void stm_move_young_weakrefs(void);
-/* void stm_update_old_weakrefs_lists(void); */
-/* void stm_visit_old_weakrefs(void); */
-/* void stm_clean_old_weakrefs(void); */
+void stm_visit_old_weakrefs(void);
 
 
 #endif
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -195,7 +195,7 @@
 }
 
 /* Allocate a weakref object. Weakref objects have a
-   reference to the referenced object at the byte-offset
+   reference to an object at the byte-offset
        stmcb_size_rounded_up(obj) - sizeof(void*)
    This reference becomes NULL if the referenced object was freed.
    You must assign the reference before the next collection may happen.
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to