[pypy-commit] pypy shadowstack-perf: Backed out changeset 31d4b032dd61, for now.

arigo noreply at buildbot.pypy.org
Thu Jul 7 12:24:38 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-perf
Changeset: r45404:11deeacd3210
Date: 2011-07-07 11:23 +0200
http://bitbucket.org/pypy/pypy/changeset/11deeacd3210/

Log:	Backed out changeset 31d4b032dd61, for now. It's subtly incorrect,
	at least because the JIT backend uses two consecutive entries to
	mean something special and doesn't clear them at function exit (see
	_call_footer_shadowstack).

diff --git a/pypy/rpython/lltypesystem/llmemory.py b/pypy/rpython/lltypesystem/llmemory.py
--- a/pypy/rpython/lltypesystem/llmemory.py
+++ b/pypy/rpython/lltypesystem/llmemory.py
@@ -435,17 +435,8 @@
         if isinstance(other, fakeaddress):
             if self == other:
                 return 0
-            # <*_subarray at n> - <*_subarray at m> == ItemOffset(n-m)
-            obj1 = self.ptr._obj
-            obj2 = other.ptr._obj
-            if (isinstance(obj1, lltype._subarray) and
-                isinstance(obj2, lltype._subarray) and
-                obj1._TYPE == obj2._TYPE and
-                obj1._parentstructure() == obj2._parentstructure()):
-                n = obj1._parent_index
-                m = obj2._parent_index
-                return ItemOffset(obj1._TYPE.OF, n - m)
-            raise TypeError("cannot subtract fakeaddresses in general")
+            else:
+                raise TypeError("cannot subtract fakeaddresses in general")
         if other == 0:
             return self
         return NotImplemented
diff --git a/pypy/rpython/memory/gctransform/shadowstack.py b/pypy/rpython/memory/gctransform/shadowstack.py
--- a/pypy/rpython/memory/gctransform/shadowstack.py
+++ b/pypy/rpython/memory/gctransform/shadowstack.py
@@ -55,25 +55,11 @@
         return top.address[0]
 
     def allocate_stack(self):
-        stackbase = llmemory.raw_malloc(self.rootstacksize)
-        if not stackbase:
-            raise MemoryError
-        self.clear_stack(stackbase, stackbase)
-        return stackbase
-
-    def clear_stack(self, stackbase, stacktop):
-        """When a function is called, the current stack top is
-        incremented by as much as needed by this function, but the old
-        content is left in the stack.  This is a speed optimization that
-        may lead to occasional leaks, because the stack may end up
-        containing dead pointers.  Another drawback is that we need to
-        clear the stack manually after every minor collection, to
-        prevent these leftover pointers from pointing to garbage."""
-        size = stackbase + self.rootstacksize - stacktop
-        llmemory.raw_memclear(stacktop, size)
+        return llmemory.raw_malloc(self.rootstacksize)
 
     def setup_root_walker(self):
         stackbase = self.allocate_stack()
+        ll_assert(bool(stackbase), "could not allocate root stack")
         self.gcdata.root_stack_top  = stackbase
         self.gcdata.root_stack_base = stackbase
         BaseRootWalker.setup_root_walker(self)
@@ -81,10 +67,9 @@
     def walk_stack_roots(self, collect_stack_root):
         gcdata = self.gcdata
         gc = self.gc
+        rootstackhook = self.rootstackhook
         addr = gcdata.root_stack_base
         end = gcdata.root_stack_top
-        self.clear_stack(addr, end)
-        rootstackhook = self.rootstackhook
         while addr != end:
             addr += rootstackhook(collect_stack_root, gc, addr)
         if self.collect_stacks_from_other_threads is not None:
@@ -122,6 +107,8 @@
             """
             if not gcdata._fresh_rootstack:
                 gcdata._fresh_rootstack = self.allocate_stack()
+                if not gcdata._fresh_rootstack:
+                    raise MemoryError
 
         def thread_run():
             """Called whenever the current thread (re-)acquired the GIL.
@@ -145,7 +132,6 @@
             gcdata.thread_stacks.setitem(aid, llmemory.NULL)
             old = gcdata.root_stack_base
             if gcdata._fresh_rootstack == llmemory.NULL:
-                self.clear_stack(old, old)
                 gcdata._fresh_rootstack = old
             else:
                 llmemory.raw_free(old)
@@ -192,10 +178,9 @@
                 # collect all valid stacks from the dict (the entry
                 # corresponding to the current thread is not valid)
                 gc = self.gc
+                rootstackhook = self.rootstackhook
                 end = stacktop - sizeofaddr
                 addr = end.address[0]
-                self.clear_stack(addr, stacktop)
-                rootstackhook = self.rootstackhook
                 while addr != end:
                     addr += rootstackhook(callback, gc, addr)
 
@@ -309,6 +294,13 @@
         c_numcolors = rmodel.inputconst(lltype.Signed, numcolors)
         llops.genop("direct_call", [gct.incr_stack_ptr, c_numcolors],
                     resulttype=llmemory.Address)
+        top_addr = llops.genop("direct_call",
+                               [gct.get_stack_top_ptr],
+                               resulttype=llmemory.Address)
+        c_null = rmodel.inputconst(llmemory.Address, llmemory.NULL)
+        for k in range(numcolors):
+            c_k = rmodel.inputconst(lltype.Signed, ~k)
+            llops.genop("raw_store", [top_addr, c_type, c_k, c_null])
         graph.startblock.operations[:0] = llops
         #
         # Put at the end of the graph: "decr_stack()"


More information about the pypy-commit mailing list