[pypy-commit] pypy x86-dump-labels: add a new _x86_labels attribute to the looptoken, and display them when disassembling the compiled code; useful to see where each resop begins

antocuni noreply at buildbot.pypy.org
Wed May 11 14:32:03 CEST 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: x86-dump-labels
Changeset: r44071:973a4fd8fc20
Date: 2011-05-11 12:08 +0200
http://bitbucket.org/pypy/pypy/changeset/973a4fd8fc20/

Log:	add a new _x86_labels attribute to the looptoken, and display them
	when disassembling the compiled code; useful to see where each resop
	begins

diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -305,6 +305,10 @@
         rawstart = mc.materialize(self.cpu.asmmemmgr, [])
         self.stack_check_slowpath = rawstart
 
+    def add_label(self, name):
+        pos = self.mc.get_relative_pos()
+        self.currently_compiling_loop._x86_labels.append((pos, name))
+
     def assemble_loop(self, inputargs, operations, looptoken, log):
         '''adds the following attributes to looptoken:
                _x86_loop_code       (an integer giving an address)
@@ -328,6 +332,7 @@
 
         self.setup(looptoken)
         self.currently_compiling_loop = looptoken
+        looptoken._x86_labels = []
         funcname = self._find_debug_merge_point(operations)
         if log:
             self._register_counter()
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -406,6 +406,7 @@
         #self.operations = operations
         while i < len(operations):
             op = operations[i]
+            self.assembler.add_label(op.repr())
             self.rm.position = i
             self.xrm.position = i
             if op.has_no_side_effect() and op.result not in self.longevity:
@@ -424,6 +425,7 @@
             i += 1
         assert not self.rm.reg_bindings
         assert not self.xrm.reg_bindings
+        self.assembler.add_label('--end of the loop--')
 
     def _compute_vars_longevity(self, inputargs, operations):
         # compute a dictionary that maps variables to index in
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -68,7 +68,8 @@
         for p in range(looptoken._x86_fullsize):
             data.append(src[p])
         data = ''.join(data)
-        lines = machine_code_dump(data, addr, self.backend_name)
+        lines = machine_code_dump(data, addr, self.backend_name,
+                                  labels=looptoken._x86_labels)
         print ''.join(lines)
 
     def compile_loop(self, inputargs, operations, looptoken, log=True):
diff --git a/pypy/jit/backend/x86/test/test_runner.py b/pypy/jit/backend/x86/test/test_runner.py
--- a/pypy/jit/backend/x86/test/test_runner.py
+++ b/pypy/jit/backend/x86/test/test_runner.py
@@ -390,6 +390,29 @@
         res = self.cpu.get_latest_value_int(0)
         assert res == 20
 
+    def test_labels(self):
+        i0 = BoxInt()
+        i1 = BoxInt()
+        i2 = BoxInt()
+        looptoken = LoopToken()
+        operations = [
+            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
+            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
+            ResOperation(rop.JUMP, [i1], None, descr=looptoken),
+            ]
+        inputargs = [i0]
+        self.cpu.compile_loop(inputargs, operations, looptoken)
+        labels = looptoken._x86_labels
+        expected = ['getfield_raw',
+                    'int_add',
+                    'setfield_raw',
+                    'int_add',
+                    'int_le',
+                    'jump',
+                    '--end of the loop--']
+        assert len(labels) == len(expected)
+        for (off, lbl), exp_lbl in zip(labels, expected):
+            assert exp_lbl in lbl
 
 class TestDebuggingAssembler(object):
     def setup_method(self, meth):
diff --git a/pypy/jit/backend/x86/tool/test/test_viewcode.py b/pypy/jit/backend/x86/tool/test/test_viewcode.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/backend/x86/tool/test/test_viewcode.py
@@ -0,0 +1,55 @@
+from cStringIO import StringIO
+from pypy.jit.backend.x86.tool.viewcode import format_code_dump_with_labels
+
+def test_format_code_dump_with_labels():
+    lines = StringIO("""
+aa00 <.data>:
+aa00: one
+aa01: two
+aa03: three
+aa04: for
+aa05: five
+aa06: six
+aa0c: seven
+aa12: eight
+""".strip()).readlines()
+    #
+    labels = [(0x00, 'AAA'), (0x03, 'BBB'), (0x0c, 'CCC')]
+    lines = format_code_dump_with_labels(0xAA00, lines, labels)
+    out = ''.join(lines)
+    assert out == """
+aa00 <.data>:
+
+AAA
+aa00: one
+aa01: two
+
+BBB
+aa03: three
+aa04: for
+aa05: five
+aa06: six
+
+CCC
+aa0c: seven
+aa12: eight
+""".strip()
+
+
+def test_format_code_dump_with_labels_no_labels():
+    input = """
+aa00 <.data>:
+aa00: one
+aa01: two
+aa03: three
+aa04: for
+aa05: five
+aa06: six
+aa0c: seven
+aa12: eight
+""".strip()
+    lines = StringIO(input).readlines()
+    #
+    lines = format_code_dump_with_labels(0xAA00, lines, labels=None)
+    out = ''.join(lines)
+    assert out.strip() == input
diff --git a/pypy/jit/backend/x86/tool/viewcode.py b/pypy/jit/backend/x86/tool/viewcode.py
--- a/pypy/jit/backend/x86/tool/viewcode.py
+++ b/pypy/jit/backend/x86/tool/viewcode.py
@@ -31,7 +31,7 @@
 if sys.platform == "win32":
     XXX   # lots more in Psyco
 
-def machine_code_dump(data, originaddr, backend_name):
+def machine_code_dump(data, originaddr, backend_name, labels=None):
     objdump_backend_option = {
         'x86': 'i386',
         'x86_64': 'x86-64',
@@ -51,7 +51,29 @@
     }, 'r')
     result = g.readlines()
     g.close()
-    return result[6:]   # drop some objdump cruft
+    lines = result[6:]   # drop some objdump cruft
+    return format_code_dump_with_labels(originaddr, lines, labels)
+
+def format_code_dump_with_labels(originaddr, lines, labels):
+    from pypy.rlib.rarithmetic import r_uint
+    if not labels:
+        labels = []
+    originaddr = r_uint(originaddr)
+    itlines = iter(lines)
+    yield itlines.next() # don't process the first line
+    for lbl_start, lbl_name in labels:
+        for line in itlines:
+            addr, _ = line.split(':', 1)
+            addr = int(addr, 16)
+            if addr >= originaddr+lbl_start:
+                yield '\n'
+                yield lbl_name + '\n'
+                yield line
+                break
+            yield line
+    # yield all the remaining lines
+    for line in itlines:
+        yield line
 
 def load_symbols(filename):
     # the program that lists symbols, and the output it gives
@@ -135,6 +157,7 @@
     def disassemble(self):
         if not hasattr(self, 'text'):
             lines = machine_code_dump(self.data, self.addr, self.world.backend_name)
+            lines = list(lines)
             # instead of adding symbol names in the dumps we could
             # also make the 0xNNNNNNNN addresses be red and show the
             # symbol name when the mouse is over them


More information about the pypy-commit mailing list