[pypy-svn] r51854 - in pypy/branch/jit-refactoring/pypy/jit/rainbow: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Feb 25 17:43:37 CET 2008
Author: arigo
Date: Mon Feb 25 17:43:35 2008
New Revision: 51854
Added:
pypy/branch/jit-refactoring/pypy/jit/rainbow/dump.py (contents, props changed)
Modified:
pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py
Log:
A (hackish) pretty-printer for JitCode objects created by codewriter.py.
This is not really a disassembler, as it is based on the source list.
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/codewriter.py Mon Feb 25 17:43:35 2008
@@ -134,8 +134,10 @@
self.make_bytecode_block(graph.startblock)
assert self.current_block is None
bytecode = self.all_graphs[graph]
+ labelpos = {}
+ code = assemble_labelpos(labelpos, self.interpreter, *self.assembler)
bytecode.__init__(graph.name,
- assemble(self.interpreter, *self.assembler),
+ code,
self.constants,
self.typekinds,
self.redboxclasses,
@@ -151,6 +153,9 @@
self.graph_color,
self.calldescs,
self.is_portal)
+ bytecode._source = self.assembler
+ bytecode._interpreter = self.interpreter
+ bytecode._labelpos = labelpos
if is_portal:
self.finish_all_graphs()
self.interpreter.set_num_global_mergepoints(
@@ -1033,9 +1038,8 @@
def __repr__(self):
return "tlabel(%r)" % (self.name, )
-def assemble(interpreter, *args):
+def assemble_labelpos(labelpos, interpreter, *args):
result = []
- labelpos = {}
def emit_2byte(index):
result.append(chr((index >> 8) & 0xff))
result.append(chr(index & 0xff))
@@ -1065,3 +1069,6 @@
result[i + 2] = chr((index >> 8) & 0xff)
result[i + 3] = chr(index & 0xff)
return "".join(result)
+
+def assemble(interpreter, *args):
+ return assemble_labelpos({}, interpreter, *args)
Added: pypy/branch/jit-refactoring/pypy/jit/rainbow/dump.py
==============================================================================
--- (empty file)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/dump.py Mon Feb 25 17:43:35 2008
@@ -0,0 +1,166 @@
+from pypy.jit.rainbow import codewriter
+
+
+class SourceIterator:
+
+ def __init__(self, jitcode, source, interpreter, labelpos):
+ self.jitcode = jitcode
+ self.source = source
+ self.interpreter = interpreter
+ self.labelpos = labelpos
+ self.index = 0
+ self.pc = 0
+
+ def finished(self):
+ return self.index == len(self.source)
+
+ def peek(self):
+ return self.source[self.index]
+
+ def get(self, expected_type, bytes_count):
+ arg = self.source[self.index]
+ assert isinstance(arg, expected_type)
+ self.index += 1
+ self.pc += bytes_count
+ return arg
+
+ def get_opname(self):
+ return self.get(str, 2)
+
+ def load_2byte(self):
+ return self.get(int, 2)
+
+ def load_bool(self):
+ return self.get(bool, 1)
+
+ def get_greenarg(self):
+ i = self.load_2byte()
+ if i < 0:
+ return self.jitcode.constants[~i]
+ return CustomRepr('g%d' % i)
+
+ def get_green_varargs(self):
+ greenargs = []
+ num = self.load_2byte()
+ for i in range(num):
+ greenargs.append(self.get_greenarg())
+ return greenargs
+
+ def get_red_varargs(self):
+ redargs = []
+ num = self.load_2byte()
+ for i in range(num):
+ redargs.append(self.get_redarg())
+ return redargs
+
+ def get_redarg(self):
+ return CustomRepr('r%d' % self.get(int, 2))
+
+ def get_greenkey(self):
+ keydescnum = self.load_2byte()
+ if keydescnum == -1:
+ return None
+ else:
+ keydesc = self.jitcode.keydescs[keydescnum]
+ return keydesc
+
+ def load_jumptarget(self):
+ tlbl = self.get(codewriter.tlabel, 4)
+ return self.labelpos[tlbl.name]
+
+
+class CustomRepr:
+ def __init__(self, s):
+ self.s = s
+ def __repr__(self):
+ return self.s
+
+
+def dump_bytecode(jitcode, file=None):
+ # XXX this is not really a disassembler, but just a pretty-printer
+ # for the '_source' attribute that codewriter.py attaches
+ source = jitcode._source
+ interpreter = jitcode._interpreter
+ labelpos = jitcode._labelpos
+ print >> file, 'JITCODE %r' % (jitcode.name,)
+
+ src = SourceIterator(jitcode, source, interpreter, labelpos)
+ noblankline = {0: True}
+ while not src.finished():
+ arg = src.peek()
+ if isinstance(arg, str):
+ startpc = src.pc
+ opname = src.get_opname()
+ opcode = interpreter.find_opcode(opname)
+ opimpl = interpreter.opcode_implementations[opcode]
+ argtypes = opimpl.argspec
+ resulttype = opimpl.resultspec
+ args = []
+
+ for argspec in argtypes:
+ if argspec == "red":
+ args.append(src.get_redarg())
+ elif argspec == "green":
+ args.append(src.get_greenarg())
+ elif argspec == "kind":
+ args.append(jitcode.typekinds[src.load_2byte()])
+ elif argspec == "jumptarget":
+ args.append(src.load_jumptarget())
+ elif argspec == "bool":
+ args.append(src.load_bool())
+ elif argspec == "redboxcls":
+ args.append(jitcode.redboxclasses[src.load_2byte()])
+ elif argspec == "2byte":
+ args.append(src.load_2byte())
+ elif argspec == "greenkey":
+ args.append(src.get_greenkey())
+ elif argspec == "promotiondesc":
+ promotiondescnum = src.load_2byte()
+ promotiondesc = jitcode.promotiondescs[promotiondescnum]
+ args.append(promotiondesc)
+ elif argspec == "green_varargs":
+ args.append(src.get_green_varargs())
+ elif argspec == "red_varargs":
+ args.append(src.get_red_varargs())
+ elif argspec == "bytecode":
+ bytecodenum = src.load_2byte()
+ called_bytecode = jitcode.called_bytecodes[bytecodenum]
+ args.append(called_bytecode.name)
+ elif argspec == "calldesc":
+ index = src.load_2byte()
+ function = jitcode.calldescs[index]
+ args.append(function)
+ elif argspec == "oopspec":
+ oopspecindex = src.load_2byte()
+ oopspec = jitcode.oopspecdescs[oopspecindex]
+ args.append(oopspec)
+ elif argspec == "structtypedesc":
+ td = jitcode.structtypedescs[src.load_2byte()]
+ args.append(td)
+ elif argspec == "arraydesc":
+ td = jitcode.arrayfielddescs[src.load_2byte()]
+ args.append(td)
+ elif argspec == "fielddesc":
+ d = jitcode.fielddescs[src.load_2byte()]
+ args.append(d)
+ elif argspec == "interiordesc":
+ d = jitcode.interiordescs[src.load_2byte()]
+ args.append(d)
+ else:
+ assert 0, "unknown argtype declaration"
+
+ args = map(str, args)
+ # XXX we should print the result from resultspec too,
+ # but it's not obvious how to do that
+ line = '%5d | %-20s %s' % (startpc, opname, ', '.join(args))
+ print >> file, line.rstrip()
+ elif isinstance(arg, codewriter.label):
+ if src.pc not in noblankline: # no duplicate blank lines
+ print >> file, '%5s |' % ''
+ noblankline[src.pc] = True
+ src.index += 1
+ else:
+ assert 0, "unexpected object: %r" % (arg,)
+
+ if src.pc != len(jitcode.code):
+ print >> file, 'WARNING: the pc column is bogus! fix dump.py!'
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/interpreter.py Mon Feb 25 17:43:35 2008
@@ -43,6 +43,10 @@
def _freeze_(self):
return True
+ def dump(self, file=None):
+ from pypy.jit.rainbow import dump
+ dump.dump_bytecode(self, file=file)
+
SIGN_EXTEND2 = 1 << 15
class STOP(object):
@@ -141,6 +145,8 @@
return
return val
wrapped.func_name = "wrap_" + func.func_name
+ wrapped.argspec = argtypes
+ wrapped.resultspec = result
return wrapped
return decorator
@@ -379,22 +385,26 @@
return rtimeshift.genptreq(self.jitstate, ptrbox1,
ptrbox2, True)
+ @arguments()
def opimpl_red_return(self):
rtimeshift.save_return(self.jitstate)
return self.dispatch()
+ @arguments()
def opimpl_gray_return(self):
rtimeshift.save_return(self.jitstate)
return self.dispatch()
+ @arguments()
def opimpl_yellow_return(self):
# save the greens to make the return value findable by collect_split
rtimeshift.save_greens(self.jitstate, self.frame.local_green)
rtimeshift.save_return(self.jitstate)
return self.dispatch()
- def opimpl_make_new_redvars(self):
- self.frame.local_boxes = self.get_red_varargs()
+ @arguments("red_varargs")
+ def opimpl_make_new_redvars(self, local_boxes):
+ self.frame.local_boxes = local_boxes
def opimpl_make_new_greenvars(self):
# an opcode with a variable number of args
@@ -407,6 +417,8 @@
for i in range(num):
newgreens.append(self.get_greenarg())
self.frame.local_green = newgreens
+ opimpl_make_new_greenvars.argspec = ("green_varargs",) # for dump.py
+ opimpl_make_new_greenvars.resultspec = None
@arguments("2byte", "greenkey")
def opimpl_local_merge(self, mergepointnum, key):
@@ -425,6 +437,7 @@
if done:
return self.dispatch()
+ @arguments()
def opimpl_guard_global_merge(self):
rtimeshift.guard_global_merge(self.jitstate, self.frame.pc)
return self.dispatch()
@@ -438,6 +451,7 @@
assert gv_switchvar.is_const
self.green_result(gv_switchvar)
+ @arguments()
def opimpl_reverse_split_queue(self):
rtimeshift.reverse_split_queue(self.frame.dispatchqueue)
@@ -448,6 +462,7 @@
# this frame will be resumed later in the next bytecode, which is
# red_after_direct_call
+ @arguments()
def opimpl_red_after_direct_call(self):
newjitstate = rtimeshift.collect_split(
self.jitstate, self.frame.pc,
@@ -465,6 +480,7 @@
# this frame will be resumed later in the next bytecode, which is
# yellow_after_direct_call
+ @arguments()
def opimpl_yellow_after_direct_call(self):
newjitstate = rtimeshift.collect_split(
self.jitstate, self.frame.pc,
@@ -640,6 +656,8 @@
args += (arg, )
result = self.rgenop.genconst(opdesc.llop(*args))
self.green_result(result)
+ implementation.argspec = ("green",) * len(list(numargs))
+ implementation.resultspec = "green"
elif color == "red":
if opdesc.nb_args == 1:
impl = rtimeshift.ll_gen1
@@ -653,6 +671,8 @@
args += (self.get_redarg(), )
result = impl(*args)
self.red_result(result)
+ implementation.argspec = ("red",) * len(list(numargs))
+ implementation.resultspec = "red"
else:
assert 0, "unknown color"
implementation.func_name = "opimpl_%s_%s" % (color, opdesc.opname)
Modified: pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py
==============================================================================
--- pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py (original)
+++ pypy/branch/jit-refactoring/pypy/jit/rainbow/test/test_serializegraph.py Mon Feb 25 17:43:35 2008
@@ -1,3 +1,4 @@
+import py
from pypy.translator.translator import TranslationContext, graphof
from pypy.jit.hintannotator.annotator import HintAnnotator
from pypy.jit.hintannotator.policy import StopAtXPolicy, HintAnnotatorPolicy
@@ -210,6 +211,48 @@
assert jitcode.is_portal
assert len(jitcode.called_bytecodes) == 0
+ def test_dump_loop(self):
+ def f(x):
+ r = 0
+ while x:
+ r += x
+ x -= 1
+ return r
+ writer, jitcode = self.serialize(f, [int])
+ import StringIO
+ output = StringIO.StringIO()
+ jitcode.dump(file=output)
+ result = output.getvalue().rstrip()
+ print '-' * 40
+ print result
+ print '-' * 40
+ # xxx slightly fragile test, it will break whenever we tweak dump.py
+ expected = """\
+JITCODE 'f'
+ 0 | make_redbox (0), 0
+ 6 | make_new_redvars [r0, r1]
+ 14 | make_new_greenvars []
+ |
+ 18 | local_merge 0, None
+ 24 | red_int_is_true r0
+ 28 | red_goto_iftrue r2, 48
+ 36 | make_new_redvars [r1]
+ 42 | make_new_greenvars []
+ |
+ 46 | red_return
+ |
+ 48 | make_new_redvars [r0, r1]
+ 56 | make_new_greenvars []
+ |
+ 60 | red_int_add r1, r0
+ 66 | make_redbox (1), 0
+ 72 | red_int_sub r0, r3
+ 78 | make_new_redvars [r4, r2]
+ 86 | make_new_greenvars []
+ 90 | goto 18
+ """.rstrip()
+ assert result == expected
+
def test_call(self):
def g(x):
return x + 1
More information about the Pypy-commit
mailing list