[pypy-commit] stmgc c7-refactor: in-progress

arigo noreply at buildbot.pypy.org
Mon Feb 17 16:09:34 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r758:4ab38af77c28
Date: 2014-02-17 16:09 +0100
http://bitbucket.org/pypy/stmgc/changeset/4ab38af77c28/

Log:	in-progress

diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -38,6 +38,9 @@
     /* objects that are allocated crossing a page boundary have this
        flag set */
     GCFLAG_CROSS_PAGE = 0x02,
+    /* only used during collections to mark an obj as moved out of the
+       generation it was in */
+    GCFLAG_MOVED = 0x04,
 };
 
 #define CROSS_PAGE_BOUNDARY(start, stop)                                \
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -3,6 +3,18 @@
 #endif
 
 
+/* Outside the nursery, we are taking from the highest addresses
+   complete pages, one at a time, which uniformly contain objects
+   of size "8 * N" for any "2 <= N < GC_N_SMALL_REQUESTS".  We are
+   taking from the lowest addresses large objects, which are
+   guaranteed to be at least 256 bytes long (actually 288),
+   allocated by largemalloc.c.
+*/
+
+#define GC_N_SMALL_REQUESTS    36
+#define GC_MEDIUM_REQUEST      (GC_N_SMALL_REQUESTS * 8)
+
+
 static void setup_gcpage(void)
 {
     /* NB. the very last page is not used, which allows a speed-up in
@@ -11,21 +23,65 @@
     uintptr_t length = (NB_PAGES - END_NURSERY_PAGE - 1) * 4096UL;
     largemalloc_init_arena(base, length);
 
-    uninitialized_page_start = (stm_char *)(END_NURSERY_PAGE * 4096UL);
-    uninitialized_page_stop = (stm_char *)((NB_PAGES - 1) * 4096UL);
+    uninitialized_page_start = stm_object_pages + END_NURSERY_PAGE * 4096UL;
+    uninitialized_page_stop  = stm_object_pages + (NB_PAGES - 1) * 4096UL;
+
+    assert(GC_MEDIUM_REQUEST >= (1 << 8));
+}
+
+static char *allocate_outside_nursery(uint64_t size)
+{
+    /* not thread-safe!  Use only when holding the mutex */
+    assert(_has_mutex());
+
+    OPT_ASSERT(size >= 16);
+    OPT_ASSERT((size & 7) == 0);
+
+    uint64_t index = size / 8;
+    if (index < GC_N_SMALL_REQUESTS) {
+        assert(index >= 2);
+        // XXX! TEMPORARY!
+        return allocate_outside_nursery(GC_MEDIUM_REQUEST);
+    }
+    else {
+        /* The object is too large to fit inside the uniform pages.
+           Allocate it with largemalloc.c from the lower addresses */
+        char *addr = large_malloc(size);
+
+        if (addr + size > uninitialized_page_start) {
+            uintptr_t pagenum =
+                (uninitialized_page_start - stm_object_pages) / 4096UL;
+            uintptr_t pagecount =
+                (addr + size - uninitialized_page_start) / 4096UL + 20;
+            uintptr_t pagemax =
+                (uninitialized_page_stop - uninitialized_page_start) / 4096UL;
+            if (pagecount > pagemax)
+                pagecount = pagemax;
+            pages_initialize_shared(pagenum, pagecount);
+
+            uninitialized_page_start += pagecount * 4096UL;
+        }
+
+        assert(get_single_creation_marker(
+                   (stm_char *)(addr - stm_object_pages)) == 0);
+        return addr;
+    }
 }
 
 object_t *_stm_allocate_old(ssize_t size_rounded_up)
 {
-    /* XXX not thread-safe! */
+    /* XXX not thread-safe!  and only for tests, don't use when a
+       transaction might be running! */
+    assert(size_rounded_up >= 16);
+    assert((size_rounded_up & 7) == 0);
+
     char *addr = large_malloc(size_rounded_up);
-    stm_char* o = (stm_char *)(addr - stm_object_pages);
 
-    if (o + size_rounded_up > uninitialized_page_start) {
+    if (addr + size_rounded_up > uninitialized_page_start) {
         uintptr_t pagenum =
-            ((uint64_t)uninitialized_page_start) / 4096UL;
+            (uninitialized_page_start - stm_object_pages) / 4096UL;
         uintptr_t pagecount =
-            (o + size_rounded_up - uninitialized_page_start) / 4096UL + 20;
+            (addr + size_rounded_up - uninitialized_page_start) / 4096UL + 20;
         uintptr_t pagemax =
             (uninitialized_page_stop - uninitialized_page_start) / 4096UL;
         if (pagecount > pagemax)
@@ -37,6 +93,7 @@
 
     memset(addr, 0, size_rounded_up);
 
+    stm_char* o = (stm_char *)(addr - stm_object_pages);
     if (CROSS_PAGE_BOUNDARY(o, o + size_rounded_up))
         ((object_t *)o)->stm_flags = GCFLAG_CROSS_PAGE;
 
diff --git a/c7/stm/gcpage.h b/c7/stm/gcpage.h
--- a/c7/stm/gcpage.h
+++ b/c7/stm/gcpage.h
@@ -1,3 +1,5 @@
 
-static stm_char *uninitialized_page_start;
-static stm_char *uninitialized_page_stop;
+static char *uninitialized_page_start;   /* within segment 0 */
+static char *uninitialized_page_stop;
+
+static char *allocate_outside_nursery(uint64_t size);
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -51,14 +51,46 @@
     return (uintptr_t)obj < NURSERY_START + NURSERY_SIZE;
 }
 
+static bool _is_young(object_t *obj)
+{
+    return _stm_in_nursery(obj);    /* for now */
+}
+
 
 /************************************************************/
 
 
 static void minor_trace_if_young(object_t **pobj)
 {
-    //...
+    /* takes a normal pointer to a thread-local pointer to an object */
+    object_t *obj = *pobj;
+    if (obj == NULL)
+        return;
+    if (!_is_young(obj))
+        return;
+
+    /* the location the object moved to is the second word in 'obj' */
+    object_t *TLPREFIX *pforwarded_array = (object_t *TLPREFIX *)obj;
+
+    if (UNLIKELY(obj->stm_flags & GCFLAG_MOVED)) {
+        *pobj = pforwarded_array[1];    /* already moved */
+        return;
+    }
+
+#if 0
+    /* move obj to somewhere else */
+    size_t size = stmcb_size_rounded_up(stm_object_pages + (uintptr_t)*pobj);
+    bool is_small;
+    object_t *moved = stm_big_small_alloc_old(size, &is_small);
+
+    memcpy((void*)real_address(moved),
+           (void*)real_address(*pobj),
+           size);
+#endif
+
     abort();
+
+    allocate_outside_nursery(-1);
 }
 
 static void minor_trace_roots(void)
diff --git a/c7/stm/pages.c b/c7/stm/pages.c
--- a/c7/stm/pages.c
+++ b/c7/stm/pages.c
@@ -94,12 +94,15 @@
     memset(addr, newvalue, size >> 8);
 }
 
+static uint8_t get_single_creation_marker(stm_char *p)
+{
+    uintptr_t cmaddr = ((uintptr_t)p) >> 8;
+    return ((stm_creation_marker_t *)cmaddr)->cm;
+}
+
 static void set_single_creation_marker(stm_char *p, int newvalue)
 {
-    assert((((uintptr_t)p) & 255) == 0);
-
     uintptr_t cmaddr = ((uintptr_t)p) >> 8;
-
     ((stm_creation_marker_t *)cmaddr)->cm = newvalue;
     LIST_APPEND(STM_PSEGMENT->creation_markers, cmaddr);
 }
diff --git a/c7/stm/pages.h b/c7/stm/pages.h
--- a/c7/stm/pages.h
+++ b/c7/stm/pages.h
@@ -30,5 +30,6 @@
 }
 
 static void set_creation_markers(stm_char *p, uint64_t size, int newvalue);
+static uint8_t get_single_creation_marker(stm_char *p);
 static void set_single_creation_marker(stm_char *p, int newvalue);
 static void reset_all_creation_markers(void);


More information about the pypy-commit mailing list