[pypy-commit] pypy tealet: Tweak delegation between rtealet.py and the GC. It seems that the
arigo
noreply at buildbot.pypy.org
Wed Jul 6 20:28:45 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: tealet
Changeset: r45383:01a6ac124f45
Date: 2011-06-12 15:53 +0200
http://bitbucket.org/pypy/pypy/changeset/01a6ac124f45/
Log: Tweak delegation between rtealet.py and the GC. It seems that the
GC needs to do a bit more, but it's not really more code in total.
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -32,6 +32,7 @@
default=False, cmdline="--tealet",
requires=[("translation.type_system", "lltype"),
("translation.gctransformer", "framework"),
+ ("translation.gcrootfinder", "shadowstack"),
("translation.thread", False)]), # XXX temporary
ChoiceOption("type_system", "Type system to use when RTyping",
["lltype", "ootype"], cmdline=None, default="lltype",
diff --git a/pypy/rlib/_tealet_rffi.py b/pypy/rlib/_tealet_rffi.py
--- a/pypy/rlib/_tealet_rffi.py
+++ b/pypy/rlib/_tealet_rffi.py
@@ -11,8 +11,7 @@
def llexternal(funcname, args, restype):
return rffi.llexternal(funcname, args, restype,
compilation_info=eci,
- sandboxsafe=True, threadsafe=False,
- _nowrapper=True)
+ sandboxsafe=True, _nowrapper=True)
TEALET_P = rffi.COpaquePtr('tealet_t', compilation_info=eci)
TEALET_RUN_P = lltype.Ptr(lltype.FuncType([TEALET_P, rffi.VOIDP], TEALET_P))
diff --git a/pypy/rlib/rtealet.py b/pypy/rlib/rtealet.py
--- a/pypy/rlib/rtealet.py
+++ b/pypy/rlib/rtealet.py
@@ -22,7 +22,6 @@
class Tealet(base_class):
lltealet = _tealet_rffi.NULL_TEALET
- _ll_saved_stack = None
def switch(self):
_switch(self)
@@ -58,8 +57,6 @@
class Switcher(object):
current = None
target = None
- count_roots = 0
- lst = None
exception = None
switcher = Switcher()
@@ -143,52 +140,37 @@
raise e
# ____________________________________________________________
+#
+# Shadow stack saving/restoring.
-ROOT_WALKER = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))
+GCPTR_ARRAY = lltype.Ptr(lltype.GcArray(llmemory.GCREF))
+SIGNED_ARRAY = lltype.Ptr(lltype.GcArray(lltype.Signed))
+WALKER_PTR = lltype.Ptr(lltype.Struct('walker',
+ ('gcptr_array', GCPTR_ARRAY),
+ ('signed_array', SIGNED_ARRAY)))
+walker = lltype.malloc(WALKER_PTR.TO, immortal=True)
-def _count_roots_walker(root):
- switcher.count_roots += 1
-
-def _save_root_walker(root):
- i = switcher.count_roots
- switcher.count_roots = i + 1
- gcobj = llmemory.cast_adr_to_ptr(root.address[0], llmemory.GCREF)
- switcher.lst[i] = gcobj
+Tealet._gc_gcptr_array = lltype.nullptr(GCPTR_ARRAY.TO)
+Tealet._gc_signed_array = lltype.nullptr(SIGNED_ARRAY.TO)
def _save_shadow_stack():
- switcher.count_roots = 0
- fn = llhelper(ROOT_WALKER, _count_roots_walker)
- llop.gc_walk_stack_roots(lltype.Void, fn)
- n = switcher.count_roots
- #
+ llop.gc_save_stack_roots(lltype.Void, walker)
tealet = switcher.current
- ll_assert(tealet._ll_saved_stack is None, "tealet stack mismatch (save)")
- tealet._ll_saved_stack = [lltype.nullptr(llmemory.GCREF.TO)] * n
- switcher.count_roots = 0
- switcher.lst = tealet._ll_saved_stack
- fn = llhelper(ROOT_WALKER, _save_root_walker)
- llop.gc_walk_stack_roots(lltype.Void, fn)
- ll_assert(n == switcher.count_roots, "tealet stack mismatch (count1)")
- switcher.lst = None
+ ll_assert(not tealet._gc_gcptr_array, "tealet stack mismatch (save)")
+ tealet._gc_gcptr_array = walker.gcptr_array
+ tealet._gc_signed_array = walker.signed_array
+ walker.gcptr_array = lltype.nullptr(GCPTR_ARRAY.TO)
+ walker.signed_array = lltype.nullptr(SIGNED_ARRAY.TO)
_save_shadow_stack._dont_inline_ = True
-def _restore_root_walker(root):
- i = switcher.count_roots
- switcher.count_roots = i + 1
- gcobj = switcher.lst[i]
- root.address[0] = llmemory.cast_ptr_to_adr(gcobj)
-
def _restore_shadow_stack():
tealet = switcher.target
- lst = tealet._ll_saved_stack
- ll_assert(lst is not None, "tealet stack mismatch (restore)")
- tealet._ll_saved_stack = None
- switcher.count_roots = 0
- switcher.lst = lst
- n = len(lst)
- fn = llhelper(ROOT_WALKER, _restore_root_walker)
- llop.gc_set_stack_roots_count(lltype.Void, n)
- llop.gc_walk_stack_roots(lltype.Void, fn)
- ll_assert(n == switcher.count_roots, "tealet stack mismatch (count2)")
- switcher.lst = None
+ ll_assert(bool(tealet._gc_gcptr_array), "tealet stack mismatch (restore)")
+ walker.gcptr_array = tealet._gc_gcptr_array
+ walker.signed_array = tealet._gc_signed_array
+ tealet._gc_gcptr_array = lltype.nullptr(GCPTR_ARRAY.TO)
+ tealet._gc_signed_array = lltype.nullptr(SIGNED_ARRAY.TO)
+ llop.gc_restore_stack_roots(lltype.Void, walker)
+ walker.gcptr_array = lltype.nullptr(GCPTR_ARRAY.TO)
+ walker.signed_array = lltype.nullptr(SIGNED_ARRAY.TO)
_restore_shadow_stack._dont_inline_ = True
diff --git a/pypy/rlib/test/test_rtealet.py b/pypy/rlib/test/test_rtealet.py
--- a/pypy/rlib/test/test_rtealet.py
+++ b/pypy/rlib/test/test_rtealet.py
@@ -1,3 +1,4 @@
+import py
from pypy.translator.c.test.test_standalone import StandaloneTests
@@ -28,3 +29,5 @@
class TestTealetAsmgcc(BaseTestTealet):
gcrootfinder = "asmgcc"
+ def setup_class(cls):
+ py.test.skip("XXX in-progress")
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -483,8 +483,8 @@
'gc_dump_rpy_heap' : LLOp(),
'gc_typeids_z' : LLOp(),
- 'gc_walk_stack_roots' : LLOp(), # for tealet support
- 'gc_set_stack_roots_count': LLOp(), # "
+ 'gc_save_stack_roots' : LLOp(), # for tealet support
+ 'gc_restore_stack_roots': LLOp(), # for tealet support
# ------- JIT & GC interaction, only for some GCs ----------
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -1006,22 +1006,21 @@
hop.genop("direct_call", [self.root_walker.thread_after_fork_ptr]
+ hop.spaceop.args)
- def gct_gc_walk_stack_roots(self, hop):
+ def gct_gc_save_stack_roots(self, hop):
# only available if tealet support is enabled
assert self.translator.config.translation.tealet
# no gc root in the stack around such an llop!
assert not self.push_roots(hop)
- hop.genop("direct_call", [self.root_walker.ll_walk_stack_roots_ptr]
+ hop.genop("direct_call", [self.root_walker.ll_save_stack_roots_ptr]
+ hop.spaceop.args)
- def gct_gc_set_stack_roots_count(self, hop):
+ def gct_gc_restore_stack_roots(self, hop):
+ # only available if tealet support is enabled
assert self.translator.config.translation.tealet
# no gc root in the stack around such an llop!
assert not self.push_roots(hop)
- if hasattr(self.root_walker, 'set_stack_roots_count_ptr'):
- hop.genop("direct_call",
- [self.root_walker.set_stack_roots_count_ptr]
- + hop.spaceop.args)
+ hop.genop("direct_call", [self.root_walker.ll_restore_stack_roots_ptr]
+ + hop.spaceop.args)
def gct_gc_get_type_info_group(self, hop):
return hop.cast_result(self.c_type_info_group)
@@ -1347,20 +1346,8 @@
self.__class__.__name__,))
def need_tealet_support(self, gctransformer, getfn):
- #
- def ll_walk_stack_roots(fnptr_stack_root):
- gcdata = self.gcdata
- gcdata._fnptr_stack_root = fnptr_stack_root
- self.walk_stack_roots(_ll_collect)
- #
- def _ll_collect(gc, root):
- gcdata = self.gcdata
- gcdata._fnptr_stack_root(root)
- #
- FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))
- s_FuncPtr = annmodel.SomePtr(FUNCPTR)
- self.ll_walk_stack_roots_ptr = getfn(ll_walk_stack_roots,
- [s_FuncPtr], annmodel.s_None)
+ raise Exception("%s does not support tealets" % (
+ self.__class__.__name__,))
class ShadowStackRootWalker(BaseRootWalker):
@@ -1424,34 +1411,45 @@
def need_tealet_support(self, gctransformer, getfn):
assert not gctransformer.translator.config.translation.jit, (
- "not supported yet: jit + shadowstack + tealet")
+ "XXX in-progress: tealet + jit + shadowstack")
assert not gctransformer.translator.config.translation.thread, (
- "not supported yet: thread + shadowstack + tealet")
+ "XXX check me: tealet + thread + shadowstack")
#
- # We need a custom version of ll_walk_stack_roots because the issue
- # is that when we try to restore the shadowstack, it initially
- # contains garbage; and the default ll_walk_stack_roots would skip
- # the NULL pointers in it.
+ GCPTR_ARRAY = lltype.Ptr(lltype.GcArray(llmemory.GCREF))
+ SIGNED_ARRAY = lltype.Ptr(lltype.GcArray(lltype.Signed))
+ WALKER_PTR = lltype.Ptr(lltype.Struct('walker',
+ ('gcptr_array', GCPTR_ARRAY),
+ ('signed_array', SIGNED_ARRAY)))
gcdata = self.gcdata
#
- def ll_walk_stack_roots(fnptr_stack_root):
+ def ll_save_stack_roots(walker):
addr = gcdata.root_stack_base
end = gcdata.root_stack_top
- while addr != end:
- fnptr_stack_root(addr)
- addr += sizeofaddr
+ count = (end - addr) // sizeofaddr
+ walker.gcptr_array = array = lltype.malloc(GCPTR_ARRAY.TO, count)
+ n = 0
+ while n < len(array):
+ array[n] = llmemory.cast_adr_to_ptr(addr.address[n],
+ llmemory.GCREF)
+ n += 1
#
- FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Void))
- s_FuncPtr = annmodel.SomePtr(FUNCPTR)
- self.ll_walk_stack_roots_ptr = getfn(ll_walk_stack_roots,
- [s_FuncPtr], annmodel.s_None)
+ def ll_restore_stack_roots(walker):
+ array = walker.gcptr_array
+ addr = gcdata.root_stack_base
+ gcdata.root_stack_top = addr + len(array) * sizeofaddr
+ n = 0
+ while n < len(array):
+ addr.address[n] = llmemory.cast_ptr_to_adr(array[n])
+ n += 1
#
- def set_stack_roots_count(count):
- bytes = count * llmemory.sizeof(llmemory.Address)
- gcdata.root_stack_top = gcdata.root_stack_base + bytes
- self.set_stack_roots_count_ptr = getfn(set_stack_roots_count,
- [annmodel.SomeInteger()],
- annmodel.s_None)
+ self.ll_save_stack_roots_ptr = getfn(ll_save_stack_roots,
+ [annmodel.SomePtr(WALKER_PTR)],
+ annmodel.s_None,
+ minimal_transform=False)
+ self.ll_restore_stack_roots_ptr = getfn(ll_restore_stack_roots,
+ [annmodel.SomePtr(WALKER_PTR)],
+ annmodel.s_None,
+ minimal_transform=False)
def need_thread_support(self, gctransformer, getfn):
from pypy.module.thread import ll_thread # xxx fish
More information about the pypy-commit
mailing list