예제 #1
0
 def store_final_boxes_in_guard(self, op):
     pendingfields = self.heap_op_optimizer.force_lazy_setfields_for_guard()
     descr = op.descr
     assert isinstance(descr, compile.ResumeGuardDescr)
     modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
     newboxes = modifier.finish(self.values, pendingfields)
     if len(
             newboxes
     ) > self.metainterp_sd.options.failargs_limit:  # XXX be careful here
         raise compile.GiveUp
     descr.store_final_boxes(op, newboxes)
     #
     if op.opnum == rop.GUARD_VALUE:
         if op.args[0] in self.bool_boxes:
             # Hack: turn guard_value(bool) into guard_true/guard_false.
             # This is done after the operation is emitted, to let
             # store_final_boxes_in_guard set the guard_opnum field
             # of the descr to the original rop.GUARD_VALUE.
             constvalue = op.args[1].getint()
             if constvalue == 0:
                 opnum = rop.GUARD_FALSE
             elif constvalue == 1:
                 opnum = rop.GUARD_TRUE
             else:
                 raise AssertionError("uh?")
             op.opnum = opnum
             op.args = [op.args[0]]
         else:
             # a real GUARD_VALUE.  Make it use one counter per value.
             descr.make_a_counter_per_value(op)
예제 #2
0
 def store_final_boxes_in_guard(self, op):
     descr = op.getdescr()
     assert isinstance(descr, compile.ResumeGuardDescr)
     modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
     try:
         newboxes = modifier.finish(self, self.pendingfields)
         if len(newboxes) > self.metainterp_sd.options.failargs_limit:
             raise resume.TagOverflow
     except resume.TagOverflow:
         raise compile.giveup()
     descr.store_final_boxes(op, newboxes)
     #
     if op.getopnum() == rop.GUARD_VALUE:
         if self.getvalue(op.getarg(0)) in self.bool_boxes:
             # Hack: turn guard_value(bool) into guard_true/guard_false.
             # This is done after the operation is emitted to let
             # store_final_boxes_in_guard set the guard_opnum field of the
             # descr to the original rop.GUARD_VALUE.
             constvalue = op.getarg(1).getint()
             if constvalue == 0:
                 opnum = rop.GUARD_FALSE
             elif constvalue == 1:
                 opnum = rop.GUARD_TRUE
             else:
                 raise AssertionError("uh?")
             newop = ResOperation(opnum, [op.getarg(0)], op.result, descr)
             newop.setfailargs(op.getfailargs())
             return newop
         else:
             # a real GUARD_VALUE.  Make it use one counter per value.
             descr.make_a_counter_per_value(op)
     return op
예제 #3
0
 def store_final_boxes_in_guard(self, op):
     descr = op.descr
     assert isinstance(descr, compile.ResumeGuardDescr)
     modifier = resume.ResumeDataVirtualAdder(
         descr, self.resumedata_memo,
         self.metainterp_sd.globaldata.storedebug)
     newboxes = modifier.finish(self.values)
     if len(newboxes) > self.metainterp_sd.options.failargs_limit:
         raise compile.GiveUp
     descr.store_final_boxes(op, newboxes)
예제 #4
0
def optimize_loop(metainterp_sd, old_loops, loop):
    if old_loops:
        assert len(old_loops) == 1
        return old_loops[0]
    else:
        # copy loop operations here
        # we need it since the backend can modify those lists, which make
        # get_guard_op in compile.py invalid
        # in fact, x86 modifies this list for moving GCs
        memo = resume.ResumeDataLoopMemo(metainterp_sd)
        newoperations = []
        for op in loop.operations:
            if op.is_guard():
                descr = op.descr
                assert isinstance(descr, compile.ResumeGuardDescr)
                modifier = resume.ResumeDataVirtualAdder(descr, memo)
                newboxes = modifier.finish(EMPTY_VALUES)
                descr.store_final_boxes(op, newboxes)
            newoperations.append(op)
        loop.operations = newoperations
        return None