[pypy-svn] r50138 - pypy/branch/llvmgcroot/pypy/translator/c

arigo at codespeak.net arigo at codespeak.net
Thu Dec 27 16:24:49 CET 2007


Author: arigo
Date: Thu Dec 27 16:24:49 2007
New Revision: 50138

Modified:
   pypy/branch/llvmgcroot/pypy/translator/c/trackgcroot.py
Log:
Add labels after each 'call' in the .s file.


Modified: pypy/branch/llvmgcroot/pypy/translator/c/trackgcroot.py
==============================================================================
--- pypy/branch/llvmgcroot/pypy/translator/c/trackgcroot.py	(original)
+++ pypy/branch/llvmgcroot/pypy/translator/c/trackgcroot.py	Thu Dec 27 16:24:49 2007
@@ -1,6 +1,6 @@
 #! /usr/bin/env python
 
-import re, sys
+import re, sys, os
 
 r_functionstart = re.compile(r"\t.type\s+(\w+),\s*[@]function\s*$")
 r_functionend   = re.compile(r"\t.size\s+\w+,\s*[.]-\w+\s*$")
@@ -26,7 +26,7 @@
     def dump(self, output):
         pass
 
-    def process(self, iterlines):
+    def process(self, iterlines, newfile):
         functionlines = None
         for line in iterlines:
             if r_functionstart.match(line):
@@ -35,16 +35,19 @@
                 functionlines = []
             if functionlines is not None:
                 functionlines.append(line)
+            else:
+                newfile.write(line)
             if r_functionend.match(line):
                 assert functionlines is not None, (
                     "missed the start of the current function")
-                self.process_function(functionlines)
+                self.process_function(functionlines, newfile)
                 functionlines = None
 
-    def process_function(self, lines):
+    def process_function(self, lines, newfile):
         tracker = FunctionGcRootTracker(lines)
         print >> sys.stderr, tracker.funcname
         self.gcmaptable.extend(tracker.computegcmaptable())
+        newfile.writelines(tracker.lines)
 
 
 class FunctionGcRootTracker(object):
@@ -57,11 +60,14 @@
 
     def computegcmaptable(self):
         self.findlabels()
-        self.calls = {}
+        self.calls = {}         # {label_after_call: state}
+        self.missing_labels_after_call = []
         self.follow_control_flow()
-        print self.calls
+        for label, state in self.calls.values():
+            print >> sys.stderr, label, '\t', state
         self.table = []
         #xxx
+        self.extend_calls_with_labels()
         return self.table
 
     def findlabels(self):
@@ -73,6 +79,12 @@
                 assert label not in self.labels, "duplicate label"
                 self.labels[label] = i
 
+    def extend_calls_with_labels(self):
+        self.missing_labels_after_call.sort()
+        self.missing_labels_after_call.reverse()
+        for linenum, label in self.missing_labels_after_call:
+            self.lines.insert(linenum, '%s:\n' % (label,))
+
     def follow_control_flow(self):
         # 'states' is a list [(framesize, gcroot0, gcroot1, gcroot2...)]
         self.states = [None] * len(self.lines)
@@ -203,7 +215,10 @@
         try:
             self.conditional_jump(line)
         except KeyError:
-            pass     # label not found: assume a tail-call turned into a jump
+            # label not found: check if it's a tail-call turned into a jump
+            match = r_unaryinsn.match(line)
+            target = match.group(1)
+            assert not target.startswith('.')
         raise LeaveBasicBlock
 
     def conditional_jump(self, line):
@@ -228,7 +243,21 @@
         target = match.group(1)
         if target == "abort":
             raise LeaveBasicBlock
-        self.calls[self.currentlinenum] = self.getstate()
+        nextline = self.lines[self.currentlinenum+1]
+        match = r_label.match(nextline)
+        if match and not match.group(1).startswith('.'):
+            label = match.group(1)
+        else:
+            k = 0
+            while 1:
+                label = '__gcmap_IN_%s_%d' % (self.funcname, k)
+                if label not in self.labels:
+                    break
+                k += 1
+            self.labels[label] = self.currentlinenum+1
+            self.missing_labels_after_call.append(
+                (self.currentlinenum+1, label))
+        self.calls[self.currentlinenum] = label, self.getstate()
 
 
 class LeaveBasicBlock(Exception):
@@ -241,7 +270,12 @@
 if __name__ == '__main__':
     tracker = GcRootTracker()
     for fn in sys.argv[1:]:
+        tmpfn = fn + '.TMP'
         f = open(fn, 'r')
-        tracker.process(f)
+        g = open(tmpfn, 'w')
+        tracker.process(f, g)
         f.close()
+        g.close()
+        os.unlink(fn)
+        os.rename(tmpfn, fn)
     tracker.dump(sys.stdout)



More information about the Pypy-commit mailing list