Author: Remi Meier <[email protected]>
Branch:
Changeset: r540:ba0819e4b5e7
Date: 2013-10-25 12:38 +0200
http://bitbucket.org/pypy/stmgc/changeset/ba0819e4b5e7/
Log: make allocate_public_integer_address use the h_original (not always
allocate stubs) if it is already public
diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -276,9 +276,14 @@
intptr_t ip = td.public_ints[i];
gcptr obj = (gcptr)ip;
assert(obj->h_tid & GCFLAG_PUBLIC);
- assert(obj->h_tid & GCFLAG_SMALLSTUB);
+ assert((obj->h_tid & GCFLAG_SMALLSTUB)
+ || (obj->h_original == 0
+ || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
check(obj);
- check((gcptr)(obj->h_revision - 2));
+ if (obj->h_revision & 2)
+ check((gcptr)(obj->h_revision - 2));
+ else if ((obj->h_revision & 3) == 0)
+ check((gcptr)(obj->h_revision));
}
}
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1549,8 +1549,8 @@
a transaction) */
/* XXX */
- fprintf(stderr, "[%lx] inevitable: %s\n",
- (long)d->public_descriptor_index, why);
+ /* fprintf(stderr, "[%lx] inevitable: %s\n", */
+ /* (long)d->public_descriptor_index, why); */
dprintf(("[%lx] inevitable: %s\n",
(long)d->public_descriptor_index, why));
diff --git a/c4/extra.c b/c4/extra.c
--- a/c4/extra.c
+++ b/c4/extra.c
@@ -85,24 +85,39 @@
spinlock_acquire(d->public_descriptor->collection_lock, 'P');
- stub = stm_stub_malloc(d->public_descriptor, 0);
- stub->h_tid = (obj->h_tid & STM_USER_TID_MASK)
- | GCFLAG_PUBLIC | GCFLAG_STUB | GCFLAG_SMALLSTUB
- | GCFLAG_OLD;
-
- stub->h_revision = ((revision_t)obj) | 2;
- if (!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL) && obj->h_original) {
- stub->h_original = obj->h_original;
+ /* it must have a h_original */
+ gcptr orig;
+ if (obj->h_original == 0 || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL) {
+ orig = obj;
+ } else {
+ 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 */
+ result = (intptr_t)orig;
}
else {
- stub->h_original = (revision_t)obj;
+ stub = stm_stub_malloc(d->public_descriptor, 0);
+ stub->h_tid = (obj->h_tid & STM_USER_TID_MASK)
+ | GCFLAG_PUBLIC | GCFLAG_STUB | GCFLAG_SMALLSTUB
+ | GCFLAG_OLD;
+
+ stub->h_revision = ((revision_t)obj) | 2;
+ if (!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL) && obj->h_original) {
+ stub->h_original = obj->h_original;
+ }
+ else {
+ stub->h_original = (revision_t)obj;
+ }
+
+ result = (intptr_t)stub;
}
-
- result = (intptr_t)stub;
spinlock_release(d->public_descriptor->collection_lock);
stm_register_integer_address(result);
- dprintf(("allocate_public_int_adr(%p): %p", obj, stub));
+ 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
@@ -22,8 +22,9 @@
/* Only computed during a major collection */
static size_t mc_total_in_use, mc_total_reserved;
-/* keeps track of registered smallstubs that will survive unless unregistered
*/
-static struct G2L registered_stubs;
+/* keeps track of registered *public* objects that will survive
+unless unregistered. For now, only smallstubs and h_originals allowed */
+static struct G2L registered_objs;
/* For tests */
long stmgcpage_count(int quantity)
@@ -66,7 +67,7 @@
(GC_PAGE_SIZE - sizeof(page_header_t)) / (WORD * i);
}
- memset(®istered_stubs, 0, sizeof(registered_stubs));
+ memset(®istered_objs, 0, sizeof(registered_objs));
}
void stmgcpage_init_tls(void)
@@ -218,27 +219,50 @@
void stm_register_integer_address(intptr_t adr)
{
+ wlog_t *found;
gcptr obj = (gcptr)adr;
- assert(obj->h_tid & GCFLAG_SMALLSTUB);
+ /* current limitations for 'adr': smallstub or h_original */
+ assert((obj->h_tid & GCFLAG_SMALLSTUB)
+ || (obj->h_original == 0 || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
assert(obj->h_tid & GCFLAG_PUBLIC);
stmgcpage_acquire_global_lock();
- g2l_insert(®istered_stubs, obj, NULL);
+
+ /* find and increment refcount; or insert */
+ G2L_FIND(registered_objs, obj, found, goto not_found);
+ found->val = (gcptr)(((revision_t)found->val) + 1);
+ goto finish;
+ not_found:
+ g2l_insert(®istered_objs, obj, (gcptr)1);
+
+ finish:
stmgcpage_release_global_lock();
dprintf(("registered %p\n", obj));
}
void stm_unregister_integer_address(intptr_t adr)
{
+ wlog_t *found;
gcptr obj = (gcptr)adr;
- assert(obj->h_tid & GCFLAG_SMALLSTUB);
+
+ assert((obj->h_tid & GCFLAG_SMALLSTUB)
+ || (obj->h_original == 0 || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
assert(obj->h_tid & GCFLAG_PUBLIC);
stmgcpage_acquire_global_lock();
- int deleted = g2l_delete_item(®istered_stubs, obj);
- assert(deleted);
+
+ /* find and decrement refcount */
+ G2L_FIND(registered_objs, obj, found, goto not_found);
+ found->val = (gcptr)(((revision_t)found->val) - 1);
+ if (found->val == NULL)
+ found->addr = NULL; /* delete it */
+
stmgcpage_release_global_lock();
dprintf(("unregistered %p\n", obj));
+ return;
+
+ not_found:
+ assert(0); /* unmatched unregister */
}
@@ -495,34 +519,40 @@
}
}
-static void mark_registered_stubs(void)
+static void mark_registered_objs(void)
{
wlog_t *item;
gcptr L;
- G2L_LOOP_FORWARD(registered_stubs, item) {
+ G2L_LOOP_FORWARD(registered_objs, item) {
gcptr R = item->addr;
- assert(R->h_tid & GCFLAG_SMALLSTUB);
- /* The following assert can fail if we have a stub pointing to
- a stub and both are registered_stubs. This case is benign. */
- //assert(!(R->h_tid & (GCFLAG_VISITED | GCFLAG_MARKED)));
+ assert(R->h_tid & GCFLAG_PUBLIC);
- R->h_tid |= (GCFLAG_MARKED | GCFLAG_VISITED);
-
- if (R->h_revision & 2) {
- L = (gcptr)(R->h_revision - 2);
- L = stmgcpage_visit(L);
- R->h_revision = ((revision_t)L) | 2;
+ 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);
}
else {
- L = (gcptr)R->h_revision;
- L = stmgcpage_visit(L);
- R->h_revision = (revision_t)L;
+ assert(R->h_tid & GCFLAG_SMALLSTUB); /* only case for now */
+ /* make sure R stays valid: */
+ R->h_tid |= (GCFLAG_MARKED | GCFLAG_VISITED);
+
+ if (R->h_revision & 2) {
+ L = (gcptr)(R->h_revision - 2);
+ L = stmgcpage_visit(L);
+ R->h_revision = ((revision_t)L) | 2;
+ }
+ else {
+ L = (gcptr)R->h_revision;
+ L = stmgcpage_visit(L);
+ R->h_revision = (revision_t)L;
+ }
+
+ /* h_original will be kept up-to-date because
+ it is either == L or L's h_original. And
+ h_originals don't move */
}
-
- /* h_original will be kept up-to-date because
- it is either == L or L's h_original. And
- h_originals don't move */
} G2L_LOOP_END;
}
@@ -961,7 +991,7 @@
assert(gcptrlist_size(&objects_to_trace) == 0);
mark_prebuilt_roots();
- mark_registered_stubs();
+ mark_registered_objs();
mark_all_stack_roots();
/* weakrefs: */
diff --git a/c4/test/test_extra.py b/c4/test/test_extra.py
--- a/c4/test/test_extra.py
+++ b/c4/test/test_extra.py
@@ -230,7 +230,9 @@
# we have stubs here:
assert ffi.cast("gcptr", p1p).h_tid & GCFLAG_PUBLIC
- assert classify(ffi.cast("gcptr", p1p)) == 'stub'
+ p1pp = ffi.cast("gcptr", p1p)
+ assert p1 == p1pp
+ assert classify(p1pp) == 'public'
assert classify(ffi.cast("gcptr", p2p)) == 'stub'
assert classify(ffi.cast("gcptr", p3p)) == 'stub'
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit