Hakan Ardo avatar Hakan Ardo committed a7a84c7 Merge

hg merge default

Comments (0)

Files changed (21)

pypy/jit/backend/x86/assembler.py

         self.is_guard_not_invalidated = is_guard_not_invalidated
 
 DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed),
-                              ('bridge', lltype.Signed), # 0 or 1
+                              ('type', lltype.Char), # 'b'ridge, 'l'abel or
+                                                     # 'e'ntry point
                               ('number', lltype.Signed))
 
 class Assembler386(object):
             debug_start('jit-backend-counts')
             for i in range(len(self.loop_run_counters)):
                 struct = self.loop_run_counters[i]
-                if not struct.bridge:
+                if struct.type == 'l':
                     prefix = 'TargetToken(%d)' % struct.number
+                elif struct.type == 'b':
+                    prefix = 'bridge ' + str(struct.number)
                 else:
-                    prefix = 'bridge ' + str(struct.number)
+                    prefix = 'entry ' + str(struct.number)
                 debug_print(prefix + ':' + str(struct.i))
             debug_stop('jit-backend-counts')
 
         self.setup(looptoken)
         if log:
             operations = self._inject_debugging_code(looptoken, operations,
-                                                     False, looptoken.number)
+                                                     'e', looptoken.number)
 
         regalloc = RegAlloc(self, self.cpu.translate_support_code)
         #
         self.setup(original_loop_token)
         if log:
             operations = self._inject_debugging_code(faildescr, operations,
-                                                     True, descr_number)
+                                                     'b', descr_number)
 
         arglocs = self.rebuild_faillocs_from_descr(failure_recovery)
         if not we_are_translated():
         return self.mc.materialize(self.cpu.asmmemmgr, allblocks,
                                    self.cpu.gc_ll_descr.gcrootmap)
 
-    def _register_counter(self, bridge, number, token):
+    def _register_counter(self, tp, number, token):
         # YYY very minor leak -- we need the counters to stay alive
         # forever, just because we want to report them at the end
         # of the process
         struct = lltype.malloc(DEBUG_COUNTER, flavor='raw',
                                track_allocation=False)
         struct.i = 0
-        struct.bridge = int(bridge)
-        if bridge:
+        struct.type = tp
+        if tp == 'b' or tp == 'e':
             struct.number = number
         else:
             assert token
             targettoken._x86_loop_code += rawstart
         self.target_tokens_currently_compiling = None
 
-    def _append_debugging_code(self, operations, bridge, number, token):
-        counter = self._register_counter(bridge, number, token)
+    def _append_debugging_code(self, operations, tp, number, token):
+        counter = self._register_counter(tp, number, token)
         c_adr = ConstInt(rffi.cast(lltype.Signed, counter))
         box = BoxInt()
         box2 = BoxInt()
         operations.extend(ops)
         
     @specialize.argtype(1)
-    def _inject_debugging_code(self, looptoken, operations, bridge, number):
+    def _inject_debugging_code(self, looptoken, operations, tp, number):
         if self._debug:
             # before doing anything, let's increase a counter
             s = 0
             looptoken._x86_debug_checksum = s
 
             newoperations = []
-            if bridge:
-                self._append_debugging_code(newoperations, bridge, number,
-                                            None)
+            self._append_debugging_code(newoperations, tp, number,
+                                        None)
             for op in operations:
                 newoperations.append(op)
                 if op.getopnum() == rop.LABEL:
-                    self._append_debugging_code(newoperations, bridge, number,
+                    self._append_debugging_code(newoperations, 'l', number,
                                                 op.getdescr())
             operations = newoperations
         return operations

pypy/jit/backend/x86/test/test_runner.py

             struct = self.cpu.assembler.loop_run_counters[0]
             assert struct.i == 1
             struct = self.cpu.assembler.loop_run_counters[1]
+            assert struct.i == 1
+            struct = self.cpu.assembler.loop_run_counters[2]
             assert struct.i == 9
             self.cpu.finish_once()
         finally:
             debug._log = None
+        l0 = ('debug_print', 'entry -1:1')
         l1 = ('debug_print', preambletoken.repr_of_descr() + ':1')
         l2 = ('debug_print', targettoken.repr_of_descr() + ':9')
-        assert ('jit-backend-counts', [l1, l2]) in dlog
+        assert ('jit-backend-counts', [l0, l1, l2]) in dlog
 
     def test_debugger_checksum(self):
         loop = """

pypy/jit/metainterp/compile.py

     """
     from pypy.jit.metainterp.optimizeopt import optimize_trace
 
-    history = metainterp.history
     metainterp_sd = metainterp.staticdata
     jitdriver_sd = metainterp.jitdriver_sd
+    history = metainterp.history
 
-    if False:
-        part = partial_trace
-        assert False
-        procedur_token = metainterp.get_procedure_token(greenkey)
-        assert procedure_token
-        all_target_tokens = []
-    else:
-        jitcell_token = make_jitcell_token(jitdriver_sd)
-        part = create_empty_loop(metainterp)
-        part.inputargs = inputargs[:]
-        h_ops = history.operations
-        part.resume_at_jump_descr = resume_at_jump_descr
-        part.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(jitcell_token))] + \
-                          [h_ops[i].clone() for i in range(start, len(h_ops))] + \
-                          [ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token)]
+    jitcell_token = make_jitcell_token(jitdriver_sd)
+    part = create_empty_loop(metainterp)
+    part.inputargs = inputargs[:]
+    h_ops = history.operations
+    part.resume_at_jump_descr = resume_at_jump_descr
+    part.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(jitcell_token))] + \
+                      [h_ops[i].clone() for i in range(start, len(h_ops))] + \
+                      [ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token)]
 
-        try:
-            optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts)
-        except InvalidLoop:
-            return None
-        target_token = part.operations[0].getdescr()
-        assert isinstance(target_token, TargetToken)
-        all_target_tokens = [target_token]
+    try:
+        optimize_trace(metainterp_sd, part, jitdriver_sd.warmstate.enable_opts)
+    except InvalidLoop:
+        return None
+    target_token = part.operations[0].getdescr()
+    assert isinstance(target_token, TargetToken)
+    all_target_tokens = [target_token]
 
     loop = create_empty_loop(metainterp)        
     loop.inputargs = part.inputargs
         metainterp_sd.stats.compiled()
     metainterp_sd.log("compiled new " + type)
     #
-    metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n, type, ops_offset)
+    loopname = jitdriver_sd.warmstate.get_location_str(greenkey)
+    metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n,
+                                      type, ops_offset,
+                                      name=loopname)
     #
     if metainterp_sd.warmrunnerdesc is not None:    # for tests
         metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(original_jitcell_token)

pypy/jit/metainterp/heapcache.py

             opnum == rop.COPYSTRCONTENT or
             opnum == rop.COPYUNICODECONTENT):
             return
-        if rop._OVF_FIRST <= opnum <= rop._OVF_LAST:
-            return
-        if rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST:
+        if (rop._OVF_FIRST <= opnum <= rop._OVF_LAST or
+            rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST or
+            rop._GUARD_FIRST <= opnum <= rop._GUARD_LAST):
             return
         if opnum == rop.CALL or opnum == rop.CALL_LOOPINVARIANT:
             effectinfo = descr.get_extra_info()

pypy/jit/metainterp/logger.py

         self.metainterp_sd = metainterp_sd
         self.guard_number = guard_number
 
-    def log_loop(self, inputargs, operations, number=0, type=None, ops_offset=None):
+    def log_loop(self, inputargs, operations, number=0, type=None, ops_offset=None, name=''):
         if type is None:
             debug_start("jit-log-noopt-loop")
             logops = self._log_operations(inputargs, operations, ops_offset)
             debug_stop("jit-log-noopt-loop")
         else:
             debug_start("jit-log-opt-loop")
-            debug_print("# Loop", number, ":", type,
+            debug_print("# Loop", number, '(%s)' % name , ":", type,
                         "with", len(operations), "ops")
             logops = self._log_operations(inputargs, operations, ops_offset)
             debug_stop("jit-log-opt-loop")

pypy/jit/metainterp/test/test_compile.py

         self.seen.append((inputargs, operations, token))
 
 class FakeLogger(object):
-    def log_loop(self, inputargs, operations, number=0, type=None, ops_offset=None):
+    def log_loop(self, inputargs, operations, number=0, type=None, ops_offset=None, name=''):
         pass
 
     def repr_of_resop(self, op):

pypy/jit/metainterp/test/test_heapcache.py

         assert h.getarrayitem(box1, descr1, index1) is box2
         assert h.getarrayitem(box1, descr1, index2) is box4
 
+        h.invalidate_caches(rop.GUARD_TRUE, None, [])
+        assert h.getfield(box1, descr1) is box2
+        assert h.getarrayitem(box1, descr1, index1) is box2
+        assert h.getarrayitem(box1, descr1, index2) is box4
+
         h.invalidate_caches(
             rop.CALL_LOOPINVARIANT, FakeCallDescr(FakeEffektinfo.EF_LOOPINVARIANT), [])
 

pypy/jit/metainterp/test/test_logger.py

     def test_intro_loop(self):
         bare_logger = logger.Logger(self.make_metainterp_sd())
         output = capturing(bare_logger.log_loop, [], [], 1, "foo")
-        assert output.splitlines()[0] == "# Loop 1 : foo with 0 ops"
+        assert output.splitlines()[0] == "# Loop 1 () : foo with 0 ops"
         pure_parse(output)
 
     def test_intro_bridge(self):

pypy/module/micronumpy/__init__.py

 class PyPyModule(MixedModule):
     interpleveldefs = {
         'debug_repr': 'interp_extras.debug_repr',
+        'remove_invalidates': 'interp_extras.remove_invalidates',
     }
     appleveldefs = {}
 

pypy/module/micronumpy/interp_extras.py

 @unwrap_spec(array=BaseArray)
 def debug_repr(space, array):
     return space.wrap(array.find_sig().debug_repr())
+
+@unwrap_spec(array=BaseArray)
+def remove_invalidates(space, array):
+    """ Array modification will no longer invalidate any of it's
+    potential children. Use only for performance debugging
+    """
+    del array.invalidates[:]
+    return space.w_None

pypy/module/micronumpy/interp_numarray.py

 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.gateway import interp2app, unwrap_spec, NoneNotWrapped
+from pypy.interpreter.gateway import interp2app, NoneNotWrapped
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
 from pypy.module.micronumpy import interp_ufuncs, interp_dtype, signature
 from pypy.module.micronumpy.strides import calculate_slice_strides
 numpy_driver = jit.JitDriver(
     greens=['shapelen', 'sig'],
     virtualizables=['frame'],
-    reds=['result_size', 'frame', 'ri', 'self', 'result']
+    reds=['result_size', 'frame', 'ri', 'self', 'result'],
+    get_printable_location=signature.new_printable_location('numpy'),
 )
 all_driver = jit.JitDriver(
     greens=['shapelen', 'sig'],
     virtualizables=['frame'],
-    reds=['frame', 'self', 'dtype']
+    reds=['frame', 'self', 'dtype'],
+    get_printable_location=signature.new_printable_location('all'),
 )
 any_driver = jit.JitDriver(
     greens=['shapelen', 'sig'],
     virtualizables=['frame'],
-    reds=['frame', 'self', 'dtype']
+    reds=['frame', 'self', 'dtype'],
+    get_printable_location=signature.new_printable_location('any'),
 )
 slice_driver = jit.JitDriver(
     greens=['shapelen', 'sig'],
     virtualizables=['frame'],
-    reds=['self', 'frame', 'source', 'res_iter']
+    reds=['self', 'frame', 'source', 'res_iter'],
+    get_printable_location=signature.new_printable_location('slice'),
 )
 
 def _find_shape_and_elems(space, w_iterable):
     def _reduce_argmax_argmin_impl(op_name):
         reduce_driver = jit.JitDriver(
             greens=['shapelen', 'sig'],
-            reds=['result', 'idx', 'frame', 'self', 'cur_best', 'dtype']
+            reds=['result', 'idx', 'frame', 'self', 'cur_best', 'dtype'],
+            get_printable_location=signature.new_printable_location(op_name),
         )
         def loop(self):
             sig = self.find_sig()

pypy/module/micronumpy/interp_ufuncs.py

 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.typedef import TypeDef, GetSetProperty, interp_attrproperty
-from pypy.module.micronumpy import interp_boxes, interp_dtype, types
-from pypy.module.micronumpy.signature import ReduceSignature, ScalarSignature, find_sig
+from pypy.module.micronumpy import interp_boxes, interp_dtype
+from pypy.module.micronumpy.signature import ReduceSignature, ScalarSignature,\
+     find_sig, new_printable_location
 from pypy.rlib import jit
 from pypy.rlib.rarithmetic import LONG_BIT
 from pypy.tool.sourcetools import func_with_new_name
 reduce_driver = jit.JitDriver(
     greens = ['shapelen', "sig"],
     virtualizables = ["frame"],
-    reds = ["frame", "self", "dtype", "value", "obj"]
+    reds = ["frame", "self", "dtype", "value", "obj"],
+    get_printable_location=new_printable_location('reduce'),
 )
 
 class W_Ufunc(Wrappable):

pypy/module/micronumpy/signature.py

 from pypy.module.micronumpy.strides import calculate_slice_strides
 from pypy.rlib.jit import hint, unroll_safe, promote
 
+def new_printable_location(driver_name):
+    def get_printable_location(shapelen, sig):
+        return 'numpy ' + sig.debug_repr() + ' [%d dims,%s]' % (shapelen, driver_name)
+    return get_printable_location
+
 def sigeq(one, two):
     return one.eq(two)
 

pypy/module/micronumpy/strides.py

+from pypy.rlib import jit
 
+
+@jit.look_inside_iff(lambda shape, start, strides, backstrides, chunks:
+    jit.isconstant(len(chunks))
+)
 def calculate_slice_strides(shape, start, strides, backstrides, chunks):
     rstrides = []
     rbackstrides = []

pypy/module/micronumpy/test/test_numarray.py

         b[0] = 3
         assert debug_repr(b) == 'Array'
 
+    def test_remove_invalidates(self):
+        from numpypy import array
+        from numpypy.pypy import remove_invalidates
+        a = array([1, 2, 3])
+        b = a + a
+        remove_invalidates(a)
+        a[0] = 14
+        assert b[0] == 28
+
     def test_virtual_views(self):
         from numpypy import arange
         a = arange(15)
                         set_param(driver, name1, int(value))
                     except ValueError:
                         raise
+                    break
+            else:
+                raise ValueError
 set_user_param._annspecialcase_ = 'specialize:arg(0)'
 
 

pypy/rlib/rsre/rsre_jit.py

                     info = '%s/%d' % (info, args[debugprint[2]])
             else:
                 info = ''
-            return '%s%s %s' % (name, info, s)
+            return 're %s%s %s' % (name, info, s)
         #
         self.get_printable_location = get_printable_location
 

pypy/tool/jitlogparser/parser.py

         self.failargs = failargs
 
     def getarg(self, i):
-        return self._getvar(self.args[i])
+        return self.args[i]
 
     def getargs(self):
-        return [self._getvar(v) for v in self.args]
+        return self.args[:]
 
     def getres(self):
-        return self._getvar(self.res)
+        return self.res
 
     def getdescr(self):
         return self.descr
 
-    def _getvar(self, v):
-        return v
-
     def is_guard(self):
         return self._is_guard
 
     def repr(self):
         args = self.getargs()
         if self.descr is not None:
-            args.append('descr=%s' % self.getdescr())
+            args.append('descr=%s' % self.descr)
         arglist = ', '.join(args)
         if self.res is not None:
             return '%s = %s(%s)' % (self.getres(), self.name, arglist)
 
     def __repr__(self):
         return self.repr()
-        ## return '<%s (%s)>' % (self.name, ', '.join([repr(a)
-        ##                                             for a in self.args]))
 
 class SimpleParser(OpParser):
 
     is_bytecode = True
     inline_level = None
 
-    def __init__(self, operations, storage):
-        if operations[0].name == 'debug_merge_point':
-            self.inline_level = int(operations[0].args[0])
-            m = re.search('<code object ([<>\w]+)\. file \'(.+?)\'\. line (\d+)> #(\d+) (\w+)',
-                         operations[0].args[1])
-            if m is None:
-                # a non-code loop, like StrLiteralSearch or something
-                self.bytecode_name = operations[0].args[1][1:-1]
-            else:
-                self.name, self.filename, lineno, bytecode_no, self.bytecode_name = m.groups()
-                self.startlineno = int(lineno)
-                self.bytecode_no = int(bytecode_no)
+    def parse_code_data(self, arg):
+        m = re.search('<code object ([<>\w]+)[\.,] file \'(.+?)\'[\.,] line (\d+)> #(\d+) (\w+)',
+                      arg)
+        if m is None:
+            # a non-code loop, like StrLiteralSearch or something
+            self.bytecode_name = arg
+        else:
+            self.name, self.filename, lineno, bytecode_no, self.bytecode_name = m.groups()
+            self.startlineno = int(lineno)
+            self.bytecode_no = int(bytecode_no)
+
+
+    def __init__(self, operations, storage, loopname):
+        for op in operations:
+            if op.name == 'debug_merge_point':
+                self.inline_level = int(op.args[0])
+                self.parse_code_data(op.args[1][1:-1])
+                break
+        else:
+            self.inline_level = 0
+            self.parse_code_data(loopname)
         self.operations = operations
         self.storage = storage
         self.code = storage.disassemble_code(self.filename, self.startlineno,
 
     def repr(self):
         if self.filename is None:
-            return "Unknown"
+            return self.bytecode_name
         return "%s, file '%s', line %d" % (self.name, self.filename,
                                            self.startlineno)
 
         self.storage = storage
 
     @classmethod
-    def from_operations(cls, operations, storage, limit=None, inputargs=''):
+    def from_operations(cls, operations, storage, limit=None, inputargs='',
+                        loopname=''):
         """ Slice given operation list into a chain of TraceForOpcode chunks.
         Also detect inlined functions and make them Function
         """
         for op in operations:
             if op.name == 'debug_merge_point':
                 if so_far:
-                    append_to_res(cls.TraceForOpcode(so_far, storage))
+                    append_to_res(cls.TraceForOpcode(so_far, storage, loopname))
                     if limit:
                         break
                     so_far = []
             so_far.append(op)
         if so_far:
-            append_to_res(cls.TraceForOpcode(so_far, storage))
+            append_to_res(cls.TraceForOpcode(so_far, storage, loopname))
         # wrap stack back up
         if not stack:
             # no ops whatsoever
 
     def repr(self):
         if self.filename is None:
-            return "Unknown"
+            return self.chunks[0].bytecode_name
         return "%s, file '%s', line %d" % (self.name, self.filename,
                                            self.startlineno)
 
     if trace.comment and 'Guard' in trace.comment:
         descrs = ['bridge ' + re.search('Guard (\d+)', trace.comment).group(1)]
     else:
-        descrs = ['']
+        descrs = ['entry ' + re.search('Loop (\d+)', trace.comment).group(1)]
     for i, op in enumerate(trace.operations):
         if op.name == 'label':
             labels.append(i)
         part = copy(trace)
         part.operations = trace.operations[start : stop + 1]
         part.descr = descrs[i]
+        part.comment = trace.comment
         parts.append(part)
     
     return parts

pypy/tool/jitlogparser/test/test_parser.py

     ''')
     res = Function.from_operations(ops.operations, LoopStorage())
     assert len(res.chunks) == 1
-    assert res.chunks[0].repr()
+    assert 'SomeRandomStuff' in res.chunks[0].repr()
 
 def test_split():
     ops = parse('''
     [i0]
+    label()
     debug_merge_point(0, "<code object stuff. file '/I/dont/exist.py'. line 200> #10 ADD")
     debug_merge_point(0, "<code object stuff. file '/I/dont/exist.py'. line 200> #11 SUB")
     i1 = int_add(i0, 1)
     debug_merge_point(0, "<code object stuff. file '/I/dont/exist.py'. line 200> #11 SUB")
     i2 = int_add(i1, 1)
     ''')
-    res = Function.from_operations(ops.operations, LoopStorage())
-    assert len(res.chunks) == 3
+    res = Function.from_operations(ops.operations, LoopStorage(), loopname='<loopname>')
+    assert len(res.chunks) == 4
     assert len(res.chunks[0].operations) == 1
-    assert len(res.chunks[1].operations) == 2
+    assert len(res.chunks[1].operations) == 1
     assert len(res.chunks[2].operations) == 2
-    assert res.chunks[2].bytecode_no == 11
+    assert len(res.chunks[3].operations) == 2
+    assert res.chunks[3].bytecode_no == 11
+    assert res.chunks[0].bytecode_name == '<loopname>'
 
 def test_inlined_call():
     ops = parse("""
     guard_true(i19, descr=<Guard2>) []
     i113 = getfield_raw(151937600, descr=<SignedFieldDescr pypysig_long_struct.c_value 0>)
     ''')
+    loop.comment = 'Loop 0'
     parts = split_trace(loop)
     assert len(parts) == 3
     assert len(parts[0].operations) == 2
     finish(i0)
     ''')
     bridge.comment = 'bridge out of Guard 2 with 1 ops'
-    loop.comment = ''
+    loop.comment = 'Loop 0'
     loops = split_trace(loop) + split_trace(bridge)
     input = ['grrr:123\nasb:12\nbridge 2:1234']
     parse_log_counts(input, loops)

pypy/translator/sandbox/pypy_interact.py

 from pypy.translator.sandbox.sandlib import SimpleIOSandboxedProc
 from pypy.translator.sandbox.sandlib import VirtualizedSandboxedProc
 from pypy.translator.sandbox.vfs import Dir, RealDir, RealFile
-from pypy.tool.lib_pypy import LIB_ROOT
+import pypy
+LIB_ROOT = os.path.dirname(os.path.dirname(pypy.__file__))
 
 class PyPySandboxedProc(VirtualizedSandboxedProc, SimpleIOSandboxedProc):
     debug = True

pypy/translator/sandbox/sandlib.py

 # load().  Also, marshal.load(f) blocks with the GIL held when
 # f is a pipe with no data immediately avaialble, preventing the
 # _waiting_thread to run.
-from pypy.tool.lib_pypy import import_from_lib_pypy
-marshal = import_from_lib_pypy('marshal')
+import pypy
+marshal = py.path.local(pypy.__file__).join('..', '..', 'lib_pypy',
+                                            'marshal.py').pyimport()
 
 # Non-marshal result types
 RESULTTYPE_STATRESULT = object()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.