[pypy-commit] stmgc c8-private-pages: fix smallmalloc and prebuilt objs

Raemi noreply at buildbot.pypy.org
Tue Jan 13 11:33:54 CET 2015


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-private-pages
Changeset: r1521:074ee9be5109
Date: 2015-01-13 11:34 +0100
http://bitbucket.org/pypy/stmgc/changeset/074ee9be5109/

Log:	fix smallmalloc and prebuilt objs

diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -63,10 +63,9 @@
 {
     /* only for tests xxx but stm_setup_prebuilt() uses this now too */
     stm_char *p = allocate_outside_nursery_large(size_rounded_up);
-    /* hardcode segment 1 */
-    memset(get_virtual_address(STM_SEGMENT->segment_num, (object_t *)p), 0, size_rounded_up);
+    object_t *o = (object_t *)p;
 
-    object_t *o = (object_t *)p;
+    memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, size_rounded_up);
     o->stm_flags = GCFLAG_WRITE_BARRIER;
 
     dprintf(("allocate_old(%lu): %p, seg=%d, page=%lu\n",
diff --git a/c8/stm/hash_id.c b/c8/stm/hash_id.c
--- a/c8/stm/hash_id.c
+++ b/c8/stm/hash_id.c
@@ -58,7 +58,7 @@
 void stm_set_prebuilt_identityhash(object_t *obj, long hash)
 {
     struct object_s *realobj = (struct object_s *)
-        REAL_ADDRESS(stm_object_pages, obj);
+        get_virtual_address(STM_SEGMENT->segment_num, obj);
 
     assert(realobj->stm_flags == GCFLAG_WRITE_BARRIER);
     realobj->stm_flags |= GCFLAG_HAS_SHADOW;
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -93,7 +93,7 @@
         realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
         size = stmcb_size_rounded_up((struct object_s *)realobj);
 
-        if (true || size > GC_LAST_SMALL_SIZE) {
+        if (size > GC_LAST_SMALL_SIZE) {
             /* case 1: object is not small enough.
                Ask gcpage.c for an allocation via largemalloc. */
             nobj = (object_t *)allocate_outside_nursery_large(size);
diff --git a/c8/stm/pages.h b/c8/stm/pages.h
--- a/c8/stm/pages.h
+++ b/c8/stm/pages.h
@@ -52,7 +52,7 @@
 
 static inline char *get_virtual_address(long segnum, object_t *obj)
 {
-    return get_segment_base(segnum) + (uintptr_t)obj;
+    return REAL_ADDRESS(get_segment_base(segnum), obj);
 }
 
 static inline bool get_page_status_in(long segnum, uintptr_t pagenum)
diff --git a/c8/stm/prebuilt.c b/c8/stm/prebuilt.c
--- a/c8/stm/prebuilt.c
+++ b/c8/stm/prebuilt.c
@@ -32,7 +32,7 @@
     object_t *nobj = _stm_allocate_old(size + sizeof(long));
 
     /* Copy the object */
-    char *realnobj = REAL_ADDRESS(stm_object_pages, nobj);
+    char *realnobj = get_virtual_address(STM_SEGMENT->segment_num, nobj);
     memcpy(realnobj, (char *)objaddr, size);
 
     /* Fix the flags in the copied object, asserting that it was zero so far */
diff --git a/c8/stm/smallmalloc.c b/c8/stm/smallmalloc.c
--- a/c8/stm/smallmalloc.c
+++ b/c8/stm/smallmalloc.c
@@ -67,11 +67,14 @@
         /* if (!_stm_largemalloc_resize_arena(uninitialized_page_stop - base)) */
         /*     goto out_of_memory; */
 
-        setup_N_pages(uninitialized_page_stop, GCPAGE_NUM_PAGES);
 
         char *p = uninitialized_page_stop;
         long i;
         for (i = 0; i < GCPAGE_NUM_PAGES; i++) {
+            /* accessible in seg0: */
+            page_mark_accessible(0, (p - stm_object_pages) / 4096UL);
+
+            /* add to free_uniform_pages list */
             ((struct small_free_loc_s *)p)->nextpage = free_uniform_pages;
             free_uniform_pages = (struct small_free_loc_s *)p;
             p += 4096;
@@ -120,6 +123,10 @@
                                                    smallpage->nextpage)))
             goto retry;
 
+        /* make page accessible in our segment too: */
+        page_mark_accessible(STM_SEGMENT->segment_num,
+                             ((char*)smallpage - stm_object_pages) / 4096UL);
+
         /* Succeeded: we have a page in 'smallpage', which is not
            initialized so far, apart from the 'nextpage' field read
            above.  Initialize it.
@@ -174,9 +181,9 @@
 object_t *_stm_allocate_old_small(ssize_t size_rounded_up)
 {
     stm_char *p = allocate_outside_nursery_small(size_rounded_up);
-    memset(stm_object_pages + (uintptr_t)p, 0, size_rounded_up);
+    object_t *o = (object_t *)p;
 
-    object_t *o = (object_t *)p;
+    memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, size_rounded_up);
     o->stm_flags = GCFLAG_WRITE_BARRIER;
 
     dprintf(("allocate_old_small(%lu): %p, seg=%d, page=%lu\n",
@@ -244,6 +251,17 @@
         }
         else if (!_smallmalloc_sweep_keep(p)) {
             /* the location should be freed now */
+            //dprintf(("free small obj %p\n", (object_t*)(p - stm_object_pages)));
+#ifdef STM_TESTS
+            /* fill location with 0xdd in all segs except seg0 */
+            int j;
+            object_t *obj = (object_t*)(p - stm_object_pages);
+            uintptr_t page = (baseptr - stm_object_pages) / 4096UL;
+            for (j = 1; j < NB_SEGMENTS; j++)
+                if (get_page_status_in(j, page) == PAGE_ACCESSIBLE)
+                    memset(get_virtual_address(j, obj), 0xdd, szword*8);
+#endif
+
             if (flprev == NULL) {
                 flprev = (struct small_free_loc_s *)p;
                 flprev->next = fl;
@@ -262,6 +280,14 @@
         }
     }
     if (!any_object_remaining) {
+        /* give page back to free_uniform_pages and thus make it
+           inaccessible from all other segments again (except seg0) */
+        uintptr_t page = (baseptr - stm_object_pages) / 4096UL;
+        for (i = 1; i < NB_SEGMENTS; i++) {
+            if (get_page_status_in(i, page) == PAGE_ACCESSIBLE)
+                page_mark_inaccessible(i, page);
+        }
+
         ((struct small_free_loc_s *)baseptr)->nextpage = free_uniform_pages;
         free_uniform_pages = (struct small_free_loc_s *)baseptr;
     }
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
@@ -42,27 +42,37 @@
 
     def test_sweep_freeing_simple(self):
         p1 = stm_allocate_old_small(16)
+        self.has_been_asked_for = []
         lib._stm_smallmalloc_sweep()
+        assert p1 in self.has_been_asked_for
 
     def test_sweep_freeing_random_subset(self):
         for i in range(50):
+            # allocate a page's worth of objs
             page0 = [stm_allocate_old_small(16) for i in range(0, 4096, 16)]
-            assert len(set(map(pageof, page0))) == 1
-            tid = lib._get_type_id(page0[0])
+            assert len(set(map(pageof, page0))) == 1, "all in the same page"
+            tid = lib._get_type_id(page0[0]) # 58
+
+            # repeatedly free a subset until no objs are left in that page
             while len(page0) > 0:
+                # keep half of them around
                 self.keep_me = set(random.sample(page0, len(page0) // 2))
                 self.has_been_asked_for = []
                 lib._stm_smallmalloc_sweep()
-                assert sorted(page0) == self.has_been_asked_for
-                page0r = []
+                assert sorted(page0) == self.has_been_asked_for, "all objs were observed"
+
+                # get list of objs that were not freed
+                page0remaining = []
                 for p in page0:
                     if p in self.keep_me:
                         assert lib._get_type_id(p) == tid
-                        page0r.append(p)
-                    else:
-                        assert lib._get_type_id(p) != tid
-                page0 = page0r
+                        page0remaining.append(p)
+                    elif len(self.keep_me) > 0: # otherwise page not accessible from seg1
+                        assert lib._get_type_id(p) != tid, "should have garbage there now (0xdd)"
+                page0 = page0remaining
+
                 if len(page0) > 10:
+                    # allocate one obj for noise if we do another iteration anyway
                     p = stm_allocate_old_small(16)
                     assert pageof(p) == pageof(page0[0])
                     page0.append(p)


More information about the pypy-commit mailing list