Author: Armin Rigo <[email protected]>
Branch: stm-thread-2
Changeset: r57154:952723b65bd2
Date: 2012-09-05 17:50 +0200
http://bitbucket.org/pypy/pypy/changeset/952723b65bd2/

Log:    In-progress

diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -1,6 +1,6 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, llarena, llgroup
 from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.rpython.lltypesystem.llmemory import raw_malloc_usage
+from pypy.rpython.lltypesystem.llmemory import raw_malloc_usage, raw_memcopy
 from pypy.rpython.memory.gc.base import GCBase, MovingGCBase
 from pypy.rpython.memory.support import mangle_hash
 from pypy.rpython.annlowlevel import llhelper
@@ -174,11 +174,9 @@
         self.nursery_size = nursery_size
         self.sharedarea = stmshared.StmGCSharedArea(self)
         #
-        def _stm_getsize(obj):     # indirection to hide 'self'
-            return self.get_size(obj)
-        self._stm_getsize = _stm_getsize
-        #
-        self.declare_write_barrier()
+        def _stm_duplicate(obj):     # indirection to hide 'self'
+            return self.stm_duplicate(obj)
+        self._stm_duplicate = _stm_duplicate
 
     def setup(self):
         """Called at run-time to initialize the GC."""
@@ -307,134 +305,26 @@
         flags |= GCFLAG_GLOBAL
         self.init_gc_object(addr, typeid16, flags)
 
-    # ----------
-
-##    TURNED OFF, maybe temporarily: the following logic is now entirely
-##    done by C macros and functions.
-##
-##    def declare_reader(self, size, TYPE):
-##        # Reading functions.  Defined here to avoid the extra burden of
-##        # passing 'self' explicitly.
-##        assert rffi.sizeof(TYPE) == size
-##        PTYPE = rffi.CArrayPtr(TYPE)
-##        stm_read_int = getattr(self.stm_operations, 'stm_read_int%d' % size)
-##        #
-##        @always_inline
-##        def reader(obj, offset):
-##            if self.header(obj).tid & GCFLAG_GLOBAL == 0:
-##                adr = rffi.cast(PTYPE, obj + offset)
-##                return adr[0]                      # local obj: read directly
-##            else:
-##                return stm_read_int(obj, offset)   # else: call a helper
-##        setattr(self, 'read_int%d' % size, reader)
-##        #
-##        @dont_inline
-##        def _read_word_global(obj, offset):
-##            hdr = self.header(obj)
-##            if hdr.tid & GCFLAG_WAS_COPIED != 0:
-##                #
-##                # Look up in the thread-local dictionary.
-##                localobj = stm_operations.tldict_lookup(obj)
-##                if localobj:
-##                    ll_assert(self.header(localobj).tid & GCFLAG_GLOBAL == 0,
-##                              "stm_read: tldict_lookup() -> GLOBAL obj")
-##                    return (localobj + offset).signed[0]
-##            #
-##            return stm_operations.stm_read_word(obj, offset)
-
-
-    def declare_write_barrier(self):
-        # Write barrier.  Defined here to avoid the extra burden of
-        # passing 'self' explicitly.
-        stm_operations = self.stm_operations
+    def stm_duplicate(self, obj):
+        size_gc_header = self.gcheaderbuilder.size_gc_header
+        size = self.get_size(obj)
+        totalsize = size_gc_header + size
+        tls = self.get_tls()
+        try:
+            localobj = tls.malloc_local_copy(totalsize)
+        except MemoryError:
+            # should not really let the exception propagate.
+            # XXX do something slightly better, like abort the transaction
+            # and raise a MemoryError when retrying
+            fatalerror("FIXME: MemoryError in stm_duplicate")
+            return llmemory.NULL
         #
-        @always_inline
-        def stm_writebarrier(obj):
-            """The write barrier must be called on any object that may be
-            a global.  It looks for, and possibly makes, a local copy of
-            this object.  The result of this call is the local copy ---
-            or 'obj' itself if it is already local.
-            """
-            if self.header(obj).tid & GCFLAG_GLOBAL != 0:
-                obj = _stm_write_barrier_global(obj)
-            return obj
-        self.stm_writebarrier = stm_writebarrier
-        #
-        @dont_inline
-        def _stm_write_barrier_global(obj):
-            # find or make a local copy of the global object
-            hdr = self.header(obj)
-            if hdr.tid & GCFLAG_WAS_COPIED == 0:
-                #
-                # in this case, we are sure that we don't have a copy
-                hdr.tid |= GCFLAG_WAS_COPIED
-                # ^^^ non-protected write, but concurrent writes should
-                #     have the same effect, so fine
-            else:
-                # in this case, we need to check first
-                localobj = stm_operations.tldict_lookup(obj)
-                if localobj:
-                    hdr = self.header(localobj)
-                    ll_assert(hdr.tid & GCFLAG_GLOBAL == 0,
-                              "stm_write: tldict_lookup() -> GLOBAL obj")
-                    ll_assert(hdr.tid & GCFLAG_WAS_COPIED != 0,
-                              "stm_write: tldict_lookup() -> non-COPIED obj")
-                    return localobj
-            #
-            # Here, we need to really make a local copy
-            size = self.get_size(obj)
-            totalsize = self.gcheaderbuilder.size_gc_header + size
-            tls = self.get_tls()
-            try:
-                localobj = tls.malloc_local_copy(totalsize)
-            except MemoryError:
-                # should not really let the exception propagate.
-                # XXX do something slightly better, like abort the transaction
-                # and raise a MemoryError when retrying
-                fatalerror("FIXME: MemoryError in _stm_write_barrier_global")
-                return llmemory.NULL
-            #
-            # Initialize the copy by doing an stm raw copy of the bytes
-            stm_operations.stm_copy_transactional_to_raw(obj, localobj, size)
-            #
-            # The raw copy done above does not include the header fields.
-            hdr = self.header(obj)
-            localhdr = self.header(localobj)
-            GCFLAGS = (GCFLAG_GLOBAL | GCFLAG_WAS_COPIED | GCFLAG_VISITED)
-            ll_assert(hdr.tid & GCFLAGS == (GCFLAG_GLOBAL | GCFLAG_WAS_COPIED),
-                      "stm_write: bogus flags on source object")
-            #
-            # Remove the GCFLAG_GLOBAL from the copy, and add GCFLAG_VISITED
-            localhdr.tid = hdr.tid + (GCFLAG_VISITED - GCFLAG_GLOBAL)
-            #
-            # Set the 'version' field of the local copy to be a pointer
-            # to the global obj.  (The field is called 'version' because
-            # of its use by the C STM library: on global objects (only),
-            # it is a version number.)
-            localhdr.version = obj
-            #
-            # Register the object as a valid copy
-            stm_operations.tldict_add(obj, localobj)
-            #
-            return localobj
-        self._stm_write_barrier_global = _stm_write_barrier_global
-        #
-        def stm_normalize_global(obj):
-            """Normalize a pointer for the purpose of equality
-            comparison with another pointer.  If 'obj' is the local
-            version of an existing global object, then returns the
-            global object.  Don't use for e.g. hashing, because if 'obj'
-            is a local object, it just returns 'obj' --- even for nursery
-            objects, which move at the next local collection.
-            """
-            if not obj:
-                return obj
-            tid = self.header(obj).tid
-            if tid & (GCFLAG_GLOBAL|GCFLAG_WAS_COPIED) != GCFLAG_WAS_COPIED:
-                return obj
-            # the only relevant case: it's the local copy of a global object
-            return self.header(obj).version
-        self.stm_normalize_global = stm_normalize_global
+        # Initialize the copy by doing a memcpy of the bytes.
+        # The object header of localobj will then be fixed by the C code.
+        llmemory.raw_memcopy(obj - size_gc_header,
+                             localobj - size_gc_header,
+                             totalsize)
+        return localobj
 
     # ----------
     # id() and identityhash() support
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py 
b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -26,11 +26,10 @@
     # any use of 'self._gc' is wrong here: it's stmgc.py that should call
     # et.c, and not the other way around.
 
-    PRIMITIVE_SIZES = {1: lltype.Char,
-                       WORD: lltype.Signed}
     CALLBACK_ENUM = lltype.Ptr(lltype.FuncType([llmemory.Address] * 3,
                                                lltype.Void))
-    GETSIZE  = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
+    DUPLICATE = lltype.Ptr(lltype.FuncType([llmemory.Address],
+                                           llmemory.Address))
 
     threadnum = 0          # 0 = main thread; 1,2,3... = transactional threads
 
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -645,7 +645,7 @@
       if (P->h_tid & GCFLAG_GLOBAL)
         P = LatestGlobalRevision(d, P, NULL, 0);
       else
-        P = (gcptr)P->h_revision;    // return the original global obj
+        P = (gcptr)P->h_revision; // LOCAL_COPY: return the original global obj
     }
   return P;
 }
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -83,8 +83,8 @@
 //gcptr _NonTransactionalReadBarrier(gcptr);
 
 
-extern gcptr pypy_g__stm_duplicate(gcptr);
-extern void pypy_g__stm_enum_callback(void *, gcptr, gcptr);
+extern void *pypy_g__stm_duplicate(void *);
+extern void pypy_g__stm_enum_callback(void *, void *, void *);
 void stm_set_tls(void *newtls);
 void *stm_get_tls(void);
 void stm_del_tls(void);
diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py
--- a/pypy/translator/stm/stmgcintf.py
+++ b/pypy/translator/stm/stmgcintf.py
@@ -29,8 +29,8 @@
 
     CALLBACK_TX     = lltype.Ptr(lltype.FuncType([rffi.VOIDP, lltype.Signed],
                                                  lltype.Signed))
-    GETSIZE         = lltype.Ptr(lltype.FuncType([llmemory.Address],
-                                                 lltype.Signed))
+    DUPLICATE       = lltype.Ptr(lltype.FuncType([llmemory.Address],
+                                                 llmemory.Address))
     CALLBACK_ENUM   = lltype.Ptr(lltype.FuncType([llmemory.Address]*3,
                                                  lltype.Void))
 
@@ -44,44 +44,25 @@
                                           [], lltype.Signed)
     add_atomic = smexternal('stm_add_atomic', [lltype.Signed], lltype.Void)
     get_atomic = smexternal('stm_get_atomic', [], lltype.Signed)
-    descriptor_init = smexternal('stm_descriptor_init', [], lltype.Signed)
-    descriptor_done = smexternal('stm_descriptor_done', [], lltype.Void)
+    descriptor_init = smexternal('DescriptorInit', [], lltype.Signed)
+    descriptor_done = smexternal('DescriptorDone', [], lltype.Void)
     begin_inevitable_transaction = smexternal(
-        'stm_begin_inevitable_transaction', [], lltype.Void)
+        'BeginInevitableTransaction', [], lltype.Void)
     commit_transaction = smexternal(
-        'stm_commit_transaction', [], lltype.Void)
+        'CommitTransaction', [], lltype.Void)
     perform_transaction = smexternal('stm_perform_transaction',
                                      [CALLBACK_TX, rffi.VOIDP, 
llmemory.Address],
                                      lltype.Void)
 
-    # for the GC: store and read a thread-local-storage field, as well
-    # as initialize and shut down the internal thread_descriptor
+    # for the GC: store and read a thread-local-storage field
     set_tls = smexternal('stm_set_tls', [llmemory.Address], lltype.Void)
     get_tls = smexternal('stm_get_tls', [], llmemory.Address)
     del_tls = smexternal('stm_del_tls', [], lltype.Void)
 
-    # lookup, add, and enumerate the content of the internal dictionary
-    # that maps GLOBAL objects to LOCAL objects
-    tldict_lookup = smexternal('stm_tldict_lookup', [llmemory.Address],
-                               llmemory.Address)
-    tldict_add = smexternal('stm_tldict_add', [llmemory.Address] * 2,
-                            lltype.Void)
+    # calls FindRootsForLocalCollect() and invokes for each such root
+    # the callback set in CALLBACK_ENUM.
     tldict_enum = smexternal('stm_tldict_enum', [], lltype.Void)
 
-    # reader functions, to call if the object is GLOBAL
-    for _size, _TYPE in PRIMITIVE_SIZES.items():
-        _name = 'stm_read_int%s' % _size
-        locals()[_name] = smexternal(_name, [llmemory.Address, lltype.Signed],
-                                     _TYPE)
-
-    # a special reader function that copies all the content of the object
-    # somewhere else
-    stm_copy_transactional_to_raw = smexternal('stm_copy_transactional_to_raw',
-                                               [llmemory.Address,
-                                                llmemory.Address,
-                                                lltype.Signed],
-                                               lltype.Void)
-
     # sets the transaction length, after which should_break_transaction()
     # returns True
     set_transaction_length = smexternal('stm_set_transaction_length',
diff --git a/pypy/translator/stm/test/test_stmgcintf.c 
b/pypy/translator/stm/test/test_stmgcintf.c
--- a/pypy/translator/stm/test/test_stmgcintf.c
+++ b/pypy/translator/stm/test/test_stmgcintf.c
@@ -34,13 +34,13 @@
 gcptr (*cb_duplicate)(gcptr);
 void (*cb_enum_callback)(void *, gcptr, gcptr);
 
-gcptr pypy_g__stm_duplicate(gcptr a) {
+void *pypy_g__stm_duplicate(void *a) {
     assert(cb_duplicate != NULL);
-    return cb_duplicate(a);
+    return cb_duplicate((gcptr)a);
 }
-void pypy_g__stm_enum_callback(void *a, gcptr b, gcptr c) {
+void pypy_g__stm_enum_callback(void *a, void *b, void *c) {
     assert(cb_enum_callback != NULL);
-    cb_enum_callback(a, b, c);
+    cb_enum_callback(a, (gcptr)b, (gcptr)c);
 }
 
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to