[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