[pypy-commit] stmgc copy-over-original: merge default
Raemi
noreply at buildbot.pypy.org
Thu Jul 11 08:00:53 CEST 2013
Author: Remi Meier <meierrem at student.ethz.ch>
Branch: copy-over-original
Changeset: r383:ee69aa1b8ef3
Date: 2013-07-11 07:13 +0200
http://bitbucket.org/pypy/stmgc/changeset/ee69aa1b8ef3/
Log: merge default
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -125,6 +125,9 @@
}
/************************************************************/
+/* list for private/protected, old roots that need to be
+ kept in old_objects_to_trace */
+static __thread struct GcPtrList private_or_protected_roots = {0, 0, NULL};
static inline gcptr create_old_object_copy(gcptr obj)
{
@@ -204,6 +207,22 @@
(revision_t)END_MARKER_ON)) {
/* 'item' is a regular, non-null pointer */
visit_if_young(end);
+
+ /* if old, private or protected, this object needs to be
+ traced again in the next minor_collect if it is
+ currently in old_objects_to_trace. Because then
+ it may be seen as write-ready in the view of
+ someone:
+ pw = write_barrier(); push_root(pw);
+ minor_collect(); pw = pop_root(); // pw still write-ready
+ */
+ if (item && item->h_tid & GCFLAG_OLD
+ && !(item->h_tid & GCFLAG_WRITE_BARRIER) /* not set in
+ obj_to_trace*/
+ && (item->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED
+ || item->h_revision == stm_private_rev_num)) {
+ gcptrlist_insert(&private_or_protected_roots, item);
+ }
}
else if (item != NULL) {
if (item == END_MARKER_OFF)
@@ -358,6 +377,19 @@
stmgc_trace(obj, &visit_if_young);
}
+
+ while (gcptrlist_size(&private_or_protected_roots) > 0) {
+ gcptr obj = gcptrlist_pop(&private_or_protected_roots);
+ /* if it has the write_barrier flag, clear it so that
+ it doesn't get inserted twice by a later write-barrier */
+ if (obj->h_tid & GCFLAG_WRITE_BARRIER) {
+ /* only insert those that were in old_obj_to_trace
+ and that we didn't insert already */
+ obj->h_tid &= ~GCFLAG_WRITE_BARRIER;
+ gcptrlist_insert(&d->old_objects_to_trace, obj);
+ dprintf(("re-add %p to old_objects_to_trace\n", obj));
+ }
+ }
}
static void fix_list_of_read_objects(struct tx_descriptor *d)
@@ -410,7 +442,7 @@
static void teardown_minor_collect(struct tx_descriptor *d)
{
- assert(gcptrlist_size(&d->old_objects_to_trace) == 0);
+ //assert(gcptrlist_size(&d->old_objects_to_trace) == 0);
assert(gcptrlist_size(&d->public_with_young_copy) == 0);
assert(gcptrlist_size(&d->public_descriptor->stolen_objects) == 0);
diff --git a/c4/test/test_et.py b/c4/test/test_et.py
--- a/c4/test/test_et.py
+++ b/c4/test/test_et.py
@@ -205,36 +205,52 @@
assert list_of_read_objects() == [p2]
def test_write_barrier_after_minor_collect():
- # maybe should fail. not sure.
p = oalloc_refs(1)
pw = lib.stm_write_barrier(p)
lib.stm_push_root(pw)
minor_collect()
+ lib.stm_push_root(ffi.NULL)
+ minor_collect()
+ lib.stm_pop_root()
+ minor_collect()
r = nalloc(HDR)
pw = lib.stm_pop_root()
assert pw.h_tid & GCFLAG_OLD
rawsetptr(pw, 0, r)
- # pw not in old_objects_to_trace. A
- # repeated write_barrier before
- # rawsetptr() would fix that
-
+ # pw needs to be readded to old_objects_to_trace
+ # before the next minor gc in order for this test to pass
lib.stm_push_root(r)
minor_collect()
+ minor_collect()
+ minor_collect()
+ q = nalloc(HDR)
r2 = lib.stm_pop_root()
check_nursery_free(r)
pr = lib.stm_read_barrier(p)
assert r != r2
- # these will fail because pw/pr was
- # not traced in the last minor_collect,
- # because they were not registered in
- # old_objects_to_trace.
assert getptr(pr, 0) != r
assert getptr(pr, 0) == r2
+ # the following shouldn't be done
+ # because pw was not saved. Just
+ # here to check that pw gets removed
+ # from old_objects_to_trace when not found
+ # on the root stack anymore
+ rawsetptr(pw, 0, q)
+ lib.stm_push_root(q)
+ minor_collect()
+ q2 = lib.stm_pop_root()
+ check_nursery_free(q)
+ pr = lib.stm_read_barrier(p)
+ assert q != q2
+ assert getptr(pr, 0) == q
+ assert getptr(pr, 0) != q2
+
+
def test_id_young_to_old():
# move out of nursery with shadow original
p = nalloc(HDR)
diff --git a/duhton/demo/trees.duh b/duhton/demo/trees.duh
--- a/duhton/demo/trees.duh
+++ b/duhton/demo/trees.duh
@@ -1,15 +1,16 @@
(defun create-tree (n)
- (if (< n 1) (list 1) (list (create-tree (/ n 2)) (create-tree (/ n 2))))
+ (if (== n 0) 1 (cons (create-tree (- n 1)) (create-tree (- n 1))))
)
(defun walk-tree (tree)
- (if (== (len tree) 1) (get tree 0)
- (+ (walk-tree (get tree 0)) (walk-tree (get tree 1)))
+ (if (pair? tree)
+ (+ (walk-tree (car tree)) (walk-tree (cdr tree)))
+ 1
)
)
-(setq tree (create-tree 1024))
+(setq tree (create-tree 10))
(print (walk-tree tree))
(setq n 0)
(while (< n 1000)
diff --git a/duhton/demo/trees2.duh b/duhton/demo/trees2.duh
--- a/duhton/demo/trees2.duh
+++ b/duhton/demo/trees2.duh
@@ -1,16 +1,18 @@
+
(defun create-tree (n)
- (if (< n 1) (list 1) (list (create-tree (/ n 2)) (create-tree (/ n 2))))
+ (if (== n 0) 1 (cons (create-tree (- n 1)) (create-tree (- n 1))))
)
(defun walk-tree (tree)
- (if (== (len tree) 1) (get tree 0)
- (+ (walk-tree (get tree 0)) (walk-tree (get tree 1)))
+ (if (pair? tree)
+ (+ (walk-tree (car tree)) (walk-tree (cdr tree)))
+ 1
)
)
(defun lookup-tree ()
- (walk-tree (create-tree 1024))
+ (walk-tree (create-tree 10))
)
(setq n 0)
diff --git a/duhton/glob.c b/duhton/glob.c
--- a/duhton/glob.c
+++ b/duhton/glob.c
@@ -527,6 +527,14 @@
return DuCons_Cdr(obj);
}
+DuObject *du_cons(DuObject *cons, DuObject *locals)
+{
+ DuObject *obj1, *obj2;
+ _du_getargs2("cons", cons, locals, &obj1, &obj2);
+
+ return DuCons_New(obj1, obj2);
+}
+
DuObject *du_not(DuObject *cons, DuObject *locals)
{
DuObject *obj;
@@ -580,6 +588,13 @@
return DuInt_FromInt(res != NULL);
}
+DuObject *du_pair(DuObject *cons, DuObject *locals)
+{
+ DuObject *obj;
+ _du_getargs1("pair?", cons, locals, &obj);
+ return DuInt_FromInt(DuCons_Check(obj));
+}
+
DuObject *du_assert(DuObject *cons, DuObject *locals)
{
DuObject *obj;
@@ -627,10 +642,12 @@
DuFrame_SetBuiltinMacro(Du_Globals, "defun", du_defun);
DuFrame_SetBuiltinMacro(Du_Globals, "car", du_car);
DuFrame_SetBuiltinMacro(Du_Globals, "cdr", du_cdr);
+ DuFrame_SetBuiltinMacro(Du_Globals, "cons", du_cons);
DuFrame_SetBuiltinMacro(Du_Globals, "not", du_not);
DuFrame_SetBuiltinMacro(Du_Globals, "transaction", du_transaction);
DuFrame_SetBuiltinMacro(Du_Globals, "sleepms", du_sleepms);
DuFrame_SetBuiltinMacro(Du_Globals, "defined?", du_defined);
+ DuFrame_SetBuiltinMacro(Du_Globals, "pair?", du_pair);
DuFrame_SetBuiltinMacro(Du_Globals, "assert", du_assert);
DuFrame_SetSymbolStr(Du_Globals, "None", Du_None);
}
diff --git a/duhton/listobject.c b/duhton/listobject.c
--- a/duhton/listobject.c
+++ b/duhton/listobject.c
@@ -75,7 +75,7 @@
void _list_append(DuListObject *ob, DuObject *x)
{
- _du_read1(ob);
+ _du_write1(ob);
DuTupleObject *olditems = ob->ob_tuple;
_du_read1(olditems);
@@ -85,8 +85,6 @@
DuTupleObject *newitems = DuTuple_New(newcount);
_du_restore3(ob, x, olditems);
- _du_write1(ob);
-
for (i=0; i<newcount-1; i++)
newitems->ob_items[i] = olditems->ob_items[i];
newitems->ob_items[newcount-1] = x;
diff --git a/duhton/test/test_cons.py b/duhton/test/test_cons.py
--- a/duhton/test/test_cons.py
+++ b/duhton/test/test_cons.py
@@ -5,6 +5,11 @@
assert run("(print ())") == "None\n"
assert run("(print None)") == "None\n"
assert run("(print (quote (1 2 3)))") == "( 1 2 3 )\n"
+ assert run("(print (cons 1 2))") == "( 1 . 2 )\n"
+
+def test_pair():
+ assert run("(print (pair? 1))") == "0\n"
+ assert run("(print (pair? (cons 1 2)))") == "1\n"
def test_car_cdr():
assert run("(print (car (quote (2 3))))") == "2\n"
More information about the pypy-commit
mailing list