Commits

Maciej Fijalkowski  committed 97b1b55

General progress

  • Participants
  • Parent commits 58d7fbf

Comments (0)

Files changed (10)

File baseviewer.py

 
-import re
 import flask
 from pypy.tool.logparser import parse_log_file, extract_category
 from pypy.jit.metainterp.test.oparser import parse
-from pypy.jit.metainterp.resoperation import rop
 from module_finder import load_code
+from loops import slice_debug_merge_points, parse_log_counts
 
 from pygments import highlight
 from pygments.lexers import PythonLexer
 from pygments.formatters import HtmlFormatter
 
-class LoopChunk(object):
-    filename = None
-    lineno = 0
-    name = None
-    
-    def __init__(self, operations):
-        self.operations = operations
-        if self.operations[0].getopnum() == rop.DEBUG_MERGE_POINT:
-            m = re.match("<code object ([<>\w]+), file '(.+?)', line (\d+)>",
-                         operations[0].getarg(0)._get_str())
-            self.name, self.filename, lineno = m.groups()
-            self.lineno = int(lineno)
-
-    def repr(self):
-        if self.filename is None:
-            return "Unknown"
-        return "%s, file '%s', line %d" % (self.name, self.filename, self.lineno)
-
-    def __repr__(self):
-        return "[%s]" % ", ".join([repr(op) for op in self.operations])
-
-class Loop(object):
-    filename = None
-    name = None
-    lineno = 0
-    
-    def __init__(self, chunks):
-        self.chunks = chunks
-        for chunk in self.chunks:
-            if chunk.filename is not None:
-                self.lineno = chunk.lineno
-                self.filename = chunk.filename
-                self.name = chunk.name
-                break
-
-    def repr(self):
-        if self.filename is None:
-            return "Unknown"
-        return "%s, file '%s', line %d" % (self.name, self.filename, self.lineno)
-
-    def key(self):
-        pass
-
-    def __repr__(self):
-        return "[%s]" % ", ".join([repr(chunk) for chunk in self.chunks])
-
-def slice_debug_merge_points(loop):
-    so_far = []
-    res = []
-    for op in loop.operations:
-        if op.getopnum() == rop.DEBUG_MERGE_POINT:
-            if so_far:
-                res.append(LoopChunk(so_far))
-                so_far = []
-        so_far.append(op)
-    if so_far:
-        res.append(LoopChunk(so_far))
-    return Loop(res)
-
 class Server(object):
     def __init__(self, loops):
         self.loops = loops
         return flask.render_template('loop.html', code=code,
                                      startline=startline)
 
-def parse_log_counts(lines):
-    for line in lines:
-        pass
-
 def main():
     log = parse_log_file('log')
     log_counts = parse_log_counts(open('log.count').readlines())

File disassembler.py

 
     def __repr__(self):
         if self.arg is None:
-            return "<%s at %d>" (self.__class__.__name__, self.pos)
+            return "<%s at %d>" % (self.__class__.__name__, self.pos)
         return "<%s (%s) at %d>" % (self.__class__.__name__, self.arg, self.pos)
 
 class CodeRepresentation(object):
+
+import re
+from pypy.jit.metainterp.resoperation import rop
+from module_finder import load_code
+from disassembler import dis
+
+class Bytecode(object):
+    filename = None
+    startlineno = 0
+    name = None
+    code = None
+    bytecode_no = 0
+    
+    def __init__(self, operations):
+        self.operations = operations
+        if self.operations[0].getopnum() == rop.DEBUG_MERGE_POINT:
+            m = re.match("<code object ([<>\w]+), file '(.+?)', line (\d+)> #(\d+)",
+                         operations[0].getarg(0)._get_str())
+            self.name, self.filename, lineno, bytecode_no = m.groups()
+            self.startlineno = int(lineno)
+            self.bytecode_no = int(bytecode_no)
+
+    def repr(self):
+        if self.filename is None:
+            return "Unknown"
+        return "%s, file '%s', line %d" % (self.name, self.filename,
+                                           self.startlineno)
+
+    def getlineno(self):
+        if self.code is None:
+            self.code = dis(load_code(self.filename, self.name,
+                                      self.startlineno))
+        return self.code.map[self.bytecode_no].lineno
+    lineno = property(getlineno)
+
+    def __repr__(self):
+        return "[%s]" % ", ".join([repr(op) for op in self.operations])
+
+class Loop(object):
+    filename = None
+    name = None
+    startlineno = 0
+    
+    def __init__(self, chunks):
+        self.chunks = chunks
+        for chunk in self.chunks:
+            if chunk.filename is not None:
+                self.startlineno = chunk.startlineno
+                self.filename = chunk.filename
+                self.name = chunk.name
+                break
+
+    def repr(self):
+        if self.filename is None:
+            return "Unknown"
+        return "%s, file '%s', line %d" % (self.name, self.filename,
+                                           self.startlineno)
+
+    def key(self):
+        pass
+
+    def __repr__(self):
+        return "[%s]" % ", ".join([repr(chunk) for chunk in self.chunks])
+
+def slice_debug_merge_points(loop):
+    so_far = []
+    res = []
+    for op in loop.operations:
+        if op.getopnum() == rop.DEBUG_MERGE_POINT:
+            if so_far:
+                res.append(Bytecode(so_far))
+                so_far = []
+        so_far.append(op)
+    if so_far:
+        res.append(Bytecode(so_far))
+    return Loop(res)
+
+def parse_log_counts(lines):
+    for line in lines:
+        pass

File test/__init__.py

Empty file added.

File test/test_base.py

-
-from pypy.jit.metainterp.test.oparser import parse
-from baseviewer import slice_debug_merge_points, parse_log_counts
-
-def test_split():
-    ops = parse('''
-    [i0]
-    debug_merge_point("<code object stuff, file '/tmp/x.py', line 200> #10 ADD")
-    debug_merge_point("<code object stuf, file '/tmp/x.py', line 201> #11 SUB")
-    i1 = int_add(i0, 1)
-    debug_merge_point("<code object stuf, file '/tmp/x.py', line 202> #11 SUB")
-    i2 = int_add(i1, 1)
-    ''', no_namespace=True, nonstrict=True)
-    res = slice_debug_merge_points(ops)
-    assert len(res.chunks) == 3
-    assert len(res.chunks[0].operations) == 1
-    assert len(res.chunks[1].operations) == 2
-    assert len(res.chunks[2].operations) == 2
-    
-def test_name():
-    ops = parse('''
-    [i0]
-    debug_merge_point("<code object stuff, file '/tmp/x.py', line 200> #10 ADD")
-    debug_merge_point("<code object stuf, file '/tmp/x.py', line 201> #11 SUB")
-    i1 = int_add(i0, 1)
-    debug_merge_point("<code object stuf, file '/tmp/x.py', line 202> #11 SUB")
-    i2 = int_add(i1, 1)
-    ''')
-    res = slice_debug_merge_points(ops)
-    assert res.repr() == res.chunks[0].repr()
-    assert res.repr() == "stuff, file '/tmp/x.py', line 200"
-    assert res.lineno == 200
-    assert res.filename == '/tmp/x.py'
-    assert res.name == 'stuff'
-
-def test_name_no_first():
-    ops = parse('''
-    [i0]
-    i3 = int_add(i0, 1)
-    debug_merge_point("<code object stuff, file '/tmp/x.py', line 200> #10 ADD")
-    debug_merge_point("<code object stuf, file '/tmp/x.py', line 201> #11 SUB")
-    i1 = int_add(i0, 1)
-    debug_merge_point("<code object stuf, file '/tmp/x.py', line 202> #11 SUB")
-    i2 = int_add(i1, 1)
-    ''')
-    res = slice_debug_merge_points(ops)
-    assert res.repr() == res.chunks[1].repr()
-
-LINES = """19883   <code object _optimize_charset, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 214> #290 FOR_ITER
-645     <code object _optimize_charset, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 214> #290 FOR_ITER
-3810    <code object _mk_bitmap, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 265> #66 FOR_ITER
-334     <code object _mk_bitmap, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 265> #66 FOR_ITER
-5       <code object _optimize_charset, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 214> #346 POP_TOP
-2256920 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 67> #24 POP_TOP
-2256864 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 46> #20 POP_TOP
-1955880 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 67> #9 STORE_FAST
-1956214 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 46> #9 STORE_FAST
-""".split("\n")
-
-#def test_parse_log_count():
-#    parse_log_counts(LINES)

File test/test_disassembler.py

         'LOAD_FAST', 'LOAD_FAST', 'BINARY_ADD', 'RETURN_VALUE']
     for i in range(4):
         assert res.opcodes[i].lineno == f.func_code.co_firstlineno + 1
+    

File test/test_loops.py

+
+from pypy.jit.metainterp.test.oparser import parse
+from loops import slice_debug_merge_points, parse_log_counts
+import py
+
+def test_split():
+    ops = parse('''
+    [i0]
+    debug_merge_point("<code object stuff, file '/tmp/x.py', line 200> #10 ADD")
+    debug_merge_point("<code object stuf, file '/tmp/x.py', line 201> #11 SUB")
+    i1 = int_add(i0, 1)
+    debug_merge_point("<code object stuf, file '/tmp/x.py', line 202> #11 SUB")
+    i2 = int_add(i1, 1)
+    ''', no_namespace=True, nonstrict=True)
+    res = slice_debug_merge_points(ops)
+    assert len(res.chunks) == 3
+    assert len(res.chunks[0].operations) == 1
+    assert len(res.chunks[1].operations) == 2
+    assert len(res.chunks[2].operations) == 2
+    assert res.chunks[2].bytecode_no == 11
+    
+def test_name():
+    ops = parse('''
+    [i0]
+    debug_merge_point("<code object stuff, file '/tmp/x.py', line 200> #10 ADD")
+    debug_merge_point("<code object stuf, file '/tmp/x.py', line 201> #11 SUB")
+    i1 = int_add(i0, 1)
+    debug_merge_point("<code object stuf, file '/tmp/x.py', line 202> #11 SUB")
+    i2 = int_add(i1, 1)
+    ''')
+    res = slice_debug_merge_points(ops)
+    assert res.repr() == res.chunks[0].repr()
+    assert res.repr() == "stuff, file '/tmp/x.py', line 200"
+    assert res.startlineno == 200
+    assert res.filename == '/tmp/x.py'
+    assert res.name == 'stuff'
+
+def test_name_no_first():
+    ops = parse('''
+    [i0]
+    i3 = int_add(i0, 1)
+    debug_merge_point("<code object stuff, file '/tmp/x.py', line 200> #10 ADD")
+    debug_merge_point("<code object stuf, file '/tmp/x.py', line 201> #11 SUB")
+    i1 = int_add(i0, 1)
+    debug_merge_point("<code object stuf, file '/tmp/x.py', line 202> #11 SUB")
+    i2 = int_add(i1, 1)
+    ''')
+    res = slice_debug_merge_points(ops)
+    assert res.repr() == res.chunks[1].repr()
+
+LINES = """19883   <code object _optimize_charset, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 214> #290 FOR_ITER
+645     <code object _optimize_charset, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 214> #290 FOR_ITER
+3810    <code object _mk_bitmap, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 265> #66 FOR_ITER
+334     <code object _mk_bitmap, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 265> #66 FOR_ITER
+5       <code object _optimize_charset, file '/home/fijal/src/pypy-trunk/lib-python/modified-2.5.2/sre_compile.py', line 214> #346 POP_TOP
+2256920 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 67> #24 POP_TOP
+2256864 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 46> #20 POP_TOP
+1955880 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 67> #9 STORE_FAST
+1956214 <code object <genexp>, file '/home/fijal/src/pypy-benchmarks/unladen_swallow/performance/bm_ai.py', line 46> #9 STORE_FAST
+""".split("\n")
+
+#def test_parse_log_count():
+#    parse_log_counts(LINES)
+
+def test_lineno():
+    fname = str(py.path.local(__file__).join('..', 'x.py'))
+    ops = parse('''
+    [i0, i1]
+    debug_merge_point("<code object f, file '%(fname)s', line 2> #0 LOAD_FAST")
+    debug_merge_point("<code object f, file '%(fname)s', line 2> #3 LOAD_FAST")
+    debug_merge_point("<code object f, file '%(fname)s', line 2> #6 BINARY_ADD")
+    debug_merge_point("<code object f, file '%(fname)s', line 2> #7 RETURN_VALUE")
+    ''' % locals())
+    res = slice_debug_merge_points(ops)
+    assert res.chunks[1].lineno == 3

File test/test_module.py

 import re
 
 def test_gather_code():
-    fname = py.path.local(__file__).join('..', 're.pyc')
+    fname = py.path.local(__file__).join('..', 'xre.pyc')
     codes = gather_all_code_objs(fname)
     assert len(codes) == 21
     assert sorted(codes.keys()) == [102, 134, 139, 144, 153, 164, 169, 181, 188, 192, 197, 206, 229, 251, 266, 271, 277, 285, 293, 294, 308]
     assert sorted(codes.keys()) == [102, 134, 139, 144, 153, 164, 169, 181, 188, 192, 197, 206, 229, 251, 266, 271, 277, 285, 293, 294, 308]
 
 def test_load_code():
-    fname = py.path.local(__file__).join('..', 're.pyc')
+    fname = py.path.local(__file__).join('..', 'xre.pyc')
     code = load_code(fname, 'name', 144)
     assert code.co_name == 'sub'
     assert code.co_filename == '/usr/lib/python2.6/re.py'
+
+def f(a, b):
+    return a + b

File test/xre.pyc

Binary file added.