Beispiel #1
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)
Beispiel #2
0
 def handle_malloc_operation(self, op):
     opnum = op.getopnum()
     if opnum == rop.NEW:
         self.handle_new_fixedsize(op.getdescr(), op)
     elif opnum == rop.NEW_WITH_VTABLE:
         classint = op.getarg(0).getint()
         descr = heaptracker.vtable2descr(self.cpu, classint)
         self.handle_new_fixedsize(descr, op)
         if self.gc_ll_descr.fielddescr_vtable is not None:
             op = ResOperation(rop.SETFIELD_GC,
                               [op.result, ConstInt(classint)], None,
                               descr=self.gc_ll_descr.fielddescr_vtable)
             self.newops.append(op)
     elif opnum == rop.NEW_ARRAY or opnum == rop.NEW_ARRAY_CLEAR:
         descr = op.getdescr()
         assert isinstance(descr, ArrayDescr)
         self.handle_new_array(descr, op)
     elif opnum == rop.NEWSTR:
         self.handle_new_array(self.gc_ll_descr.str_descr, op,
                               kind=FLAG_STR)
     elif opnum == rop.NEWUNICODE:
         self.handle_new_array(self.gc_ll_descr.unicode_descr, op,
                               kind=FLAG_UNICODE)
     else:
         raise NotImplementedError(op.getopname())
Beispiel #3
0
 def handle_malloc_operation(self, op):
     opnum = op.getopnum()
     if opnum == rop.NEW:
         self.handle_new_fixedsize(op.getdescr(), op)
     elif opnum == rop.NEW_WITH_VTABLE:
         classint = op.getarg(0).getint()
         descr = heaptracker.vtable2descr(self.cpu, classint)
         self.handle_new_fixedsize(descr, op)
         if self.gc_ll_descr.fielddescr_vtable is not None:
             op = ResOperation(rop.SETFIELD_GC,
                               [op.result, ConstInt(classint)],
                               None,
                               descr=self.gc_ll_descr.fielddescr_vtable)
             self.newops.append(op)
     elif opnum == rop.NEW_ARRAY or opnum == rop.NEW_ARRAY_CLEAR:
         descr = op.getdescr()
         assert isinstance(descr, ArrayDescr)
         self.handle_new_array(descr, op)
     elif opnum == rop.NEWSTR:
         self.handle_new_array(self.gc_ll_descr.str_descr,
                               op,
                               kind=FLAG_STR)
     elif opnum == rop.NEWUNICODE:
         self.handle_new_array(self.gc_ll_descr.unicode_descr,
                               op,
                               kind=FLAG_UNICODE)
     else:
         raise NotImplementedError(op.getopname())
Beispiel #4
0
 def has_pure_result(self, opnum, args, descr):
     op = ResOperation(opnum, args, None, descr)
     key = self.optimizer.make_args_key(op)
     op = self.pure_operations.get(key, None)
     if op is None:
         return False
     return op.getdescr() is descr
Beispiel #5
0
 def handle_malloc_operation(self, op):
     opnum = op.getopnum()
     if opnum == rop.NEW:
         self.handle_new_fixedsize(op.getdescr(), op)
     elif opnum == rop.NEW_WITH_VTABLE:
         descr = op.getdescr()
         self.handle_new_fixedsize(descr, op)
         if self.gc_ll_descr.fielddescr_vtable is not None:
             op = ResOperation(rop.SETFIELD_GC,
                               [op, ConstInt(descr.get_vtable())],
                               descr=self.gc_ll_descr.fielddescr_vtable)
             self.emit_op(op)
     elif opnum == rop.NEW_ARRAY or opnum == rop.NEW_ARRAY_CLEAR:
         descr = op.getdescr()
         assert isinstance(descr, ArrayDescr)
         self.handle_new_array(descr, op)
     elif opnum == rop.NEWSTR:
         self.handle_new_array(self.gc_ll_descr.str_descr, op,
                               kind=FLAG_STR)
     elif opnum == rop.NEWUNICODE:
         self.handle_new_array(self.gc_ll_descr.unicode_descr, op,
                               kind=FLAG_UNICODE)
     else:
         raise NotImplementedError(op.getopname())
Beispiel #6
0
    def propagate_all_forward(self, starting_state, export_state=True):
        self.optimizer.exporting_state = export_state
        loop = self.optimizer.loop
        self.optimizer.clear_newoperations()

        start_label = loop.operations[0]
        if start_label.getopnum() == rop.LABEL:
            loop.operations = loop.operations[1:]
            # We need to emit the label op before import_state() as emitting it
            # will clear heap caches
            self.optimizer.send_extra_operation(start_label)
        else:
            start_label = None

        patchguardop = None
        if len(loop.operations) > 1:
            patchguardop = loop.operations[-2]
            if patchguardop.getopnum() != rop.GUARD_FUTURE_CONDITION:
                patchguardop = None

        jumpop = loop.operations[-1]
        if jumpop.getopnum() == rop.JUMP or jumpop.getopnum() == rop.LABEL:
            loop.operations = loop.operations[:-1]
        else:
            jumpop = None

        self.import_state(start_label, starting_state)
        self.optimizer.propagate_all_forward(clear=False)

        if not jumpop:
            return

        cell_token = jumpop.getdescr()
        assert isinstance(cell_token, JitCellToken)
        stop_label = ResOperation(rop.LABEL, jumpop.getarglist(), None, TargetToken(cell_token))

        if jumpop.getopnum() == rop.JUMP:
            if self.jump_to_already_compiled_trace(jumpop, patchguardop):
                # Found a compiled trace to jump to
                if self.short:
                    # Construct our short preamble
                    assert start_label
                    self.close_bridge(start_label)
                return

            if start_label and self.jump_to_start_label(start_label, stop_label):
                # Initial label matches, jump to it
                jumpop = ResOperation(rop.JUMP, stop_label.getarglist(), None,
                                      descr=start_label.getdescr())
                if self.short:
                    # Construct our short preamble
                    self.close_loop(start_label, jumpop, patchguardop)
                else:
                    self.optimizer.send_extra_operation(jumpop)
                return

            if cell_token.target_tokens:
                limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
                if cell_token.retraced_count < limit:
                    cell_token.retraced_count += 1
                    debug_print('Retracing (%d/%d)' % (cell_token.retraced_count, limit))
                else:
                    debug_print("Retrace count reached, jumping to preamble")
                    assert cell_token.target_tokens[0].virtual_state is None
                    jumpop = jumpop.clone()
                    jumpop.setdescr(cell_token.target_tokens[0])
                    self.optimizer.send_extra_operation(jumpop)
                    return

        # Found nothing to jump to, emit a label instead

        if self.short:
            # Construct our short preamble
            assert start_label
            self.close_bridge(start_label)

        self.optimizer.flush()
        if export_state:
            KillHugeIntBounds(self.optimizer).apply()

        loop.operations = self.optimizer.get_newoperations()
        if export_state:
            jd_sd = self.optimizer.jitdriver_sd
            try:
                threshold = jd_sd.warmstate.disable_unrolling_threshold
            except AttributeError:    # tests only
                threshold = sys.maxint
            if len(loop.operations) > threshold:
                if loop.operations[0].getopnum() == rop.LABEL:
                    # abandoning unrolling, too long
                    new_descr = stop_label.getdescr()
                    if loop.operations[0].getopnum() == rop.LABEL:
                        new_descr = loop.operations[0].getdescr()
                    stop_label = stop_label.copy_and_change(rop.JUMP,
                                        descr=new_descr)
                    self.optimizer.send_extra_operation(stop_label)
                    loop.operations = self.optimizer.get_newoperations()
                    return None
            final_state = self.export_state(stop_label)
        else:
            final_state = None
        loop.operations.append(stop_label)
        return final_state