Author: Remi Meier <remi.me...@gmail.com> Branch: Changeset: r548:68677625f2be Date: 2013-11-18 11:19 +0100 http://bitbucket.org/pypy/stmgc/changeset/68677625f2be/
Log: fix public ints (usage of public h_originals is not always right, they need to be PREBUILT_ORIGINALs to be sure...) diff --git a/c4/demo_random.c b/c4/demo_random.c --- a/c4/demo_random.c +++ b/c4/demo_random.c @@ -278,8 +278,7 @@ gcptr obj = (gcptr)ip; assert(obj->h_tid & GCFLAG_PUBLIC); assert((obj->h_tid & GCFLAG_SMALLSTUB) - || (obj->h_original == 0 - || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)); + || (obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)); check(obj); if (obj->h_revision & 2) check((gcptr)(obj->h_revision - 2)); @@ -304,7 +303,9 @@ if (td.num_public_ints == 0) return; + push_roots(); stm_unregister_integer_address(td.public_ints[--td.num_public_ints]); + pop_roots(); } gcptr read_barrier(gcptr p) diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -138,6 +138,7 @@ d->count_reads++; assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), stmgc_is_in_nursery(d, P))); + assert(G->h_revision != 0); restart_all: if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) @@ -355,7 +356,7 @@ assert(P->h_tid & GCFLAG_PUBLIC); assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), stmgc_is_in_nursery(thread_descriptor, P))); - + assert(P->h_revision != 0); revision_t v = ACCESS_ONCE(P->h_revision); assert(IS_POINTER(v)); /* "is a pointer", "has a more recent revision" */ @@ -660,6 +661,7 @@ gcptr stm_RepeatWriteBarrier(gcptr P) { + assert(P->h_revision != 0); assert(IMPLIES(!(P->h_tid & GCFLAG_OLD), stmgc_is_in_nursery(thread_descriptor, P))); @@ -673,6 +675,7 @@ gcptr stm_WriteBarrier(gcptr P) { + assert(P->h_revision != 0); assert(!(P->h_tid & GCFLAG_IMMUTABLE)); assert((P->h_tid & GCFLAG_STUB) || stmgc_size(P) > sizeof(struct stm_stub_s) - WORD); diff --git a/c4/extra.c b/c4/extra.c --- a/c4/extra.c +++ b/c4/extra.c @@ -65,7 +65,7 @@ intptr_t stm_allocate_public_integer_address(gcptr obj) -{ +{ /* push roots! */ struct tx_descriptor *d = thread_descriptor; gcptr stub; intptr_t result; @@ -75,6 +75,12 @@ During major collections, we visit them and update their references. */ + /* stm_register_integer_address needs to run in inevitable + transaction */ + stm_push_root(obj); + stm_become_inevitable("stm_allocate_public_integer_address"); + obj = stm_pop_root(); + /* we don't want to deal with young objs */ if (!(obj->h_tid & GCFLAG_OLD)) { stm_push_root(obj); @@ -93,9 +99,11 @@ orig = (gcptr)obj->h_original; } - if (orig->h_tid & GCFLAG_PUBLIC) { - /* the original is public, so we can take that as a non-movable - object to register */ + if ((orig->h_tid & (GCFLAG_PUBLIC | GCFLAG_PREBUILT_ORIGINAL)) + == (GCFLAG_PUBLIC | GCFLAG_PREBUILT_ORIGINAL)) { + /* public is not enough as public stubs may get replaced + by the protected object they point to, if they are in the + same thread (I think...) */ result = (intptr_t)orig; } else { @@ -115,9 +123,11 @@ result = (intptr_t)stub; } spinlock_release(d->public_descriptor->collection_lock); + + dprintf(("allocate_public_int_adr(%p): %p", obj, (void*)result)); + stm_register_integer_address(result); - dprintf(("allocate_public_int_adr(%p): %p", obj, (void*)result)); return result; } diff --git a/c4/gcpage.c b/c4/gcpage.c --- a/c4/gcpage.c +++ b/c4/gcpage.c @@ -218,10 +218,11 @@ /***** registering of small stubs as integer addresses *****/ void stm_register_integer_address(intptr_t adr) -{ +{ /* needs to be inevitable! */ wlog_t *found; gcptr obj = (gcptr)adr; /* current limitations for 'adr': smallstub or h_original */ + assert(stm_active == 2); assert((obj->h_tid & GCFLAG_SMALLSTUB) || (obj->h_original == 0 || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)); assert(obj->h_tid & GCFLAG_PUBLIC); @@ -241,7 +242,7 @@ } void stm_unregister_integer_address(intptr_t adr) -{ +{ /* push roots! */ wlog_t *found; gcptr obj = (gcptr)adr; @@ -249,6 +250,11 @@ || (obj->h_original == 0 || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)); assert(obj->h_tid & GCFLAG_PUBLIC); + /* become inevitable because we would have to re-register them + on abort, but make sure only to re-register if not registered + in the same aborted transaction (XXX) */ + stm_become_inevitable("stm_unregister_integer_address()"); + stmgcpage_acquire_global_lock(); /* find and decrement refcount */ @@ -527,12 +533,18 @@ G2L_LOOP_FORWARD(registered_objs, item) { gcptr R = item->addr; assert(R->h_tid & GCFLAG_PUBLIC); - - if ((R->h_original == 0) || (R->h_tid & GCFLAG_PREBUILT_ORIGINAL)) { - /* the obj is an original and will therefore survive: */ - gcptr V = stmgcpage_visit(R); - assert(V == R); + + if (R->h_tid & GCFLAG_PREBUILT_ORIGINAL) { + /* already done by mark_prebuilt_roots */ + assert((R->h_tid & (GCFLAG_MARKED|GCFLAG_VISITED|GCFLAG_PUBLIC)) + == (GCFLAG_MARKED|GCFLAG_VISITED|GCFLAG_PUBLIC)); + continue; } + /* else if (R->h_original == 0) { */ + /* /\* the obj is an original and will therefore survive: *\/ */ + /* gcptr V = visit_public(R, NULL); */ + /* assert(V == R); */ + /* } */ else { assert(R->h_tid & GCFLAG_SMALLSTUB); /* only case for now */ /* make sure R stays valid: */ diff --git a/c4/stmgc.h b/c4/stmgc.h --- a/c4/stmgc.h +++ b/c4/stmgc.h @@ -40,7 +40,7 @@ not be freed until stm_unregister_integer_address is called on the result (push roots!) */ intptr_t stm_allocate_public_integer_address(gcptr); -void stm_unregister_integer_address(intptr_t); +void stm_unregister_integer_address(intptr_t); /* push roots too! */ /* returns a never changing hash for the object */ @@ -193,6 +193,7 @@ void stm_call_on_abort(void *key, void callback(void *)); /* only user currently is stm_allocate_public_integer_address() */ +/* needs to be in an inevitable transaction! */ void stm_register_integer_address(intptr_t); /* enter single-threaded mode. Used e.g. when patching assembler _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit