[pypy-commit] stmgc default: fix public ints (usage of public h_originals is not always right, they
Raemi
noreply at buildbot.pypy.org
Mon Nov 18 11:20:03 CET 2013
Author: Remi Meier <remi.meier at 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
More information about the pypy-commit
mailing list