[pypy-svn] r68553 - in pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc: . test

afa at codespeak.net afa at codespeak.net
Fri Oct 16 23:55:36 CEST 2009


Author: afa
Date: Fri Oct 16 23:55:35 2009
New Revision: 68553

Added:
   pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/autopath.py
      - copied unchanged from r68546, pypy/branch/msvc-asmgcroot/pypy/translator/c/autopath.py
   pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/instruction.py
Modified:
   pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_asmgcroot.py
   pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_trackgcroot.py
   pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py
Log:
Start to refactor trackgcroot, try to separate asm parsing from flow analysis
On windows, run tests for both msvc and mingw32 compilers


Added: pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/instruction.py
==============================================================================
--- (empty file)
+++ pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/instruction.py	Fri Oct 16 23:55:35 2009
@@ -0,0 +1,228 @@
+CALLEE_SAVE_REGISTERS_NOEBP = ['%ebx', '%esi', '%edi']
+CALLEE_SAVE_REGISTERS = CALLEE_SAVE_REGISTERS_NOEBP + ['%ebp']
+
+LOC_NOWHERE   = 0
+LOC_REG       = 1
+LOC_EBP_BASED = 2
+LOC_ESP_BASED = 3
+LOC_MASK      = 0x03
+
+REG2LOC = {}
+for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS):
+    REG2LOC[_reg] = LOC_REG | (_i<<2)
+
+def frameloc(base, offset):
+    assert base in (LOC_EBP_BASED, LOC_ESP_BASED)
+    assert offset % 4 == 0
+    return base | offset
+
+
+
+class SomeNewValue(object):
+    pass
+somenewvalue = SomeNewValue()
+
+class LocalVar(object):
+    # A local variable location at position 'ofs_from_frame_end',
+    # which is counted from the end of the stack frame (so it is always
+    # negative, unless it refers to arguments of the current function).
+    def __init__(self, ofs_from_frame_end, hint=None):
+        self.ofs_from_frame_end = ofs_from_frame_end
+        self.hint = hint
+
+    def __repr__(self):
+        return '<%+d;%s>' % (self.ofs_from_frame_end, self.hint or 'e*p')
+
+    def __hash__(self):
+        return hash(self.ofs_from_frame_end)
+
+    def __cmp__(self, other):
+        if isinstance(other, LocalVar):
+            return cmp(self.ofs_from_frame_end, other.ofs_from_frame_end)
+        else:
+            return 1
+
+    def getlocation(self, framesize, uses_frame_pointer):
+        if (self.hint == 'esp' or not uses_frame_pointer
+            or self.ofs_from_frame_end % 2 != 0):
+            # try to use esp-relative addressing
+            ofs_from_esp = framesize + self.ofs_from_frame_end
+            if ofs_from_esp % 2 == 0:
+                return frameloc(LOC_ESP_BASED, ofs_from_esp)
+            # we can get an odd value if the framesize is marked as bogus
+            # by visit_andl()
+        assert uses_frame_pointer
+        ofs_from_ebp = self.ofs_from_frame_end + 4
+        return frameloc(LOC_EBP_BASED, ofs_from_ebp)
+
+
+class Insn(object):
+    _args_ = []
+    _locals_ = []
+
+    def __repr__(self):
+        return '%s(%s)' % (self.__class__.__name__,
+                           ', '.join([str(getattr(self, name))
+                                      for name in self._args_]))
+    def requestgcroots(self, tracker):
+        return {}
+
+    def source_of(self, localvar, tag):
+        return localvar
+
+    def all_sources_of(self, localvar):
+        return [localvar]
+
+class Label(Insn):
+    _args_ = ['label', 'lineno']
+    def __init__(self, label, lineno):
+        self.label = label
+        self.lineno = lineno
+        self.previous_insns = []   # all insns that jump (or fallthrough) here
+
+class InsnFunctionStart(Insn):
+    framesize = 0
+    previous_insns = ()
+    def __init__(self):
+        self.arguments = {}
+        for reg in CALLEE_SAVE_REGISTERS:
+            self.arguments[reg] = somenewvalue
+
+    def source_of(self, localvar, tag):
+        if localvar not in self.arguments:
+            if localvar in ('%eax', '%edx', '%ecx'):
+                # xxx this might show a bug in trackgcroot.py failing to
+                # figure out which instruction stored a value in these
+                # registers.  However, this case also occurs when the
+                # the function's calling convention was optimized by gcc:
+                # the 3 registers above are then used to pass arguments
+                pass
+            else:
+                assert (isinstance(localvar, LocalVar) and
+                        localvar.ofs_from_frame_end > 0), (
+                    "must come from an argument to the function, got %r" %
+                    (localvar,))
+            self.arguments[localvar] = somenewvalue
+        return self.arguments[localvar]
+
+    def all_sources_of(self, localvar):
+        return []
+
+class InsnSetLocal(Insn):
+    _args_ = ['target', 'sources']
+    _locals_ = ['target', 'sources']
+
+    def __init__(self, target, sources=()):
+        self.target = target
+        self.sources = sources
+
+    def source_of(self, localvar, tag):
+        if localvar == self.target:
+            return somenewvalue
+        return localvar
+
+    def all_sources_of(self, localvar):
+        if localvar == self.target:
+            return self.sources
+        return [localvar]
+
+class InsnCopyLocal(Insn):
+    _args_ = ['source', 'target']
+    _locals_ = ['source', 'target']
+
+    def __init__(self, source, target):
+        self.source = source
+        self.target = target
+
+    def source_of(self, localvar, tag):
+        if localvar == self.target:
+            return self.source
+        return localvar
+
+    def all_sources_of(self, localvar):
+        if localvar == self.target:
+            return [self.source]
+        return [localvar]
+
+class InsnStackAdjust(Insn):
+    _args_ = ['delta']
+    def __init__(self, delta):
+        assert delta % 2 == 0     # should be "% 4", but there is the special
+        self.delta = delta        # case of 'pushw' to handle
+
+class InsnCannotFollowEsp(InsnStackAdjust):
+    def __init__(self):
+        self.delta = -7     # use an odd value as marker
+
+class InsnStop(Insn):
+    pass
+
+class InsnRet(InsnStop):
+    framesize = 0
+    def requestgcroots(self, tracker):
+        # no need to track the value of these registers in the caller
+        # function if we are the main(), or if we are flagged as a
+        # "bottom" function (a callback from C code)
+        if tracker.is_stack_bottom:
+            return {}
+        else:
+            return dict(zip(CALLEE_SAVE_REGISTERS, CALLEE_SAVE_REGISTERS))
+
+class InsnCall(Insn):
+    _args_ = ['lineno', 'gcroots']
+    def __init__(self, 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
+        # (register names or LocalVar instances).  The value
+        # corresponding to a key is the "tag", which is None for a
+        # normal gc root, or else the name of a callee-saved register.
+        # In the latter case it means that this is only a gc root if the
+        # corresponding register in the caller was really containing a
+        # gc pointer.  A typical example:
+        #
+        #   InsnCall({LocalVar(-8)': None,
+        #             '%esi': '%esi',
+        #             LocalVar(-12)': '%ebx'})
+        #
+        # means that the value at -8 from the frame end is a gc root
+        # across this call; that %esi is a gc root if it was in the
+        # caller (typically because %esi is not modified at all in the
+        # current function); and that the value at -12 from the frame
+        # end is a gc root if %ebx was a gc root in the caller
+        # (typically because the current function saves and restores
+        # %ebx from there in the prologue and epilogue).
+        self.gcroots = {}
+        self.lineno = lineno
+
+    def source_of(self, localvar, tag):
+        tag1 = self.gcroots.setdefault(localvar, tag)
+        assert tag1 == tag, (
+            "conflicting entries for InsnCall.gcroots[%s]:\n%r and %r" % (
+            localvar, tag1, tag))
+        return localvar
+
+    def all_sources_of(self, localvar):
+        return [localvar]
+
+class InsnGCROOT(Insn):
+    _args_ = ['loc']
+    _locals_ = ['loc']
+    def __init__(self, loc):
+        self.loc = loc
+    def requestgcroots(self, tracker):
+        return {self.loc: None}
+
+class InsnPrologue(Insn):
+    def __setattr__(self, attr, value):
+        if attr == 'framesize':
+            assert value == 4, ("unrecognized function prologue - "
+                                "only supports push %ebp; movl %esp, %ebp")
+        Insn.__setattr__(self, attr, value)
+
+class InsnEpilogue(Insn):
+    def __init__(self, framesize=None):
+        if framesize is not None:
+            self.framesize = framesize
+
+

Modified: pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_asmgcroot.py
==============================================================================
--- pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_asmgcroot.py	(original)
+++ pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_asmgcroot.py	Fri Oct 16 23:55:35 2009
@@ -6,18 +6,20 @@
 from pypy.annotation.listdef import s_list_of_strings
 from pypy import conftest
 
-def setup_module(module):
-    if sys.platform == 'win32':
-        if not ('mingw' in os.popen('gcc --version').read() and
-                'GNU' in os.popen('make --version').read()):
-            py.test.skip("mingw32 and MSYS are required for asmgcc on Windows")
-
 class AbstractTestAsmGCRoot:
     # the asmgcroot gc transformer doesn't generate gc_reload_possibly_moved
     # instructions:
     should_be_moving = False
 
     @classmethod
+    def make_config(cls):
+        from pypy.config.pypyoption import get_pypy_config
+        config = get_pypy_config(translating=True)
+        config.translation.gc = cls.gcpolicy
+        config.translation.gcrootfinder = "asmgcc"
+        return config
+
+    @classmethod
     def _makefunc2(cls, func):
         def main(argv):
             arg0 = int(argv[1])
@@ -32,12 +34,7 @@
                 else:
                     print 'Result: "%s"' % (res,)
             return 0
-        from pypy.config.pypyoption import get_pypy_config
-        config = get_pypy_config(translating=True)
-        config.translation.gc = cls.gcpolicy
-        config.translation.gcrootfinder = "asmgcc"
-        if sys.platform == 'win32':
-            config.translation.cc = 'mingw32'
+        config = cls.make_config()
         t = TranslationContext(config=config)
         a = t.buildannotator()
         a.build_types(main, [s_list_of_strings])
@@ -159,3 +156,24 @@
 
         def define_callback_with_collect(cls):
             return lambda: 0
+
+
+class TestAsmGCRootWithSemiSpaceGC_Mingw32(TestAsmGCRootWithSemiSpaceGC):
+    # for the individual tests see
+    # ====> ../../test/test_newgc.py
+
+    @classmethod
+    def setup_class(cls):
+        if sys.platform != 'win32':
+            py.test.skip("mingw32 specific test")
+        if not ('mingw' in os.popen('gcc --version').read() and
+                'GNU' in os.popen('make --version').read()):
+            py.test.skip("mingw32 and MSYS are required for this test")
+
+        test_newgc.TestSemiSpaceGC.setup_class.im_func(cls)
+
+    @classmethod
+    def make_config(cls):
+        config = TestAsmGCRootWithSemiSpaceGC.make_config()
+        config.translation.cc = 'mingw32'
+        return config

Modified: pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_trackgcroot.py
==============================================================================
--- pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_trackgcroot.py	(original)
+++ pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/test/test_trackgcroot.py	Fri Oct 16 23:55:35 2009
@@ -4,7 +4,8 @@
 from pypy.translator.c.gcc.trackgcroot import format_callshape
 from pypy.translator.c.gcc.trackgcroot import LOC_NOWHERE, LOC_REG
 from pypy.translator.c.gcc.trackgcroot import LOC_EBP_BASED, LOC_ESP_BASED
-from pypy.translator.c.gcc.trackgcroot import GcRootTracker
+from pypy.translator.c.gcc.trackgcroot import ElfAssemblerParser
+from pypy.translator.c.gcc.trackgcroot import DarwinAssemblerParser
 from pypy.translator.c.gcc.trackgcroot import FunctionGcRootTracker
 from pypy.translator.c.gcc.trackgcroot import compress_callshape
 from pypy.translator.c.gcc.trackgcroot import decompress_callshape
@@ -63,7 +64,7 @@
 \tMORE STUFF
 """
     lines = source.splitlines(True)
-    parts = list(GcRootTracker().find_functions(iter(lines)))
+    parts = list(ElfAssemblerParser().find_functions(iter(lines)))
     assert len(parts) == 5
     assert parts[0] == (False, lines[:2])
     assert parts[1] == (True,  lines[2:5])
@@ -96,7 +97,7 @@
 \t.section stuff
 """
     lines = source.splitlines(True)
-    parts = list(GcRootTracker(format='darwin').find_functions(iter(lines)))
+    parts = list(DarwinAssemblerParser().find_functions(iter(lines)))
     assert len(parts) == 7
     assert parts[0] == (False, lines[:3])
     assert parts[1] == (True,  lines[3:7])

Modified: pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py	(original)
+++ pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py	Fri Oct 16 23:55:35 2009
@@ -1,7 +1,10 @@
 #! /usr/bin/env python
+import autopath
 
 import re, sys, os, random
 
+from pypy.translator.c.gcc.instruction import *
+
 LABEL               = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
 r_functionstart_elf = re.compile(r"\t.type\s+"+LABEL+",\s*[@]function\s*$")
 r_functionend_elf   = re.compile(r"\t.size\s+"+LABEL+",\s*[.]-"+LABEL+"\s*$")
@@ -48,6 +51,120 @@
 r_localvar_esp  = re.compile(r"(\d*)[(]%esp[)]")
 r_localvar_ebp  = re.compile(r"(-?\d*)[(]%ebp[)]")
 
+class AssemblerParser(object):
+    def __init__(self, verbose=0, shuffle=False):
+        self.verbose = verbose
+        self.shuffle = shuffle
+        self.gcmaptable = []
+        self.seen_main = False
+
+    def process(self, iterlines, newfile, entrypoint='main', filename='?'):
+        for in_function, lines in self.find_functions(iterlines):
+            if in_function:
+                lines = self.process_function(lines, entrypoint, filename)
+            newfile.writelines(lines)
+        if self.verbose == 1:
+            sys.stderr.write('\n')
+
+    def process_function(self, lines, entrypoint, filename):
+        tracker = FunctionGcRootTracker(lines, filetag=getidentifier(filename),
+                                        format=self.format)
+        is_main = tracker.funcname == entrypoint
+        tracker.is_stack_bottom = is_main
+        if self.verbose == 1:
+            sys.stderr.write('.')
+        elif self.verbose > 1:
+            print >> sys.stderr, '[trackgcroot:%s] %s' % (filename,
+                                                          tracker.funcname)
+        table = tracker.computegcmaptable(self.verbose)
+        if self.verbose > 1:
+            for label, state in table:
+                print >> sys.stderr, label, '\t', format_callshape(state)
+        table = compress_gcmaptable(table)
+        if self.shuffle and random.random() < 0.5:
+            self.gcmaptable[:0] = table
+        else:
+            self.gcmaptable.extend(table)
+        self.seen_main |= is_main
+        return tracker.lines
+
+class ElfAssemblerParser(AssemblerParser):
+    format = "elf"
+
+    @classmethod
+    def find_functions(cls, iterlines):
+        functionlines = []
+        in_function = False
+        for line in iterlines:
+            if r_functionstart_elf.match(line):
+                assert not in_function, (
+                    "missed the end of the previous function")
+                yield False, functionlines
+                in_function = True
+                functionlines = []
+            functionlines.append(line)
+            if r_functionend_elf.match(line):
+                assert in_function, (
+                    "missed the start of the current function")
+                yield True, functionlines
+                in_function = False
+                functionlines = []
+        assert not in_function, (
+            "missed the end of the previous function")
+        yield False, functionlines
+
+class DarwinAssemblerParser(AssemblerParser):
+    format = "darwin"
+
+    @classmethod
+    def find_functions(cls, iterlines):
+        functionlines = []
+        in_text = False
+        in_function = False
+        for n, line in enumerate(iterlines):
+            if r_textstart.match(line):
+                assert not in_text, "unexpected repeated .text start: %d" % n
+                in_text = True
+            elif r_sectionstart.match(line):
+                if in_function:
+                    yield in_function, functionlines
+                    functionlines = []
+                in_text = False
+                in_function = False
+            elif in_text and r_functionstart_darwin.match(line):
+                yield in_function, functionlines
+                functionlines = []
+                in_function = True
+            functionlines.append(line)
+
+        if functionlines:
+            yield in_function, functionlines
+
+    def process_function(self, lines, entrypoint, filename):
+        entrypoint = '_' + entrypoint
+        return super(DarwinAssemblerParser, self).process_function(
+            lines, entrypoint, filename)
+
+class Mingw32AssemblerParser(DarwinAssemblerParser):
+    format = "mingw32"
+
+    @classmethod
+    def find_functions(cls, iterlines):
+        functionlines = []
+        in_text = False
+        in_function = False
+        for n, line in enumerate(iterlines):
+            if r_textstart.match(line):
+                in_text = True
+            elif r_sectionstart.match(line):
+                in_text = False
+            elif in_text and r_functionstart_darwin.match(line):
+                yield in_function, functionlines
+                functionlines = []
+                in_function = True
+            functionlines.append(line)
+        if functionlines:
+            yield in_function, functionlines
 
 class GcRootTracker(object):
 
@@ -55,9 +172,6 @@
         self.verbose = verbose
         self.shuffle = shuffle     # to debug the sorting logic in asmgcroot.py
         self.format = format
-        self.clear()
-
-    def clear(self):
         self.gcmaptable = []
         self.seen_main = False
 
@@ -172,102 +286,20 @@
         _label('__gccallshapes')
         output.writelines(shapelines)
 
-    def find_functions(self, iterlines):
-        _find_functions = getattr(self, '_find_functions_' + self.format)
-        return _find_functions(iterlines)
-            
-    def _find_functions_elf(self, iterlines):
-        functionlines = []
-        in_function = False
-        for line in iterlines:
-            if r_functionstart_elf.match(line):
-                assert not in_function, (
-                    "missed the end of the previous function")
-                yield False, functionlines
-                in_function = True
-                functionlines = []
-            functionlines.append(line)
-            if r_functionend_elf.match(line):
-                assert in_function, (
-                    "missed the start of the current function")
-                yield True, functionlines
-                in_function = False
-                functionlines = []
-        assert not in_function, (
-            "missed the end of the previous function")
-        yield False, functionlines
-
-    def _find_functions_darwin(self, iterlines):
-        functionlines = []
-        in_text = False
-        in_function = False
-        for n, line in enumerate(iterlines):
-            if r_textstart.match(line):
-                assert not in_text, "unexpected repeated .text start: %d" % n
-                in_text = True
-            elif r_sectionstart.match(line):
-                if in_function:
-                    yield in_function, functionlines
-                    functionlines = []
-                in_text = False
-                in_function = False
-            elif in_text and r_functionstart_darwin.match(line):
-                yield in_function, functionlines
-                functionlines = []
-                in_function = True
-            functionlines.append(line)
-
-        if functionlines:
-            yield in_function, functionlines
-
-    def _find_functions_mingw32(self, iterlines):
-        functionlines = []
-        in_text = False
-        in_function = False
-        for n, line in enumerate(iterlines):
-            if r_textstart.match(line):
-                in_text = True
-            elif r_sectionstart.match(line):
-                in_text = False
-            elif in_text and r_functionstart_darwin.match(line):
-                yield in_function, functionlines
-                functionlines = []
-                in_function = True
-            functionlines.append(line)
-        if functionlines:
-            yield in_function, functionlines
-
     def process(self, iterlines, newfile, entrypoint='main', filename='?'):
-        if self.format in ('darwin', 'mingw32'):
-            entrypoint = '_' + entrypoint
-        for in_function, lines in self.find_functions(iterlines):
+        cls = globals()[self.format.title() + "AssemblerParser"]
+        parser = cls(verbose=self.verbose, shuffle=self.shuffle)
+        for in_function, lines in parser.find_functions(iterlines):
             if in_function:
-                lines = self.process_function(lines, entrypoint, filename)
+                lines = parser.process_function(lines, entrypoint, filename)
             newfile.writelines(lines)
         if self.verbose == 1:
             sys.stderr.write('\n')
-
-    def process_function(self, lines, entrypoint, filename):
-        tracker = FunctionGcRootTracker(lines, filetag=getidentifier(filename),
-                                        format=self.format)
-        is_main = tracker.funcname == entrypoint
-        tracker.is_stack_bottom = is_main
-        if self.verbose == 1:
-            sys.stderr.write('.')
-        elif self.verbose > 1:
-            print >> sys.stderr, '[trackgcroot:%s] %s' % (filename,
-                                                          tracker.funcname)
-        table = tracker.computegcmaptable(self.verbose)
-        if self.verbose > 1:
-            for label, state in table:
-                print >> sys.stderr, label, '\t', format_callshape(state)
-        table = compress_gcmaptable(table)
         if self.shuffle and random.random() < 0.5:
-            self.gcmaptable[:0] = table
+            self.gcmaptable[:0] = parser.gcmaptable
         else:
-            self.gcmaptable.extend(table)
-        self.seen_main |= is_main
-        return tracker.lines
+            self.gcmaptable.extend(parser.gcmaptable)
+        self.seen_main |= parser.seen_main
 
 
 class FunctionGcRootTracker(object):
@@ -893,213 +925,6 @@
 class NoPatternMatch(Exception):
     pass
 
-class SomeNewValue(object):
-    pass
-somenewvalue = SomeNewValue()
-
-class LocalVar(object):
-    # A local variable location at position 'ofs_from_frame_end',
-    # which is counted from the end of the stack frame (so it is always
-    # negative, unless it refers to arguments of the current function).
-    def __init__(self, ofs_from_frame_end, hint=None):
-        self.ofs_from_frame_end = ofs_from_frame_end
-        self.hint = hint
-
-    def __repr__(self):
-        return '<%+d;%s>' % (self.ofs_from_frame_end, self.hint or 'e*p')
-
-    def __hash__(self):
-        return hash(self.ofs_from_frame_end)
-
-    def __cmp__(self, other):
-        if isinstance(other, LocalVar):
-            return cmp(self.ofs_from_frame_end, other.ofs_from_frame_end)
-        else:
-            return 1
-
-    def getlocation(self, framesize, uses_frame_pointer):
-        if (self.hint == 'esp' or not uses_frame_pointer
-            or self.ofs_from_frame_end % 2 != 0):
-            # try to use esp-relative addressing
-            ofs_from_esp = framesize + self.ofs_from_frame_end
-            if ofs_from_esp % 2 == 0:
-                return frameloc(LOC_ESP_BASED, ofs_from_esp)
-            # we can get an odd value if the framesize is marked as bogus
-            # by visit_andl()
-        assert uses_frame_pointer
-        ofs_from_ebp = self.ofs_from_frame_end + 4
-        return frameloc(LOC_EBP_BASED, ofs_from_ebp)
-
-
-class Insn(object):
-    _args_ = []
-    _locals_ = []
-
-    def __repr__(self):
-        return '%s(%s)' % (self.__class__.__name__,
-                           ', '.join([str(getattr(self, name))
-                                      for name in self._args_]))
-    def requestgcroots(self, tracker):
-        return {}
-
-    def source_of(self, localvar, tag):
-        return localvar
-
-    def all_sources_of(self, localvar):
-        return [localvar]
-
-class Label(Insn):
-    _args_ = ['label', 'lineno']
-    def __init__(self, label, lineno):
-        self.label = label
-        self.lineno = lineno
-        self.previous_insns = []   # all insns that jump (or fallthrough) here
-
-class InsnFunctionStart(Insn):
-    framesize = 0
-    previous_insns = ()
-    def __init__(self):
-        self.arguments = {}
-        for reg in CALLEE_SAVE_REGISTERS:
-            self.arguments[reg] = somenewvalue
-
-    def source_of(self, localvar, tag):
-        if localvar not in self.arguments:
-            if localvar in ('%eax', '%edx', '%ecx'):
-                # xxx this might show a bug in trackgcroot.py failing to
-                # figure out which instruction stored a value in these
-                # registers.  However, this case also occurs when the
-                # the function's calling convention was optimized by gcc:
-                # the 3 registers above are then used to pass arguments
-                pass
-            else:
-                assert (isinstance(localvar, LocalVar) and
-                        localvar.ofs_from_frame_end > 0), (
-                    "must come from an argument to the function, got %r" %
-                    (localvar,))
-            self.arguments[localvar] = somenewvalue
-        return self.arguments[localvar]
-
-    def all_sources_of(self, localvar):
-        return []
-
-class InsnSetLocal(Insn):
-    _args_ = ['target', 'sources']
-    _locals_ = ['target', 'sources']
-
-    def __init__(self, target, sources=()):
-        self.target = target
-        self.sources = sources
-
-    def source_of(self, localvar, tag):
-        if localvar == self.target:
-            return somenewvalue
-        return localvar
-
-    def all_sources_of(self, localvar):
-        if localvar == self.target:
-            return self.sources
-        return [localvar]
-
-class InsnCopyLocal(Insn):
-    _args_ = ['source', 'target']
-    _locals_ = ['source', 'target']
-
-    def __init__(self, source, target):
-        self.source = source
-        self.target = target
-
-    def source_of(self, localvar, tag):
-        if localvar == self.target:
-            return self.source
-        return localvar
-
-    def all_sources_of(self, localvar):
-        if localvar == self.target:
-            return [self.source]
-        return [localvar]
-
-class InsnStackAdjust(Insn):
-    _args_ = ['delta']
-    def __init__(self, delta):
-        assert delta % 2 == 0     # should be "% 4", but there is the special
-        self.delta = delta        # case of 'pushw' to handle
-
-class InsnCannotFollowEsp(InsnStackAdjust):
-    def __init__(self):
-        self.delta = -7     # use an odd value as marker
-
-class InsnStop(Insn):
-    pass
-
-class InsnRet(InsnStop):
-    framesize = 0
-    def requestgcroots(self, tracker):
-        # no need to track the value of these registers in the caller
-        # function if we are the main(), or if we are flagged as a
-        # "bottom" function (a callback from C code)
-        if tracker.is_stack_bottom:
-            return {}
-        else:
-            return dict(zip(CALLEE_SAVE_REGISTERS, CALLEE_SAVE_REGISTERS))
-
-class InsnCall(Insn):
-    _args_ = ['lineno', 'gcroots']
-    def __init__(self, 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
-        # (register names or LocalVar instances).  The value
-        # corresponding to a key is the "tag", which is None for a
-        # normal gc root, or else the name of a callee-saved register.
-        # In the latter case it means that this is only a gc root if the
-        # corresponding register in the caller was really containing a
-        # gc pointer.  A typical example:
-        #
-        #   InsnCall({LocalVar(-8)': None,
-        #             '%esi': '%esi',
-        #             LocalVar(-12)': '%ebx'})
-        #
-        # means that the value at -8 from the frame end is a gc root
-        # across this call; that %esi is a gc root if it was in the
-        # caller (typically because %esi is not modified at all in the
-        # current function); and that the value at -12 from the frame
-        # end is a gc root if %ebx was a gc root in the caller
-        # (typically because the current function saves and restores
-        # %ebx from there in the prologue and epilogue).
-        self.gcroots = {}
-        self.lineno = lineno
-
-    def source_of(self, localvar, tag):
-        tag1 = self.gcroots.setdefault(localvar, tag)
-        assert tag1 == tag, (
-            "conflicting entries for InsnCall.gcroots[%s]:\n%r and %r" % (
-            localvar, tag1, tag))
-        return localvar
-
-    def all_sources_of(self, localvar):
-        return [localvar]
-
-class InsnGCROOT(Insn):
-    _args_ = ['loc']
-    _locals_ = ['loc']
-    def __init__(self, loc):
-        self.loc = loc
-    def requestgcroots(self, tracker):
-        return {self.loc: None}
-
-class InsnPrologue(Insn):
-    def __setattr__(self, attr, value):
-        if attr == 'framesize':
-            assert value == 4, ("unrecognized function prologue - "
-                                "only supports push %ebp; movl %esp, %ebp")
-        Insn.__setattr__(self, attr, value)
-
-class InsnEpilogue(Insn):
-    def __init__(self, framesize=None):
-        if framesize is not None:
-            self.framesize = framesize
-
 
 if sys.platform != 'win32':
     FUNCTIONS_NOT_RETURNING = {
@@ -1117,24 +942,6 @@
         '__wassert': None,
         }
 
-CALLEE_SAVE_REGISTERS_NOEBP = ['%ebx', '%esi', '%edi']
-CALLEE_SAVE_REGISTERS = CALLEE_SAVE_REGISTERS_NOEBP + ['%ebp']
-
-LOC_NOWHERE   = 0
-LOC_REG       = 1
-LOC_EBP_BASED = 2
-LOC_ESP_BASED = 3
-LOC_MASK      = 0x03
-
-REG2LOC = {}
-for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS):
-    REG2LOC[_reg] = LOC_REG | (_i<<2)
-
-def frameloc(base, offset):
-    assert base in (LOC_EBP_BASED, LOC_ESP_BASED)
-    assert offset % 4 == 0
-    return base | offset
-
 # __________ debugging output __________
 
 def format_location(loc):
@@ -1314,6 +1121,5 @@
             f.close()
             if output_raw_table:
                 tracker.dump_raw_table(sys.stdout)
-                tracker.clear()
     if not output_raw_table:
         tracker.dump(sys.stdout)



More information about the Pypy-commit mailing list