Author: Remi Meier <[email protected]>
Branch:
Changeset: r1572:509da83c0d5d
Date: 2015-01-22 16:26 +0100
http://bitbucket.org/pypy/stmgc/changeset/509da83c0d5d/
Log: construct a list of unique objs again during major gc. it's still
necessary because large objects get traced many many times
otherwise, since they are split into multiple slices
diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -307,29 +307,53 @@
some of the pages) */
long i;
+ struct list_s *uniques = list_create();
+
for (i = 1; i < NB_SEGMENTS; i++) {
char *base = get_segment_base(i);
+ OPT_ASSERT(list_is_empty(uniques));
+ /* the mod_old_objects list may contain maanny slices for
+ the same *huge* object. it seems worth to first construct
+ a list of unique objects. we use the VISITED flag for this
+ purpose as it is never set outside of seg0: */
struct list_s *lst = get_priv_segment(i)->modified_old_objects;
+
struct stm_undo_s *modified = (struct stm_undo_s *)lst->items;
struct stm_undo_s *end = (struct stm_undo_s *)(lst->items +
lst->count);
-
for (; modified < end; modified++) {
object_t *obj = modified->object;
- /* All modified objs have all pages accessible for now.
- This is because we create a backup of the whole obj
- and thus make all pages accessible. */
- assert_obj_accessible_in(i, obj);
+ struct object_s *dst = (struct object_s*)REAL_ADDRESS(base, obj);
- assert(!is_new_object(obj)); /* should never be in that list */
+ if (!(dst->stm_flags & GCFLAG_VISITED)) {
+ LIST_APPEND(uniques, obj);
+ dst->stm_flags |= GCFLAG_VISITED;
+ }
+ }
- if (!mark_visited_test_and_set(obj)) {
- /* trace shared, committed version */
- mark_and_trace(obj, stm_object_pages);
- }
- mark_and_trace(obj, base); /* private, modified version */
- }
+ LIST_FOREACH_R(uniques, object_t*,
+ ({
+ /* clear the VISITED flags again and actually visit them */
+ struct object_s *dst = (struct object_s*)REAL_ADDRESS(base,
item);
+ dst->stm_flags &= ~GCFLAG_VISITED;
+
+ /* All modified objs have all pages accessible for now.
+ This is because we create a backup of the whole obj
+ and thus make all pages accessible. */
+ assert_obj_accessible_in(i, item);
+
+ assert(!is_new_object(item)); /* should never be in that list */
+
+ if (!mark_visited_test_and_set(item)) {
+ /* trace shared, committed version */
+ mark_and_trace(item, stm_object_pages);
+ }
+ mark_and_trace(item, base); /* private, modified version */
+ }));
+
+ list_clear(uniques);
}
+ LIST_FREE(uniques);
}
static void mark_visit_from_roots(void)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit