Пример #1
0
 def enable(self, space, fileno, period_usec):
     if self.is_enabled:
         raise oefmt(space.w_ValueError, "_vmprof already enabled")
     self.fileno = fileno
     self.is_enabled = True
     self.write_header(fileno, period_usec)
     if not self.ever_enabled:
         if we_are_translated():
             res = pypy_vmprof_init()
             if res:
                 raise OperationError(
                     space.w_IOError,
                     space.wrap(rffi.charp2str(vmprof_get_error())))
         self.ever_enabled = True
     self.gather_all_code_objs(space)
     space.register_code_callback(vmprof_register_code)
     if we_are_translated():
         # does not work untranslated
         res = vmprof_enable(fileno, period_usec, 0,
                             lltype.nullptr(rffi.CCHARP.TO), 0)
     else:
         res = 0
     if res == -1:
         raise wrap_oserror(space, OSError(rposix.get_saved_errno(),
                                           "_vmprof.enable"))
Пример #2
0
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type,
                         orig_inpargs, memo):
    forget_optimization_info(loop.operations)
    forget_optimization_info(loop.inputargs)
    vinfo = jitdriver_sd.virtualizable_info
    if vinfo is not None:
        vable = orig_inpargs[jitdriver_sd.index_of_virtualizable].getref_base()
        patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd, vable)

    original_jitcell_token = loop.original_jitcell_token
    globaldata = metainterp_sd.globaldata
    original_jitcell_token.number = n = globaldata.loopnumbering
    globaldata.loopnumbering += 1

    if not we_are_translated():
        show_procedures(metainterp_sd, loop)
        loop.check_consistency()

    if metainterp_sd.warmrunnerdesc is not None:
        hooks = metainterp_sd.warmrunnerdesc.hooks
        debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops,
                                  original_jitcell_token, loop.operations,
                                  type, greenkey)
        hooks.before_compile(debug_info)
    else:
        debug_info = None
        hooks = None
    operations = get_deep_immutable_oplist(loop.operations)
    metainterp_sd.profiler.start_backend()
    debug_start("jit-backend")
    try:
        loopname = jitdriver_sd.warmstate.get_location_str(greenkey)
        unique_id = jitdriver_sd.warmstate.get_unique_id(greenkey)
        asminfo = do_compile_loop(jitdriver_sd.index, unique_id, metainterp_sd,
                                  loop.inputargs,
                                  operations, original_jitcell_token,
                                  name=loopname,
                                  log=have_debug_prints(),
                                  memo=memo)
    finally:
        debug_stop("jit-backend")
    metainterp_sd.profiler.end_backend()
    if hooks is not None:
        debug_info.asminfo = asminfo
        hooks.after_compile(debug_info)
    metainterp_sd.stats.add_new_loop(loop)
    if not we_are_translated():
        metainterp_sd.stats.compiled()
    metainterp_sd.log("compiled new " + type)
    #
    if asminfo is not None:
        ops_offset = asminfo.ops_offset
    else:
        ops_offset = None
    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)
Пример #3
0
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token):
    if not we_are_translated():
        show_procedures(metainterp_sd)
        seen = dict.fromkeys(inputargs)
        TreeLoop.check_consistency_of_branch(operations, seen)
    if metainterp_sd.warmrunnerdesc is not None:
        hooks = metainterp_sd.warmrunnerdesc.hooks
        debug_info = JitDebugInfo(
            jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, "bridge", fail_descr=faildescr
        )
        hooks.before_compile_bridge(debug_info)
    else:
        hooks = None
        debug_info = None
    operations = get_deep_immutable_oplist(operations)
    metainterp_sd.profiler.start_backend()
    debug_start("jit-backend")
    try:
        asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token)
    finally:
        debug_stop("jit-backend")
    metainterp_sd.profiler.end_backend()
    if hooks is not None:
        debug_info.asminfo = asminfo
        hooks.after_compile_bridge(debug_info)
    if not we_are_translated():
        metainterp_sd.stats.compiled()
    metainterp_sd.log("compiled new bridge")
    #
    if asminfo is not None:
        ops_offset = asminfo.ops_offset
    else:
        ops_offset = None
    metainterp_sd.logger_ops.log_bridge(inputargs, operations, None, faildescr, ops_offset)
Пример #4
0
 def edge_to(self, to, arg=None, failarg=False, label=None):
     if self is to:
         return
     dep = self.depends_on(to)
     if not dep:
         #if force or self.independent(idx_from, idx_to):
         dep = Dependency(self, to, arg, failarg)
         self.adjacent_list.append(dep)
         dep_back = Dependency(to, self, arg, failarg)
         dep.backward = dep_back
         to.adjacent_list_back.append(dep_back)
         if not we_are_translated():
             if label is None:
                 label = ''
             dep.label = label
     else:
         if not dep.because_of(arg):
             dep.add_dependency(self,to,arg)
         # if a fail argument is overwritten by another normal
         # dependency it will remove the failarg flag
         if not (dep.is_failarg() and failarg):
             dep.set_failarg(False)
         if not we_are_translated() and label is not None:
             _label = getattr(dep, 'label', '')
             dep.label = _label + ", " + label
     return dep
Пример #5
0
 def f():
     state.data = []
     state.datalen1 = 0
     state.datalen2 = 0
     state.datalen3 = 0
     state.datalen4 = 0
     state.threadlocals = gil.GILThreadLocals()
     state.threadlocals.setup_threads(space)
     thread.gc_thread_prepare()
     subident = thread.start_new_thread(bootstrap, ())
     mainident = thread.get_ident()
     runme(True)
     still_waiting = 3000
     while len(state.data) < 2*N:
         debug_print(len(state.data))
         if not still_waiting:
             raise ValueError("time out")
         still_waiting -= 1
         if not we_are_translated(): gil.before_external_call()
         time.sleep(0.01)
         if not we_are_translated(): gil.after_external_call()
     debug_print("leaving!")
     i1 = i2 = 0
     for tid, i in state.data:
         if tid == mainident:
             assert i == i1; i1 += 1
         elif tid == subident:
             assert i == i2; i2 += 1
         else:
             assert 0
     assert i1 == N + skew
     assert i2 == N - skew
     return len(state.data)
Пример #6
0
    def emit_store(self, value, addr, typ):
        """Emit a typed store operation of a value into the heap.

        Given a jsvalue, a heap address, and a HeapType, this method generates
        a generic "store to heap" instruction of the following form:

            HEAPVIEW[(addr) >> shift] = value;

        """
        assert isinstance(addr, jsval.AbstractValue)
        # When running untranslated, we can't guarantee alignment of doubles.
        # We have to store it into a properly aligned chunk, then
        # copy to final destination as two 32-bit ints.
        tempaddr = None
        if not we_are_translated() and typ is jsval.Float64:
            tempaddr = self.allocate_intvar()
            self.emit_assignment(tempaddr, addr)
            addr = jsval.tempDoublePtr
        self.emit(typ.heap_name)
        self.emit("[(")
        self.emit_value(addr)
        self.emit(")>>")
        self.emit(str(typ.shift))
        self.emit("]=")
        self.emit_value(value)
        self.emit(";\n")
        if not we_are_translated() and typ is jsval.Float64:
            pt1 = jsval.HeapData(jsval.Int32, addr)
            self.emit_store(pt1, tempaddr, jsval.Int32)
            pt2 = jsval.HeapData(jsval.Int32, jsval.Plus(addr, jsval.word))
            self.emit_store(pt2, jsval.Plus(tempaddr, jsval.word), jsval.Int32)
            self.free_intvar(tempaddr)
Пример #7
0
    def _really_force(self, optforce):
        op = self.source_op
        assert op is not None
        # ^^^ This case should not occur any more (see test_bug_3).
        #
        if not we_are_translated():
            op.name = 'FORCE ' + self.source_op.name

        if self._is_immutable_and_filled_with_constants():
            box = optforce.optimizer.constant_fold(op)
            self.make_constant(box)
            for ofs, value in self._fields.iteritems():
                subbox = value.force_box(optforce)
                assert isinstance(subbox, Const)
                execute(optforce.optimizer.cpu, None, rop.SETFIELD_GC,
                        ofs, box, subbox)
            # keep self._fields, because it's all immutable anyway
        else:
            optforce.emit_operation(op)
            self.box = box = op.result
            #
            iteritems = self._fields.iteritems()
            if not we_are_translated(): #random order is fine, except for tests
                iteritems = list(iteritems)
                iteritems.sort(key=lambda (x, y): x.sort_key())
            for ofs, value in iteritems:
                if value.is_null():
                    continue
                subbox = value.force_box(optforce)
                op = ResOperation(rop.SETFIELD_GC, [box, subbox], None,
                                  descr=ofs)

                optforce.emit_operation(op)
Пример #8
0
 def f():
     state.data = []
     state.datalen1 = 0
     state.datalen2 = 0
     state.datalen3 = 0
     state.datalen4 = 0
     state.threadlocals = my_gil_threadlocals
     state.threadlocals.setup_threads(space)
     subident = thread.start_new_thread(bootstrap, ())
     mainident = thread.get_ident()
     runme(True)
     still_waiting = 3000
     while len(state.data) < 2*N:
         debug_print(len(state.data))
         if not still_waiting:
             llop.debug_print(lltype.Void, "timeout. progress: "
                              "%d of 2*N (= %f%%)" % \
                              (len(state.data), 2*N, 100*len(state.data)/(2.0*N)))
             raise ValueError("time out")
         still_waiting -= 1
         if not we_are_translated(): rgil.release()
         time.sleep(0.1)
         if not we_are_translated(): rgil.acquire()
     debug_print("leaving!")
     i1 = i2 = 0
     for tid, i in state.data:
         if tid == mainident:
             assert i == i1; i1 += 1
         elif tid == subident:
             assert i == i2; i2 += 1
         else:
             assert 0
     assert i1 == N + skew
     assert i2 == N - skew
     return len(state.data)
Пример #9
0
def run_load_stdlib():
    global stdlib_loaded
    if stdlib_loaded.is_true():
        return
    import pixie.vm.compiler as compiler
    import pixie.vm.reader as reader
    f = open(rpath.rjoin(str(rt.name(load_path.deref())), "pixie/stdlib.pxi"))
    data = f.read()
    f.close()
    rdr = reader.MetaDataReader(reader.StringReader(unicode(data)), u"pixie/stdlib.pxi")
    result = nil

    if not we_are_translated():
        print "Loading stdlib while interpreted, this will take some time..."

    with compiler.with_ns(u"pixie.stdlib"):
        while True:
            if not we_are_translated():
                sys.stdout.write(".")
                sys.stdout.flush()
            form = reader.read(rdr, False)
            if form is reader.eof:
                break
            result = compiler.compile(form).invoke([])

    if not we_are_translated():
        print "done"

    stdlib_loaded.set_true()
Пример #10
0
    def get_new_loc(self, box):
        size = self.frame_size(box.type)
        # frame_depth is rounded up to a multiple of 'size', assuming
        # that 'size' is a power of two.  The reason for doing so is to
        # avoid obscure issues in jump.py with stack locations that try
        # to move from position (6,7) to position (7,8).
        newloc = self.freelist.pop(size, box.type)
        if newloc is None:
            #
            index = self.get_frame_depth()
            if index & 1 and size == 2:
                # we can't allocate it at odd position
                self.freelist._append(index)
                newloc = self.frame_pos(index + 1, box.type)
                self.current_frame_depth += 3
                index += 1 # for test
            else:
                newloc = self.frame_pos(index, box.type)
                self.current_frame_depth += size
            #
            if not we_are_translated():    # extra testing
                testindex = self.get_loc_index(newloc)
                assert testindex == index
            #

        self.bindings[box] = newloc
        if not we_are_translated():
            self._check_invariants()
        return newloc
Пример #11
0
def load_reader(rdr):
    import pixie.vm.reader as reader
    import pixie.vm.compiler as compiler
    import sys

    if not we_are_translated():
        print "Loading file while interpreted, this may take time"

    val = PXIC_WRITER.deref()
    if val is nil:
        pxic_writer = None
    else:
        pxic_writer = val.get_pxic_writer()

    with compiler.with_ns(u"user"):
        compiler.NS_VAR.deref().include_stdlib()
        while True:
            if not we_are_translated():
                sys.stdout.write(".")
                sys.stdout.flush()
            form = reader.read(rdr, False)
            if form is reader.eof:
                return nil
            compiled = compiler.compile(form)

            if pxic_writer is not None:
                pxic_writer.write_object(compiled)

            compiled.invoke([])

    if not we_are_translated():
        print "done"

    return nil
Пример #12
0
def get_const_ptr_for_string(s):
    from rpython.rtyper.annlowlevel import llstr
    if not we_are_translated():
        try:
            return _const_ptr_for_string[s]
        except KeyError:
            pass
    result = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, llstr(s)))
    if not we_are_translated():
        _const_ptr_for_string[s] = result
    return result
Пример #13
0
def load_reader(rdr):
    import pixie.vm.reader as reader
    import pixie.vm.compiler as compiler
    import sys

    if not we_are_translated():
        print "Loading file while interpreted, this may take time"

    val = PXIC_WRITER.deref()
    if val is nil:
        pxic_writer = None
    else:
        pxic_writer = val.get_pxic_writer()

    with compiler.with_ns(u"user"):
        compiler.NS_VAR.deref().include_stdlib()
        while True:
            if not we_are_translated():
                sys.stdout.write(".")
                sys.stdout.flush()
            form = reader.read(rdr, False)
            if form is reader.eof:
                return nil

            try:
                compiled = compiler.compile(form)

            except WrappedException as ex:
                meta = rt.meta(form)
                if meta is not nil:
                    ci = rt.interpreter_code_info(meta)
                    add_info(ex, ci.__repr__())
                add_info(ex, u"Compiling: " + rt.name(rt.str(form)))
                raise ex

            try:
                if pxic_writer is not None:
                    pxic_writer.write_object(compiled)

                compiled.invoke([])

            except WrappedException as ex:
                meta = rt.meta(form)
                if meta is not nil:
                    ci = rt.interpreter_code_info(meta)
                    add_info(ex, ci.__repr__())
                add_info(ex, u"Running: " + rt.name(rt.str(form)))
                raise ex


    if not we_are_translated():
        print "done"

    return nil
Пример #14
0
 def walk_operations(self, inputargs, operations):
     from rpython.jit.backend.ppc.ppc_assembler import (
         operations as asm_operations)
     i = 0
     self.limit_loop_break = (self.assembler.mc.get_relative_pos() +
                                  LIMIT_LOOP_BREAK)
     self.operations = operations
     while i < len(operations):
         op = operations[i]
         self.assembler.mc.mark_op(op)
         self.rm.position = i
         self.fprm.position = i
         self.vrm.position = i
         opnum = op.opnum
         if rop.has_no_side_effect(opnum) and op not in self.longevity:
             i += 1
             self.possibly_free_vars_for_op(op)
             continue
         #
         for j in range(op.numargs()):
             box = op.getarg(j)
             if box.is_vector():
                 if box.type != VOID:
                     self.vrm.temp_boxes.append(box)
             elif box.type != FLOAT:
                 self.rm.temp_boxes.append(box)
             else:
                 self.fprm.temp_boxes.append(box)
         #
         if not we_are_translated() and opnum == rop.FORCE_SPILL:
             self._consider_force_spill(op)
         else:
             arglocs = oplist[opnum](self, op)
             asm_operations[opnum](self.assembler, op, arglocs, self)
         self.free_op_vars()
         self.possibly_free_var(op)
         self.rm._check_invariants()
         self.fprm._check_invariants()
         self.vrm._check_invariants()
         if self.assembler.mc.get_relative_pos() > self.limit_loop_break:
             self.assembler.break_long_loop(self)
             self.limit_loop_break = (self.assembler.mc.get_relative_pos() +
                                          LIMIT_LOOP_BREAK)
         i += 1
     assert not self.rm.reg_bindings
     assert not self.fprm.reg_bindings
     if not we_are_translated():
         self.assembler.mc.trap()
     self.flush_loop()
     self.assembler.mc.mark_op(None) # end of the loop
     self.operations = None
     for arg in inputargs:
         self.possibly_free_var(arg)
Пример #15
0
def get_const_ptr_for_unicode(s):
    from rpython.rtyper.annlowlevel import llunicode
    if not we_are_translated():
        try:
            return _const_ptr_for_unicode[s]
        except KeyError:
            pass
    if isinstance(s, str):
        s = unicode(s)
    result = ConstPtr(lltype.cast_opaque_ptr(llmemory.GCREF, llunicode(s)))
    if not we_are_translated():
        _const_ptr_for_unicode[s] = result
    return result
Пример #16
0
def record_loop_or_bridge(metainterp_sd, loop):
    """Do post-backend recordings and cleanups on 'loop'.
    """
    # get the original jitcell token corresponding to jitcell form which
    # this trace starts
    original_jitcell_token = loop.original_jitcell_token
    assert original_jitcell_token is not None
    if metainterp_sd.warmrunnerdesc is not None:    # for tests
        assert original_jitcell_token.generation > 0     # has been registered with memmgr
    wref = weakref.ref(original_jitcell_token)
    for op in loop.operations:
        descr = op.getdescr()
        if isinstance(descr, ResumeDescr):
            descr.wref_original_loop_token = wref   # stick it there
            n = descr.index
            if n >= 0:       # we also record the resumedescr number
                original_jitcell_token.compiled_loop_token.record_faildescr_index(n)
        elif isinstance(descr, JitCellToken):
            # for a CALL_ASSEMBLER: record it as a potential jump.
            if descr is not original_jitcell_token:
                original_jitcell_token.record_jump_to(descr)
            descr.exported_state = None
            op.cleardescr()    # clear reference, mostly for tests
        elif isinstance(descr, TargetToken):
            # for a JUMP: record it as a potential jump.
            # (the following test is not enough to prevent more complicated
            # cases of cycles, but at least it helps in simple tests of
            # test_memgr.py)
            if descr.original_jitcell_token is not original_jitcell_token:
                assert descr.original_jitcell_token is not None
                original_jitcell_token.record_jump_to(descr.original_jitcell_token)
            # exported_state is clear by optimizeopt when the short preamble is
            # constrcucted. if that did not happen the label should not show up
            # in a trace that will be used
            assert descr.exported_state is None
            if not we_are_translated():
                op._descr_wref = weakref.ref(op._descr)
            op.cleardescr()    # clear reference to prevent the history.Stats
                               # from keeping the loop alive during tests
    # record this looptoken on the QuasiImmut used in the code
    if loop.quasi_immutable_deps is not None:
        for qmut in loop.quasi_immutable_deps:
            qmut.register_loop_token(wref)
        # XXX maybe we should clear the dictionary here
    # mostly for tests: make sure we don't keep a reference to the LoopToken
    loop.original_jitcell_token = None
    if not we_are_translated():
        loop._looptoken_number = original_jitcell_token.number
Пример #17
0
Файл: ffi.py Проект: kidaa/pixie
def ffi_prep_callback(tp, f):
    """(ffi-prep-callback callback-tp fn)
       Prepares a Pixie function for use as a c callback. callback-tp is a ffi callback type,
       fn is a pixie function (can be a closure, native fn or any object that implements -invoke.
       Returns a function pointer that can be passed to c and invoked as a callback."""
    affirm(isinstance(tp, CFunctionType), u"First argument to ffi-prep-callback must be a CFunctionType")
    raw_closure = rffi.cast(rffi.VOIDP, clibffi.closureHeap.alloc())

    if not we_are_translated():
        unique_id = id_generator.get_next()
    else:
        unique_id = rffi.cast(lltype.Signed, raw_closure)

    res = clibffi.c_ffi_prep_closure(rffi.cast(clibffi.FFI_CLOSUREP, raw_closure), tp.get_cd().cif,
                             invoke_callback,
                             rffi.cast(rffi.VOIDP, unique_id))


    if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
        registered_callbacks[unique_id] = None
        runtime_error(u"libffi failed to build this callback")

    cb = CCallback(tp, raw_closure, unique_id, f)
    registered_callbacks[unique_id] = cb

    return cb
Пример #18
0
    def test_we_are_translated(self):
        assert we_are_translated() is False

        def fn():
            return we_are_translated()
        res = self.interpret(fn, [])
        assert res is True
Пример #19
0
def failnbail_transformation(msg):
    msg = '%s\n' % msg
    if we_are_translated():
        llop.debug_print(lltype.Void, msg)
    else:
        import pdb; pdb.set_trace()
    raise NotImplementedError(msg)
Пример #20
0
    def walk_and_emit(self, state):
        """ Emit all the operations into the oplist parameter.
            Initiates the scheduling. """
        assert isinstance(state, SchedulerState)
        while state.has_more():
            node = self.next(state)
            if node:
                if not state.emit(node, self):
                    if not node.emitted:
                        state.pre_emit(node)
                        self.mark_emitted(node, state)
                        if not node.is_imaginary():
                            op = node.getoperation()
                            state.seen[op] = None
                            state.oplist.append(op)
                continue

            # it happens that packs can emit many nodes that have been
            # added to the scheuldable_nodes list, in this case it could
            # be that no next exists even though the list contains elements
            if not state.has_more():
                break

            if self.try_to_trash_pack(state):
                continue

            raise AssertionError("schedule failed cannot continue. possible reason: cycle")

        if not we_are_translated():
            for node in state.graph.nodes:
                assert node.emitted
Пример #21
0
 def setraw(value):
     if we_are_translated():
         _threadlocalref_seeme(self)
         addr = llop.threadlocalref_addr(llmemory.Address)
         llop.raw_store(lltype.Void, addr, offset, value)
     else:
         self.local.rawvalue = value
Пример #22
0
def gc_thread_after_fork(result_of_fork, opaqueaddr):
    """To call just after fork().
    """
    if we_are_translated():
        llop.gc_thread_after_fork(lltype.Void, result_of_fork, opaqueaddr)
    else:
        assert opaqueaddr == llmemory.NULL
Пример #23
0
 def __init__(self, translated=None):
     if translated is None:
         translated = we_are_translated()
     if translated:
         self.init_block_builder()
     else:
         self._become_a_plain_block_builder()
Пример #24
0
 def __init__(self, value):
     if not we_are_translated():
         if is_valid_int(value):
             value = int(value)    # bool -> int
         else:
             assert isinstance(value, Symbolic)
     self.value = value
Пример #25
0
 def get_or_make_raw():
     if we_are_translated():
         _threadlocalref_seeme(self)
         addr = llop.threadlocalref_addr(llmemory.Address)
         return llop.raw_load(FIELDTYPE, addr, offset)
     else:
         return getattr(self.local, 'rawvalue', zero)
Пример #26
0
def Py_DecRef(space, obj):
    if not obj:
        return
    assert lltype.typeOf(obj) == PyObject

    obj.c_ob_refcnt -= 1
    if DEBUG_REFCOUNT:
        debug_refcount("DECREF", obj, obj.c_ob_refcnt, frame_stackdepth=3)
    if obj.c_ob_refcnt == 0:
        state = space.fromcache(RefcountState)
        ptr = rffi.cast(ADDR, obj)
        if ptr not in state.py_objects_r2w:
            # this is a half-allocated object, lets call the deallocator
            # without modifying the r2w/w2r dicts
            _Py_Dealloc(space, obj)
        else:
            w_obj = state.py_objects_r2w[ptr]
            del state.py_objects_r2w[ptr]
            w_type = space.type(w_obj)
            if not w_type.is_cpytype():
                _Py_Dealloc(space, obj)
            del state.py_objects_w2r[w_obj]
            # if the object was a container for borrowed references
            state.delete_borrower(w_obj)
    else:
        if not we_are_translated() and obj.c_ob_refcnt < 0:
            message = "Negative refcount for obj %s with type %s" % (
                obj, rffi.charp2str(obj.c_ob_type.c_tp_name))
            print >>sys.stderr, message
            assert False, message
Пример #27
0
def gc_thread_die():
    """To call just before the final GIL release done by a dying
    thread.  After a thread_die(), no more gc operation should
    occur in this thread.
    """
    if we_are_translated():
        llop.gc_thread_die(lltype.Void)
Пример #28
0
 def get_location_str(greenkey):
     greenargs = unwrap_greenkey(greenkey)
     fn = support.maybe_on_top_of_llinterp(rtyper, get_location_ptr)
     llres = fn(*greenargs)
     if not we_are_translated() and isinstance(llres, str):
         return llres
     return hlstr(llres)
Пример #29
0
 def record_interpreter_traceback(self):
     """Records the current traceback inside the interpreter.
     This traceback is only useful to debug the interpreter, not the
     application."""
     if not we_are_translated():
         if RECORD_INTERPLEVEL_TRACEBACK:
             self.debug_excs.append(sys.exc_info())
Пример #30
0
 def free_temp_buffers(self, space):
     for buf in self.to_free:
         if not we_are_translated():
             buf[0] = '\00' # invalidate the buffer, so that
                            # test_keepalive_temp_buffer can fail
         lltype.free(buf, flavor='raw')
     self.to_free = []
Пример #31
0
def warn_missing_slot(space, method_name, slot_name, w_type):
    if not we_are_translated():
        if slot_name not in missing_slots:
            missing_slots[slot_name] = w_type.getname(space)
            print "missing slot %r/%r, discovered on %r" % (
                method_name, slot_name, w_type.getname(space))
Пример #32
0
def main(filename,
         rest_of_args,
         cgi,
         gcdump,
         debugger_pipes=(-1, -1),
         bench_mode=False,
         bench_no=-1):
    space = getspace()
    interp = Interpreter(space)

    absname = rpath.abspath(filename)

    try:
        ini_data = open('hippy.ini').read(-1)
    except (OSError, IOError):
        ini_data = None

    if ini_data is not None:
        try:
            load_ini(interp, ini_data)
        except:
            os.write(2, "error reading `hippy.ini`")

    try:
        bc = space.bytecode_cache.compile_file(absname, space)
    except ParseError as e:
        print 'Parse error:  %s' % e
        return 2
    except LexerError as e:
        print 'Parse error:  %s on line %d' % (e.message, e.source_pos + 1)
        return 2
    except IOError as e:
        print 'Could not open input file: %s' % filename
        return 2
    except Exception as e:
        print 'Got exception %s with message %s' % (e.__class__.__name__, e)
        return 2
    #
    if bench_mode:
        no = bench_no
    else:
        no = 1

    exitcode = 0
    space.ec.init_signals()
    for i in range(no):
        # load the ini file situated in the current wc
        interp.setup(cgi, argv=[filename] + rest_of_args)
        if bc is None:
            return 1
        # The script originally called is considered an "included file,"
        # so it will be listed together with the files
        # referenced by include and family.
        interp.cached_files[filename] = bc
        #
        exitcode = 0
        try:
            try:
                if debugger_pipes != (-1, -1):
                    interp.setup_debugger(debugger_pipes[0],
                                          debugger_pipes[1],
                                          start_paused=True)
                interp.run_main(space, bc, top_main=True)
            finally:
                interp.shutdown()
        except InterpreterError, e:
            tb = e.traceback
            if tb is not None:
                tb = tb[:]
                tb.reverse()
                for filename, funcname, line, source in tb:
                    os.write(
                        2, "function %s, file %s:%d\n" %
                        (funcname, filename, line))
                    os.write(2, source + "\n")
            if we_are_translated():
                os.write(2, "Fatal interpreter error %s\n" % e.msg)
            else:
                print >> sys.stderr, "%s: %s\n" % (e.__class__.__name__, e.msg)

        except ParseError as e:
            print e.__str__()
            return 1
Пример #33
0
 def __init__(self, pattern):
     self.pattern = pattern
     # check we don't get the old value of MAXREPEAT
     # during the untranslated tests
     if not we_are_translated():
         assert 65535 not in pattern
Пример #34
0
Файл: cintf.py Проект: Mu-L/pypy
def leave_code(s):
    if not we_are_translated():
        assert vmprof_tl_stack.getraw() == s
    vmprof_tl_stack.setraw(s.c_next)
    lltype.free(s, flavor='raw')
Пример #35
0
def dict_allocate():
    if not we_are_translated(): count_alloc(+1)
    return lltype.malloc(DICT, flavor="raw")
Пример #36
0
 def rewrite(self, operations, gcrefs_output_list):
     # we can only remember one malloc since the next malloc can possibly
     # collect; but we can try to collapse several known-size mallocs into
     # one, both for performance and to reduce the number of write
     # barriers.  We do this on each "basic block" of operations, which in
     # this case means between CALLs or unknown-size mallocs.
     #
     self.gcrefs_output_list = gcrefs_output_list
     self.gcrefs_map = None
     self.gcrefs_recently_loaded = None
     operations = self.remove_bridge_exception(operations)
     self._changed_op = None
     for i in range(len(operations)):
         op = operations[i]
         if op.get_forwarded():
             msg = '[rewrite] operations at %d has forwarded info %s\n' % (
                 i, op.repr({}))
             if we_are_translated():
                 llop.debug_print(lltype.Void, msg)
             raise NotImplementedError(msg)
         if op.getopnum() == rop.DEBUG_MERGE_POINT:
             continue
         if op is self._changed_op:
             op = self._changed_op_to
         # ---------- GC_LOAD/STORE transformations --------------
         if self.transform_to_gc_load(op):
             continue
         # ---------- turn NEWxxx into CALL_MALLOC_xxx ----------
         if rop.is_malloc(op.opnum):
             self.handle_malloc_operation(op)
             continue
         if (rop.is_guard(op.opnum)
                 or self.could_merge_with_next_guard(op, i, operations)):
             self.emit_pending_zeros()
         elif rop.can_malloc(op.opnum):
             self.emitting_an_operation_that_can_collect()
         elif op.getopnum() == rop.LABEL:
             self.emit_label()
         # ---------- write barriers ----------
         if self.gc_ll_descr.write_barrier_descr is not None:
             if op.getopnum() == rop.SETFIELD_GC:
                 self.consider_setfield_gc(op)
                 self.handle_write_barrier_setfield(op)
                 continue
             if op.getopnum() == rop.SETINTERIORFIELD_GC:
                 self.handle_write_barrier_setinteriorfield(op)
                 continue
             if op.getopnum() == rop.SETARRAYITEM_GC:
                 self.consider_setarrayitem_gc(op)
                 self.handle_write_barrier_setarrayitem(op)
                 continue
         else:
             # this is dead code, but in case we have a gc that does
             # not have a write barrier and does not zero memory, we would
             # need to call it
             if op.getopnum() == rop.SETFIELD_GC:
                 self.consider_setfield_gc(op)
             elif op.getopnum() == rop.SETARRAYITEM_GC:
                 self.consider_setarrayitem_gc(op)
         # ---------- call assembler -----------
         if OpHelpers.is_call_assembler(op.getopnum()):
             self.handle_call_assembler(op)
             continue
         if op.getopnum() == rop.JUMP or op.getopnum() == rop.FINISH:
             self.emit_pending_zeros()
         #
         self.emit_op(op)
     return self._newops
Пример #37
0
    def spill_or_move_registers_before_call(self,
                                            save_sublist,
                                            force_store=[],
                                            save_all_regs=SAVE_DEFAULT_REGS):
        """Spill or move some registers before a call.

        By default, this means: for every register in 'save_sublist',
        if there is a variable there and it survives longer than
        the current operation, then it is spilled/moved somewhere else.

        WARNING: this might do the equivalent of possibly_free_vars()
        on variables dying in the current operation.  It won't
        immediately overwrite registers that used to be occupied by
        these variables, though.  Use this function *after* you finished
        calling self.loc() or self.make_sure_var_in_reg(), i.e. when you
        know the location of all input arguments.  These locations stay
        valid, but only *if they are in self.save_around_call_regs,*
        not if they are callee-saved registers!

        'save_all_regs' can be SAVE_DEFAULT_REGS (default set of registers),
        SAVE_ALL_REGS (do that for all registers), or SAVE_GCREF_REGS (default
        + gc ptrs).

        Overview of what we do (the implementation does it differently,
        for the same result):

        * we first check the set of registers that are free: call it F.

        * possibly_free_vars() is implied for all variables (except
          the ones listed in force_store): if they don't survive past
          the current operation, they are forgotten now.  (Their
          register remain not in F, because they are typically
          arguments to the call, so they should not be overwritten by
          the next step.)

        * then for every variable that needs to be spilled/moved: if
          there is an entry in F that is acceptable, pick it and emit a
          move.  Otherwise, emit a spill.  Start doing this with the
          variables that survive the shortest time, to give them a
          better change to remain in a register---similar algo as
          _pick_variable_to_spill().

        Note: when a register is moved, it often (but not always) means
        we could have been more clever and picked a better register in
        the first place, when we did so earlier.  It is done this way
        anyway, as a local hack in this function, because on x86 CPUs
        such register-register moves are almost free.
        """
        if not we_are_translated():
            # 'save_sublist' is either the whole
            # 'self.save_around_call_regs', or a sublist thereof, and
            # then only those registers are spilled/moved.  But when
            # we move them, we never move them to other registers in
            # 'self.save_around_call_regs', to avoid ping-pong effects
            # where the same value is constantly moved around.
            for reg in save_sublist:
                assert reg in self.save_around_call_regs

        new_free_regs = []
        move_or_spill = []

        for v, reg in self.reg_bindings.items():
            max_age = self.longevity[v].last_usage
            if v not in force_store and max_age <= self.position:
                # variable dies
                del self.reg_bindings[v]
                new_free_regs.append(reg)
                continue

            if save_all_regs == SAVE_ALL_REGS:
                # we need to spill all registers in this mode
                self._bc_spill(v, new_free_regs)
                #
            elif save_all_regs == SAVE_GCREF_REGS and v.type == REF:
                # we need to spill all GC ptrs in this mode
                self._bc_spill(v, new_free_regs)
                #
            elif reg not in save_sublist:
                continue  # in a register like ebx/rbx: it is fine where it is
                #
            else:
                # this is a register like eax/rax, which needs either
                # spilling or moving.
                move_or_spill.append(v)

        if len(move_or_spill) > 0:
            free_regs = [
                reg for reg in self.free_regs
                if reg not in self.save_around_call_regs
            ]
            # chose which to spill using the usual spill heuristics
            while len(move_or_spill) > len(free_regs):
                v = self._pick_variable_to_spill([], regs=move_or_spill)
                self._bc_spill(v, new_free_regs)
                move_or_spill.remove(v)
            assert len(move_or_spill) <= len(free_regs)
            for v in move_or_spill:
                # search next good reg
                new_reg = None
                while True:
                    new_reg = self.free_regs.pop()
                    if new_reg in self.save_around_call_regs:
                        new_free_regs.append(new_reg)  # not this register...
                        continue
                    break
                assert new_reg is not None  # must succeed
                reg = self.reg_bindings[v]
                self.assembler.num_moves_calls += 1
                self.assembler.regalloc_mov(reg, new_reg)
                self.reg_bindings[v] = new_reg  # change the binding
                new_free_regs.append(reg)

        # re-add registers in 'new_free_regs', but in reverse order,
        # so that the last ones (added just above, from
        # save_around_call_regs) are picked last by future '.pop()'
        while len(new_free_regs) > 0:
            self.free_regs.append(new_free_regs.pop())
Пример #38
0
 def _check_type(self, v):
     if not we_are_translated() and self.box_types is not None:
         assert isinstance(v, TempVar) or v.type in self.box_types
Пример #39
0
def not_implemented(msg):
    msg = '[llsupport/regalloc] %s\n' % msg
    if we_are_translated():
        llop.debug_print(lltype.Void, msg)
    raise NotImplementedError(msg)
Пример #40
0
    def unicode_escape(s):
        size = len(s)
        result = StringBuilder(size)

        if quotes:
            if prefix:
                result.append(prefix)
            if s.find('\'') != -1 and s.find('\"') == -1:
                quote = ord('\"')
                result.append('"')
            else:
                quote = ord('\'')
                result.append('\'')
        else:
            quote = 0

            if size == 0:
                return ''

        pos = 0
        while pos < size:
            oc = codepoint_at_pos(s, pos)
            ch = s[pos]

            # Escape quotes
            if quotes and (oc == quote or ch == '\\'):
                result.append('\\')
                next_pos = next_codepoint_pos(s, pos)
                result.append_slice(s, pos, next_pos)
                pos = next_pos
                continue

            # The following logic is enabled only if MAXUNICODE == 0xffff, or
            # for testing on top of a host Python where sys.maxunicode == 0xffff
            if (not we_are_translated() and sys.maxunicode == 0xFFFF
                    and 0xD800 <= oc < 0xDC00 and pos + 3 < size):
                # Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes
                pos += 3
                oc2 = codepoint_at_pos(s, pos)

                if 0xDC00 <= oc2 <= 0xDFFF:
                    ucs = (((oc & 0x03FF) << 10) | (oc2 & 0x03FF)) + 0x00010000
                    char_escape_helper(result, ucs)
                    pos += 3
                    continue
                # Fall through: isolated surrogates are copied as-is
                pos -= 3

            # Map special whitespace to '\t', \n', '\r'
            if ch == '\t':
                result.append('\\t')
            elif ch == '\n':
                result.append('\\n')
            elif ch == '\r':
                result.append('\\r')
            elif ch == '\\':
                result.append('\\\\')

            # Map non-printable or non-ascii to '\xhh' or '\uhhhh'
            elif pass_printable and not (oc <= 0x10ffff
                                         and unicodedb.isprintable(oc)):
                char_escape_helper(result, oc)
            elif not pass_printable and (oc < 32 or oc >= 0x7F):
                char_escape_helper(result, oc)

            # Copy everything else as-is
            else:
                if oc < 128:
                    result.append(ch)
                else:
                    next_pos = next_codepoint_pos(s, pos)
                    result.append_slice(s, pos, next_pos)
            pos = next_codepoint_pos(s, pos)

        if quotes:
            result.append(chr(quote))
        return result.build()
Пример #41
0
def dict_delete(d):
    dict_delete_entries(d.entries)
    lltype.free(d, flavor="raw")
    if not we_are_translated(): count_alloc(-1)
Пример #42
0
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type,
                         orig_inpargs, memo):
    forget_optimization_info(loop.operations)
    forget_optimization_info(loop.inputargs)
    vinfo = jitdriver_sd.virtualizable_info
    if vinfo is not None:
        vable = orig_inpargs[jitdriver_sd.index_of_virtualizable].getref_base()
        patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd, vable)

    original_jitcell_token = loop.original_jitcell_token
    original_jitcell_token.number = n = metainterp_sd.jitlog.trace_id

    if not we_are_translated():
        show_procedures(metainterp_sd, loop)
        loop.check_consistency()

    debug_info = None
    hooks = None
    if metainterp_sd.warmrunnerdesc is not None:
        hooks = metainterp_sd.warmrunnerdesc.hooks
        if hooks.are_hooks_enabled():
            debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops,
                                      original_jitcell_token, loop.operations,
                                      type, greenkey)
            hooks.before_compile(debug_info)
        else:
            hooks = None
    operations = get_deep_immutable_oplist(loop.operations)
    metainterp_sd.profiler.start_backend()
    debug_start("jit-backend")
    log = have_debug_prints() or jl.jitlog_enabled()
    try:
        loopname = jitdriver_sd.warmstate.get_location_str(greenkey)
        unique_id = jitdriver_sd.warmstate.get_unique_id(greenkey)
        asminfo = do_compile_loop(jitdriver_sd.index,
                                  unique_id,
                                  metainterp_sd,
                                  loop.inputargs,
                                  operations,
                                  original_jitcell_token,
                                  name=loopname,
                                  log=log,
                                  memo=memo)
    finally:
        debug_stop("jit-backend")
    metainterp_sd.profiler.end_backend()
    if hooks is not None:
        debug_info.asminfo = asminfo
        hooks.after_compile(debug_info)
    metainterp_sd.stats.add_new_loop(loop)
    if not we_are_translated():
        metainterp_sd.stats.compiled()
    metainterp_sd.log("compiled new " + type)
    #
    if asminfo is not None:
        ops_offset = asminfo.ops_offset
    else:
        ops_offset = None
    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)
Пример #43
0
 def assert_stack_index(self, index):
     if we_are_translated():
         return
     assert self._check_stack_index(index)
Пример #44
0
                    continue
                except jitexc.DoneWithThisFrameVoid:
                    assert result_kind == 'void'
                    return
                except jitexc.DoneWithThisFrameInt, e:
                    assert result_kind == 'int'
                    return specialize_value(RESULT, e.result)
                except jitexc.DoneWithThisFrameRef, e:
                    assert result_kind == 'ref'
                    return specialize_value(RESULT, e.result)
                except jitexc.DoneWithThisFrameFloat, e:
                    assert result_kind == 'float'
                    return specialize_value(RESULT, e.result)
                except jitexc.ExitFrameWithExceptionRef, e:
                    value = ts.cast_to_baseclass(e.value)
                    if not we_are_translated():
                        raise LLException(ts.get_typeptr(value), value)
                    else:
                        value = cast_base_ptr_to_instance(Exception, value)
                        raise Exception, value

        def handle_jitexception(e):
            # XXX the bulk of this function is mostly a copy-paste from above
            try:
                raise e
            except jitexc.ContinueRunningNormally, e:
                args = ()
                for ARGTYPE, attrname, count in portalfunc_ARGS:
                    x = getattr(e, attrname)[count]
                    x = specialize_value(ARGTYPE, x)
                    args = args + (x, )
Пример #45
0
    def _write_barrier_fastpath(self,
                                mc,
                                descr,
                                arglocs,
                                regalloc,
                                array=False,
                                is_frame=False):
        # Write code equivalent to write_barrier() in the GC: it checks
        # a flag in the object at arglocs[0], and if set, it calls a
        # helper piece of assembler.  The latter saves registers as needed
        # and call the function remember_young_pointer() from the GC.
        if we_are_translated():
            cls = self.cpu.gc_ll_descr.has_write_barrier_class()
            assert cls is not None and isinstance(descr, cls)
        #
        card_marking_mask = 0
        mask = descr.jit_wb_if_flag_singlebyte
        if array and descr.jit_wb_cards_set != 0:
            # assumptions the rest of the function depends on:
            assert (
                descr.jit_wb_cards_set_byteofs == descr.jit_wb_if_flag_byteofs)
            card_marking_mask = descr.jit_wb_cards_set_singlebyte
        #
        loc_base = arglocs[0]
        assert loc_base.is_reg()
        if is_frame:
            assert loc_base is r.SPP
        assert check_imm_value(descr.jit_wb_if_flag_byteofs)
        mc.LLGC(r.SCRATCH2, l.addr(descr.jit_wb_if_flag_byteofs, loc_base))
        mc.LGR(r.SCRATCH, r.SCRATCH2)
        mc.NILL(r.SCRATCH, l.imm(mask & 0xFF))

        jz_location = mc.get_relative_pos()
        mc.reserve_cond_jump(short=True)  # patched later with 'EQ'

        # for cond_call_gc_wb_array, also add another fast path:
        # if GCFLAG_CARDS_SET, then we can just set one bit and be done
        if card_marking_mask:
            # GCFLAG_CARDS_SET is in the same byte, loaded in r2 already
            mc.LGR(r.SCRATCH, r.SCRATCH2)
            mc.NILL(r.SCRATCH, l.imm(card_marking_mask & 0xFF))
            js_location = mc.get_relative_pos()
            mc.reserve_cond_jump()  # patched later with 'NE'
        else:
            js_location = 0

        # Write only a CALL to the helper prepared in advance, passing it as
        # argument the address of the structure we are writing into
        # (the first argument to COND_CALL_GC_WB).
        helper_num = (card_marking_mask != 0)
        if is_frame:
            helper_num = 4
        elif regalloc.fprm.reg_bindings:
            helper_num += 2
        if self.wb_slowpath[helper_num] == 0:  # tests only
            assert not we_are_translated()
            assert not is_frame
            self.cpu.gc_ll_descr.write_barrier_descr = descr
            self._build_wb_slowpath(card_marking_mask != 0,
                                    bool(regalloc.fprm.reg_bindings))
            assert self.wb_slowpath[helper_num] != 0
        #
        if not is_frame:
            mc.LGR(r.r0, loc_base)  # unusual argument location

        mc.load_imm(r.r14, self.wb_slowpath[helper_num])
        mc.BASR(r.r14, r.r14)

        if card_marking_mask:
            # The helper ends again with a check of the flag in the object.
            # So here, we can simply write again a beq, which will be
            # taken if GCFLAG_CARDS_SET is still not set.
            jns_location = mc.get_relative_pos()
            mc.reserve_cond_jump(short=True)
            #
            # patch the 'NE' above
            currpos = mc.currpos()
            pmc = OverwritingBuilder(mc, js_location, 1)
            pmc.BRCL(c.NE, l.imm(currpos - js_location))
            pmc.overwrite()
            #
            # case GCFLAG_CARDS_SET: emit a few instructions to do
            # directly the card flag setting
            loc_index = arglocs[1]
            if loc_index.is_reg():
                tmp_loc = arglocs[2]
                n = descr.jit_wb_card_page_shift

                assert tmp_loc is not loc_index

                # compute in tmp_loc the byte offset:
                #   tmp_loc = ~(index >> (card_page_shift + 3))
                mc.SRLG(tmp_loc, loc_index, l.addr(n + 3))
                # invert the bits of tmp_loc

                # compute in SCRATCH the index of the bit inside the byte:
                #    scratch = (index >> card_page_shift) & 7
                # 0x80 sets zero flag. will store 0 into all not selected bits
                mc.RISBG(r.SCRATCH, loc_index, l.imm(61), l.imm(0x80 | 63),
                         l.imm(64 - n))
                mc.LGHI(r.SCRATCH2, l.imm(-1))
                mc.XGR(tmp_loc, r.SCRATCH2)

                # set SCRATCH2 to 1 << r1
                mc.LGHI(r.SCRATCH2, l.imm(1))
                mc.SLLG(r.SCRATCH2, r.SCRATCH2, l.addr(0, r.SCRATCH))

                # set this bit inside the byte of interest
                addr = l.addr(0, loc_base, tmp_loc)
                mc.LLGC(r.SCRATCH, addr)
                mc.OGRK(r.SCRATCH, r.SCRATCH, r.SCRATCH2)
                mc.STCY(r.SCRATCH, addr)
                # done
            else:
                byte_index = loc_index.value >> descr.jit_wb_card_page_shift
                byte_ofs = ~(byte_index >> 3)
                byte_val = 1 << (byte_index & 7)
                assert check_imm_value(byte_ofs,
                                       lower_bound=-2**19,
                                       upper_bound=2**19 - 1)

                addr = l.addr(byte_ofs, loc_base)
                mc.LLGC(r.SCRATCH, addr)
                mc.OILL(r.SCRATCH, l.imm(byte_val))
                mc.STCY(r.SCRATCH, addr)
            #
            # patch the beq just above
            currpos = mc.currpos()
            pmc = OverwritingBuilder(mc, jns_location, 1)
            pmc.BRC(c.EQ, l.imm(currpos - jns_location))
            pmc.overwrite()

        # patch the JZ above
        currpos = mc.currpos()
        pmc = OverwritingBuilder(mc, jz_location, 1)
        pmc.BRC(c.EQ, l.imm(currpos - jz_location))
        pmc.overwrite()
Пример #46
0
def compile_loop(metainterp,
                 greenkey,
                 start,
                 inputargs,
                 jumpargs,
                 use_unroll=True):
    """Try to compile a new procedure by closing the current history back
    to the first operation.
    """
    metainterp_sd = metainterp.staticdata
    jitdriver_sd = metainterp.jitdriver_sd
    history = metainterp.history
    trace = history.trace
    warmstate = jitdriver_sd.warmstate
    #
    metainterp_sd.jitlog.start_new_trace(metainterp_sd,
                                         faildescr=None,
                                         entry_bridge=False)
    #
    enable_opts = jitdriver_sd.warmstate.enable_opts
    jitcell_token = make_jitcell_token(jitdriver_sd)
    cut_at = history.get_trace_position()
    history.record(rop.JUMP, jumpargs, None, descr=jitcell_token)
    if start != (0, 0, 0):
        trace = trace.cut_trace_from(start, inputargs)
    if not use_unroll:
        return compile_simple_loop(metainterp, greenkey, trace, jumpargs,
                                   enable_opts, cut_at)
    call_pure_results = metainterp.call_pure_results
    preamble_data = PreambleCompileData(trace,
                                        jumpargs,
                                        call_pure_results=call_pure_results,
                                        enable_opts=enable_opts)
    try:
        start_state, preamble_ops = preamble_data.optimize_trace(
            metainterp_sd, jitdriver_sd, metainterp.box_names_memo)
    except InvalidLoop:
        metainterp_sd.jitlog.trace_aborted()
        history.cut(cut_at)
        return None

    metainterp_sd = metainterp.staticdata
    jitdriver_sd = metainterp.jitdriver_sd
    start_descr = TargetToken(jitcell_token,
                              original_jitcell_token=jitcell_token)
    jitcell_token.target_tokens = [start_descr]
    loop_data = UnrolledLoopData(trace,
                                 jitcell_token,
                                 start_state,
                                 call_pure_results=call_pure_results,
                                 enable_opts=enable_opts)
    try:
        loop_info, loop_ops = loop_data.optimize_trace(
            metainterp_sd, jitdriver_sd, metainterp.box_names_memo)
    except InvalidLoop:
        metainterp_sd.jitlog.trace_aborted()
        history.cut(cut_at)
        return None

    if ((warmstate.vec and jitdriver_sd.vec) or warmstate.vec_all) and \
        metainterp.cpu.vector_ext and metainterp.cpu.vector_ext.is_enabled():
        from rpython.jit.metainterp.optimizeopt.vector import optimize_vector
        loop_info, loop_ops = optimize_vector(trace, metainterp_sd,
                                              jitdriver_sd, warmstate,
                                              loop_info, loop_ops,
                                              jitcell_token)
    #
    loop = create_empty_loop(metainterp)
    loop.original_jitcell_token = jitcell_token
    loop.inputargs = start_state.renamed_inputargs
    quasi_immutable_deps = {}
    if start_state.quasi_immutable_deps:
        quasi_immutable_deps.update(start_state.quasi_immutable_deps)
    if loop_info.quasi_immutable_deps:
        quasi_immutable_deps.update(loop_info.quasi_immutable_deps)
    if quasi_immutable_deps:
        loop.quasi_immutable_deps = quasi_immutable_deps
    start_label = ResOperation(rop.LABEL,
                               start_state.renamed_inputargs,
                               descr=start_descr)
    label_token = loop_info.label_op.getdescr()
    assert isinstance(label_token, TargetToken)
    if label_token.short_preamble:
        metainterp_sd.logger_ops.log_short_preamble([],
                                                    label_token.short_preamble,
                                                    metainterp.box_names_memo)
    loop.operations = ([start_label] + preamble_ops + loop_info.extra_same_as +
                       loop_info.extra_before_label + [loop_info.label_op] +
                       loop_ops)
    if not we_are_translated():
        loop.check_consistency()
    send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop",
                         inputargs, metainterp.box_names_memo)
    record_loop_or_bridge(metainterp_sd, loop)
    loop_info.post_loop_compilation(loop, jitdriver_sd, metainterp,
                                    jitcell_token)
    return start_descr
Пример #47
0
 def __init__(self, error=None):
     self.error = error
     if not we_are_translated():
         Exception.__init__(self, error)
Пример #48
0
    os.write(2, str + os.linesep)
    
prebuilt_space = objspace.ObjSpace()

def safe_entry_point(argv):
    try:
        return entry_point(argv)
    except error.Exit, e:
        print_error("Exited: %s" % e.msg)
        return -1
    except error.SmalltalkException, e:
        print_error("Unhandled %s. Message: %s" % (e.exception_type, e.msg))
        return -1
    except BaseException, e:
        print_error("Exception: %s" % str(e))
        if not objectmodel.we_are_translated():
            import traceback
            traceback.print_exc()
        return -1
    finally:
        prebuilt_space.strategy_factory.logger.print_aggregated_log()

def entry_point(argv):
    # == Main execution parameters
    path = None
    selector = None
    code = ""
    number = 0
    have_number = False
    stringarg = None
    headless = True
Пример #49
0
 def operations(self):
     if not we_are_translated(): # For tests
         ops = self.short_boxes.values()
         ops.sort(key=str, reverse=True)
         return ops
     return self.short_boxes.values()
Пример #50
0
def isVMTranslated(interp, s_frame, w_rcvr):
    from rpython.rlib.objectmodel import we_are_translated
    if we_are_translated():
        return interp.space.w_true
    else:
        return interp.space.w_false
Пример #51
0
 def perform(self, executioncontext, frame):
     if we_are_translated():
         _rawrefcount_perform(self.space)
Пример #52
0
 def bigint_w(self, space, allow_conversion=True):
     from rpython.rlib.rbigint import rbigint
     x = 42
     if we_are_translated():
         x = NonConstant(x)
     return rbigint.fromint(x)
Пример #53
0
 def compile(self, ctx):
     if we_are_translated():
         raise NotImplementedError
     else:
         raise NotImplementedError(type(self).__name__)
Пример #54
0
 def __init__(self, string, match_start, end, flags):
     FixedMatchContext.__init__(self, match_start, end, flags)
     self._string = string
     if not we_are_translated() and isinstance(string, unicode):
         self.flags |= rsre_char.SRE_FLAG_UNICODE  # for rsre_re.py
Пример #55
0
def round_double(value, ndigits, half_even=False):
    """Round a float half away from zero.

    Specify half_even=True to round half even instead.
    The argument 'value' must be a finite number.  This
    function may return an infinite number in case of
    overflow (only if ndigits is a very negative integer).
    """
    if ndigits == 0:
        # fast path for this common case
        if half_even:
            return round_half_even(value)
        else:
            return round_away(value)

    if value == 0.0:
        return 0.0

    # The basic idea is very simple: convert and round the double to
    # a decimal string using _Py_dg_dtoa, then convert that decimal
    # string back to a double with _Py_dg_strtod.  There's one minor
    # difficulty: Python 2.x expects round to do
    # round-half-away-from-zero, while _Py_dg_dtoa does
    # round-half-to-even.  So we need some way to detect and correct
    # the halfway cases.

    # a halfway value has the form k * 0.5 * 10**-ndigits for some
    # odd integer k.  Or in other words, a rational number x is
    # exactly halfway between two multiples of 10**-ndigits if its
    # 2-valuation is exactly -ndigits-1 and its 5-valuation is at
    # least -ndigits.  For ndigits >= 0 the latter condition is
    # automatically satisfied for a binary float x, since any such
    # float has nonnegative 5-valuation.  For 0 > ndigits >= -22, x
    # needs to be an integral multiple of 5**-ndigits; we can check
    # this using fmod.  For -22 > ndigits, there are no halfway
    # cases: 5**23 takes 54 bits to represent exactly, so any odd
    # multiple of 0.5 * 10**n for n >= 23 takes at least 54 bits of
    # precision to represent exactly.

    sign = copysign(1.0, value)
    value = abs(value)

    # find 2-valuation value
    m, expo = math.frexp(value)
    while m != math.floor(m):
        m *= 2.0
        expo -= 1

    # determine whether this is a halfway case.
    halfway_case = 0
    if not half_even and expo == -ndigits - 1:
        if ndigits >= 0:
            halfway_case = 1
        elif ndigits >= -22:
            # 22 is the largest k such that 5**k is exactly
            # representable as a double
            five_pow = 1.0
            for i in range(-ndigits):
                five_pow *= 5.0
            if math.fmod(value, five_pow) == 0.0:
                halfway_case = 1

    # round to a decimal string; use an extra place for halfway case
    strvalue = formatd(value, 'f', ndigits + halfway_case)

    if not half_even and halfway_case:
        buf = [c for c in strvalue]
        if ndigits >= 0:
            endpos = len(buf) - 1
        else:
            endpos = len(buf) + ndigits
        # Sanity checks: there should be exactly ndigits+1 places
        # following the decimal point, and the last digit in the
        # buffer should be a '5'
        if not objectmodel.we_are_translated():
            assert buf[endpos] == '5'
            if '.' in buf:
                assert endpos == len(buf) - 1
                assert buf.index('.') == len(buf) - ndigits - 2

        # increment and shift right at the same time
        i = endpos - 1
        carry = 1
        while i >= 0:
            digit = ord(buf[i])
            if digit == ord('.'):
                buf[i + 1] = chr(digit)
                i -= 1
                digit = ord(buf[i])

            carry += digit - ord('0')
            buf[i + 1] = chr(carry % 10 + ord('0'))
            carry /= 10
            i -= 1
        buf[0] = chr(carry + ord('0'))
        if ndigits < 0:
            buf.append('0')

        strvalue = ''.join(buf)

    return sign * rstring_to_float(strvalue)
Пример #56
0
    def move_real_result_and_call_reacqgil_addr(self, fastgil):
        from rpython.jit.backend.x86 import rx86
        #
        # check if we need to call the reacqgil() function or not
        # (to acquiring the GIL, remove the asmgcc head from
        # the chained list, etc.)
        mc = self.mc
        restore_edx = False
        if not self.asm._is_asmgcc():
            css = 0
            css_value = imm(0)
            old_value = ecx
        else:
            from rpython.memory.gctransform import asmgcroot
            css = WORD * (PASS_ON_MY_FRAME - asmgcroot.JIT_USE_WORDS)
            if IS_X86_32:
                assert css >= 16
                if self.restype == 'L':  # long long result: eax/edx
                    if not self.result_value_saved_early:
                        mc.MOV_sr(12, edx.value)
                        restore_edx = True
                css_value = edx  # note: duplicated in ReacqGilSlowPath
                old_value = ecx  #
            elif IS_X86_64:
                css_value = edi
                old_value = esi
            mc.LEA_rs(css_value.value, css)
        #
        # Use XCHG as an atomic test-and-set-lock.  It also implicitly
        # does a memory barrier.
        mc.MOV(old_value, imm(1))
        if rx86.fits_in_32bits(fastgil):
            mc.XCHG_rj(old_value.value, fastgil)
        else:
            mc.MOV_ri(X86_64_SCRATCH_REG.value, fastgil)
            mc.XCHG_rm(old_value.value, (X86_64_SCRATCH_REG.value, 0))
        mc.CMP(old_value, css_value)
        #
        gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap
        if bool(gcrootmap) and gcrootmap.is_shadow_stack:
            from rpython.jit.backend.x86.assembler import heap
            #
            # When doing a call_release_gil with shadowstack, there
            # is the risk that the 'rpy_fastgil' was free but the
            # current shadowstack can be the one of a different
            # thread.  So here we check if the shadowstack pointer
            # is still the same as before we released the GIL (saved
            # in 'ebx'), and if not, we fall back to 'reacqgil_addr'.
            mc.J_il(rx86.Conditions['NE'], 0xfffff)  # patched later
            early_jump_addr = mc.get_relative_pos(break_basic_block=False)
            # ^^^ this jump will go to almost the same place as the
            # ReacqGilSlowPath() computes, but one instruction farther,
            # i.e. just after the "MOV(heap(fastgil), ecx)".

            # here, ecx (=old_value) is zero (so rpy_fastgil was in 'released'
            # state before the XCHG, but the XCHG acquired it by writing 1)
            rst = gcrootmap.get_root_stack_top_addr()
            mc = self.mc
            mc.CMP(ebx, heap(rst))
            sp = self.ReacqGilSlowPath(mc, rx86.Conditions['NE'])
            sp.early_jump_addr = early_jump_addr
            sp.fastgil = fastgil
        else:
            sp = self.ReacqGilSlowPath(mc, rx86.Conditions['NE'])
        sp.callbuilder = self
        sp.set_continue_addr(mc)
        self.asm.pending_slowpaths.append(sp)
        #
        if restore_edx:
            mc.MOV_rs(edx.value, 12)  # restore this
        #
        if self.result_value_saved_early:
            self.restore_result_value(save_edx=True)
        #
        if not we_are_translated():  # for testing: now we can accesss
            mc.SUB(ebp, imm(1))  # ebp again
        #
        # Now that we required the GIL, we can reload a possibly modified ebp
        if self.asm._is_asmgcc():
            # special-case: reload ebp from the css
            from rpython.memory.gctransform import asmgcroot
            index_of_ebp = css + WORD * (2 + asmgcroot.INDEX_OF_EBP)
            mc.MOV_rs(ebp.value, index_of_ebp)  # MOV EBP, [css.ebp]
Пример #57
0
 def check_frame(subframe):
     if we_are_translated():
         llinterpcall(lltype.Void, check_ll_frame, subframe)
Пример #58
0
    def prepare_arguments(self):
        src_locs = []
        dst_locs = []
        xmm_src_locs = []
        xmm_dst_locs = []
        singlefloats = None

        arglocs = self.arglocs
        argtypes = self.argtypes

        on_stack = 0
        for i in range(len(arglocs)):
            loc = arglocs[i]
            if loc.is_float():
                tgt = self._unused_xmm()
                if tgt is None:
                    tgt = RawEspLoc(on_stack * WORD, FLOAT)
                    on_stack += 1
                xmm_src_locs.append(loc)
                xmm_dst_locs.append(tgt)
            elif i < len(argtypes) and argtypes[i] == 'S':
                # Singlefloat argument
                if singlefloats is None:
                    singlefloats = []
                tgt = self._unused_xmm()
                if tgt is None:
                    tgt = RawEspLoc(on_stack * WORD, INT)
                    on_stack += 1
                singlefloats.append((loc, tgt))
            else:
                tgt = self._unused_gpr(hint=loc)
                if tgt is None:
                    tgt = RawEspLoc(on_stack * WORD, INT)
                    on_stack += 1
                src_locs.append(loc)
                dst_locs.append(tgt)

        if not self.fnloc_is_immediate:
            self.fnloc = dst_locs[-1]  # the last "argument" prepared above

        if not we_are_translated():  # assert that we got the right stack depth
            floats = 0
            for i in range(len(arglocs)):
                arg = arglocs[i]
                if arg.is_float() or (i < len(argtypes)
                                      and argtypes[i] == 'S'):
                    floats += 1
            all_args = len(arglocs)
            stack_depth = (
                max(all_args - floats - len(self.ARGUMENTS_GPR), 0) +
                max(floats - len(self.ARGUMENTS_XMM), 0))
            assert stack_depth == on_stack

        self.subtract_esp_aligned(on_stack - self.stack_max)

        # Handle register arguments: first remap the xmm arguments
        num_moves = remap_frame_layout(self.asm, xmm_src_locs, xmm_dst_locs,
                                       X86_64_XMM_SCRATCH_REG)
        # Load the singlefloat arguments from main regs or stack to xmm regs
        if singlefloats is not None:
            for src, dst in singlefloats:
                if isinstance(dst, RawEspLoc):
                    # XXX too much special logic
                    if isinstance(src, RawEbpLoc):
                        num_moves += 2
                        self.mc.MOV32(X86_64_SCRATCH_REG, src)
                        self.mc.MOV32(dst, X86_64_SCRATCH_REG)
                    else:
                        num_moves += 1
                        self.mc.MOV32(dst, src)
                    continue
                if isinstance(src, ImmedLoc):
                    num_moves += 1
                    self.mc.MOV(X86_64_SCRATCH_REG, src)
                    src = X86_64_SCRATCH_REG
                num_moves += 1
                self.mc.MOVD32(dst, src)
        # Finally remap the arguments in the main regs
        num_moves += remap_frame_layout(self.asm, src_locs, dst_locs,
                                        X86_64_SCRATCH_REG)
        self.num_moves = num_moves
Пример #59
0
def dict_delete_entries(entries):
    lltype.free(entries, flavor="raw")
    if not we_are_translated(): count_alloc(-1)
Пример #60
0
 def mallocstr(length):
     ll_assert(length >= 0, "negative string length")
     r = malloc(TP, length)
     if not we_are_translated() or not malloc_zero_filled:
         r.hash = 0
     return r