[pypy-commit] pypy stmgc-static-barrier: import stmgc/e14cbe1e040b
arigo
noreply at buildbot.pypy.org
Thu Aug 22 21:18:10 CEST 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-static-barrier
Changeset: r66295:98d1111982c2
Date: 2013-08-22 21:16 +0200
http://bitbucket.org/pypy/pypy/changeset/98d1111982c2/
Log: import stmgc/e14cbe1e040b
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
@@ -7,7 +7,6 @@
*/
#include "stmimpl.h"
-#ifdef _GC_DEBUG
char tmp_buf[128];
char* stm_dbg_get_hdr_str(gcptr obj)
{
@@ -27,7 +26,6 @@
cur += sprintf(cur, "tid=%ld", stm_get_tid(obj));
return tmp_buf;
}
-#endif
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
@@ -24,6 +24,53 @@
stm_bytes_to_clear_on_abort = bytes;
}
+
+intptr_t stm_allocate_public_integer_address(gcptr obj)
+{
+ struct tx_descriptor *d = thread_descriptor;
+ gcptr stub;
+ intptr_t result;
+ /* plan: we allocate a small stub whose reference
+ we never give to the caller except in the form
+ of an integer.
+ During major collections, we visit them and update
+ their references. */
+
+ /* we don't want to deal with young objs */
+ if (!(obj->h_tid & GCFLAG_OLD)) {
+ stm_push_root(obj);
+ stm_minor_collect();
+ obj = stm_pop_root();
+ }
+
+ 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;
+ }
+ else {
+ stub->h_original = (revision_t)obj;
+ }
+
+ 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));
+ return result;
+}
+
+
+
+
+
+
/************************************************************/
/* Each object has a h_original pointer to an old copy of
the same object (e.g. an old revision), the "original".
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,6 +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;
+
/* For tests */
long stmgcpage_count(int quantity)
{
@@ -63,6 +66,8 @@
nblocks_for_size[i] =
(GC_PAGE_SIZE - sizeof(page_header_t)) / (WORD * i);
}
+
+ memset(®istered_stubs, 0, sizeof(registered_stubs));
}
void stmgcpage_init_tls(void)
@@ -209,6 +214,34 @@
}
+/***** registering of small stubs as integer addresses *****/
+
+void stm_register_integer_address(intptr_t adr)
+{
+ gcptr obj = (gcptr)adr;
+ assert(obj->h_tid & GCFLAG_SMALLSTUB);
+ assert(obj->h_tid & GCFLAG_PUBLIC);
+
+ stmgcpage_acquire_global_lock();
+ g2l_insert(®istered_stubs, obj, NULL);
+ stmgcpage_release_global_lock();
+ dprintf(("registered %p\n", obj));
+}
+
+void stm_unregister_integer_address(intptr_t adr)
+{
+ gcptr obj = (gcptr)adr;
+ assert(obj->h_tid & GCFLAG_SMALLSTUB);
+ assert(obj->h_tid & GCFLAG_PUBLIC);
+
+ stmgcpage_acquire_global_lock();
+ g2l_delete_item(®istered_stubs, obj);
+ stmgcpage_release_global_lock();
+ dprintf(("unregistered %p\n", obj));
+}
+
+
+
/***** Major collections: marking *****/
static struct GcPtrList objects_to_trace;
@@ -460,6 +493,27 @@
}
}
+static void mark_registered_stubs(void)
+{
+ wlog_t *item;
+ G2L_LOOP_FORWARD(registered_stubs, item) {
+ gcptr R = item->addr;
+ assert(R->h_tid & GCFLAG_SMALLSTUB);
+
+ R->h_tid |= (GCFLAG_MARKED | GCFLAG_VISITED);
+
+ gcptr L = (gcptr)(R->h_revision - 2);
+ L = stmgcpage_visit(L);
+ R->h_revision = ((revision_t)L) | 2;
+
+ /* 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;
+
+}
+
+
static void mark_roots(gcptr *root, gcptr *end)
{
assert(*root == END_MARKER_ON);
@@ -898,6 +952,7 @@
assert(gcptrlist_size(&objects_to_trace) == 0);
mark_prebuilt_roots();
+ mark_registered_stubs();
mark_all_stack_roots();
do {
visit_all_objects();
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 @@
-c7b63aa9d1ad
+e14cbe1e040b
diff --git a/rpython/translator/stm/src_stm/steal.c b/rpython/translator/stm/src_stm/steal.c
--- a/rpython/translator/stm/src_stm/steal.c
+++ b/rpython/translator/stm/src_stm/steal.c
@@ -20,6 +20,59 @@
};
static __thread struct tx_steal_data *steal_data;
+static void replace_ptr_to_immutable_with_stub(gcptr * pobj)
+{
+ gcptr stub, obj = *pobj;
+ assert(obj->h_tid & GCFLAG_IMMUTABLE);
+ assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
+ if (obj->h_tid & GCFLAG_PUBLIC) {
+ /* young public, replace with stolen old copy */
+ assert(obj->h_tid & GCFLAG_MOVED);
+ assert(IS_POINTER(obj->h_revision));
+ stub = (gcptr)obj->h_revision;
+ assert(!IS_POINTER(stub->h_revision)); /* not outdated */
+ goto done;
+ }
+
+ /* old or young protected! mark as PUBLIC */
+ if (!(obj->h_tid & GCFLAG_OLD)) {
+ /* young protected */
+ gcptr O;
+
+ if (obj->h_tid & GCFLAG_HAS_ID) {
+ /* use id-copy for us */
+ O = (gcptr)obj->h_original;
+ obj->h_tid &= ~GCFLAG_HAS_ID;
+ stm_copy_to_old_id_copy(obj, O);
+ O->h_original = 0;
+ } else {
+ O = stmgc_duplicate_old(obj);
+
+ /* young and without original? */
+ if (!(obj->h_original))
+ obj->h_original = (revision_t)O;
+ }
+ obj->h_tid |= (GCFLAG_MOVED | GCFLAG_PUBLIC);
+ obj->h_revision = (revision_t)O;
+
+ O->h_tid |= GCFLAG_PUBLIC;
+ /* here it is fine if it stays in read caches because
+ the object is immutable anyway and there are no
+ write_barriers allowed. */
+ dprintf(("steal prot immutable -> public: %p -> %p\n", obj, O));
+ stub = O;
+ goto done;
+ }
+ /* old protected: */
+ dprintf(("prot immutable -> public: %p\n", obj));
+ obj->h_tid |= GCFLAG_PUBLIC;
+
+ return;
+ done:
+ *pobj = stub;
+ dprintf((" stolen: fixing *%p: %p -> %p\n", pobj, obj, stub));
+}
+
static void replace_ptr_to_protected_with_stub(gcptr *pobj)
{
gcptr stub, obj = *pobj;
@@ -28,49 +81,7 @@
return;
if (obj->h_tid & GCFLAG_IMMUTABLE) {
- assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
- if (obj->h_tid & GCFLAG_PUBLIC) {
- /* young public, replace with stolen old copy */
- assert(obj->h_tid & GCFLAG_MOVED);
- assert(IS_POINTER(obj->h_revision));
- stub = (gcptr)obj->h_revision;
- assert(!IS_POINTER(stub->h_revision)); /* not outdated */
- goto done;
- }
-
- /* old or young protected! mark as PUBLIC */
- if (!(obj->h_tid & GCFLAG_OLD)) {
- /* young protected */
- gcptr O;
-
- if (obj->h_tid & GCFLAG_HAS_ID) {
- /* use id-copy for us */
- O = (gcptr)obj->h_original;
- obj->h_tid &= ~GCFLAG_HAS_ID;
- stm_copy_to_old_id_copy(obj, O);
- O->h_original = 0;
- } else {
- O = stmgc_duplicate_old(obj);
-
- /* young and without original? */
- if (!(obj->h_original))
- obj->h_original = (revision_t)O;
- }
- obj->h_tid |= (GCFLAG_MOVED | GCFLAG_PUBLIC);
- obj->h_revision = (revision_t)O;
-
- O->h_tid |= GCFLAG_PUBLIC;
- /* here it is fine if it stays in read caches because
- the object is immutable anyway and there are no
- write_barriers allowed. */
- dprintf(("steal prot immutable -> public: %p -> %p\n", obj, O));
- stub = O;
- goto done;
- }
- /* old protected: */
- dprintf(("prot immutable -> public: %p\n", obj));
- obj->h_tid |= GCFLAG_PUBLIC;
-
+ replace_ptr_to_immutable_with_stub(pobj);
return;
}
diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -29,12 +29,21 @@
#define PREBUILT_REVISION 1
+/* push roots around allocating functions! */
+
/* allocate an object out of the local nursery */
gcptr stm_allocate(size_t size, unsigned long tid);
/* allocate an object that is be immutable. it cannot be changed with
a stm_write_barrier() or after the next commit */
gcptr stm_allocate_immutable(size_t size, unsigned long tid);
+/* allocates a public reference to the object that will
+ not be freed until stm_unregister_integer_address is
+ called on the result */
+intptr_t stm_allocate_public_integer_address(gcptr);
+void stm_unregister_integer_address(intptr_t);
+
+
/* returns a never changing hash for the object */
revision_t stm_hash(gcptr);
/* returns a number for the object which is unique during its lifetime */
@@ -172,6 +181,8 @@
extern __thread void *stm_to_clear_on_abort;
extern __thread size_t stm_bytes_to_clear_on_abort;
+/* only user currently is stm_allocate_public_integer_address() */
+void stm_register_integer_address(intptr_t);
/* macro functionality */
More information about the pypy-commit
mailing list