[pypy-commit] pypy stacklet: Fixes, and also copies most of the last checkin done in the

arigo noreply at buildbot.pypy.org
Sun Aug 21 16:04:33 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46686:b02950d06234
Date: 2011-08-21 14:09 +0000
http://bitbucket.org/pypy/pypy/changeset/b02950d06234/

Log:	Fixes, and also copies most of the last checkin done in the custom-
	trace branch.

diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -373,85 +373,85 @@
         # rlib/_stacklet_shadowstack.  That's why it is written as
         # an iterator that can also be used with a custom_trace.
         #
-        def iterator_setup():
-            self._iter_frame_addr = llmemory.NULL
-            self._iter_callshape = llmemory.NULL
-            self._iter_saved_prev = llmemory.NULL
-        #
-        def iterator_next(gc, prev, range_lowest):
-            # Return the "next" valid GC object' address.  "prev" is the
-            # previous result (or the highest end of the shadowstack to start
-            # with), and "range_lowest" is the lowest end of the shadowstack.
-            # We enumerating backwards, starting from the higher addresses.
-            #
-            while True:
+        class RootIterator:
+            _alloc_flavor_ = "raw"
+            frame_addr = 0
+
+            def next(iself, gc, prev, range_lowest):
+                # Return the "next" valid GC object' address.  We enumerating
+                # backwards, starting from the high addresses, until we reach
+                # the 'range_lowest'.  The 'prev' argument is the previous
+                # result (or the high end of the shadowstack to start with).
                 #
-                # If we are not iterating right now in a JIT frame
-                if self._iter_frame_addr == llmemory.NULL:
+                while True:
                     #
-                    # Look for the previous shadowstack address that contains
-                    # a valid pointer
-                    while prev != range_lowest:
-                        prev -= llmemory.sizeof(llmemory.Address)
-                        if gc.points_to_valid_gc_object(prev):
-                            break
+                    # If we are not iterating right now in a JIT frame
+                    if iself.frame_addr == 0:
+                        #
+                        # Look for the previous shadowstack address that
+                        # contains a valid pointer
+                        while prev != range_lowest:
+                            prev -= llmemory.sizeof(llmemory.Address)
+                            if gc.points_to_valid_gc_object(prev):
+                                break
+                        else:
+                            return llmemory.NULL
+                        #
+                        # Now a "valid" pointer can be either really valid, or
+                        # it can be a pointer to a JIT frame in the stack.  The
+                        # important part here is that points_to_valid_gc_object
+                        # above returns True even for a pointer to a MARKER
+                        # (which is word-aligned).
+                        if prev.address[0].signed[0] != self.MARKER:
+                            return prev
+                        #
+                        # It's a JIT frame.  Save away 'prev' for later, and
+                        # go into JIT-frame-exploring mode.
+                        iself.saved_prev = prev
+                        frame_addr = prev.signed[0] - self.marker_ofs
+                        iself.frame_addr = frame_addr
+                        addr = llmemory.cast_int_to_adr(frame_addr +
+                                                        self.force_index_ofs)
+                        force_index = addr.signed[0]
+                        if force_index < 0:
+                            force_index = ~force_index
+                        # NB: the next line reads a still-alive _callshapes,
+                        # because we ensure that just before we called this
+                        # piece of assembler, we put on the (same) stack a
+                        # pointer to a loop_token that keeps the force_index
+                        # alive.
+                        callshape = self._callshapes[force_index]
                     else:
-                        return llmemory.NULL
+                        # Continuing to explore this JIT frame
+                        callshape = iself.callshape
                     #
-                    # Now a "valid" pointer can be either really valid, or it
-                    # can be a pointer to a JIT frame in the stack.  The
-                    # important part here is that 'points_to_valid_gc_object'
-                    # above returns True even for a pointer to a MARKER
-                    # (which is word-aligned).
-                    if prev.address[0].signed[0] != self.MARKER:
-                        return prev
+                    # 'callshape' points to the next INT of the callshape.
+                    # If it's zero we are done with the JIT frame.
+                    while callshape[0] != 0:
+                        #
+                        # Non-zero: it's an offset inside the JIT frame.
+                        # Read it and increment 'callshape'.
+                        offset = callshape[0]
+                        callshape = lltype.direct_ptradd(callshape, 1)
+                        addr = llmemory.cast_int_to_adr(iself.frame_addr +
+                                                        offset)
+                        if gc.points_to_valid_gc_object(addr):
+                            #
+                            # The JIT frame contains a valid GC pointer at
+                            # this address (as opposed to NULL).  Save
+                            # 'callshape' for the next call, and return the
+                            # address.
+                            iself.callshape = callshape
+                            return addr
                     #
-                    # It's a JIT frame.  Save away 'prev' for later, and
-                    # go into JIT-frame-exploring mode.
-                    self._iter_saved_prev = prev
-                    frame_addr = prev.signed[0] - self.marker_ofs
-                    self._iter_frame_addr = frame_addr
-                    addr = llmemory.cast_int_to_adr(frame_addr +
-                                                    self.force_index_ofs)
-                    force_index = addr.signed[0]
-                    if force_index < 0:
-                        force_index = ~force_index
-                    # NB: the next line reads a still-alive _callshapes,
-                    # because we ensure that just before we called this piece
-                    # of assembler, we put on the (same) stack a pointer to a
-                    # loop_token that keeps the force_index alive.
-                    callshape = self._callshapes[force_index]
-                else:
-                    # Continuing to explore this JIT frame
-                    callshape = self._iter_callshape
-                #
-                # 'callshape' points to the next INT of the callshape.
-                # If it's zero we are done with the JIT frame.
-                while callshape[0] != 0:
-                    #
-                    # Non-zero: it's an offset inside the JIT frame.
-                    # Read it and increment 'callshape'.
-                    offset = callshape[0]
-                    callshape = lltype.direct_ptradd(callshape, 1)
-                    addr = llmemory.cast_int_to_adr(self._iter_frame_addr +
-                                                    offset)
-                    if gc.points_to_valid_gc_object(addr):
-                        #
-                        # The JIT frame contains a valid GC pointer at
-                        # this address (and not e.g. NULL).  Save 'callshape'
-                        # for the next call, and return it.
-                        self._iter_callshape = callshape
-                        return addr
-                #
-                # Restore 'prev' and loop back to the start.
-                prev = self._iter_saved_prev
-                self._iter_frame_addr = llmemory.NULL
+                    # Restore 'prev' and loop back to the start.
+                    prev = iself.saved_prev
+                    iself.frame_addr = 0
 
         # ---------------
         #
         jit2gc.update({
-            'root_iterator_setup': iterator_setup,
-            'root_iterator_next': iterator_next,
+            'root_iterator': RootIterator(),
             })
 
     def initialize(self):
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
@@ -28,13 +28,11 @@
 
         translator = gctransformer.translator
         if hasattr(translator, '_jit2gc'):
-            iterator_setup = translator._jit2gc['root_iterator_setup']
-            iterator_next  = translator._jit2gc['root_iterator_next']
+            root_iterator = translator._jit2gc['root_iterator']
             def jit_walk_stack_root(callback, addr, end):
                 gc = self.gc
-                iterator_setup()
                 while True:
-                    end = iterator_next(end, addr)
+                    end = root_iterator.next(gc, end, addr)
                     if end == llmemory.NULL:
                         return
                     callback(gc, end)
@@ -262,14 +260,13 @@
 
     translator = gctransformer.translator
     if hasattr(translator, '_jit2gc'):
-        iterator_setup = translator._jit2gc['root_iterator_setup']
-        iterator_next  = translator._jit2gc['root_iterator_next']
+        gc = gctransformer.gcdata.gc
+        root_iterator = translator._jit2gc['root_iterator']
         def customtrace(obj, prev):
             if not prev:
-                iterator_setup()
                 prev = llmemory.cast_adr_to_ptr(obj, SHADOWSTACKREFPTR).top
             base = llmemory.cast_adr_to_ptr(obj, SHADOWSTACKREFPTR).base
-            return iterator_next(prev, base)
+            return root_iterator.next(gc, prev, base)
     else:
         def customtrace(obj, prev):
             # a simple but not JIT-ready version


More information about the pypy-commit mailing list