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