[pypy-commit] pypy stmgc-c8: import stmgc-c8 509da83c0d5d

Raemi noreply at buildbot.pypy.org
Thu Jan 22 16:28:31 CET 2015


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: stmgc-c8
Changeset: r75483:df00e75f0207
Date: 2015-01-22 16:28 +0100
http://bitbucket.org/pypy/pypy/changeset/df00e75f0207/

Log:	import stmgc-c8 509da83c0d5d

diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-5cfce5d61c50
+509da83c0d5d
diff --git a/rpython/translator/stm/src_stm/stm/core.c b/rpython/translator/stm/src_stm/stm/core.c
--- a/rpython/translator/stm/src_stm/stm/core.c
+++ b/rpython/translator/stm/src_stm/stm/core.c
@@ -3,6 +3,32 @@
 # error "must be compiled via stmgc.c"
 #endif
 
+/* *** MISC *** */
+static void free_bk(struct stm_undo_s *undo)
+{
+    free(undo->backup);
+    assert(undo->backup = (char*)-88);
+    increment_total_allocated(-SLICE_SIZE(undo->slice));
+}
+
+static struct stm_commit_log_entry_s *malloc_cle(long entries)
+{
+    size_t byte_len = sizeof(struct stm_commit_log_entry_s) +
+        entries * sizeof(struct stm_undo_s);
+    struct stm_commit_log_entry_s *result = malloc(byte_len);
+    increment_total_allocated(byte_len);
+    return result;
+}
+
+static void free_cle(struct stm_commit_log_entry_s *e)
+{
+    size_t byte_len = sizeof(struct stm_commit_log_entry_s) +
+        e->written_count * sizeof(struct stm_undo_s);
+    increment_total_allocated(-byte_len);
+    free(e);
+}
+/* *** MISC *** */
+
 
 /* General helper: copies objects into our own segment, from some
    source described by a range of 'struct stm_undo_s'.  Maybe later
@@ -150,6 +176,9 @@
     /* make our page write-ready */
     page_mark_accessible(my_segnum, pagenum);
 
+    /* account for this page now: XXX */
+    /* increment_total_allocated(4096); */
+
     if (copy_from_segnum == -1) {
         /* this page is only accessible in the sharing segment so far (new
            allocation). We can thus simply mark it accessible here. */
@@ -390,6 +419,7 @@
     return !needs_abort;
 }
 
+
 static struct stm_commit_log_entry_s *_create_commit_log_entry(void)
 {
     /* puts all modified_old_objects in a new commit log entry */
@@ -399,9 +429,7 @@
     struct list_s *list = STM_PSEGMENT->modified_old_objects;
     OPT_ASSERT((list_count(list) % 3) == 0);
     size_t count = list_count(list) / 3;
-    size_t byte_len = sizeof(struct stm_commit_log_entry_s) +
-        count * sizeof(struct stm_undo_s);
-    struct stm_commit_log_entry_s *result = malloc(byte_len);
+    struct stm_commit_log_entry_s *result = malloc_cle(count);
 
     result->next = NULL;
     result->segment_num = STM_SEGMENT->segment_num;
@@ -427,7 +455,7 @@
     while (1) {
         if (!_stm_validate()) {
             if (new != INEV_RUNNING)
-                free(new);
+                free_cle((struct stm_commit_log_entry_s*)new);
             stm_abort_transaction();
         }
 
@@ -601,8 +629,10 @@
 
         /* make backup slice: */
         char *bk_slice = malloc(slice_sz);
+        increment_total_allocated(slice_sz);
         memcpy(bk_slice, realobj + slice_off, slice_sz);
 
+        /* !! follows layout of "struct stm_undo_s" !! */
         STM_PSEGMENT->modified_old_objects = list_append3(
             STM_PSEGMENT->modified_old_objects,
             (uintptr_t)obj,     /* obj */
@@ -860,7 +890,7 @@
         dprintf(("reset_modified_from_backup_copies(%d): obj=%p off=%lu bk=%p\n",
                  segment_num, obj, SLICE_OFFSET(undo->slice), undo->backup));
 
-        free(undo->backup);
+        free_bk(undo);
     }
 
     /* check that all objects have the GCFLAG_WRITE_BARRIER afterwards */
@@ -1089,7 +1119,7 @@
             if (get_page_status_in(i, page) != PAGE_NO_ACCESS) {
                 /* shared or private, but never segfault */
                 char *dst = REAL_ADDRESS(get_segment_base(i), frag);
-                dprintf(("-> flush %p to seg %lu, sz=%lu\n", frag, i, frag_size));
+                //dprintf(("-> flush %p to seg %lu, sz=%lu\n", frag, i, frag_size));
                 memcpy(dst, src, frag_size);
             }
         }
diff --git a/rpython/translator/stm/src_stm/stm/core.h b/rpython/translator/stm/src_stm/stm/core.h
--- a/rpython/translator/stm/src_stm/stm/core.h
+++ b/rpython/translator/stm/src_stm/stm/core.h
@@ -149,6 +149,8 @@
 #define SLICE_SIZE(slice)    ((int)((slice) & 0xFFFF))
 #define NEW_SLICE(offset, size) (((uint64_t)(offset)) << 16 | (size))
 
+
+
 /* The model is: we have a global chained list, from 'commit_log_root',
    of 'struct stm_commit_log_entry_s' entries.  Every one is fully
    read-only apart from the 'next' field.  Every one stands for one
@@ -168,6 +170,11 @@
 static struct stm_commit_log_entry_s commit_log_root;
 
 
+static void free_bk(struct stm_undo_s *undo);
+static struct stm_commit_log_entry_s *malloc_cle(long entries);
+static void free_cle(struct stm_commit_log_entry_s *e);
+
+
 #ifndef STM_TESTS
 static char *stm_object_pages;
 #else
diff --git a/rpython/translator/stm/src_stm/stm/gcpage.c b/rpython/translator/stm/src_stm/stm/gcpage.c
--- a/rpython/translator/stm/src_stm/stm/gcpage.c
+++ b/rpython/translator/stm/src_stm/stm/gcpage.c
@@ -308,29 +308,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)
@@ -485,7 +509,7 @@
 {
     /* this is called by _stm_largemalloc_sweep() */
     object_t *obj = (object_t *)(data - stm_object_pages);
-    dprintf(("keep obj %p ? -> %d\n", obj, mark_visited_test(obj)));
+    //dprintf(("keep obj %p ? -> %d\n", obj, mark_visited_test(obj)));
     if (!mark_visited_test_and_clear(obj)) {
         /* This is actually needed in order to avoid random write-read
            conflicts with objects read and freed long in the past.
@@ -511,7 +535,7 @@
     /* XXX: identical to largemalloc_keep_object_at()? */
     /* this is called by _stm_smallmalloc_sweep() */
     object_t *obj = (object_t *)(data - stm_object_pages);
-    dprintf(("keep small obj %p ? -> %d\n", obj, mark_visited_test(obj)));
+    //dprintf(("keep small obj %p ? -> %d\n", obj, mark_visited_test(obj)));
     if (!mark_visited_test_and_clear(obj)) {
         /* This is actually needed in order to avoid random write-read
            conflicts with objects read and freed long in the past.
@@ -558,8 +582,14 @@
         cl = next;
         rev_num = cl->rev_num;
 
+        /* free bk copies of entries: */
+        long count = cl->written_count;
+        while (count-->0) {
+            free_bk(&cl->written[count]);
+        }
+
         next = cl->next;
-        free(cl);
+        free_cle(cl);
         if (next == INEV_RUNNING) {
             was_inev = true;
             break;
diff --git a/rpython/translator/stm/src_stm/stm/nursery.c b/rpython/translator/stm/src_stm/stm/nursery.c
--- a/rpython/translator/stm/src_stm/stm/nursery.c
+++ b/rpython/translator/stm/src_stm/stm/nursery.c
@@ -104,7 +104,7 @@
             nobj = (object_t *)allocate_outside_nursery_small(size);
         }
 
-        dprintf(("move %p -> %p\n", obj, nobj));
+        //dprintf(("move %p -> %p\n", obj, nobj));
 
         /* copy the object */
     copy_large_object:;
@@ -175,7 +175,7 @@
 {
     assert(!_is_young(obj));
 
-    dprintf(("_collect_now: %p\n", obj));
+    //dprintf(("_collect_now: %p\n", obj));
 
     assert(!(obj->stm_flags & GCFLAG_WRITE_BARRIER));
 
diff --git a/rpython/translator/stm/src_stm/stm/pages.c b/rpython/translator/stm/src_stm/stm/pages.c
--- a/rpython/translator/stm/src_stm/stm/pages.c
+++ b/rpython/translator/stm/src_stm/stm/pages.c
@@ -75,9 +75,6 @@
 
     /* set this flag *after* we un-protected it, because XXX later */
     set_page_status_in(segnum, pagenum, PAGE_ACCESSIBLE);
-
-    // XXX: maybe?
-    //increment_total_allocated(4096);
 }
 
 __attribute__((unused))
@@ -95,7 +92,4 @@
         perror("mprotect");
         stm_fatalerror("mprotect failed! Consider running 'sysctl vm.max_map_count=16777216'");
     }
-
-    // XXX: maybe?
-    //increment_total_allocated(-4096);
 }
diff --git a/rpython/translator/stm/src_stm/stm/smallmalloc.c b/rpython/translator/stm/src_stm/stm/smallmalloc.c
--- a/rpython/translator/stm/src_stm/stm/smallmalloc.c
+++ b/rpython/translator/stm/src_stm/stm/smallmalloc.c
@@ -181,8 +181,8 @@
             (_allocate_small_slowpath(size) - stm_object_pages);
 
     *fl = result->next;
-    dprintf(("allocate_outside_nursery_small(%lu): %p\n",
-             size, (char*)((char *)result - stm_object_pages)));
+    /* dprintf(("allocate_outside_nursery_small(%lu): %p\n", */
+    /*          size, (char*)((char *)result - stm_object_pages))); */
     return (stm_char*)
         ((char *)result - stm_object_pages);
 }


More information about the pypy-commit mailing list