Esempio n. 1
0
 def gen_initialize_tid(self, v_newgcobj, tid):
     if self.gc_ll_descr.fielddescr_tid is not None:
         # produce a SETFIELD to initialize the GC header
         op = ResOperation(rop.SETFIELD_GC,
                           [v_newgcobj, ConstInt(tid)],
                           None,
                           descr=self.gc_ll_descr.fielddescr_tid)
         self.newops.append(op)
Esempio n. 2
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.fakemetainterp._got_exc:  # overflow detected
         assert isinstance(builder.fakemetainterp._got_exc, OverflowError)
         op = ResOperation(rop.GUARD_OVERFLOW, [], None)
         # the overflowed result should not be used any more, but can
         # be used on the failure path: recompute fail_subset including
         # the result, and then remove it from builder.intvars.
         fail_subset = builder.subset_of_intvars(r)
         builder.intvars[:] = original_intvars
     else:
         op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
     op.setdescr(BasicFailDescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Esempio n. 3
0
 def generate_modified_call(self, oopspecindex, args, result, mode):
     oopspecindex += mode.OS_offset
     cic = self.optimizer.metainterp_sd.callinfocollection
     calldescr, func = cic.callinfo_for_oopspec(oopspecindex)
     op = ResOperation(rop.CALL, [ConstInt(func)] + args,
                       result,
                       descr=calldescr)
     self.emit_operation(op)
Esempio n. 4
0
 def gen_write_barrier(self, v_base, v_value):
     write_barrier_descr = self.gc_ll_descr.write_barrier_descr
     args = [v_base, v_value]
     self.newops.append(
         ResOperation(rop.COND_CALL_GC_WB,
                      args,
                      None,
                      descr=write_barrier_descr))
Esempio n. 5
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     original_intvars = builder.intvars[:]
     super(AbstractOvfOperation, self).produce_into(builder, r)
     if builder.cpu._overflow_flag:  # overflow detected
         del builder.cpu._overflow_flag
         op = ResOperation(rop.GUARD_OVERFLOW, [], None)
         # the overflowed result should not be used any more, but can
         # be used on the failure path: recompute fail_subset including
         # the result, and then remove it from builder.intvars.
         fail_subset = builder.subset_of_intvars(r)
         builder.intvars[:] = original_intvars
     else:
         op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
     op.descr = builder.make_fail_descr()
     op.fail_args = fail_subset
     builder.loop.operations.append(op)
Esempio n. 6
0
 def handle_str_equal_level1(self, v1, v2, resultbox, mode):
     l2box = v2.getstrlen(None, mode, None)
     if isinstance(l2box, ConstInt):
         if l2box.value == 0:
             lengthbox = v1.getstrlen(self, mode, None)
             seo = self.optimizer.send_extra_operation
             seo(ResOperation(rop.INT_EQ, [lengthbox, CONST_0], resultbox))
             return True
         if l2box.value == 1:
             l1box = v1.getstrlen(None, mode, None)
             if isinstance(l1box, ConstInt) and l1box.value == 1:
                 # comparing two single chars
                 vchar1 = self.strgetitem(v1, optimizer.CVAL_ZERO, mode)
                 vchar2 = self.strgetitem(v2, optimizer.CVAL_ZERO, mode)
                 seo = self.optimizer.send_extra_operation
                 seo(
                     ResOperation(
                         rop.INT_EQ,
                         [vchar1.force_box(self),
                          vchar2.force_box(self)], resultbox))
                 return True
             if isinstance(v1, VStringSliceValue):
                 vchar = self.strgetitem(v2, optimizer.CVAL_ZERO, mode)
                 do = EffectInfo.OS_STREQ_SLICE_CHAR
                 self.generate_modified_call(do, [
                     v1.vstr.force_box(self),
                     v1.vstart.force_box(self),
                     v1.vlength.force_box(self),
                     vchar.force_box(self)
                 ], resultbox, mode)
                 return True
     #
     if v2.is_null():
         if v1.is_nonnull():
             self.make_constant(resultbox, CONST_0)
             return True
         if v1.is_null():
             self.make_constant(resultbox, CONST_1)
             return True
         op = ResOperation(rop.PTR_EQ,
                           [v1.force_box(self), llhelper.CONST_NULL],
                           resultbox)
         self.emit_operation(op)
         return True
     #
     return False
Esempio n. 7
0
 def gen_guard(self, builder, r):
     if not builder.ptrvars:
         raise CannotProduceOperation
     box = r.choice(builder.ptrvars)[0]
     op = ResOperation(self.opnum, [box], None)
     passing = ((self.opnum == rop.GUARD_NONNULL and box.value)
                or (self.opnum == rop.GUARD_ISNULL and not box.value))
     return op, passing
Esempio n. 8
0
 def make_guards(self, box):
     guards = []
     if self.level == LEVEL_CONSTANT:
         op = ResOperation(rop.GUARD_VALUE, [box, self.box], None)
         guards.append(op)
     elif self.level == LEVEL_KNOWNCLASS:
         op = ResOperation(rop.GUARD_NONNULL, [box], None)
         guards.append(op)
         op = ResOperation(rop.GUARD_CLASS, [box, self.known_class], None)
         guards.append(op)
     else:
         if self.level == LEVEL_NONNULL:
             op = ResOperation(rop.GUARD_NONNULL, [box], None)
             guards.append(op)
         self.intbound.make_guards(box, guards)
         if self.lenbound:
             lenbox = BoxInt()
             if self.lenbound.mode == MODE_ARRAY:
                 op = ResOperation(rop.ARRAYLEN_GC, [box], lenbox,
                                   self.lenbound.descr)
             elif self.lenbound.mode == MODE_STR:
                 op = ResOperation(rop.STRLEN, [box], lenbox,
                                   self.lenbound.descr)
             elif self.lenbound.mode == MODE_UNICODE:
                 op = ResOperation(rop.UNICODELEN, [box], lenbox,
                                   self.lenbound.descr)
             else:
                 debug_print("Unknown lenbound mode")
                 assert False
             guards.append(op)
             self.lenbound.bound.make_guards(lenbox, guards)
     return guards
Esempio n. 9
0
 def do(self, opnum, argboxes, descr=None):
     self.fakemetainterp._got_exc = None
     v_result = execute_nonspec(self.cpu, self.fakemetainterp, opnum,
                                argboxes, descr)
     if isinstance(v_result, Const):
         v_result = v_result.clonebox()
     self.loop.operations.append(
         ResOperation(opnum, argboxes, v_result, descr))
     return v_result
Esempio n. 10
0
 def optimize_VIRTUAL_REF(self, op):
     indexbox = op.args[1]
     #
     # get some constants
     vrefinfo = self.metainterp_sd.virtualref_info
     c_cls = vrefinfo.jit_virtual_ref_const_class
     descr_virtual_token = vrefinfo.descr_virtual_token
     descr_virtualref_index = vrefinfo.descr_virtualref_index
     #
     # Replace the VIRTUAL_REF operation with a virtual structure of type
     # 'jit_virtual_ref'.  The jit_virtual_ref structure may be forced soon,
     # but the point is that doing so does not force the original structure.
     op = ResOperation(rop.NEW_WITH_VTABLE, [c_cls], op.result)
     vrefvalue = self.make_virtual(c_cls, op.result, op)
     tokenbox = BoxInt()
     self.emit_operation(ResOperation(rop.FORCE_TOKEN, [], tokenbox))
     vrefvalue.setfield(descr_virtual_token, self.getvalue(tokenbox))
     vrefvalue.setfield(descr_virtualref_index, self.getvalue(indexbox))
Esempio n. 11
0
def _int_sub(string_optimizer, box1, box2):
    if isinstance(box2, ConstInt):
        if box2.value == 0:
            return box1
        if isinstance(box1, ConstInt):
            return ConstInt(box1.value - box2.value)
    resbox = BoxInt()
    string_optimizer.emit_operation(ResOperation(rop.INT_SUB, [box1, box2], resbox))
    return resbox
Esempio n. 12
0
 def _optimize_oois_ooisnot(self, op, expect_isnot, unary_opnum):
     value0 = self.getvalue(op.args[0])
     value1 = self.getvalue(op.args[1])
     if value0.is_virtual():
         if value1.is_virtual():
             intres = (value0 is value1) ^ expect_isnot
             self.make_constant_int(op.result, intres)
         else:
             self.make_constant_int(op.result, expect_isnot)
     elif value1.is_virtual():
         self.make_constant_int(op.result, expect_isnot)
     elif value1.is_null():
         op = ResOperation(unary_opnum, [op.args[0]], op.result)
         self._optimize_nullness(op, expect_isnot, self.cpu.ts.CONST_NULL)
     elif value0.is_null():
         op = ResOperation(unary_opnum, [op.args[1]], op.result)
         self._optimize_nullness(op, expect_isnot, self.cpu.ts.CONST_NULL)
     else:
         self.optimize_default(op)
Esempio n. 13
0
 def optimize_NEW_ARRAY(self, op):
     sizebox = self.get_constant_box(op.args[0])
     if sizebox is not None:
         # if the original 'op' did not have a ConstInt as argument,
         # build a new one with the ConstInt argument
         if not isinstance(op.args[0], ConstInt):
             op = ResOperation(rop.NEW_ARRAY, [sizebox],
                               op.result,
                               descr=op.descr)
         self.make_varray(op.descr, sizebox.getint(), op.result, op)
     else:
         self.optimize_default(op)
Esempio n. 14
0
 def optimize_NEW_ARRAY(self, op):
     sizebox = self.get_constant_box(op.getarg(0))
     if sizebox is not None:
         # if the original 'op' did not have a ConstInt as argument,
         # build a new one with the ConstInt argument
         if not isinstance(op.getarg(0), ConstInt):
             op = ResOperation(rop.NEW_ARRAY, [sizebox], op.result,
                               descr=op.getdescr())
         self.make_varray(op.getdescr(), sizebox.getint(), op.result, op)
     else:
         self.getvalue(op.result).ensure_nonnull()
         self.emit_operation(op)
Esempio n. 15
0
def prepare_last_operation(new_loop, target_loop_token):
    op = new_loop.operations[-1]
    if not isinstance(target_loop_token, TerminatingLoopToken):
        # normal case
        op.descr = target_loop_token     # patch the jump target
    else:
        # The target_loop_token is a pseudo loop token,
        # e.g. loop_tokens_done_with_this_frame_void[0]
        # Replace the operation with the real operation we want, i.e. a FINISH
        descr = target_loop_token.finishdescr
        new_op = ResOperation(rop.FINISH, op.args, None, descr=descr)
        new_loop.operations[-1] = new_op
Esempio n. 16
0
 def optimize_VIRTUAL_REF_FINISH(self, op):
     # Set the 'forced' field of the virtual_ref.
     # In good cases, this is all virtual, so has no effect.
     # Otherwise, this forces the real object -- but only now, as
     # opposed to much earlier.  This is important because the object is
     # typically a PyPy PyFrame, and now is the end of its execution, so
     # forcing it now does not have catastrophic effects.
     vrefinfo = self.metainterp_sd.virtualref_info
     # op.args[1] should really never point to null here
     # - set 'forced' to point to the real object
     op1 = ResOperation(rop.SETFIELD_GC,
                        op.args,
                        None,
                        descr=vrefinfo.descr_forced)
     self.optimize_SETFIELD_GC(op1)
     # - set 'virtual_token' to TOKEN_NONE
     args = [op.args[0], ConstInt(vrefinfo.TOKEN_NONE)]
     op1 = ResOperation(rop.SETFIELD_GC,
                        args,
                        None,
                        descr=vrefinfo.descr_virtual_token)
     self.optimize_SETFIELD_GC(op1)
Esempio n. 17
0
def _strgetitem(string_optimizer, strbox, indexbox, mode, resbox=None):
    if isinstance(strbox, ConstPtr) and isinstance(indexbox, ConstInt):
        if mode is mode_string:
            s = strbox.getref(lltype.Ptr(rstr.STR))
            return ConstInt(ord(s.chars[indexbox.getint()]))
        else:
            s = strbox.getref(lltype.Ptr(rstr.UNICODE))
            return ConstInt(ord(s.chars[indexbox.getint()]))
    if resbox is None:
        resbox = BoxInt()
    string_optimizer.emit_operation(
        ResOperation(mode.STRGETITEM, [strbox, indexbox], resbox))
    return resbox
Esempio n. 18
0
 def parse_result_op(self, line):
     res, op = line.split("=", 1)
     res = res.strip()
     op = op.strip()
     opnum, args, descr, fail_args = self.parse_op(op)
     if res in self.vars:
         raise ParseError("Double assign to var %s in line: %s" %
                          (res, line))
     rvar = self.box_for_var(res)
     self.vars[res] = rvar
     res = ResOperation(opnum, args, rvar, descr)
     res.fail_args = fail_args
     return res
Esempio n. 19
0
 def _optimize_NEWSTR(self, op, mode):
     length_box = self.get_constant_box(op.getarg(0))
     if length_box:
         # if the original 'op' did not have a ConstInt as argument,
         # build a new one with the ConstInt argument
         if not isinstance(op.getarg(0), ConstInt):
             op = ResOperation(mode.NEWSTR, [length_box], op.result)
         vvalue = self.make_vstring_plain(op.result, op, mode)
         vvalue.setup(length_box.getint())
     else:
         self.getvalue(op.result).ensure_nonnull()
         self.emit_operation(op)
         self.pure(mode.STRLEN, [op.result], op.getarg(0))
Esempio n. 20
0
def _int_add(string_optimizer, box1, box2):
    if isinstance(box1, ConstInt):
        if box1.value == 0:
            return box2
        if isinstance(box2, ConstInt):
            return ConstInt(box1.value + box2.value)
    elif isinstance(box2, ConstInt) and box2.value == 0:
        return box1
    if string_optimizer is None:
        return None
    resbox = BoxInt()
    string_optimizer.emit_operation(ResOperation(rop.INT_ADD, [box1, box2], resbox))
    return resbox
Esempio n. 21
0
 def insert_label(self, loop, position, r):
     assert not hasattr(loop, '_targettoken')
     for i in range(position):
         op = loop.operations[i]
         if (not op.has_no_side_effect()
                 or not isinstance(op.result, (BoxInt, BoxFloat))):
             position = i
             break  # cannot move the LABEL later
         randompos = r.randrange(0, len(self.startvars) + 1)
         self.startvars.insert(randompos, op.result)
     loop._targettoken = TargetToken()
     loop.operations.insert(
         position,
         ResOperation(rop.LABEL, self.startvars, None, loop._targettoken))
Esempio n. 22
0
 def initialize_forced_string(self, string_optimizer, targetbox, offsetbox,
                              mode):
     for i in range(len(self._chars)):
         assert isinstance(targetbox, BoxPtr)  # ConstPtr never makes sense
         charvalue = self.getitem(i)
         if charvalue is not None:
             charbox = charvalue.force_box(string_optimizer)
             if not (isinstance(charbox, Const)
                     and charbox.same_constant(CONST_0)):
                 op = ResOperation(mode.STRSETITEM,
                                   [targetbox, offsetbox, charbox], None)
                 string_optimizer.emit_operation(op)
         offsetbox = _int_add(string_optimizer, offsetbox, CONST_1)
     return offsetbox
Esempio n. 23
0
 def gen_guard(self, builder, r):
     v = r.choice(builder.intvars)
     if r.random() > 0.8:
         other = r.choice(builder.intvars)
     else:
         if r.random() < 0.75:
             value = v.value
         elif r.random() < 0.5:
             value = v.value ^ 1
         else:
             value = r.random_integer()
         other = ConstInt(value)
     op = ResOperation(self.opnum, [v, other], None)
     return op, (v.value == other.value)
Esempio n. 24
0
 def _really_force(self):
     assert self.source_op is not None
     newoperations = self.optimizer.newoperations
     newoperations.append(self.source_op)
     self.box = box = self.source_op.result
     for index in range(len(self._items)):
         subvalue = self._items[index]
         if subvalue is not self.constvalue:
             subbox = subvalue.force_box()
             op = ResOperation(rop.SETARRAYITEM_GC,
                               [box, ConstInt(index), subbox],
                               None,
                               descr=self.arraydescr)
             newoperations.append(op)
Esempio n. 25
0
 def _really_force(self):
     assert self.source_op is not None
     newoperations = self.optimizer.newoperations
     newoperations.append(self.source_op)
     self.box = box = self.source_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:
         subbox = value.force_box()
         op = ResOperation(rop.SETFIELD_GC, [box, subbox], None, descr=ofs)
         newoperations.append(op)
     self._fields = None
Esempio n. 26
0
def test_remove_consts_and_duplicates():
    class FakeStaticData:
        cpu = None
        warmrunnerdesc = None
    def is_another_box_like(box, referencebox):
        assert box is not referencebox
        assert isinstance(box, referencebox.clonebox().__class__)
        assert box.value == referencebox.value
        return True
    metainterp = pyjitpl.MetaInterp(FakeStaticData(), None)
    metainterp.history = History()
    b1 = BoxInt(1)
    b2 = BoxInt(2)
    c3 = ConstInt(3)
    boxes = [b1, b2, b1, c3]
    dup = {}
    metainterp.remove_consts_and_duplicates(boxes, 4, dup)
    assert boxes[0] is b1
    assert boxes[1] is b2
    assert is_another_box_like(boxes[2], b1)
    assert is_another_box_like(boxes[3], c3)
    assert equaloplists(metainterp.history.operations, [
        ResOperation(rop.SAME_AS, [b1], boxes[2]),
        ResOperation(rop.SAME_AS, [c3], boxes[3]),
        ])
    assert dup == {b1: None, b2: None}
    #
    del metainterp.history.operations[:]
    b4 = BoxInt(4)
    boxes = [b2, b4, "something random"]
    metainterp.remove_consts_and_duplicates(boxes, 2, dup)
    assert is_another_box_like(boxes[0], b2)
    assert boxes[1] is b4
    assert equaloplists(metainterp.history.operations, [
        ResOperation(rop.SAME_AS, [b2], boxes[0]),
        ])
Esempio n. 27
0
 def gen_guard(self, builder, r):
     ptrvars = [(v, S) for (v, S) in builder.ptrvars
                if isinstance(S, lltype.Struct) and S._names[0] == 'parent']
     if not ptrvars:
         raise test_random.CannotProduceOperation
     v, S = r.choice(ptrvars)
     if r.random() < 0.3:
         v2, S2 = v, S
     else:
         v2, S2 = builder.get_structptr_var(r, must_have_vtable=True)
     vtable = S._hints['vtable']._as_ptr()
     vtable2 = S2._hints['vtable']._as_ptr()
     c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2), builder.cpu)
     op = ResOperation(self.opnum, [v, c_vtable2], None)
     return op, (vtable == vtable2)
Esempio n. 28
0
 def produce_into(self, builder, r):
     fail_subset = builder.subset_of_intvars(r)
     subset, f, exc = self.raising_func_code(builder, r)
     TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
     ptr = llhelper(lltype.Ptr(TP), f)
     c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
     args = [c_addr] + subset
     descr = self.getcalldescr(builder, TP)
     self.put(builder, args, descr)
     exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
     op = ResOperation(rop.GUARD_EXCEPTION, [exc_box],
                       BoxPtr(),
                       descr=BasicFailDescr())
     op.setfailargs(fail_subset)
     builder.loop.operations.append(op)
Esempio n. 29
0
 def runjitcelltoken(self):
     if self.startvars == self.loop.inputargs:
         return self.loop._jitcelltoken
     if not hasattr(self, '_initialjumploop_celltoken'):
         self._initialjumploop_celltoken = JitCellToken()
         args = []
         for box in self.startvars:
             if box not in self.loop.inputargs:
                 box = box.constbox()
             args.append(box)
         self.cpu.compile_loop(self.loop.inputargs, [
             ResOperation(
                 rop.JUMP, args, None, descr=self.loop._targettoken)
         ], self._initialjumploop_celltoken)
     return self._initialjumploop_celltoken
Esempio n. 30
0
 def _get_loop_for_call(self, argnum, calldescr):
     loop = calldescr._generated_mp
     if loop is None:
         args = [BoxInt() for i in range(argnum + 1)]
         if calldescr.res_index < 0:
             result = None
         elif calldescr.res_index == self.SIZE_GCPTR:
             result = BoxPtr(lltype.nullptr(llmemory.GCREF.TO))
         else:
             result = BoxInt(0)
         result_list = []
         if result is not None:
             result_list.append(result)
         operations = [
             ResOperation(rop.CALL, args, result, calldescr),
             ResOperation(rop.GUARD_NO_EXCEPTION, [], None),
             ResOperation(rop.FAIL, result_list, None)]
         operations[1].suboperations = [ResOperation(rop.FAIL, [], None)]
         loop = history.TreeLoop('call')
         loop.inputargs = args
         loop.operations = operations
         self.compile_operations(loop)
         calldescr._generated_mp = loop
     return loop