[pypy-svn] r76382 - in pypy/trunk/pypy/jit/backend/x86: . test
fijal at codespeak.net
fijal at codespeak.net
Wed Jul 28 11:30:29 CEST 2010
Author: fijal
Date: Wed Jul 28 11:30:28 2010
New Revision: 76382
Modified:
pypy/trunk/pypy/jit/backend/x86/assembler.py
pypy/trunk/pypy/jit/backend/x86/runner.py
pypy/trunk/pypy/jit/backend/x86/test/test_runner.py
Log:
Merge part of improved-asm-debugging branch. I'm not sure what to do with
this data, but it's already fairly useful (branch will probably continue)
Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/assembler.py Wed Jul 28 11:30:28 2010
@@ -1,4 +1,4 @@
-import sys
+import sys, os
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.metainterp.history import Const, Box, BoxInt, BoxPtr, BoxFloat
from pypy.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT,\
@@ -17,6 +17,7 @@
from pypy.jit.backend.x86.support import values_array
from pypy.rlib.debug import debug_print
from pypy.rlib import rgc
+from pypy.rlib.streamio import open_file_as_stream
# our calling convention - we pass first 6 args in registers
# and the rest stays on the stack
@@ -99,6 +100,7 @@
mc_size = MachineCodeBlockWrapper.MC_DEFAULT_SIZE
_float_constants = None
_regalloc = None
+ _output_loop_log = None
def __init__(self, cpu, translate_support_code=False,
failargs_limit=1000):
@@ -113,17 +115,25 @@
self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
self.fail_boxes_float = values_array(lltype.Float, failargs_limit)
self.fail_ebp = 0
+ self.loop_run_counter = values_array(lltype.Signed, 10000)
+ self.loop_names = []
+ # if we have 10000 loops, we have some other problems I guess
self.loc_float_const_neg = None
self.loc_float_const_abs = None
self.malloc_fixedsize_slowpath1 = 0
self.malloc_fixedsize_slowpath2 = 0
self.setup_failure_recovery()
+ self._loop_counter = 0
+ self._debug = False
def leave_jitted_hook(self):
ptrs = self.fail_boxes_ptr.ar
llop.gc_assume_young_pointers(lltype.Void,
llmemory.cast_ptr_to_adr(ptrs))
+ def set_debug(self, v):
+ self._debug = v
+
def make_sure_mc_exists(self):
if self.mc is None:
# the address of the function called by 'new'
@@ -157,6 +167,22 @@
self._build_float_constants()
if hasattr(gc_ll_descr, 'get_malloc_fixedsize_slowpath_addr'):
self._build_malloc_fixedsize_slowpath()
+ s = os.environ.get('PYPYLOG')
+ if s:
+ if s.find(':') != -1:
+ s = s.split(':')[-1]
+ self.set_debug(True)
+ self._output_loop_log = s + ".count"
+
+ def finish_once(self):
+ if self._debug:
+ output_log = self._output_loop_log
+ assert output_log is not None
+ f = open_file_as_stream(output_log, "w")
+ for i in range(self._loop_counter):
+ f.write(self.loop_names[i] + ":" +
+ str(self.loop_run_counter.getitem(i)) + "\n")
+ f.close()
def _build_float_constants(self):
# 11 words: 8 words for the data, and up to 3 words for alignment
@@ -207,9 +233,9 @@
_x86_param_depth
_x86_arglocs
"""
+ self.make_sure_mc_exists()
funcname = self._find_debug_merge_point(operations)
- self.make_sure_mc_exists()
regalloc = RegAlloc(self, self.cpu.translate_support_code)
arglocs = regalloc.prepare_loop(inputargs, operations, looptoken)
looptoken._x86_arglocs = arglocs
@@ -244,9 +270,9 @@
def assemble_bridge(self, faildescr, inputargs, operations):
+ self.make_sure_mc_exists()
funcname = self._find_debug_merge_point(operations)
- self.make_sure_mc_exists()
arglocs = self.rebuild_faillocs_from_descr(
faildescr._x86_failure_recovery_bytecode)
if not we_are_translated():
@@ -278,10 +304,18 @@
self.mc.end_function()
def _find_debug_merge_point(self, operations):
+
for op in operations:
if op.opnum == rop.DEBUG_MERGE_POINT:
- return op.args[0]._get_str()
- return ""
+ funcname = op.args[0]._get_str()
+ break
+ else:
+ funcname = "<loop %d>" % self._loop_counter
+ # invent the counter, so we don't get too confused
+ if self._debug:
+ self.loop_names.append(funcname)
+ self._loop_counter += 1
+ return funcname
def patch_jump_for_descr(self, faildescr, adr_new_target):
adr_jump_offset = faildescr._x86_adr_jump_offset
@@ -292,6 +326,15 @@
def _assemble(self, regalloc, operations):
self._regalloc = regalloc
+ if self._debug:
+ # before doing anything, let's increase a counter
+ # we need one register free (a bit of a hack, but whatever)
+ self.mc.PUSH(eax)
+ adr = self.loop_run_counter.get_addr_for_num(self._loop_counter - 1)
+ self.mc.MOV(eax, heap(adr))
+ self.mc.ADD(eax, imm(1))
+ self.mc.MOV(heap(adr), eax)
+ self.mc.POP(eax)
regalloc.walk_operations(operations)
self.mc.done()
self.mc2.done()
Modified: pypy/trunk/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/runner.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/runner.py Wed Jul 28 11:30:28 2010
@@ -44,6 +44,7 @@
self.profile_agent.startup()
def finish_once(self):
+ self.assembler.finish_once()
self.profile_agent.shutdown()
def compile_loop(self, inputargs, operations, looptoken):
Modified: pypy/trunk/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_runner.py (original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_runner.py Wed Jul 28 11:30:28 2010
@@ -9,8 +9,11 @@
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp.executor import execute
from pypy.jit.backend.test.runner_test import LLtypeBackendTest
+from pypy.jit.metainterp.test.oparser import parse
+from pypy.tool.udir import udir
import ctypes
import sys
+import os
class FakeStats(object):
pass
@@ -390,3 +393,35 @@
self.cpu.set_future_value_int(0, base_v.value)
self.cpu.execute_token(looptoken)
assert self.cpu.get_latest_value_int(0) == 1024
+
+class TestDebuggingAssembler(object):
+ def setup_method(self, meth):
+ self.pypylog = os.environ.get('PYPYLOG', None)
+ self.logfile = str(udir.join('x86_runner.log'))
+ os.environ['PYPYLOG'] = "mumble:" + self.logfile
+ self.cpu = CPU(rtyper=None, stats=FakeStats())
+
+ def teardown_method(self, meth):
+ if self.pypylog is not None:
+ os.environ['PYPYLOG'] = self.pypylog
+
+ def test_debugger_on(self):
+ loop = """
+ [i0]
+ debug_merge_point('xyz')
+ i1 = int_add(i0, 1)
+ i2 = int_ge(i1, 10)
+ guard_false(i2) []
+ jump(i1)
+ """
+ ops = parse(loop)
+ self.cpu.assembler.set_debug(True)
+ self.cpu.compile_loop(ops.inputargs, ops.operations, ops.token)
+ self.cpu.set_future_value_int(0, 0)
+ self.cpu.execute_token(ops.token)
+ # check debugging info
+ assert self.cpu.assembler.loop_names == ["xyz"]
+ assert self.cpu.assembler.loop_run_counter.getitem(0) == 10
+ self.cpu.finish_once()
+ lines = py.path.local(self.logfile + ".count").readlines()
+ assert lines[0] == 'xyz:10\n'
More information about the Pypy-commit
mailing list