[pypy-svn] r50307 - in pypy/branch/asmgcroot/pypy: config rpython/memory/gctransform translator/c translator/c/src

arigo at codespeak.net arigo at codespeak.net
Fri Jan 4 12:05:38 CET 2008


Author: arigo
Date: Fri Jan  4 12:05:36 2008
New Revision: 50307

Modified:
   pypy/branch/asmgcroot/pypy/config/translationoption.py
   pypy/branch/asmgcroot/pypy/rpython/memory/gctransform/asmgcroot.py
   pypy/branch/asmgcroot/pypy/translator/c/src/mem.h
   pypy/branch/asmgcroot/pypy/translator/c/trackgcroot.py
Log:
Some support for --asmgcroot in --llvm-via-c.  This still needs a bit of hand-tweaking
of the C file generated by llvm.  More precisely, the function pypy_asm_gcroot()
must be removed and replaced by the macro defined in translator/c/src/mem.h.


Modified: pypy/branch/asmgcroot/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/asmgcroot/pypy/config/translationoption.py	(original)
+++ pypy/branch/asmgcroot/pypy/config/translationoption.py	Fri Jan  4 12:05:36 2008
@@ -68,8 +68,7 @@
                          ("translation.backend", "llvm")]),
     BoolOption("asmgcroot", "Use the 'trackgcroot' asm hack to find roots",
                default=False, cmdline="--asmgcroot",
-               requires=[("translation.gctransformer", "framework"),
-                         ("translation.backend", "c")]),
+               requires=[("translation.gctransformer", "framework")]),
     BoolOption("thread", "enable use of threading primitives",
                default=False, cmdline="--thread",
                requires=[("translation.gc", "boehm")]),

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	Fri Jan  4 12:05:36 2008
@@ -2,7 +2,9 @@
 from pypy.rpython.memory.gctransform.framework import BaseRootWalker
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.rpython.rbuiltin import gen_cast
 from pypy.rpython.annlowlevel import llhelper
+from pypy.objspace.flow.model import Constant
 from pypy.rlib.debug import ll_assert
 
 
@@ -26,7 +28,15 @@
             return
         # mark the values as gc roots
         for var in livevars:
-            hop.genop("asm_gcroot", [var])
+            if 0:
+                # uses direct support in genc - more compact code,
+                # but it's probably not changing anything
+                hop.genop("asm_gcroot", [var])
+            else:
+                v_adr = gen_cast(hop.llops, llmemory.Address, var)
+                v_newaddr = hop.genop("direct_call", [c_asm_gcroot, v_adr],
+                                      resulttype=llmemory.Address)
+                hop.genop("gc_reload_possibly_moved", [v_newaddr, var])
 
     def build_root_walker(self):
         return AsmStackRootWalker(self)
@@ -176,8 +186,8 @@
         # track where the caller_frame saved the registers from its own
         # caller
         #
-        if framesize == 0:     # a marker that means "I'm the frame
-            return False       # of the entry point, stop walking"
+        if shape.signed[1] == -1:     # 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]
@@ -284,3 +294,10 @@
                                      lltype.Void,
                                      sandboxsafe=True,
                                      _nowrapper=True)
+
+pypy_asm_gcroot = rffi.llexternal('pypy_asm_gcroot',
+                                  [llmemory.Address],
+                                  llmemory.Address,
+                                  sandboxsafe=True,
+                                  _nowrapper=True)
+c_asm_gcroot = Constant(pypy_asm_gcroot, lltype.typeOf(pypy_asm_gcroot))

Modified: pypy/branch/asmgcroot/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/branch/asmgcroot/pypy/translator/c/src/mem.h	(original)
+++ pypy/branch/asmgcroot/pypy/translator/c/src/mem.h	Fri Jan  4 12:05:36 2008
@@ -13,6 +13,10 @@
 extern char* __gcmap_frame_address(void);
 
 #define PYPY_GCROOT(p)  asm ("/* GCROOT %0 */" : "=g" (p) : "0" (p) : "memory")
+#define pypy_asm_gcroot(p) ({void*_r; \
+               asm ("/* GCROOT %0 */" : "=g" (_r) : "0" (p) : "memory"); \
+               _r; })
+
 #define OP_LLVM_GCMAPSTART(r)	r = &__gcmapstart
 #define OP_LLVM_GCMAPEND(r)	r = &__gcmapend
 #define OP_LLVM_FRAMEADDRESS(r)	asm ("pypygetframeaddress %0" : "=r" (r))

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	Fri Jan  4 12:05:36 2008
@@ -67,7 +67,7 @@
                 lst = ['__gcmap_shape']
                 for n in state:
                     if n < 0:
-                        n = 'minus%d' % (-n,)
+                        n = 'm%d' % (-n,)
                     lst.append(str(n))
                 shapes[state] = '_'.join(lst)
             print >> output, '\t.long\t%s' % (label,)
@@ -116,21 +116,31 @@
             for label, state in table:
                 print >> sys.stderr, label, '\t', state
         if tracker.is_main:
-            assert tracker.uses_frame_pointer
-            table = self.fixup_entrypoint_table(table)
+            fp = tracker.uses_frame_pointer
+            table = self.fixup_entrypoint_table(table, fp)
         self.gcmaptable.extend(table)
         newfile.writelines(tracker.lines)
 
-    def fixup_entrypoint_table(self, table):
+    def fixup_entrypoint_table(self, table, uses_frame_pointer):
         self.seen_main = True
-        # 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.
+        # as an end marker, set the CALLEE_SAVE_REGISTERS locations to -1.
+        # this info is not useful because we don't go to main()'s caller.
         newtable = []
+        MARKERS = (-1, -1, -1, -1)
         for label, shape in table:
-            newtable.append((label, (0,) + shape[1:]))
-        return newtable
+            newtable.append((label, shape[:1] + MARKERS + shape[5:]))
+        table = newtable
+
+        if uses_frame_pointer:
+            # the main() function may contain strange code that aligns the
+            # stack pointer to a multiple of 16, which messes up our framesize
+            # computation.  So just for this function, we use a frame size
+            # of 0 to ask asmgcroot to read %ebp to find the frame pointer.
+            newtable = []
+            for label, shape in table:
+                newtable.append((label, (0,) + shape[1:]))
+            table = newtable
+        return table
 
 
 class FunctionGcRootTracker(object):
@@ -452,10 +462,14 @@
         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
+            # If gcc compiled main() with a frame pointer, then it should use
+            # %ebp-relative addressing and not %esp-relative addressing
+            # and asmgcroot will read %ebp to find the frame.  If main()
+            # is compiled without a frame pointer, the total frame size that
+            # we compute ends up being bogus but that's ok because gcc has
+            # to use %esp-relative addressing only and we don't need to walk
+            # to caller frames because it's main().
             assert self.is_main
-            self.uses_frame_pointer = True
             return []
         else:
             return self.binary_insn(line)


More information about the pypy-svn mailing list