[pypy-commit] pypy shadowstack-no-move-2: Backout the issue #2017 fixes, now that they are not really needed

arigo noreply at buildbot.pypy.org
Fri Sep 25 16:46:36 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-no-move-2
Changeset: r79827:c137e4ccaacd
Date: 2015-09-25 16:46 +0200
http://bitbucket.org/pypy/pypy/changeset/c137e4ccaacd/

Log:	Backout the issue #2017 fixes, now that they are not really needed
	any more. This should indirectly fix issue #2141.

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
@@ -180,7 +180,7 @@
                 thread_stacks[gcdata.active_tid] = old_ref
             #
             # no GC operation from here -- switching shadowstack!
-            shadow_stack_pool.save_current_state_away(old_ref, llmemory.NULL)
+            shadow_stack_pool.save_current_state_away(old_ref)
             if new_ref:
                 shadow_stack_pool.restore_state_from(new_ref)
             else:
@@ -225,18 +225,11 @@
 # ____________________________________________________________
 
 class ShadowStackPool(object):
-    """Manages a pool of shadowstacks.  The MAX most recently used
-    shadowstacks are fully allocated and can be directly jumped into
-    (called "full stacks" below).
-    The rest are stored in a more virtual-memory-friendly way, i.e.
-    with just the right amount malloced.  Before they can run, they
-    must be copied into a full shadowstack.
+    """Manages a pool of shadowstacks.
     """
     _alloc_flavor_ = "raw"
     root_stack_depth = 163840
 
-    MAX = 20
-
     def __init__(self, gcdata):
         self.unused_full_stack = llmemory.NULL
         self.gcdata = gcdata
@@ -249,28 +242,18 @@
         """Allocate an empty SHADOWSTACKREF object."""
         return lltype.malloc(SHADOWSTACKREF, zero=True)
 
-    def save_current_state_away(self, shadowstackref, ncontext):
+    def save_current_state_away(self, shadowstackref):
         """Save the current state away into 'shadowstackref'.
         This either works, or raise MemoryError and nothing is done.
         To do a switch, first call save_current_state_away() or
         forget_current_state(), and then call restore_state_from()
         or start_fresh_new_state().
         """
-        fresh_free_fullstack = shadowstackref.prepare_free_slot()
-        if self.unused_full_stack:
-            if fresh_free_fullstack:
-                llmemory.raw_free(fresh_free_fullstack)
-        elif fresh_free_fullstack:
-            self.unused_full_stack = fresh_free_fullstack
-        else:
-            self._prepare_unused_stack()
-        #
+        self._prepare_unused_stack()
         shadowstackref.base = self.gcdata.root_stack_base
         shadowstackref.top  = self.gcdata.root_stack_top
-        shadowstackref.context = ncontext
         ll_assert(shadowstackref.base <= shadowstackref.top,
                   "save_current_state_away: broken shadowstack")
-        shadowstackref.attach()
         #
         # cannot use llop.gc_writebarrier() here, because
         # we are in a minimally-transformed GC helper :-/
@@ -293,7 +276,6 @@
         ll_assert(bool(shadowstackref.base), "empty shadowstackref!")
         ll_assert(shadowstackref.base <= shadowstackref.top,
                   "restore_state_from: broken shadowstack")
-        self.unused_full_stack = shadowstackref.rebuild(self.unused_full_stack)
         self.gcdata.root_stack_base = shadowstackref.base
         self.gcdata.root_stack_top  = shadowstackref.top
         self._cleanup(shadowstackref)
@@ -306,127 +288,28 @@
     def _cleanup(self, shadowstackref):
         shadowstackref.base = llmemory.NULL
         shadowstackref.top = llmemory.NULL
-        shadowstackref.context = llmemory.NULL
 
     def _prepare_unused_stack(self):
-        ll_assert(self.unused_full_stack == llmemory.NULL,
-                  "already an unused_full_stack")
-        root_stack_size = sizeofaddr * self.root_stack_depth
-        self.unused_full_stack = llmemory.raw_malloc(root_stack_size)
         if self.unused_full_stack == llmemory.NULL:
-            raise MemoryError
+            root_stack_size = sizeofaddr * self.root_stack_depth
+            self.unused_full_stack = llmemory.raw_malloc(root_stack_size)
+            if self.unused_full_stack == llmemory.NULL:
+                raise MemoryError
 
 
 def get_shadowstackref(root_walker, gctransformer):
     if hasattr(gctransformer, '_SHADOWSTACKREF'):
         return gctransformer._SHADOWSTACKREF
 
-    # Helpers to same virtual address space by limiting to MAX the
-    # number of full shadow stacks.  If there are more, we compact
-    # them into a separately-allocated zone of memory of just the right
-    # size.  See the comments in the definition of fullstack_cache below.
-
-    def ll_prepare_free_slot(_unused):
-        """Free up a slot in the array of MAX entries, ready for storing
-        a new shadowstackref.  Return the memory of the now-unused full
-        shadowstack.
-        """
-        index = fullstack_cache[0]
-        if index > 0:
-            return llmemory.NULL     # there is already at least one free slot
-        #
-        # make a compact copy in one old entry and return the
-        # original full-sized memory
-        index = -index
-        ll_assert(index > 0, "prepare_free_slot: cache[0] == 0")
-        compacting = lltype.cast_int_to_ptr(SHADOWSTACKREFPTR,
-                                            fullstack_cache[index])
-        index += 1
-        if index >= ShadowStackPool.MAX:
-            index = 1
-        fullstack_cache[0] = -index    # update to the next value in order
-        #
-        compacting.detach()
-        original = compacting.base
-        size = compacting.top - original
-        new = llmemory.raw_malloc(size)
-        if new == llmemory.NULL:
-            return llmemory.NULL
-        llmemory.raw_memcopy(original, new, size)
-        compacting.base = new
-        compacting.top = new + size
-        return original
-
-    def ll_attach(shadowstackref):
-        """After prepare_free_slot(), store a shadowstackref in that slot."""
-        index = fullstack_cache[0]
-        ll_assert(index > 0, "fullstack attach: no free slot")
-        fullstack_cache[0] = fullstack_cache[index]
-        fullstack_cache[index] = lltype.cast_ptr_to_int(shadowstackref)
-        ll_assert(shadowstackref.fsindex == 0, "fullstack attach: already one?")
-        shadowstackref.fsindex = index    # > 0
-
-    def ll_detach(shadowstackref):
-        """Detach a shadowstackref from the array of MAX entries."""
-        index = shadowstackref.fsindex
-        ll_assert(index > 0, "detach: unattached shadowstackref")
-        ll_assert(fullstack_cache[index] ==
-                  lltype.cast_ptr_to_int(shadowstackref),
-                  "detach: bad fullstack_cache")
-        shadowstackref.fsindex = 0
-        fullstack_cache[index] = fullstack_cache[0]
-        fullstack_cache[0] = index
-
-    def ll_rebuild(shadowstackref, fullstack_base):
-        if shadowstackref.fsindex > 0:
-            shadowstackref.detach()
-            return fullstack_base
-        else:
-            # make an expanded copy of the compact shadowstack stored in
-            # 'shadowstackref' and free that
-            compact = shadowstackref.base
-            size = shadowstackref.top - compact
-            shadowstackref.base = fullstack_base
-            shadowstackref.top = fullstack_base + size
-            llmemory.raw_memcopy(compact, fullstack_base, size)
-            llmemory.raw_free(compact)
-            return llmemory.NULL
-
     SHADOWSTACKREFPTR = lltype.Ptr(lltype.GcForwardReference())
     SHADOWSTACKREF = lltype.GcStruct('ShadowStackRef',
-        ('base', llmemory.Address),
-        ('top', llmemory.Address),
-        ('context', llmemory.Address),
-        ('fsindex', lltype.Signed),
-        rtti=True,
-        adtmeths={'prepare_free_slot': ll_prepare_free_slot,
-                  'attach': ll_attach,
-                  'detach': ll_detach,
-                  'rebuild': ll_rebuild})
+                                     ('base', llmemory.Address),
+                                     ('top', llmemory.Address),
+                                     rtti=True)
     SHADOWSTACKREFPTR.TO.become(SHADOWSTACKREF)
 
-    # Items 1..MAX-1 of the following array can be SHADOWSTACKREF
-    # addresses cast to integer.  Or, they are small numbers and they
-    # make up a free list, rooted in item 0, which goes on until
-    # terminated with a negative item.  This negative item gives (the
-    # opposite of) the index of the entry we try to remove next.
-    # Initially all items are in this free list and the end is '-1'.
-    fullstack_cache = lltype.malloc(lltype.Array(lltype.Signed),
-                                    ShadowStackPool.MAX,
-                                    flavor='raw', immortal=True)
-    for i in range(len(fullstack_cache) - 1):
-        fullstack_cache[i] = i + 1
-    fullstack_cache[len(fullstack_cache) - 1] = -1
-
     def customtrace(gc, obj, callback, arg):
         obj = llmemory.cast_adr_to_ptr(obj, SHADOWSTACKREFPTR)
-        index = obj.fsindex
-        if index > 0:
-            # Haaaaaaack: fullstack_cache[] is just an integer, so it
-            # doesn't follow the SHADOWSTACKREF when it moves.  But we
-            # know this customtrace() will be called just after the
-            # move.  So we fix the fullstack_cache[] now... :-/
-            fullstack_cache[index] = lltype.cast_ptr_to_int(obj)
         addr = obj.top
         start = obj.base
         while addr != start:
@@ -440,22 +323,10 @@
         (SHADOWSTACKREF, customtrace))
 
     def shadowstack_destructor(shadowstackref):
-        if root_walker.stacklet_support:
-            from rpython.rlib import _rffi_stacklet as _c
-            h = shadowstackref.context
-            h = llmemory.cast_adr_to_ptr(h, _c.handle)
-            shadowstackref.context = llmemory.NULL
-        #
-        if shadowstackref.fsindex > 0:
-            shadowstackref.detach()
         base = shadowstackref.base
         shadowstackref.base    = llmemory.NULL
         shadowstackref.top     = llmemory.NULL
         llmemory.raw_free(base)
-        #
-        if root_walker.stacklet_support:
-            if h:
-                _c.destroy(h)
 
     destrptr = gctransformer.annotate_helper(shadowstack_destructor,
                                              [SHADOWSTACKREFPTR], lltype.Void)


More information about the pypy-commit mailing list