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