Author: Spenser Bauman <saba...@gmail.com> Branch: clean-exported-state Changeset: r87721:9e5f013afa17 Date: 2016-10-12 11:27 -0400 http://bitbucket.org/pypy/pypy/changeset/9e5f013afa17/
Log: Ensure all optimization info is removed from all data referenced by ExportedState Two cases to watch for: * After the ExportedState is constructed * When optimization fails (InvalidLoop) and the ExportedState object is reused for for another attempt (i.e. retracing) diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -126,6 +126,10 @@ return opt.optimize_peeled_loop(self.trace, self.celltoken, self.state, self.call_pure_results, self.inline_short_preamble) + def forget_optimization_info(self): + self.state.forget_optimization_info() + CompileData.forget_optimization_info(self) + def show_procedures(metainterp_sd, procedure=None, error=None): # debugging if option and (option.view or option.viewloops): @@ -515,7 +519,7 @@ for item in lst: item.set_forwarded(None) # XXX we should really do it, but we need to remember the values - # somehoe for ContinueRunningNormally + # somehow for ContinueRunningNormally if reset_values: item.reset_value() diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py --- a/rpython/jit/metainterp/optimizeopt/optimizer.py +++ b/rpython/jit/metainterp/optimizeopt/optimizer.py @@ -27,6 +27,9 @@ class LoopInfo(object): label_op = None + def forget_optimization_info(self): + pass + class BasicLoopInfo(LoopInfo): def __init__(self, inputargs, quasi_immutable_deps, jump_op): self.inputargs = inputargs @@ -561,7 +564,8 @@ return (BasicLoopInfo(trace.inputargs, self.quasi_immutable_deps, last_op), self._newoperations) - def _clean_optimization_info(self, lst): + @staticmethod + def _clean_optimization_info(lst): for op in lst: if op.get_forwarded() is not None: op.set_forwarded(None) diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -462,7 +462,6 @@ op = produced_op.short_op.res if not isinstance(op, Const): self._expand_info(op, infos) - self.optimizer._clean_optimization_info(end_args) return ExportedState(label_args, end_args, virtual_state, infos, short_boxes, renamed_inputargs, short_inputargs, runtime_boxes, memo) @@ -472,6 +471,7 @@ # to actually emit. Update the info assert (len(exported_state.next_iteration_args) == len(targetargs)) + exported_state._check_no_forwarding(self) for i, target in enumerate(exported_state.next_iteration_args): source = targetargs[i] assert source is not target @@ -542,6 +542,7 @@ self.short_inputargs = short_inputargs self.runtime_boxes = runtime_boxes self.dump(memo) + self.forget_optimization_info() def dump(self, memo): if have_debug_prints(): @@ -551,5 +552,32 @@ debug_print(" " + box.repr(memo)) debug_stop("jit-log-exported-state") + def _check_no_forwarding(self, optimizer): + """ Ensures that no optimization state is attached to relevant operations + before importing anything. """ + shortops = [pop.short_op.res for pop in self.short_boxes] + optimizer._check_no_forwarding([ + self.end_args, self.next_iteration_args, self.renamed_inputargs, + self.short_inputargs, shortops, self.exported_infos.keys()]) + + def forget_optimization_info(self): + """ Clean up optimization info on all operations stored in the ExportedState. + + This function needs to be called when exporting the optimizer state to + prevent leaking of optimization information between invocations of the + optimizer. + + That includes cleaning up in the event that optimize_peeled_loop() fails + with an InvalidLoop exception, as optimize_peeled_loop() mutates the + contents of ExportedState. + """ + # These first two may be subsumed by clearing self.exported_infos + # but I am not 100% certain + Optimizer._clean_optimization_info(self.end_args) + Optimizer._clean_optimization_info(self.next_iteration_args) + Optimizer._clean_optimization_info(self.renamed_inputargs) + Optimizer._clean_optimization_info(self.short_inputargs) + Optimizer._clean_optimization_info(self.exported_infos.keys()) + def final(self): return False _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit