[pypy-svn] r71476 - in pypy/branch/asmgcc-cantcollect/pypy: rpython/memory/gctransform translator/c/gcc translator/c/src

afa at codespeak.net afa at codespeak.net
Thu Feb 25 00:05:55 CET 2010


Author: afa
Date: Thu Feb 25 00:05:54 2010
New Revision: 71476

Modified:
   pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py
   pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py
   pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py
   pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h
Log:
Add a marker after each call to a function that cannot collect,
and skip these calls in trackgcroot.
Tests pass on Windows, let's try with the buildbot


Modified: pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py	(original)
+++ pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/asmgcroot.py	Thu Feb 25 00:05:54 2010
@@ -40,6 +40,9 @@
     def build_root_walker(self):
         return AsmStackRootWalker(self)
 
+    def mark_call_cannotcollect(self, hop, name):
+        hop.genop("direct_call", [c_asm_nocollect, name])
+
     def gct_direct_call(self, hop):
         fnptr = hop.spaceop.args[0].value
         try:
@@ -487,6 +490,12 @@
                                   _nowrapper=True)
 c_asm_gcroot = Constant(pypy_asm_gcroot, lltype.typeOf(pypy_asm_gcroot))
 
+pypy_asm_nocollect = rffi.llexternal('pypy_asm_gc_nocollect',
+                                     [rffi.CCHARP], lltype.Void,
+                                     sandboxsafe=True,
+                                     _nowrapper=True)
+c_asm_nocollect = Constant(pypy_asm_nocollect, lltype.typeOf(pypy_asm_nocollect))
+
 QSORT_CALLBACK_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address,
                                                  llmemory.Address], rffi.INT))
 qsort = rffi.llexternal('qsort',

Modified: pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/asmgcc-cantcollect/pypy/rpython/memory/gctransform/framework.py	Thu Feb 25 00:05:54 2010
@@ -577,6 +577,11 @@
             self.pop_roots(hop, livevars)
         else:
             self.default(hop)
+            if hop.spaceop.opname == "direct_call":
+                self.mark_call_cannotcollect(hop, hop.spaceop.args[0])
+
+    def mark_call_cannotcollect(self, hop, name):
+        pass
 
     gct_indirect_call = gct_direct_call
 

Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py	(original)
+++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py	Thu Feb 25 00:05:54 2010
@@ -164,8 +164,8 @@
             return dict(zip(self.registers, self.registers))
 
 class InsnCall(Insn):
-    _args_ = ['lineno', 'gcroots']
-    def __init__(self, lineno):
+    _args_ = ['lineno', 'name', 'gcroots']
+    def __init__(self, name, lineno):
         # 'gcroots' is a dict built by side-effect during the call to
         # FunctionGcRootTracker.trackgcroots().  Its meaning is as
         # follows: the keys are the locations that contain gc roots
@@ -189,6 +189,7 @@
         # %ebx from there in the prologue and epilogue).
         self.gcroots = {}
         self.lineno = lineno
+        self.name = name
 
     def source_of(self, localvar, tag):
         tag1 = self.gcroots.setdefault(localvar, tag)

Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py	(original)
+++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py	Thu Feb 25 00:05:54 2010
@@ -38,6 +38,7 @@
         self.filetag = filetag
         # a "stack bottom" function is either main() or a callback from C code
         self.is_stack_bottom = False
+        self.cannot_collect = {}
 
     def computegcmaptable(self, verbose=0):
         self.findlabels()
@@ -45,6 +46,7 @@
         try:
             if not self.list_call_insns():
                 return []
+            self.find_noncollecting_calls()
             self.findframesize()
             self.fixlocalvars()
             self.trackgcroots()
@@ -65,6 +67,8 @@
         for insn in self.list_call_insns():
             if not hasattr(insn, 'framesize'):
                 continue     # calls that never end up reaching a RET
+            if insn.name in self.cannot_collect:
+                continue
             if self.is_stack_bottom:
                 retaddr = LOC_NOWHERE     # end marker for asmgcroot.py
             elif self.uses_frame_pointer:
@@ -81,10 +85,11 @@
                 if isinstance(localvar, LocalVar):
                     loc = localvar.getlocation(insn.framesize,
                                                self.uses_frame_pointer)
-                else:
-                    assert localvar in self.REG2LOC, "%s: %s" % (self.funcname,
-                                                                 localvar)
+                elif localvar in self.REG2LOC:
                     loc = self.REG2LOC[localvar]
+                else:
+                    assert False, "%s: %s" % (self.funcname,
+                                              localvar)
                 assert isinstance(loc, int)
                 if tag is None:
                     gcroots.append(loc)
@@ -116,6 +121,17 @@
                 assert label not in self.labels, "duplicate label: %s" % label
                 self.labels[label] = Label(label, lineno)
 
+    def find_noncollecting_calls(self):
+        for line in self.lines:
+            match = self.r_gcnocollect_marker.search(line)
+            if match:
+                name = match.group(1)
+                if name in ('pypy_g_walk_roots', 'pypy_asm_stackwalk'):
+                    continue
+                if self.format in ('darwin', 'mingw32', 'msvc'):
+                    name = '_' + name
+                self.cannot_collect[name] = True
+
     def append_instruction(self, insn):
         # Add the instruction to the list, and link it to the previous one.
         previnsn = self.insns[-1]
@@ -641,7 +657,7 @@
 
         if match is None:
             assert self.r_unaryinsn_star.match(line)   # indirect call
-            return [InsnCall(self.currentlineno),
+            return [InsnCall('<indirect>', self.currentlineno),
                     InsnSetLocal(self.EAX)]      # the result is there
 
         target = match.group(1)
@@ -691,7 +707,7 @@
                 assert  lineoffset in (1,2)
                 return [InsnStackAdjust(-4)]
 
-        insns = [InsnCall(self.currentlineno),
+        insns = [InsnCall(target, self.currentlineno),
                  InsnSetLocal(self.EAX)]      # the result is there
         if self.format in ('mingw32', 'msvc'):
             # handle __stdcall calling convention:
@@ -737,6 +753,7 @@
     r_jmptable_end  = re.compile(r"\t.text|\t.section\s+.text|\t\.align|"+LABEL)
 
     r_gcroot_marker = re.compile(r"\t/[*] GCROOT ("+LOCALVARFP+") [*]/")
+    r_gcnocollect_marker = re.compile(r"\t/[*] GC_NOCOLLECT ("+OPERAND+") [*]/")
     r_bottom_marker = re.compile(r"\t/[*] GC_STACK_BOTTOM [*]/")
 
     FUNCTIONS_NOT_RETURNING = {
@@ -813,6 +830,7 @@
 
     r_gcroot_marker = re.compile(r"$1") # never matches
     r_gcroot_marker_var = re.compile(r"DWORD PTR .+_constant_always_one_.+pypy_asm_gcroot")
+    r_gcnocollect_marker = re.compile(r"\spypy_asm_gc_nocollect\(("+OPERAND+")\);")
     r_bottom_marker = re.compile(r"; .+\tpypy_asm_stack_bottom\(\);")
 
     FUNCTIONS_NOT_RETURNING = {

Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h
==============================================================================
--- pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h	(original)
+++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/src/mem.h	Thu Feb 25 00:05:54 2010
@@ -34,6 +34,9 @@
                     "0" (p), "m" (__gcnoreorderhack)); \
                _r; })
 
+#define pypy_asm_gc_nocollect(f) asm volatile ("/* GC_NOCOLLECT " #f " */" \
+                                               : : )
+
 #define pypy_asm_keepalive(v)  asm volatile ("/* keepalive %0 */" : : \
                                              "g" (v))
 
@@ -58,6 +61,8 @@
     return _r1;
 }
 
+#define pypy_asm_gc_nocollect(f) "/* GC_NOCOLLECT " #f " */"
+
 #define pypy_asm_keepalive(v)    __asm { }
 static __declspec(noinline) void pypy_asm_stack_bottom() { }
 



More information about the Pypy-commit mailing list