[pypy-commit] pypy shadowstack-perf-2: tweaks for threads

arigo pypy.commits at gmail.com
Sat Mar 4 16:48:45 EST 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-perf-2
Changeset: r90545:b4fbb27942b9
Date: 2017-03-04 22:47 +0100
http://bitbucket.org/pypy/pypy/changeset/b4fbb27942b9/

Log:	tweaks for threads

diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py
--- a/rpython/memory/gctransform/shadowstack.py
+++ b/rpython/memory/gctransform/shadowstack.py
@@ -3,6 +3,7 @@
 from rpython.rlib.debug import ll_assert
 from rpython.rlib.nonconst import NonConstant
 from rpython.rlib import rgc
+from rpython.rlib.objectmodel import specialize
 from rpython.rtyper import rmodel
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.rtyper.lltypesystem import lltype, llmemory
@@ -57,6 +58,38 @@
             return top
         self.decr_stack = decr_stack
 
+        @specialize.call_location()
+        def walk_stack_root(invoke, arg0, arg1, start, addr, is_minor):
+            skip = 0
+            while addr != start:
+                addr -= sizeofaddr
+                #XXX reintroduce support for tagged values?
+                #if gc.points_to_valid_gc_object(addr):
+                #    callback(gc, addr)
+
+                if skip & 1 == 0:
+                    content = addr.address[0]
+                    n = llmemory.cast_adr_to_int(content)
+                    if n & 1 == 0:
+                        if content:   # non-0, non-odd: a regular ptr
+                            invoke(arg0, arg1, addr)
+                    else:
+                        # odd number: a skip bitmask
+                        if n > 0:       # initially, an unmarked value
+                            if is_minor:
+                                newcontent = llmemory.cast_int_to_adr(-n)
+                                addr.address[0] = newcontent   # mark
+                            skip = n
+                        else:
+                            # a marked value
+                            if is_minor:
+                                return
+                            skip = -n
+                skip >>= 1
+        self.rootstackhook = walk_stack_root
+        self.invoke_collect_stack_root = specialize.call_location()(
+            lambda arg0, arg1, addr: arg0(self.gc, addr))
+
         self.shadow_stack_pool = ShadowStackPool(gcdata)
         rsd = gctransformer.root_stack_depth
         if rsd is not None:
@@ -75,36 +108,10 @@
         BaseRootWalker.setup_root_walker(self)
 
     def walk_stack_roots(self, collect_stack_root, is_minor=False):
-        gc = self.gc
         gcdata = self.gcdata
-        start = gcdata.root_stack_base
-        addr = gcdata.root_stack_top
-        skip = 0
-        while addr != start:
-            addr -= sizeofaddr
-            #XXX reintroduce support for tagged values?
-            #if gc.points_to_valid_gc_object(addr):
-            #    callback(gc, addr)
-
-            if skip & 1 == 0:
-                content = addr.address[0]
-                n = llmemory.cast_adr_to_int(content)
-                if n & 1 == 0:
-                    if content:   # non-0, non-odd: a regular ptr
-                        collect_stack_root(gc, addr)
-                else:
-                    # odd number: a skip bitmask
-                    if n > 0:       # initially, an unmarked value
-                        if is_minor:
-                            newcontent = llmemory.cast_int_to_adr(-n)
-                            addr.address[0] = newcontent   # mark
-                        skip = n
-                    else:
-                        # a marked value
-                        if is_minor:
-                            return
-                        skip = -n
-            skip >>= 1
+        self.rootstackhook(self.invoke_collect_stack_root, collect_stack_root,
+                           None, gcdata.root_stack_base, gcdata.root_stack_top,
+                           is_minor=is_minor)
 
     def need_thread_support(self, gctransformer, getfn):
         from rpython.rlib import rthread    # xxx fish
@@ -322,11 +329,9 @@
 
     def customtrace(gc, obj, callback, arg):
         obj = llmemory.cast_adr_to_ptr(obj, SHADOWSTACKREFPTR)
-        addr = obj.top
-        start = obj.base
-        while addr != start:
-            addr -= sizeofaddr
-            gc._trace_callback(callback, arg, addr)
+        root_walker.rootstackhook(gc._trace_callback, callback, arg,
+                                  obj.base, obj.top,
+                                  is_minor=False)   # xxx optimize?
 
     gc = gctransformer.gcdata.gc
     assert not hasattr(gc, 'custom_trace_dispatcher')
diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py
--- a/rpython/translator/c/gc.py
+++ b/rpython/translator/c/gc.py
@@ -450,7 +450,7 @@
         #
         yield ('typedef struct { void %s; } pypy_ss_t;'
                    % ', '.join(['*s%d' % i for i in range(numcolors)]))
-        yield 'pypy_ss_t *ss = (pypy_ss_t *)%s;' % gcpol_ss
+        yield 'pypy_ss_t *ss;'
         funcgen.gcpol_ss = gcpol_ss
 
     def OP_GC_PUSH_ROOTS(self, funcgen, op):
@@ -460,7 +460,8 @@
         raise Exception("gc_pop_roots should be removed by postprocess_graph")
 
     def OP_GC_ENTER_ROOTS_FRAME(self, funcgen, op):
-        return '%s = (void *)(ss+1);' % funcgen.gcpol_ss
+        return 'ss = (pypy_ss_t *)%s; %s = (void *)(ss+1);' % (
+            funcgen.gcpol_ss, funcgen.gcpol_ss)
 
     def OP_GC_LEAVE_ROOTS_FRAME(self, funcgen, op):
         return '%s = (void *)ss;' % funcgen.gcpol_ss


More information about the pypy-commit mailing list