Author: Richard Plangger <[email protected]>
Branch: new-jit-log
Changeset: r83847:a02168e4834f
Date: 2016-04-25 08:38 +0200
http://bitbucket.org/pypy/pypy/changeset/a02168e4834f/

Log:    hurrayy! the new get_location function API is now extensible and
        pypy translates (this took me quite a while)

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
@@ -10,7 +10,7 @@
 from rpython.jit.metainterp.history import (Const, VOID, ConstInt)
 from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT
 from rpython.jit.metainterp.compile import ResumeGuardDescr
-from rpython.jit.metainterp.jitlog import MARK_TRACE_ASM
+from rpython.rlib.jitlog import MARK_TRACE_ASM
 from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rtyper.annlowlevel import cast_instance_to_gcref
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
@@ -17,7 +17,7 @@
 from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp.resume import (PENDINGFIELDSP,
         ResumeDataDirectReader, AccumInfo)
-from rpython.jit.metainterp.jitlog import MARK_TRACE_OPT
+from rpython.rlib.jitlog import MARK_TRACE_OPT
 from rpython.jit.metainterp.resumecode import NUMBERING
 from rpython.jit.codewriter import heaptracker, longlong
 
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,351 +0,0 @@
-from rpython.rlib.rvmprof import cintf
-from rpython.jit.metainterp import resoperation as resoperations
-from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.metainterp.history import ConstInt, ConstFloat
-from rpython.rlib.objectmodel import we_are_translated
-from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
-from rpython.rlib.objectmodel import compute_unique_id, always_inline
-from rpython.rlib import jitlog as jl
-import sys
-import weakref
-import struct
-
-JITLOG_VERSION = 1
-JITLOG_VERSION_16BIT_LE = struct.pack("<H", JITLOG_VERSION)
-
-MARK_INPUT_ARGS = 0x10
-MARK_RESOP_META = 0x11
-MARK_RESOP = 0x12
-MARK_RESOP_DESCR = 0x13
-MARK_ASM_ADDR = 0x14
-MARK_ASM = 0x15
-
-# which type of trace is logged after this
-# the trace as it is recorded by the tracer
-MARK_TRACE = 0x16
-# the trace that has passed the optimizer
-MARK_TRACE_OPT = 0x17
-# the trace assembled to machine code (after rewritten)
-MARK_TRACE_ASM = 0x18
-
-# the machine code was patched (e.g. guard)
-MARK_STITCH_BRIDGE = 0x19
-
-MARK_JITLOG_COUNTER = 0x20
-MARK_START_TRACE = 0x21
-MARK_INIT_MERGE_POINT = 0x22
-
-MARK_JITLOG_HEADER = 0x23
-MARK_JITLOG_DEBUG_MERGE_POINT = 0x24
-
-IS_32_BIT = sys.maxint == 2**31-1
-
-@always_inline
-def encode_str(string):
-    return encode_le_32bit(len(string)) + string
-
-@always_inline
-def encode_le_16bit(val):
-    return chr((val >> 0) & 0xff) + chr((val >> 8) & 0xff)
-
-@always_inline
-def encode_le_32bit(val):
-    return ''.join([chr((val >> 0) & 0xff),
-                    chr((val >> 8) & 0xff),
-                    chr((val >> 16) & 0xff),
-                    chr((val >> 24) & 0xff)])
-
-@always_inline
-def encode_le_64bit(val):
-    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)])
-
-@always_inline
-def encode_le_addr(val):
-    if IS_32_BIT:
-        return encode_le_32bit(val)
-    else:
-        return encode_le_64bit(val)
-
-def encode_type(type, value):
-    if type == "s":
-        return encode_str(value)
-    elif type == "q":
-        return encode_le_64bit(value)
-    elif type == "i":
-        return encode_le_32bit(value)
-    elif type == "h":
-        return encode_le_32bit(value)
-    else:
-        raise NotImplementedError
-
-def assemble_header():
-    version = JITLOG_VERSION_16BIT_LE
-    count = len(resoperations.opname)
-    content = [version, chr(MARK_RESOP_META),
-               encode_le_16bit(count)]
-    for opnum, opname in resoperations.opname.items():
-        content.append(encode_le_16bit(opnum))
-        content.append(encode_str(opname.lower()))
-    return ''.join(content)
-
-class VMProfJitLogger(object):
-    def __init__(self):
-        self.cintf = cintf.setup()
-        self.memo = {}
-        self.trace_id = 0
-
-    def setup_once(self):
-        if self.cintf.jitlog_enabled():
-            return
-        self.cintf.jitlog_try_init_using_env()
-        if not self.cintf.jitlog_enabled():
-            return
-        blob = assemble_header()
-        self.cintf.jitlog_write_marked(MARK_JITLOG_HEADER, blob, len(blob))
-
-    def finish(self):
-        self.cintf.jitlog_teardown()
-
-    def start_new_trace(self, faildescr=None, entry_bridge=False):
-        if not self.cintf.jitlog_enabled():
-            return
-        content = [encode_le_addr(self.trace_id)]
-        if faildescr:
-            content.append(encode_str('bridge'))
-            descrnmr = compute_unique_id(faildescr)
-            content.append(encode_le_addr(descrnmr))
-        else:
-            content.append(encode_str('loop'))
-            content.append(encode_le_addr(int(entry_bridge)))
-        self._write_marked(MARK_START_TRACE, ''.join(content))
-        self.trace_id += 1
-
-    def _write_marked(self, mark, line):
-        if not we_are_translated():
-            assert self.cintf.jitlog_enabled()
-        self.cintf.jitlog_write_marked(mark, line, len(line))
-
-    def log_jit_counter(self, struct):
-        if not self.cintf.jitlog_enabled():
-            return
-        le_addr = encode_le_addr(struct.number)
-        # not an address (but a number) but it is a machine word
-        le_count = encode_le_addr(struct.i)
-        self._write_marked(MARK_JITLOG_COUNTER, le_addr + le_count)
-
-    def log_trace(self, tag, metainterp_sd, mc, memo=None):
-        if not self.cintf.jitlog_enabled():
-            return EMPTY_TRACE_LOG
-        assert isinstance(tag, int)
-        if memo is None:
-            memo = {}
-        return LogTrace(tag, memo, metainterp_sd, mc, self)
-
-    def log_patch_guard(self, descr_number, addr):
-        if not self.cintf.jitlog_enabled():
-            return
-        le_descr_number = encode_le_addr(descr_number)
-        le_addr = encode_le_addr(addr)
-        lst = [le_descr_number, le_addr]
-        self._write_marked(MARK_STITCH_BRIDGE, ''.join(lst))
-
-class BaseLogTrace(object):
-    def write_trace(self, trace):
-        return None
-
-    def write(self, args, ops, ops_offset={}):
-        return None
-
-EMPTY_TRACE_LOG = BaseLogTrace()
-
-class LogTrace(BaseLogTrace):
-    def __init__(self, tag, memo, metainterp_sd, mc, logger):
-        self.memo = memo
-        self.metainterp_sd = metainterp_sd
-        self.ts = None
-        if self.metainterp_sd is not None:
-            self.ts = metainterp_sd.cpu.ts
-        self.tag = tag
-        self.mc = mc
-        self.logger = logger
-        self.merge_point_file = None
-
-    def write_trace(self, trace):
-        ops = []
-        i = trace.get_iter()
-        while not i.done():
-            ops.append(i.next())
-        self.write(i.inputargs, ops)
-
-    def write(self, args, ops, ops_offset={}):
-        log = self.logger
-        log._write_marked(self.tag, encode_le_addr(self.logger.trace_id))
-
-        # input args
-        str_args = [self.var_to_str(arg) for arg in args]
-        string = encode_str(','.join(str_args))
-        log._write_marked(MARK_INPUT_ARGS, string)
-
-        # 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 = encode_le_addr(absaddr)
-            le_addr2 = encode_le_addr(absaddr + rel)
-            log._write_marked(MARK_ASM_ADDR, le_addr1 + le_addr2)
-        for i,op in enumerate(ops):
-            if rop.DEBUG_MERGE_POINT == op.getopnum():
-                self.encode_debug_info(op)
-                continue
-            mark, line = self.encode_op(op)
-            log._write_marked(mark, line)
-            self.write_core_dump(ops, i, op, ops_offset)
-
-        self.memo = {}
-
-    def encode_once(self):
-        pass
-
-    def encode_debug_info(self, op):
-        log = self.logger
-        jd_sd = self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()]
-        if not jd_sd.warmstate.get_location:
-            return
-        types = jd_sd.warmstate.get_location_types
-        values = jd_sd.warmstate.get_location(op.getarglist()[3:])
-        if values is None:
-            # indicates that this function is not provided to the jit driver
-            return
-
-        if self.merge_point_file is None:
-            # first time visiting a merge point
-            positions = jd_sd.warmstate.get_location_positions
-            encoded_types = []
-            for i, (semantic_type, _) in enumerate(positions):
-                encoded_types.append(chr(semantic_type))
-                if semantic_type == jl.MP_FILENAME:
-                    self.common_prefix = values[i]
-            log._write_marked(MARK_INIT_MERGE_POINT, ''.join(encoded_types))
-
-
-        # the types have already been written
-        line = []
-        for i,(sem_type,gen_type) in enumerate(types):
-            value = values[i]
-            if sem_type == jl.PM_FILENAME:
-                self.common_prefix = os.path.commonpath([self.common_prefix, 
value])
-                log._write_marked(MARK_COMMON_PREFIX, chr(jl.PM_FILENAME) + \
-                                                      
encode_str(self.common_prefix))
-            line.append(encode_type(gen_type, value))
-        log._write_marked(MARK_JITLOG_DEBUG_MERGE_POINT, ''.join(line))
-
-
-    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_opnum = encode_le_16bit(op.getopnum())
-        str_res = self.var_to_str(op)
-        line = ','.join([str_res] + str_args)
-        if descr:
-            descr_str = descr.repr_of_descr()
-            line = line + ',' + descr_str
-            string = encode_str(line)
-            descr_number = compute_unique_id(descr)
-            le_descr_number = encode_le_addr(descr_number)
-            return MARK_RESOP_DESCR, le_opnum + string + le_descr_number
-        else:
-            string = encode_str(line)
-            return MARK_RESOP, le_opnum + string
-
-
-    def write_core_dump(self, operations, i, op, ops_offset):
-        if self.mc is None:
-            return
-
-        op2 = None
-        j = i+1
-        # find the next op that is in the offset hash
-        while j < len(operations):
-            op2 = operations[j]
-            if op in ops_offset:
-                break
-            j += 1
-
-        # this op has no known offset in the machine code (it might be
-        # a debug operation)
-        if op not in ops_offset:
-            return
-        # there is no well defined boundary for the end of the
-        # next op in the assembler
-        if op2 is not None and op2 not in ops_offset:
-            return
-        dump = []
-
-        start_offset = ops_offset[op]
-        assert start_offset >= 0
-        # end offset is either the last pos in the assembler
-        # or the offset of op2
-        if op2 is None:
-            end_offset = self.mc.get_relative_pos()
-        else:
-            end_offset = ops_offset[op2]
-
-        count = end_offset - start_offset
-        dump = self.mc.copy_core_dump(self.mc.absolute_addr(), start_offset, 
count)
-        offset = encode_le_16bit(start_offset)
-        edump = encode_str(dump)
-        self.logger._write_marked(MARK_ASM, offset + edump)
-
-    def var_to_str(self, arg):
-        try:
-            mv = self.memo[arg]
-        except KeyError:
-            mv = len(self.memo)
-            self.memo[arg] = mv
-        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:
-            return 'None'
-        elif arg.is_vector():
-            return 'v' + str(mv)
-        elif arg.type == 'i':
-            return 'i' + str(mv)
-        elif arg.type == 'r':
-            return 'p' + str(mv)
-        elif arg.type == 'f':
-            return 'f' + str(mv)
-        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
@@ -7,7 +7,7 @@
 from rpython.jit.metainterp.optimizeopt.simplify import OptSimplify
 from rpython.jit.metainterp.optimizeopt.pure import OptPure
 from rpython.jit.metainterp.optimizeopt.earlyforce import OptEarlyForce
-from rpython.jit.metainterp.jitlog import MARK_TRACE
+from rpython.rlib.jitlog import MARK_TRACE
 from rpython.rlib.jit import PARAMETERS, ENABLE_ALL_OPTS
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.debug import debug_start, debug_stop, debug_print
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -13,7 +13,7 @@
 from rpython.jit.metainterp.logger import Logger
 from rpython.jit.metainterp.optimizeopt.util import args_dict
 from rpython.jit.metainterp.resoperation import rop, OpHelpers, GuardResOp
-from rpython.jit.metainterp import jitlog
+from rpython.rlib import jitlog as jl
 from rpython.rlib import nonconst, rstack
 from rpython.rlib.debug import debug_start, debug_stop, debug_print
 from rpython.rlib.debug import have_debug_prints, make_sure_not_resized
@@ -1760,7 +1760,7 @@
         self.cpu = cpu
         self.stats = self.cpu.stats
         self.options = options
-        self.jitlog = jitlog.VMProfJitLogger()
+        self.jitlog = jl.VMProfJitLogger()
         self.logger_noopt = Logger(self)
         self.logger_ops = Logger(self, guard_number=True)
 
diff --git a/rpython/jit/metainterp/warmstate.py 
b/rpython/jit/metainterp/warmstate.py
--- a/rpython/jit/metainterp/warmstate.py
+++ b/rpython/jit/metainterp/warmstate.py
@@ -684,14 +684,13 @@
         if get_location_ptr is not None:
             types = self.jitdriver_sd._get_loc_types
             unwrap_greenkey = self.make_unwrap_greenkey()
-            unrolled_types = unrolling_iterable(types)
+            unrolled_types = unrolling_iterable(enumerate(types))
             def get_location(greenkey):
                 greenargs = unwrap_greenkey(greenkey)
                 fn = support.maybe_on_top_of_llinterp(rtyper, get_location_ptr)
                 value_tuple = fn(*greenargs)
                 values = []
-                i = 0
-                for sem_type,gen_type in unrolled_types:
+                for i, (sem_type,gen_type) in unrolled_types:
                     if gen_type == "s":
                         value = getattr(value_tuple, 'item' + str(i))
                         values.append(jl.wrap(sem_type,gen_type,hlstr(value)))
@@ -700,7 +699,6 @@
                         
values.append(jl.wrap(sem_type,gen_type,intmask(value)))
                     else:
                         raise NotImplementedError
-                    i += 1
                 return values
             self.get_location_types = list(types)
             self.get_location = get_location
diff --git a/rpython/rlib/jitlog.py b/rpython/rlib/jitlog.py
--- a/rpython/rlib/jitlog.py
+++ b/rpython/rlib/jitlog.py
@@ -81,7 +81,7 @@
 MP_OPCODE = (0x10, "s")
 
 class WrappedValue(object):
-    def encode(self, i, prefixes):
+    def encode(self, log, i, prefixes):
         raise NotImplementedError
 
 class StringValue(WrappedValue):
@@ -89,30 +89,31 @@
         self.value = value
 
     def encode(self, log, i, prefixes):
-        str_value = self.value
-        if len(str_value) < 5:
-            enc_value = encode_str(chr(0xff) + str_value)
-        else:
-            cp = commonprefix([prefixes[i], str_value])
-            if cp != prefixes[i]:
-                if len(cp) == 0:
-                    # they are fully different!
-                    prefixes[i] = str_value
-                    enc_value = encode_str(chr(0xff) + str_value)
-                else:
-                    # the prefix changed
-                    prefixes[i] = cp
-                    # common prefix of field i
-                    assert i != 0xff
-                    log._write_marked(MARK_COMMON_PREFIX, chr(i) \
-                                                      + encode_str(cp))
-                    enc_value = encode_str(chr(i) + str_value)
-            else:
-                enc_value = encode_str(chr(i) + str_value)
-        #
-        if prefixes[i] is None:
-            prefixes[i] = str_value
-        return enc_value
+        return encode_str(self.value)
+        #str_value = self.value
+        #if len(str_value) < 5:
+        #    enc_value = encode_str(chr(0xff) + str_value)
+        #else:
+        #    cp = commonprefix([prefixes[i], str_value])
+        #    if cp != prefixes[i]:
+        #        if len(cp) == 0:
+        #            # they are fully different!
+        #            prefixes[i] = str_value
+        #            enc_value = encode_str(chr(0xff) + str_value)
+        #        else:
+        #            # the prefix changed
+        #            prefixes[i] = cp
+        #            # common prefix of field i
+        #            assert i != 0xff
+        #            log._write_marked(MARK_COMMON_PREFIX, chr(i) \
+        #                                              + encode_str(cp))
+        #            enc_value = encode_str(chr(i) + str_value)
+        #    else:
+        #        enc_value = encode_str(chr(i) + str_value)
+        ##
+        #if prefixes[i] is None:
+        #    prefixes[i] = str_value
+        #return enc_value
 
 class IntValue(WrappedValue):
     def __init__(self, sem_type, gen_type, value):
@@ -264,9 +265,6 @@
     unrolled = unrolling_iterable(values)
     i = 0
     for value in unrolled:
-        cp = value.encode_common_prefix(i, prefixes)
-        if cp is not None:
-            log._write_marked(MARK_COMMON_PREFIX, cp)
         line.append(value.encode(log,i,prefixes))
         i += 1
     return ''.join(line)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to