[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(&registered_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(&registered_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(&registered_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