[pypy-commit] pypy default: (fijal, arigo)
arigo
noreply at buildbot.pypy.org
Sat Jan 28 19:30:21 CET 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r51929:f0d095a1d379
Date: 2012-01-28 19:18 +0100
http://bitbucket.org/pypy/pypy/changeset/f0d095a1d379/
Log: (fijal, arigo)
Change the order of the shadowstack processing. We now process it
right-to-left instead of left-to-right (it's an array, so "left" is
0 and "right" is the end).
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
@@ -394,13 +394,13 @@
This is the class supporting --gcrootfinder=shadowstack.
"""
is_shadow_stack = True
- MARKER = 8
+ MARKER_FRAME = 8 # this marker now *follows* the frame addr
# The "shadowstack" is a portable way in which the GC finds the
# roots that live in the stack. Normally it is just a list of
# pointers to GC objects. The pointers may be moved around by a GC
- # collection. But with the JIT, an entry can also be MARKER, in
- # which case the next entry points to an assembler stack frame.
+ # collection. But with the JIT, an entry can also be MARKER_FRAME,
+ # in which case the previous entry points to an assembler stack frame.
# During a residual CALL from the assembler (which may indirectly
# call the GC), we use the force_index stored in the assembler
# stack frame to identify the call: we can go from the force_index
@@ -436,11 +436,13 @@
def setcontext(iself, context):
iself.context = context
- def next(iself, gc, next, range_highest):
- # Return the "next" valid GC object' address. This usually
- # means just returning "next", until we reach "range_highest",
- # except that we are skipping NULLs. If "next" contains a
- # MARKER instead, then we go into JIT-frame-lookup mode.
+ def nextleft(iself, gc, range_lowest, prev):
+ # Return the next valid GC object's address, in right-to-left
+ # order from the shadowstack array. This usually means just
+ # returning "prev - sizeofaddr", until we reach "range_lowest",
+ # except that we are skipping NULLs. If "prev - sizeofaddr"
+ # contains a MARKER_FRAME instead, then we go into
+ # JIT-frame-lookup mode.
#
while True:
#
@@ -449,20 +451,20 @@
#
# Look for the next shadowstack address that
# contains a valid pointer
- while next != range_highest:
- if next.signed[0] == self.MARKER:
+ while prev != range_lowest:
+ prev -= llmemory.sizeof(llmemory.Address)
+ if prev.signed[0] == self.MARKER_FRAME:
break
- if gc.points_to_valid_gc_object(next):
- return next
- next += llmemory.sizeof(llmemory.Address)
+ if gc.points_to_valid_gc_object(prev):
+ return prev
else:
return llmemory.NULL # done
#
- # It's a JIT frame. Save away 'next' for later, and
+ # It's a JIT frame. Save away 'prev' for later, and
# go into JIT-frame-exploring mode.
- next += llmemory.sizeof(llmemory.Address)
- frame_addr = next.signed[0]
- iself.saved_next = next
+ prev -= llmemory.sizeof(llmemory.Address)
+ frame_addr = prev.signed[0]
+ iself.saved_prev = prev
iself.frame_addr = frame_addr
addr = llmemory.cast_int_to_adr(frame_addr +
self.force_index_ofs)
@@ -502,8 +504,7 @@
#
# Restore 'prev' and loop back to the start.
iself.frame_addr = 0
- next = iself.saved_next
- next += llmemory.sizeof(llmemory.Address)
+ prev = iself.saved_prev
# ---------------
#
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -774,7 +774,7 @@
self.mc.RET()
def _call_header_shadowstack(self, gcrootmap):
- # we need to put two words into the shadowstack: the MARKER
+ # we need to put two words into the shadowstack: the MARKER_FRAME
# and the address of the frame (ebp, actually)
rst = gcrootmap.get_root_stack_top_addr()
if rx86.fits_in_32bits(rst):
@@ -783,9 +783,10 @@
self.mc.MOV_ri(r13.value, rst) # MOV r13, rootstacktop
self.mc.MOV_rm(eax.value, (r13.value, 0)) # MOV eax, [r13]
#
- self.mc.LEA_rm(ebx.value, (eax.value, 2*WORD)) # LEA ebx, [eax+2*WORD]
- self.mc.MOV_mi((eax.value, 0), gcrootmap.MARKER) # MOV [eax], MARKER
- self.mc.MOV_mr((eax.value, WORD), ebp.value) # MOV [eax+WORD], ebp
+ MARKER = gcrootmap.MARKER_FRAME
+ self.mc.LEA_rm(ebx.value, (eax.value, 2*WORD)) # LEA ebx, [eax+2*WORD]
+ self.mc.MOV_mi((eax.value, WORD), MARKER) # MOV [eax+WORD], MARKER
+ self.mc.MOV_mr((eax.value, 0), ebp.value) # MOV [eax], ebp
#
if rx86.fits_in_32bits(rst):
self.mc.MOV_jr(rst, ebx.value) # MOV [rootstacktop], ebx
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,15 +28,15 @@
self.decr_stack = decr_stack
root_iterator = get_root_iterator(gctransformer)
- def walk_stack_root(callback, addr, end):
+ def walk_stack_root(callback, start, end):
root_iterator.setcontext(NonConstant(llmemory.NULL))
gc = self.gc
+ addr = end
while True:
- addr = root_iterator.next(gc, addr, end)
+ addr = root_iterator.nextleft(gc, start, addr)
if addr == llmemory.NULL:
return
callback(gc, addr)
- addr += sizeofaddr
self.rootstackhook = walk_stack_root
self.shadow_stack_pool = ShadowStackPool(gcdata)
@@ -333,11 +333,11 @@
return True
def setcontext(self, context):
pass
- def next(self, gc, addr, end):
- while addr != end:
+ def nextleft(self, gc, start, addr):
+ while addr != start:
+ addr -= sizeofaddr
if gc.points_to_valid_gc_object(addr):
return addr
- addr += sizeofaddr
return llmemory.NULL
result = RootIterator()
gctransformer._root_iterator = result
@@ -364,10 +364,8 @@
obj = llmemory.cast_adr_to_ptr(obj, SHADOWSTACKREFPTR)
if not prev:
root_iterator.setcontext(obj.context)
- next = obj.base
- else:
- next = prev + sizeofaddr
- return root_iterator.next(gc, next, obj.top)
+ prev = obj.top
+ return root_iterator.nextleft(gc, obj.base, prev)
CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
llmemory.Address)
More information about the pypy-commit
mailing list