[pypy-commit] pypy new-jit-log: added patch mark (rewrite machinecode). some refactoring to parse it more easily
plan_rich
pypy.commits at gmail.com
Mon Mar 21 11:56:23 EDT 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: new-jit-log
Changeset: r83221:0b922ecc3d86
Date: 2016-03-21 16:55 +0100
http://bitbucket.org/pypy/pypy/changeset/0b922ecc3d86/
Log: added patch mark (rewrite machinecode). some refactoring to parse it
more easily
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -533,9 +533,8 @@
looptoken._x86_ops_offset = ops_offset
looptoken._ll_function_addr = rawstart
if logger:
- logger.log_trace(MARK_TRACE_ASM, inputargs, operations,
- ops_offset=ops_offset, mc=self.mc)
-
+ log = logger.log_trace(MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, None, ops_offset)
self.fixup_target_tokens(rawstart)
self.teardown()
# oprofile support
@@ -583,14 +582,15 @@
debug_bridge(descr_number, rawstart, codeendpos)
self.patch_pending_failure_recoveries(rawstart)
# patch the jump from original guard
+ if logger:
+ logger.log_patch_guard(faildescr.adr_new_target, rawstart)
self.patch_jump_for_descr(faildescr, rawstart)
ops_offset = self.mc.ops_offset
frame_depth = max(self.current_clt.frame_info.jfi_frame_depth,
frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
if logger:
- logger.log_trace(MARK_TRACE_ASM, inputargs, operations,
- faildescr=faildescr, ops_offset=ops_offset,
- mc=self.mc)
+ log = logger.log_trace(MARK_TRACE_ASM, None, self.mc)
+ log.write(inputargs, operations, faildescr, ops_offset)
self.fixup_target_tokens(rawstart)
self.update_frame_depth(frame_depth)
self.teardown()
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -481,7 +481,8 @@
def do_compile_loop(jd_id, unique_id, metainterp_sd, inputargs, operations,
looptoken, log=True, name='', memo=None):
- metainterp_sd.jitlog.log_trace(MARK_TRACE_OPT, inputargs, operations)
+ log = metainterp_sd.jitlog.log_trace(MARK_TRACE_OPT, metainterp_sd, None)
+ log.write(inputargs, operations)
# TODO remove old
metainterp_sd.logger_ops.log_loop(inputargs, operations, -2,
'compiling', None, name, memo)
@@ -493,8 +494,8 @@
def do_compile_bridge(metainterp_sd, faildescr, inputargs, operations,
original_loop_token, log=True, memo=None):
- metainterp_sd.jitlog.log_trace(MARK_TRACE_OPT, inputargs, operations,
- faildescr=faildescr)
+ log = metainterp_sd.jitlog.log_trace(MARK_TRACE_OPT, metainterp_sd, None)
+ log.write(inputargs, operations, faildescr=faildescr)
# TODO remove old
metainterp_sd.logger_ops.log_bridge(inputargs, operations, "compiling",
memo=memo)
diff --git a/rpython/jit/metainterp/jitlog.py b/rpython/jit/metainterp/jitlog.py
--- a/rpython/jit/metainterp/jitlog.py
+++ b/rpython/jit/metainterp/jitlog.py
@@ -1,6 +1,8 @@
from rpython.rlib.rvmprof.rvmprof import cintf
from rpython.jit.metainterp import resoperation as resoperations
from rpython.jit.metainterp.history import ConstInt, ConstFloat
+from rpython.rlib.objectmodel import we_are_translated
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
import sys
import weakref
@@ -24,27 +26,6 @@
IS_32_BIT = sys.maxint == 2**31-1
-# why is there no rlib/rstruct/pack.py?
-def encode_le_16bit(val):
- return chr((val >> 0) & 0xff) + chr((val >> 8) & 0xff)
-def encode_le_32bit(val):
- return ''.join([chr((val >> 0) & 0xff),
- chr((val >> 8) & 0xff),
- chr((val >> 16) & 0xff),
- chr((val >> 24) & 0xff)])
-def encode_le_addr(val):
- if IS_32_BIT:
- return encode_be_32bit(val)
- else:
- return ''.join([chr((val >> 0) & 0xff),
- chr((val >> 8) & 0xff),
- chr((val >> 16) & 0xff),
- chr((val >> 24) & 0xff),
- chr((val >> 32) & 0xff),
- chr((val >> 40) & 0xff),
- chr((val >> 48) & 0xff),
- chr((val >> 56)& 0xff)])
-
class VMProfJitLogger(object):
def __init__(self):
@@ -58,7 +39,7 @@
count = len(resoperations.opname)
mark = MARK_RESOP_META
for opnum, opname in resoperations.opname.items():
- line = encode_le_16bit(opnum) + opname.lower()
+ line = self.encode_le_16bit(opnum) + opname.lower()
self.write_marked(mark, line)
def teardown(self):
@@ -67,52 +48,106 @@
def write_marked(self, mark, line):
self.cintf.jitlog_write_marked(mark, line, len(line))
- def encode(self, op):
+ def log_trace(self, tag, metainterp_sd, mc, memo=None):
+ if self.cintf.jitlog_filter(tag):
+ return
+ assert isinstance(tag, int)
+ if memo is None:
+ memo = {}
+ return LogTrace(tag, memo, metainterp_sd, mc, self)
+
+ def log_patch_guard(self, addr, target_addr):
+ if self.cintf.jitlog_filter(tag):
+ return
+ le_addr_write = self.encode_le_addr(addr)
+ le_len = self.encode_le_32bit(8)
+ le_addr = self.encode_le_addr(target_addr)
+ lst = [le_addr, le_len, le_addr]
+ self.cintf.jitlog_filter(MARK_ASM_PATCH, ''.join(lst))
+
+ def encode_le_16bit(self, val):
+ return chr((val >> 0) & 0xff) + chr((val >> 8) & 0xff)
+
+ def encode_le_32bit(self, val):
+ return ''.join([chr((val >> 0) & 0xff),
+ chr((val >> 8) & 0xff),
+ chr((val >> 16) & 0xff),
+ chr((val >> 24) & 0xff)])
+
+ def encode_le_addr(self,val):
+ if IS_32_BIT:
+ return encode_be_32bit(val)
+ else:
+ return ''.join([chr((val >> 0) & 0xff),
+ chr((val >> 8) & 0xff),
+ chr((val >> 16) & 0xff),
+ chr((val >> 24) & 0xff),
+ chr((val >> 32) & 0xff),
+ chr((val >> 40) & 0xff),
+ chr((val >> 48) & 0xff),
+ chr((val >> 56)& 0xff)])
+
+
+class LogTrace(object):
+ def __init__(self, tag, memo, metainterp_sd, mc, logger):
+ self.memo = memo
+ self.metainterp_sd = metainterp_sd
+ if self.metainterp_sd is not None:
+ self.ts = metainterp_sd.cpu.ts
+ self.tag = tag
+ self.mc = mc
+ self.logger = logger
+
+ def write(self, args, ops, faildescr=None, ops_offset={}):
+ log = self.logger
+
+ # write the initial tag
+ if faildescr is None:
+ log.write_marked(self.tag, 'loop')
+ else:
+ log.write_marked(self.tag, 'bridge')
+
+ # input args
+ str_args = [self.var_to_str(arg) for arg in args]
+ log.write_marked(MARK_INPUT_ARGS, ','.join(str_args))
+
+ # assembler address (to not duplicate it in write_code_dump)
+ if self.mc is not None:
+ absaddr = self.mc.absolute_addr()
+ rel = self.mc.get_relative_pos()
+ # packs <start addr> <end addr> as two unsigend longs
+ le_addr1 = self.encode_le_addr(absaddr)
+ le_addr2 = self.encode_le_addr(absaddr + rel)
+ log.write_marked(MARK_ASM_ADDR, le_addr1 + le_addr2)
+ for i,op in enumerate(ops):
+ mark, line = self.encode_op(op)
+ log.write_marked(mark, line)
+ self.write_core_dump(ops, i, op, ops_offset)
+
+ self.memo = {}
+
+ def encode_op(self, op):
+ """ an operation is written as follows:
+ <marker> <opid (16 bit)> \
+ <len (32 bit)> \
+ <res_val>,<arg_0>,...,<arg_n>,<descr>
+ The marker indicates if the last argument is
+ a descr or a normal argument.
+ """
str_args = [self.var_to_str(arg) for arg in op.getarglist()]
descr = op.getdescr()
- le_len = encode_le_32bit(op.getopnum())
- line = le_len + ','.join(str_args)
+ le_opnum = self.logger.encode_le_16bit(op.getopnum())
+ str_res = self.var_to_str(op)
+ line = le_opnum + ','.join([str_res] + str_args)
if descr:
- line += "|" + str(descr)
- return MARK_RESOP_DESCR, line
+ descr_str = descr.repr_of_descr()
+ return MARK_RESOP_DESCR, line + ',' + descr_str
else:
return MARK_RESOP, line
- def log_trace(self, tag, args, ops,
- faildescr=None, ops_offset={}, mc=None):
- # this is a mixture of binary and text!
- if self.cintf.jitlog_filter(tag):
- return
- assert isinstance(tag, int)
- # write the initial tag
- if faildescr is None:
- self.write_marked(tag, 'loop')
- else:
- self.write_marked(tag, 'bridge')
-
- # input args
- str_args = [self.var_to_str(arg) for arg in args]
- self.write_marked(MARK_INPUT_ARGS, ','.join(str_args))
-
- # assembler address (to not duplicate it in write_code_dump)
- if mc is not None:
- absaddr = mc.absolute_addr()
- rel = mc.get_relative_pos()
- # packs <start addr> <end addr> as two unsigend longs
- le_addr1 = encode_le_addr(absaddr)
- le_addr2 = encode_le_addr(absaddr + rel)
- self.write_marked(MARK_ASM_ADDR, le_addr1 + le_addr2)
- for i,op in enumerate(ops):
- mark, line = self.encode(op)
- self.write_marked(mark, line)
- self.write_core_dump(ops, i, op, ops_offset, mc)
-
- self.memo = {}
-
- def write_core_dump(self, operations, i, op, ops_offset, mc):
- return
- if mc is None:
+ def write_core_dump(self, operations, i, op, ops_offset):
+ if self.mc is None:
return
op2 = None
@@ -138,12 +173,12 @@
# end offset is either the last pos in the assembler
# or the offset of op2
if op2 is None:
- end_offset = mc.get_relative_pos()
+ end_offset = self.mc.get_relative_pos()
else:
end_offset = ops_offset[op2]
- dump = mc.copy_core_dump(mc.absolute_addr(), start_offset)
- self.write_marked(MARK_ASM, dump)
+ dump = self.mc.copy_core_dump(self.mc.absolute_addr(), start_offset)
+ self.logger.write_marked(MARK_ASM, dump)
def var_to_str(self, arg):
try:
@@ -151,18 +186,17 @@
except KeyError:
mv = len(self.memo)
self.memo[arg] = mv
- # TODO
- #if isinstance(arg, ConstInt):
- # if int_could_be_an_address(arg.value):
- # addr = arg.getaddr()
- # name = self.metainterp_sd.get_name_from_address(addr)
- # if name:
- # return 'ConstClass(' + name + ')'
- # return str(arg.value)
- #elif isinstance(arg, self.ts.ConstRef):
- # if arg.value:
- # return 'ConstPtr(ptr' + str(mv) + ')'
- # return 'ConstPtr(null)'
+ if isinstance(arg, ConstInt):
+ if self.metainterp_sd and int_could_be_an_address(arg.value):
+ addr = arg.getaddr()
+ name = self.metainterp_sd.get_name_from_address(addr)
+ if name:
+ return 'ConstClass(' + name + ')'
+ return str(arg.value)
+ elif self.ts is not None and isinstance(arg, self.ts.ConstRef):
+ if arg.value:
+ return 'ConstPtr(ptr' + str(mv) + ')'
+ return 'ConstPtr(null)'
if isinstance(arg, ConstFloat):
return str(arg.getfloat())
elif arg is None:
@@ -178,3 +212,9 @@
else:
return '?'
+def int_could_be_an_address(x):
+ if we_are_translated():
+ x = rffi.cast(lltype.Signed, x) # force it
+ return not (-32768 <= x <= 32767)
+ else:
+ return isinstance(x, llmemory.AddressAsInt)
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -55,8 +55,8 @@
debug_start("jit-optimize")
inputargs = compile_data.start_label.getarglist()
try:
- metainterp_sd.jitlog.log_trace(MARK_TRACE, inputargs,
- compile_data.operations)
+ log = metainterp_sd.jitlog.log_trace(MARK_TRACE, metainterp_sd, None)
+ log.write(inputargs, compile_data.operations)
#
metainterp_sd.logger_noopt.log_loop(inputargs,
compile_data.operations,
More information about the pypy-commit
mailing list