Author: Remi Meier <[email protected]>
Branch: c8-private-pages
Changeset: r1541:6520222bf6c8
Date: 2015-01-19 10:27 +0100
http://bitbucket.org/pypy/stmgc/changeset/6520222bf6c8/

Log:    sweep small objs too in major gc

diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -410,6 +410,34 @@
     _stm_largemalloc_sweep();
 }
 
+static inline bool smallmalloc_keep_object_at(char *data)
+{
+    /* 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)));
+    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.
+           It is probably rare enough, but still, we want to avoid any
+           false conflict. (test_random hits it sometimes) */
+        long i;
+        for (i = 1; i < NB_SEGMENTS; i++) {
+            /* reset read marker */
+            *((char *)(get_segment_base(i) + (((uintptr_t)obj) >> 4))) = 0;
+        }
+        return false;
+    }
+    return true;
+}
+
+static void sweep_small_objects(void)
+{
+    _stm_smallmalloc_sweep();
+}
+
+
+
 static void major_collection_now_at_safe_point(void)
 {
     dprintf(("\n"));
@@ -438,7 +466,7 @@
 
     /* /\* sweeping *\/ */
     sweep_large_objects();
-    /* //sweep_uniform_pages(); */
+    sweep_small_objects();
 
     dprintf((" | used after collection:  %ld\n",
              (long)pages_ctl.total_allocated));
diff --git a/c8/stm/gcpage.h b/c8/stm/gcpage.h
--- a/c8/stm/gcpage.h
+++ b/c8/stm/gcpage.h
@@ -21,3 +21,4 @@
 static void major_collection_if_requested(void);
 static void major_collection_now_at_safe_point(void);
 static bool largemalloc_keep_object_at(char *data);   /* for largemalloc.c */
+static bool smallmalloc_keep_object_at(char *data);   /* for smallmalloc.c */
diff --git a/c8/stm/misc.c b/c8/stm/misc.c
--- a/c8/stm/misc.c
+++ b/c8/stm/misc.c
@@ -104,4 +104,13 @@
 {
     return increment_total_allocated(0);
 }
+
+
+void _stm_smallmalloc_sweep_test()
+{
+    acquire_all_privatization_locks();
+    _stm_smallmalloc_sweep();
+    release_all_privatization_locks();
+}
+
 #endif
diff --git a/c8/stm/smallmalloc.c b/c8/stm/smallmalloc.c
--- a/c8/stm/smallmalloc.c
+++ b/c8/stm/smallmalloc.c
@@ -22,7 +22,9 @@
 static fpsz_t *get_fpsz(char *smallpage)
 {
     uintptr_t pagenum = (((char *)smallpage) - END_NURSERY_PAGE * 4096UL - 
stm_object_pages) / 4096;
-    assert(PAGE_SMSIZE_START <= pagenum && pagenum < PAGE_SMSIZE_END);
+    /* <= PAGE_SMSIZE_END because we may ask for it when there is no
+       page with smallobjs yet and uninit_page_stop == NB_PAGES... */
+    assert(PAGE_SMSIZE_START <= pagenum && pagenum <= PAGE_SMSIZE_END);
     return &full_pages_object_size[pagenum - PAGE_SMSIZE_START];
 }
 
@@ -162,6 +164,8 @@
 
     struct small_free_loc_s *result = *fl;
 
+    increment_total_allocated(size);
+
     if (UNLIKELY(result == NULL))
         return (stm_char*)
             (_allocate_small_slowpath(size) - stm_object_pages);
@@ -201,8 +205,7 @@
         return _stm_smallmalloc_keep((char*)(p - stm_object_pages));
     }
 #endif
-    return true;
-    //return smallmalloc_keep_object_at(p);
+    return smallmalloc_keep_object_at(p);
 }
 
 void check_order_inside_small_page(struct small_free_loc_s *page)
@@ -248,6 +251,7 @@
         }
         else if (!_smallmalloc_sweep_keep(p)) {
             /* the location should be freed now */
+            increment_total_allocated(-szword*8);
 #ifdef STM_TESTS
             /* fill location with 0xdd in all segs except seg0 */
             int j;
@@ -301,7 +305,6 @@
 
 void _stm_smallmalloc_sweep(void)
 {
-    acquire_all_privatization_locks(); /* should be done outside, but tests... 
*/
     long i, szword;
     for (szword = 2; szword < GC_N_SMALL_REQUESTS; szword++) {
         struct small_free_loc_s *page = small_page_lists[szword];
@@ -350,5 +353,4 @@
             sweep_small_page(pageptr, NULL, sz);
         }
     }
-    release_all_privatization_locks();
 }
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -96,7 +96,7 @@
 char *stm_file_pages;
 object_t *_stm_allocate_old_small(ssize_t size_rounded_up);
 bool (*_stm_smallmalloc_keep)(char *data);
-void _stm_smallmalloc_sweep(void);
+void _stm_smallmalloc_sweep_test(void);
 
 void _stm_start_safe_point(void);
 void _stm_stop_safe_point(void);
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -116,7 +116,7 @@
 
 object_t *_stm_allocate_old_small(ssize_t size_rounded_up);
 bool (*_stm_smallmalloc_keep)(char *data);
-void _stm_smallmalloc_sweep(void);
+void _stm_smallmalloc_sweep_test(void);
 
 """)
 
@@ -291,7 +291,6 @@
     }
 }
 
-
 ''', sources=source_files,
      define_macros=[('STM_TESTS', '1'),
                     ('STM_NO_AUTOMATIC_SETJMP', '1'),
diff --git a/c8/test/test_gcpage.py b/c8/test/test_gcpage.py
--- a/c8/test/test_gcpage.py
+++ b/c8/test/test_gcpage.py
@@ -331,7 +331,8 @@
 
     def test_small_major_collection(self):
         self.start_transaction()
-        new = stm_allocate(16)
+        new = stm_allocate(16) # small
+        assert lib._stm_total_allocated() == 0
         self.push_root(new)
         stm_minor_collect()
         assert lib._stm_total_allocated() == 16
diff --git a/c8/test/test_smallmalloc.py b/c8/test/test_smallmalloc.py
--- a/c8/test/test_smallmalloc.py
+++ b/c8/test/test_smallmalloc.py
@@ -40,10 +40,13 @@
             assert p == seen[0]
             seen.pop(0)
 
+    def test_sweep_trivial(self):
+        lib._stm_smallmalloc_sweep_test()
+
     def test_sweep_freeing_simple(self):
         p1 = stm_allocate_old_small(16)
         self.has_been_asked_for = []
-        lib._stm_smallmalloc_sweep()
+        lib._stm_smallmalloc_sweep_test()
         assert p1 in self.has_been_asked_for
 
     def test_sweep_freeing_random_subset(self):
@@ -59,7 +62,7 @@
                 # keep half of them around
                 self.keep_me = set(random.sample(page0, len(page0) // 2))
                 self.has_been_asked_for = []
-                lib._stm_smallmalloc_sweep()
+                lib._stm_smallmalloc_sweep_test()
 
                 print len(page0), len(self.has_been_asked_for)
                 assert sorted(page0) == self.has_been_asked_for, "all objs 
were observed"
@@ -84,6 +87,6 @@
         page0 = [stm_allocate_old_small(16) for i in range(0, 4096, 16)]
         tid = lib._get_type_id(page0[0])
         self.keep_me = set(page0)
-        lib._stm_smallmalloc_sweep()
+        lib._stm_smallmalloc_sweep_test()
         for p in page0:
             assert lib._get_type_id(p) == tid
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to