[pypy-commit] pypy stm-gc: Writing code before tests: trying to write something in order to have

arigo noreply at buildbot.pypy.org
Thu Mar 22 16:32:49 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r53901:909e01366467
Date: 2012-03-22 15:54 +0100
http://bitbucket.org/pypy/pypy/changeset/909e01366467/

Log:	Writing code before tests: trying to write something in order to
	have a clue about where to go from here. Seems that the idea can
	work.

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
@@ -102,7 +102,7 @@
     def _free_nursery(self, nursery):
         llarena.arena_free(nursery)
 
-    def setup_thread(self, in_main_thread):
+    def setup_thread(self, in_main_thread=False):
         """Setup a thread.  Allocates the thread-local data structures.
         Must be called only once per OS-level thread."""
         tls = lltype.malloc(self.GCTLS, zero=True, flavor='raw')
@@ -123,9 +123,6 @@
             tls.malloc_flags = -1   # don't malloc outside a transaction!
         return tls
 
-    def _setup_secondary_thread(self):
-        self.setup_thread(False)
-
     @staticmethod
     def reset_nursery(tls):
         """Clear and forget all locally allocated objects."""
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
--- a/pypy/rpython/memory/gctransform/stmframework.py
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -1,19 +1,30 @@
 from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer
 from pypy.rpython.memory.gctransform.framework import BaseRootWalker
+from pypy.rpython.memory.gctransform.framework import sizeofaddr
 from pypy.rpython.lltypesystem import llmemory
 from pypy.annotation import model as annmodel
+from pypy.rlib.debug import fatalerror_notb
 
 
 class StmFrameworkGCTransformer(FrameworkGCTransformer):
 
     def _declare_functions(self, GCClass, getfn, s_gc, *args):
+        #
+        def setup_thread(gc):
+            self.root_walker.allocate_shadow_stack()
+            gc.setup_thread()
+        #
+        def teardown_thread(gc):
+            gc.teardown_thread()
+            self.root_walker.free_shadow_stack()
+        #
         super(StmFrameworkGCTransformer, self)._declare_functions(
             GCClass, getfn, s_gc, *args)
         self.setup_secondary_thread_ptr = getfn(
-            GCClass._setup_secondary_thread.im_func,
+            setup_thread,
             [s_gc], annmodel.s_None)
         self.teardown_thread_ptr = getfn(
-            GCClass.teardown_thread.im_func,
+            teardown_thread,
             [s_gc], annmodel.s_None)
         self.stm_writebarrier_ptr = getfn(
             self.gcdata.gc.stm_writebarrier,
@@ -28,14 +39,8 @@
             self.gcdata.gc.commit_transaction.im_func,
             [s_gc], annmodel.s_None)
 
-    def push_roots(self, hop, keep_current_args=False):
-        pass
-
-    def pop_roots(self, hop, livevars):
-        pass
-
     def build_root_walker(self):
-        return StmStackRootWalker(self)
+        return StmShadowStackRootWalker(self)
 
     def gct_stm_descriptor_init(self, hop):
         hop.genop("direct_call", [self.setup_secondary_thread_ptr,
@@ -69,7 +74,73 @@
         hop.genop("direct_call", [self.stm_commit_ptr, self.c_const_gc])
 
 
-class StmStackRootWalker(BaseRootWalker):
+class StmShadowStackRootWalker(BaseRootWalker):
+    need_root_stack = True
+    root_stack_depth = 163840
+
+    def __init__(self, gctransformer):
+        from pypy.rpython.memory.gctransform import shadowstack
+        #
+        BaseRootWalker.__init__(self, gctransformer)
+        # we use the thread-local self.stackgcdata to store state;
+        # 'self' is frozen.
+        STACKGCDATA = lltype.Struct('STACKGCDATA',
+            ('root_stack_top',  llmemory.Address),
+            ('root_stack_base', llmemory.Address),
+            hints={'stm_thread_local': True})
+        stackgcdata = lltype.malloc(STACKGCDATA, immortal=True)
+        self.stackgcdata = stackgcdata
+
+        def incr_stack(n):
+            top = stackgcdata.root_stack_top
+            stackgcdata.root_stack_top = top + n*sizeofaddr
+            return top
+        self.incr_stack = incr_stack
+
+        def decr_stack(n):
+            top = stackgcdata.root_stack_top - n*sizeofaddr
+            stackgcdata.root_stack_top = top
+            return top
+        self.decr_stack = decr_stack
+
+        root_iterator = shadowstack.get_root_iterator(gctransformer)
+        def walk_stack_root(callback, start, end):
+            root_iterator.setcontext(NonConstant(llmemory.NULL))
+            gc = self.gc
+            addr = end
+            while True:
+                addr = root_iterator.nextleft(gc, start, addr)
+                if addr == llmemory.NULL:
+                    return
+                callback(gc, addr)
+        self.rootstackhook = walk_stack_root
+
+        rsd = gctransformer.root_stack_depth
+        if rsd is not None:
+            self.root_stack_depth = rsd
+
+    def setup_root_walker(self):
+        self.allocate_shadow_stack()
+        self.gcdata.main_thread_stack_base = self.stackgcdata.root_stack_base
+        BaseRootWalker.setup_root_walker(self)
+
+    def allocate_shadow_stack(self):
+        root_stack_size = sizeofaddr * self.root_stack_depth
+        base = llmemory.raw_malloc(root_stack_size)
+        if base == llmemory.NULL:
+            raise MemoryError
+        self.stackgcdata.root_stack_base = base
+        self.stackgcdata.root_stack_top  = base
+
+    def free_shadow_stack(self):
+        base = self.stackgcdata.root_stack_base
+        llmemory.raw_free(base)
 
     def walk_stack_roots(self, collect_stack_root):
-        raise NotImplementedError
+        # XXX only to walk the main thread's shadow stack, so far
+        stackgcdata = self.stackgcdata
+        if self.gcdata.main_thread_stack_base != stackgcdata.root_stack_base:
+            fatalerror_notb("XXX not implemented: walk_stack_roots in thread")
+        self.rootstackhook(collect_stack_root,
+                           stackgcdata.root_stack_base,
+                           stackgcdata.root_stack_top)


More information about the pypy-commit mailing list