Author: Remi Meier <meier...@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" _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit