[pypy-svn] r50293 - in pypy/branch/asmgcroot/pypy: rpython/memory/gctransform translator/c
arigo at codespeak.net
arigo at codespeak.net
Thu Jan 3 18:58:04 CET 2008
Author: arigo
Date: Thu Jan 3 18:58:04 2008
New Revision: 50293
Modified:
pypy/branch/asmgcroot/pypy/rpython/memory/gctransform/asmgcroot.py
pypy/branch/asmgcroot/pypy/translator/c/trackgcroot.py
Log:
targetgcbench runs!
Modified: pypy/branch/asmgcroot/pypy/rpython/memory/gctransform/asmgcroot.py
==============================================================================
--- pypy/branch/asmgcroot/pypy/rpython/memory/gctransform/asmgcroot.py (original)
+++ pypy/branch/asmgcroot/pypy/rpython/memory/gctransform/asmgcroot.py Thu Jan 3 18:58:04 2008
@@ -153,7 +153,12 @@
#
shape = item.address[1]
framesize = shape.signed[0]
- caller.frame_address = callee.frame_address + framesize
+ if framesize == 0:
+ # frame size not known, use %ebp to find the frame address
+ caller_ebp = callee.regs_stored_at[INDEX_OF_EBP].address[0]
+ caller.frame_address = caller_ebp + 4
+ else:
+ caller.frame_address = callee.frame_address + framesize
#
# enumerate the GC roots in the caller frame
#
@@ -171,8 +176,8 @@
# track where the caller_frame saved the registers from its own
# caller
#
- if shape.signed[1] == -1: # a marker that means "I'm the frame
- return False # of the entry point, stop walking"
+ if framesize == 0: # a marker that means "I'm the frame
+ return False # of the entry point, stop walking"
reg = 0
while reg < CALLEE_SAVED_REGS:
location = shape.signed[1+reg]
@@ -260,6 +265,7 @@
# that's the last word of the frame in memory)
#
CALLEE_SAVED_REGS = 4 # there are 4 callee-saved registers
+INDEX_OF_EBP = 3
FRAME_PTR = CALLEE_SAVED_REGS # the frame is at index 4 in the array
ASM_CALLBACK_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address],
Modified: pypy/branch/asmgcroot/pypy/translator/c/trackgcroot.py
==============================================================================
--- pypy/branch/asmgcroot/pypy/translator/c/trackgcroot.py (original)
+++ pypy/branch/asmgcroot/pypy/translator/c/trackgcroot.py Thu Jan 3 18:58:04 2008
@@ -40,7 +40,7 @@
pypy_asm_stackwalk:
/* See description in asmgcroot.py */
movl 4(%esp), %edx /* my argument, which is the callback */
- movl (%esp), %eax /* my return address */
+ movl %esp, %eax /* my frame top address */
pushl %eax /* ASM_FRAMEDATA[4] */
pushl %ebp /* ASM_FRAMEDATA[3] */
pushl %edi /* ASM_FRAMEDATA[2] */
@@ -107,6 +107,7 @@
def process_function(self, lines, newfile, entrypoint, filename):
tracker = FunctionGcRootTracker(lines)
+ tracker.is_main = tracker.funcname == entrypoint
if self.verbose:
print >> sys.stderr, '[trackgcroot:%s] %s' % (filename,
tracker.funcname)
@@ -114,24 +115,21 @@
if self.verbose > 1:
for label, state in table:
print >> sys.stderr, label, '\t', state
- if tracker.funcname == entrypoint:
+ if tracker.is_main:
+ assert tracker.uses_frame_pointer
table = self.fixup_entrypoint_table(table)
self.gcmaptable.extend(table)
newfile.writelines(tracker.lines)
def fixup_entrypoint_table(self, table):
self.seen_main = True
- # we don't need to track where the main() function saved its
- # own caller's registers. So as a marker, we set the
- # corresponding entries in the shape to -1. The code in
- # asmgcroot recognizes these markers as meaning "stop walking
- # the stack".
+ # the main() function contains strange code that aligns the stack
+ # pointer to a multiple of 16, which messes up our framesize
+ # computation. So just for this function, and as an end marker,
+ # we use a frame size of 0.
newtable = []
for label, shape in table:
- shape = list(shape)
- for i in range(len(CALLEE_SAVE_REGISTERS)):
- shape[1+i] = -1
- newtable.append((label, tuple(shape)))
+ newtable.append((label, (0,) + shape[1:]))
return newtable
@@ -146,6 +144,7 @@
self.lines = lines
self.uses_frame_pointer = False
self.r_localvar = r_localvarnofp
+ self.is_main = False
def computegcmaptable(self, verbose=0):
self.findlabels()
@@ -274,7 +273,7 @@
yield size_delta # continue walking backwards
for insn in self.insns:
- if insn.requestgcroots():
+ if isinstance(insn, (InsnRet, InsnEpilogue, InsnGCROOT)):
deltas = {}
self.walk_instructions_backwards(walker, insn, 0)
size_at_insn = []
@@ -433,11 +432,6 @@
else:
return []
-## visit_incl = unary_insn
-## visit_decl = unary_insn
-## visit_notl = unary_insn
-## visit_negl = unary_insn
-
def binary_insn(self, line):
match = r_binaryinsn.match(line)
if not match:
@@ -449,11 +443,34 @@
raise UnrecognizedOperation(line)
visit_xorl = binary_insn # used in "xor reg, reg" to create a NULL GC ptr
-## visit_orl = binary_insn
-## visit_andl = binary_insn
-## visit_movzbl = binary_insn
-## visit_movzwl = binary_insn
- visit_leal = binary_insn
+ visit_orl = binary_insn
+
+ def visit_andl(self, line):
+ match = r_binaryinsn.match(line)
+ target = match.group(2)
+ if target == '%esp':
+ # only for andl $-16, %esp used to align the stack in main().
+ # gcc should not use %esp-relative addressing in such a function
+ # so we can just ignore it
+ assert self.is_main
+ return []
+ else:
+ return self.binary_insn(line)
+
+ def visit_leal(self, line):
+ match = r_binaryinsn.match(line)
+ target = match.group(2)
+ if target == '%esp':
+ # only for leal -12(%ebp), %esp in function epilogues
+ source = match.group(1)
+ match = r_localvar_ebp.match(source)
+ if not match:
+ raise UnrecognizedOperation(line)
+ ofs_from_ebp = int(match.group(1) or '0')
+ assert ofs_from_ebp < 0
+ return InsnEpilogue(framesize = 4 - ofs_from_ebp)
+ else:
+ return self.binary_insn(line)
def unary_or_binary_insn(self, line):
if r_binaryinsn.match(line):
@@ -461,12 +478,6 @@
else:
return self.unary_insn(line)
-## visit_shll = unary_or_binary_insn
-## visit_shrl = unary_or_binary_insn
-## visit_sall = unary_or_binary_insn
-## visit_sarl = unary_or_binary_insn
-## visit_imull = unary_or_binary_insn
-
def insns_for_copy(self, source, target):
if source == '%esp' or target == '%esp':
raise UnrecognizedOperation('%s -> %s' % (source, target))
@@ -507,10 +518,10 @@
self.r_localvar = r_localvarfp
return [InsnPrologue()]
- def _visit_epilogue(self):
+ def _visit_epilogue(self, framesize=4):
if not self.uses_frame_pointer:
raise UnrecognizedOperation('epilogue without prologue')
- return [InsnEpilogue()]
+ return [InsnEpilogue(framesize)]
def visit_leave(self, line):
return self._visit_epilogue() + self._visit_pop('%ebp')
@@ -722,10 +733,8 @@
Insn.__setattr__(self, attr, value)
class InsnEpilogue(Insn):
- framesize = 4
- def requestgcroots(self):
- return dict(zip(CALLEE_SAVE_REGISTERS_NOEBP,
- CALLEE_SAVE_REGISTERS_NOEBP))
+ def __init__(self, framesize=4):
+ self.framesize = framesize
FUNCTIONS_NOT_RETURNING = {
More information about the Pypy-commit
mailing list