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)
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
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)
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