[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