Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r926:cd8fc6f649af
Date: 2014-03-02 19:46 +0100
http://bitbucket.org/pypy/stmgc/changeset/cd8fc6f649af/

Log:    Start stm_setup_prebuilt()

diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -101,12 +101,12 @@
 
 object_t *_stm_allocate_old(ssize_t size_rounded_up)
 {
-    /* only for tests */
+    /* only for tests xxx but stm_setup_prebuilt() uses this now too */
     char *p = allocate_outside_nursery_large(size_rounded_up);
     memset(p, 0, size_rounded_up);
 
     object_t *o = (object_t *)(p - stm_object_pages);
-    o->stm_flags = STM_FLAGS_PREBUILT;
+    o->stm_flags = GCFLAG_WRITE_BARRIER;
 
     if (testing_prebuilt_objs == NULL)
         testing_prebuilt_objs = list_create();
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -96,7 +96,7 @@
             char *allocated = allocate_outside_nursery_large(size);
             nobj = (object_t *)(allocated - stm_object_pages);
 
-            /* Copy the object  */
+            /* Copy the object */
             char *realnobj = REAL_ADDRESS(STM_SEGMENT->segment_base, nobj);
             memcpy(realnobj, realobj, size);
 
diff --git a/c7/stm/prebuilt.c b/c7/stm/prebuilt.c
--- a/c7/stm/prebuilt.c
+++ b/c7/stm/prebuilt.c
@@ -3,80 +3,36 @@
 #endif
 
 
-static uint64_t prebuilt_readmarkers_start = 0;
-static uint64_t prebuilt_readmarkers_end   = 0;
-static uint64_t prebuilt_objects_start     = 0;
+#define GCWORD_PREBUILT_MOVED  ((object_t *) 42)
 
 
-/* XXX NOT TESTED, AND NOT WORKING RIGHT NOW */
+object_t *stm_setup_prebuilt(object_t *staticobj_invalid)
+{
+    /* All variable names in "_invalid" here mean that although the
+       type is really "object_t *", it should not actually be accessed
+       via %gs.
 
-void stm_copy_prebuilt_objects(object_t *target, char *source, ssize_t size)
-{
-    /* Initialize a region of 'size' bytes at the 'target' address,
-       containing prebuilt objects copied from 'source'.  The caller
-       must ensure that the 'target' address is valid.  It might be
-       called several times but care must be taken not to overlap the
-       ranges.  The exact rules are a bit complicated:
+       If the object was already moved, its first word was set to
+       GCWORD_PREBUILT_MOVED.  In that case, the forwarding location,
+       i.e. where the object moved to, is stored in the second word.
+    */
+    uintptr_t objaddr = (uintptr_t)staticobj_invalid;
+    struct object_s *obj = (struct object_s *)objaddr;
+    object_t **pforwarded_array = (object_t **)objaddr;
 
-       - the range [target, target + size] must be inside the
-         range [131072, FIRST_READMARKER_PAGE*4096]
-
-       - the range [target / 16, (target + size) / 16] will be
-         used by read markers, so it must be fully before the
-         range [target, target + size].
-
-       The objects themselves can contain more pointers to other
-       prebuilt objects.  Their stm_flags field must be initialized
-       with STM_FLAGS_PREBUILT.
-    */
-
-    uint64_t utarget = (uint64_t)target;
-    uint64_t rm_start = utarget / 16;
-    uint64_t rm_end   = (utarget + size + 15) / 16;
-
-    if (rm_start < 8192 || rm_end > (utarget & ~4095) ||
-            utarget + size > FIRST_READMARKER_PAGE * 4096UL) {
-        fprintf(stderr,
-                "stm_copy_prebuilt_objects: invalid range (0x%lx, 0x%lx)\n",
-                (long)utarget, (long)size);
-        abort();
+    if (pforwarded_array[0] == GCWORD_PREBUILT_MOVED) {
+        return pforwarded_array[1];    /* already moved */
     }
 
-    if (prebuilt_readmarkers_start == 0) {
-        prebuilt_readmarkers_start = rm_start;
-        prebuilt_readmarkers_end   = rm_end;
-        prebuilt_objects_start     = utarget & ~4095;
-    }
-    else {
-        if (prebuilt_readmarkers_start > rm_start)
-            prebuilt_readmarkers_start = rm_start;
-        if (prebuilt_readmarkers_end < rm_end)
-            prebuilt_readmarkers_end = rm_end;
-        if (prebuilt_objects_start > (utarget & ~4095))
-            prebuilt_objects_start = utarget & ~4095;
+    /* We need to make a copy of this object. */
+    size_t size = stmcb_size_rounded_up(obj);
+    object_t *nobj = _stm_allocate_old(size);
 
-        if (prebuilt_readmarkers_end > prebuilt_objects_start) {
-            fprintf(stderr,
-                    "stm_copy_prebuilt_objects: read markers ending at 0x%lx "
-                    "overlap with prebuilt objects starting at 0x%lx\n",
-                    (long)prebuilt_readmarkers_end,
-                    (long)prebuilt_objects_start);
-            abort();
-        }
-    }
+    /* Copy the object */
+    char *realnobj = REAL_ADDRESS(stm_object_pages, nobj);
+    memcpy(realnobj, (char *)objaddr, size);
 
-    uint64_t start_page = utarget / 4096;
-    uint64_t end_page = (utarget + size + 4095) / 4096;
-    pages_initialize_shared(start_page, end_page - start_page);
+    // XXX REFERENCES HERE
 
-    char *segment_base = get_segment_base(0);
-    memcpy(REAL_ADDRESS(segment_base, utarget), source, size);
+    return nobj;
 }
-
-#if 0
-static void reset_transaction_read_version_prebuilt(void)
-{
-    memset(REAL_ADDRESS(STM_SEGMENT->segment_base, prebuilt_readmarkers_start),
-           0, prebuilt_readmarkers_end - prebuilt_readmarkers_start);
-}
-#endif
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -100,7 +100,6 @@
 #define _STM_GCFLAG_WRITE_BARRIER      0x01
 #define _STM_NSE_SIGNAL_MAX               1
 #define _STM_FAST_ALLOC           (66*1024)
-#define STM_FLAGS_PREBUILT   _STM_GCFLAG_WRITE_BARRIER
 
 
 /* ==================== HELPERS ==================== */
@@ -253,6 +252,15 @@
 /* Forces a collection. */
 void stm_collect(long level);
 
+/* Prepare an immortal "prebuilt" object managed by the GC.  Takes a
+   pointer to an 'object_t', which should not actually be a GC-managed
+   structure but a real static structure.  Returns the equivalent
+   GC-managed pointer.  Works by copying it into the GC pages, following
+   and fixing all pointers it contains, by doing stm_setup_prebuilt() on
+   each of them recursively.  (Note that this will leave garbage in the
+   static structure, but it should never be used anyway.) */
+object_t *stm_setup_prebuilt(object_t *);
+
 
 /* ==================== END ==================== */
 
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -27,7 +27,7 @@
 void stm_teardown(void);
 void stm_register_thread_local(stm_thread_local_t *tl);
 void stm_unregister_thread_local(stm_thread_local_t *tl);
-//void stm_copy_prebuilt_objects(object_t *target, char *source, ssize_t size);
+object_t *stm_setup_prebuilt(object_t *);
 
 bool _checked_stm_write(object_t *obj);
 bool _stm_was_read(object_t *obj);
diff --git a/gil-c7/stmgc.h b/gil-c7/stmgc.h
--- a/gil-c7/stmgc.h
+++ b/gil-c7/stmgc.h
@@ -33,7 +33,6 @@
 
 #define _STM_GCFLAG_WRITE_BARRIER      0x01
 #define _STM_FAST_ALLOC           (66*1024)
-#define STM_FLAGS_PREBUILT   _STM_GCFLAG_WRITE_BARRIER
 
 
 object_t *_stm_allocate_old(ssize_t size);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to