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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit