[pypy-svn] r35849 - pypy/dist/pypy/jit/codegen/i386
arigo at codespeak.net
arigo at codespeak.net
Mon Dec 18 14:47:20 CET 2006
Author: arigo
Date: Mon Dec 18 14:47:19 2006
New Revision: 35849
Modified:
pypy/dist/pypy/jit/codegen/i386/rgenop.py
pypy/dist/pypy/jit/codegen/i386/ri386setup.py
Log:
(pedronis, arre, arigo)
Fixed the stack alignment code. If the DEBUG_CALL_ALIGN variable is True,
add a run-time sanity check. Note: if the test fail you get a signal that
is reported as "Floating point error" :-/
Modified: pypy/dist/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/rgenop.py Mon Dec 18 14:47:19 2006
@@ -9,6 +9,7 @@
from pypy.rpython.annlowlevel import llhelper
WORD = 4
+DEBUG_CALL_ALIGN = True
if sys.platform == 'darwin':
CALL_ALIGN = 4
else:
@@ -18,16 +19,17 @@
def __init__(self, stackpos):
# 'stackpos' is an index relative to the pushed arguments
- # (where N is the number of arguments of the function):
+ # (where N is the number of arguments of the function
+ # and B is a small integer for stack alignment purposes):
#
- # 0 = last arg
- # = ...
- # N-1 = 1st arg
- # N = return address
- # N+1 = local var
- # N+2 = ...
- # ... <--- esp+4
- # local var <--- esp
+ # B + 0 = last arg
+ # = ...
+ # B +N-1 = 1st arg
+ # B + N = return address
+ # B +N+1 = local var
+ # B +N+2 = ...
+ # ... <--- esp+4
+ # local var <--- esp
#
self.stackpos = stackpos
@@ -292,7 +294,9 @@
self._open()
numargs = sigtoken # for now
#self.mc.BREAKPOINT()
- return [Var(pos) for pos in range(numargs-1, -1, -1)]
+ # self.stackdepth-1 is the return address; the arguments
+ # come just before
+ return [Var(self.stackdepth-2-n) for n in range(numargs)]
def _close(self):
self.closed = True
@@ -428,13 +432,18 @@
MASK = CALL_ALIGN-1
if MASK:
final_depth = self.stackdepth + numargs
- delta = (final_depth+MASK)&~MASK-final_depth
+ delta = ((final_depth+MASK)&~MASK)-final_depth
if delta:
self.mc.SUB(esp, imm(delta*WORD))
self.stackdepth += delta
for i in range(numargs-1, -1, -1):
gv_arg = args_gv[i]
self.push(gv_arg.operand(self))
+ if DEBUG_CALL_ALIGN:
+ self.mc.MOV(eax, esp)
+ self.mc.AND(eax, imm8((WORD*CALL_ALIGN)-1))
+ self.mc.ADD(eax, imm32(sys.maxint)) # overflows unless eax == 0
+ self.mc.INTO()
if gv_fnptr.is_const:
target = gv_fnptr.revealconst(lltype.Signed)
self.mc.CALL(rel32(target))
@@ -481,8 +490,7 @@
def finish_and_return(self, sigtoken, gv_returnvar):
self._open()
- numargs = sigtoken # for now
- initialstackdepth = numargs + 1
+ initialstackdepth = self.rgenop._initial_stack_depth(sigtoken)
self.mc.MOV(eax, gv_returnvar.operand(self))
self.mc.ADD(esp, imm(WORD * (self.stackdepth - initialstackdepth)))
self.mc.RET()
@@ -985,14 +993,25 @@
return Builder(self, stackdepth)
def newgraph(self, sigtoken, name):
- numargs = sigtoken # for now
- initialstackdepth = numargs+1
- builder = self.openbuilder(initialstackdepth)
+ builder = self.openbuilder(self._initial_stack_depth(sigtoken))
builder._open() # Force builder to have an mc
entrypoint = builder.mc.tell()
inputargs_gv = builder._write_prologue(sigtoken)
return builder, IntConst(entrypoint), inputargs_gv
+ def _initial_stack_depth(self, sigtoken):
+ # If a stack depth is a multiple of CALL_ALIGN then the
+ # arguments are correctly aligned for a call. We have to
+ # precompute initialstackdepth to guarantee that. For OS/X the
+ # convention is that the stack should be aligned just after all
+ # arguments are pushed, i.e. just before the return address is
+ # pushed by the CALL instruction. In other words, after
+ # 'numargs' arguments have been pushed the stack is aligned:
+ numargs = sigtoken # for now
+ MASK = CALL_ALIGN - 1
+ initialstackdepth = ((numargs+MASK)&~MASK) + 1
+ return initialstackdepth
+
def replay(self, label, kinds):
return ReplayBuilder(self), [dummy_var] * len(kinds)
Modified: pypy/dist/pypy/jit/codegen/i386/ri386setup.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/ri386setup.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/ri386setup.py Mon Dec 18 14:47:19 2006
@@ -414,6 +414,9 @@
INT = Instruction()
INT.mode1(IMM8, ['\xCD', immediate(1, 'b')])
+INTO = Instruction()
+INTO.mode0(['\xCE'])
+
BREAKPOINT = Instruction() # INT 3
BREAKPOINT.mode0(['\xCC'])
BREAKPOINT.as_alias = "INT3"
More information about the Pypy-commit
mailing list