Author: Remi Meier <[email protected]>
Branch: stmgc-c4
Changeset: r67599:a4d501389912
Date: 2013-10-25 14:33 +0200
http://bitbucket.org/pypy/pypy/changeset/a4d501389912/
Log: import stmgc with better constptr allocation
diff --git a/rpython/translator/stm/src_stm/et.c
b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -1550,8 +1550,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/rpython/translator/stm/src_stm/extra.c
b/rpython/translator/stm/src_stm/extra.c
--- a/rpython/translator/stm/src_stm/extra.c
+++ b/rpython/translator/stm/src_stm/extra.c
@@ -86,24 +86,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/rpython/translator/stm/src_stm/gcpage.c
b/rpython/translator/stm/src_stm/gcpage.c
--- a/rpython/translator/stm/src_stm/gcpage.c
+++ b/rpython/translator/stm/src_stm/gcpage.c
@@ -23,8 +23,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)
@@ -67,7 +68,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)
@@ -219,27 +220,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 */
}
@@ -496,34 +520,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;
}
@@ -962,7 +992,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/rpython/translator/stm/src_stm/revision
b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-d92fcb9e5246
+ba0819e4b5e7
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit