Author: Armin Rigo <[email protected]>
Branch:
Changeset: r123:171f8b47b009
Date: 2013-06-14 15:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/171f8b47b009/
Log: Next test
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -391,14 +391,6 @@
#endif
}
-gcptr stmgc_duplicate(gcptr P)
-{
- size_t size = stmcb_size(P);
- gcptr L = stm_malloc(size);
- memcpy(L, P, size);
- return L;
-}
-
static gcptr LocalizeProtected(struct tx_descriptor *d, gcptr P)
{
gcptr B;
@@ -447,6 +439,7 @@
0);
L->h_revision = stm_private_rev_num;
g2l_insert(&d->public_to_private, R, L);
+ gcptrlist_insert(&d->public_to_young, R);
fprintf(stderr, "write_barrier: adding %p -> %p to public_to_private\n",
R, L);
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -172,7 +172,6 @@
gcptr stm_get_private_from_protected(long); /* debugging */
gcptr stm_get_read_obj(long); /* debugging */
void stm_clear_read_cache(void); /* debugging */
-gcptr stmgc_duplicate(gcptr);
int DescriptorInit(void);
void DescriptorDone(void);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -26,13 +26,13 @@
stm_free(d->nursery_base, GC_NURSERY);
gcptrlist_delete(&d->old_objects_to_trace);
+ gcptrlist_delete(&d->public_to_young);
}
static char *collect_and_allocate_size(size_t size); /* forward */
-gcptr stm_allocate(size_t size, unsigned long tid)
+inline static char *allocate_nursery(size_t size)
{
- /* XXX inline the fast path */
struct tx_descriptor *d = thread_descriptor;
char *cur = d->nursery_current;
char *end = cur + size;
@@ -40,15 +40,47 @@
if (end > d->nursery_end) {
cur = collect_and_allocate_size(size);
}
- gcptr P = (gcptr)cur;
+ return cur;
+}
+
+gcptr stm_allocate(size_t size, unsigned long tid)
+{
+ /* XXX inline the fast path */
+ gcptr P = (gcptr)allocate_nursery(size);
assert(tid == (tid & STM_USER_TID_MASK));
P->h_tid = tid;
P->h_revision = stm_private_rev_num;
return P;
}
+gcptr stmgc_duplicate(gcptr P)
+{
+ size_t size = stmcb_size(P);
+ gcptr L = (gcptr)allocate_nursery(size);
+ memcpy(L, P, size);
+ L->h_tid &= ~GCFLAG_OLD;
+ return L;
+}
+
/************************************************************/
+static inline gcptr create_old_object_copy(gcptr obj)
+{
+ assert(!(obj->h_tid & GCFLAG_NURSERY_MOVED));
+ assert(!(obj->h_tid & GCFLAG_VISITED));
+ assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
+ assert(!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
+ assert(!(obj->h_tid & GCFLAG_OLD));
+
+ size_t size = stmcb_size(obj);
+ gcptr fresh_old_copy = stm_malloc(size);
+ memcpy(fresh_old_copy, obj, size);
+ fresh_old_copy->h_tid |= GCFLAG_OLD;
+
+ fprintf(stderr, "minor: %p is copied to %p\n", obj, fresh_old_copy);
+ return fresh_old_copy;
+}
+
static void visit_if_young(gcptr *root)
{
gcptr obj = *root;
@@ -60,12 +92,8 @@
}
else {
/* a nursery object */
- assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
- assert(!(obj->h_tid & GCFLAG_OLD));
- assert(!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
-
/* make a copy of it outside */
- fresh_old_copy = stmgc_duplicate(obj);
+ fresh_old_copy = create_old_object_copy(obj);
obj->h_tid |= GCFLAG_NURSERY_MOVED;
obj->h_revision = (revision_t)fresh_old_copy;
@@ -77,22 +105,40 @@
}
}
-static void mark_young_roots(gcptr *root, gcptr *end)
+static void mark_young_roots(struct tx_descriptor *d)
{
+ gcptr *root = d->shadowstack;
+ gcptr *end = *d->shadowstack_end_ref;
+
/* XXX use a way to avoid walking all roots again and again */
for (; root != end; root++) {
visit_if_young(root);
}
}
+static void mark_public_to_young(struct tx_descriptor *d)
+{
+ long i, size = d->public_to_young.size;
+ gcptr *items = d->public_to_young.items;
+
+ for (i = 0; i < size; i++) {
+ gcptr P = items[i];
+ wlog_t *item;
+
+ G2L_FIND(d->public_to_private, P, item, continue);
+ visit_if_young(&item->val);
+ }
+ gcptrlist_clear(&d->public_to_young);
+}
+
static void visit_all_outside_objects(struct tx_descriptor *d)
{
while (gcptrlist_size(&d->old_objects_to_trace) > 0) {
gcptr obj = gcptrlist_pop(&d->old_objects_to_trace);
- assert(!(obj->h_tid & GCFLAG_OLD));
+ assert(obj->h_tid & GCFLAG_OLD);
assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
- obj->h_tid |= GCFLAG_OLD | GCFLAG_WRITE_BARRIER;
+ obj->h_tid |= GCFLAG_WRITE_BARRIER;
stmcb_trace(obj, &visit_if_young);
}
@@ -123,13 +169,15 @@
/* acquire the "collection lock" first */
setup_minor_collect(d);
- mark_young_roots(d->shadowstack, *d->shadowstack_end_ref);
+ mark_young_roots(d);
#if 0
mark_private_from_protected(d);
+#endif
mark_public_to_young(d);
+#if 0
mark_private_old_pointing_to_young(d);
#endif
diff --git a/c4/nursery.h b/c4/nursery.h
--- a/c4/nursery.h
+++ b/c4/nursery.h
@@ -10,7 +10,8 @@
char *nursery_current; \
char *nursery_end; \
char *nursery_base; \
- struct GcPtrList old_objects_to_trace;
+ struct GcPtrList old_objects_to_trace; \
+ struct GcPtrList public_to_young;
struct tx_descriptor; /* from et.h */
@@ -18,5 +19,6 @@
void stmgc_done_nursery(void);
void stmgc_minor_collect(void);
int stmgc_minor_collect_anything_to_do(struct tx_descriptor *);
+gcptr stmgc_duplicate(gcptr);
#endif
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -71,6 +71,7 @@
gcptr stm_get_read_obj(long index);
void *STUB_THREAD(gcptr);
void stm_clear_read_cache(void);
+ int in_nursery(gcptr);
gcptr getptr(gcptr, long);
void setptr(gcptr, long, gcptr);
@@ -183,6 +184,13 @@
rawsetlong(obj, index, newvalue);
}
+ int in_nursery(gcptr obj)
+ {
+ struct tx_descriptor *d = thread_descriptor;
+ return (d->nursery_base <= (char*)obj &&
+ ((char*)obj) < d->nursery_end);
+ }
+
gcptr pseudoprebuilt(size_t size, int tid)
{
gcptr x = calloc(1, size);
diff --git a/c4/test/test_nursery.py b/c4/test/test_nursery.py
--- a/c4/test/test_nursery.py
+++ b/c4/test/test_nursery.py
@@ -49,3 +49,25 @@
lib.stm_finalize()
check_inaccessible(p1)
lib.stm_initialize_tests(0)
+
+def test_local_copy_out_of_nursery():
+ p1 = palloc(HDR + WORD)
+ lib.rawsetlong(p1, 0, 420063)
+ assert not lib.in_nursery(p1)
+ assert p1.h_revision != lib.get_private_rev_num()
+ #
+ p2 = lib.stm_write_barrier(p1)
+ assert lib.rawgetlong(p2, 0) == 420063
+ lib.rawsetlong(p2, 0, -91467)
+ assert lib.in_nursery(p2)
+ assert p2.h_revision == lib.get_private_rev_num()
+ #
+ lib.stm_push_root(p1)
+ minor_collect()
+ p1b = lib.stm_pop_root()
+ assert p1b == p1
+ assert lib.rawgetlong(p1b, 0) == 420063
+ #
+ p3 = lib.stm_read_barrier(p1)
+ assert not lib.in_nursery(p3) and p3 != p2
+ assert lib.rawgetlong(p3, 0) == -91467
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit