Author: Spenser Bauman <saba...@gmail.com> Branch: clean-exported-state Changeset: r87741:c29b256fd536 Date: 2016-10-12 21:04 -0400 http://bitbucket.org/pypy/pypy/changeset/c29b256fd536/
Log: Merge with default diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -32,7 +32,7 @@ .. toctree:: - whatsnew-pypy3.3-5.5.0.rst + whatsnew-pypy3-5.5.0.rst CPython 3.2 compatible versions ------------------------------- diff --git a/pypy/doc/release-pypy3.3-5.5.0.rst b/pypy/doc/release-pypy3.3-5.5.0.rst deleted file mode 100644 --- a/pypy/doc/release-pypy3.3-5.5.0.rst +++ /dev/null @@ -1,35 +0,0 @@ -======================== -What's new in PyPy3 2.4+ -======================== - -.. this is the revision after pypy3-release-2.4.x was branched -.. startrev: 3f967c2be00e - -.. branch: py3k-memoryview - -Implement new memoryview features. - -.. branch: py3.3 - -.. branch: py3.3-hashfix - -Use intobject hash function for specialisedtuple - -.. branch: follow_symlinks - -Add support for dir_fd and follow_symlinks in posix.stat() - -.. branch: stat_ns - -Implement the st_xtime_ns fields in stat_result() - -.. branch: 33_fix_itertools - -Add pickling support for the itertools classes - -.. branch: py3k-update - -.. branch: py3k-get_clock_info - -.. branch: py3k-update - diff --git a/pypy/doc/release-pypy3.3-v5.5.0.rst b/pypy/doc/release-pypy3.3-v5.5.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-pypy3.3-v5.5.0.rst @@ -0,0 +1,68 @@ +============ +PyPy3 v5.5.0 +============ + +We're pleased to announce the release of PyPy3 v5.5.0. Coming four months +after PyPy3.3 v5.2, it improves compatibility with Python 3.3 (3.3.5). We +strongly recommend updating from previous PyPy3 versions. + +We would like to thank all of the people who donated_ to the `py3k proposal`_ +for supporting the work that went into this release. + +You can download the PyPy3.3 v5.5.0 release here: + + http://pypy.org/download.html#python-3-3-5-compatible-pypy3-3-v5-5 + +Highlights +========== + +* Improved Python 3.3.5 support. + + - os.get_terminal_size(), time.monotonic(), str.casefold() + + - faulthandler module + + - There are still some `missing features`_ such as a + `PEP 393-like space efficient string representation`_ and `known issues`_ + including performance regressions (e.g. issue `#2305`_). The focus for this + release has been updating to 3.3 compatibility. Windows is also not yet + supported. + +* `ensurepip`_ is also included (it's only included in CPython 3 >= 3.4). + +What is PyPy? +============== + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7.10 and 3.3.5. It's fast due to its integrated tracing JIT +compiler. + +We also welcome developers of other `dynamic languages`_ to see what RPython +can do for them. + +This release supports: + + * **x86** machines on most common operating systems except Windows + (Linux 32/64, Mac OS X 64, OpenBSD, FreeBSD), + + * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux, + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +Please try it out and let us know what you think. We welcome feedback, we know +you are using PyPy, please tell us about it! + +Cheers + +The PyPy Team + +.. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html +.. _`py3k proposal`: http://pypy.org/py3donate.html +.. _`PEP 393-like space efficient string representation`: https://bitbucket.org/pypy/pypy/issues/2309/optimized-unicode-representation +.. _`missing features`: https://bitbucket.org/pypy/pypy/issues?status=new&status=open&component=PyPy3+%28running+Python+3.x%29&kind=enhancement +.. _`known issues`: https://bitbucket.org/pypy/pypy/issues?status=new&status=open&component=PyPy3%20%28running%20Python%203.x%29 +.. _`#2305`: https://bitbucket.org/pypy/pypy/issues/2305 +.. _`ensurepip`: https://docs.python.org/3/library/ensurepip.html#module-ensurepip +.. _`dynamic languages`: http://pypyjs.org diff --git a/pypy/doc/whatsnew-pypy3-5.5.0.rst b/pypy/doc/whatsnew-pypy3-5.5.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-pypy3-5.5.0.rst @@ -0,0 +1,59 @@ +========================= +What's new in PyPy3 5.5.0 +========================= + +.. this is the revision after 5.2.0 was branched +.. startrev: 2dd24a7eb90b + +.. pull request #454 + +Update fallback code in time to match CPython. + +.. d93d0a6c41f9 + +Add str.casefold(). + +.. f1c0e13019d5 + +Update Unicode character database to version 6.1.0. + +.. pull request #461 + +Make win_perf_counter expose the clock info. +Add a couple more fallbacks. +Make time.monotonic conditionally available depending on platform. + +.. issue 2346 + +Make hash(-1) return -2, like it does on CPython. + +.. pull request #469 + +Fix the mappingproxy type to behave as in CPython. + +.. branch: py3k-kwonly-builtin + +Implement keyword-only arguments for built-in functions. Fix functions in the +posix module to have keyword-only arguments wherever CPython has them, instead +of regular keyword arguments. + +.. pull request #475 + +Add os.get_terminal_size(). + +.. memoryview stuff + +Implement slicing of memoryview objects and improve their compatibility with +CPython. + +.. bdd0b2244dd3 + +Set up ImportError attributes properly in _imp.load_dynamic(). + +.. 494a05343a22 + +Allow __len__ to return any index-like. + +.. branch: py3k-faulthandler + +Replace stub faulthandler module with a working implementation. diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -1067,6 +1067,7 @@ def prepare_op_guard_not_forced_2(self, op, fcond): self.rm.before_call(op.getfailargs(), save_all_regs=True) + self.vfprm.before_call(op.getfailargs(), save_all_regs=True) fail_locs = self._prepare_guard(op) self.assembler.store_force_descr(op, fail_locs[1:], fail_locs[0].value) self.possibly_free_vars(op.getfailargs()) diff --git a/rpython/jit/backend/ppc/regalloc.py b/rpython/jit/backend/ppc/regalloc.py --- a/rpython/jit/backend/ppc/regalloc.py +++ b/rpython/jit/backend/ppc/regalloc.py @@ -965,6 +965,7 @@ def prepare_guard_not_forced_2(self, op): self.rm.before_call(op.getfailargs(), save_all_regs=True) + self.fprm.before_call(op.getfailargs(), save_all_regs=True) arglocs = self._prepare_guard(op) return arglocs diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -2647,6 +2647,32 @@ deadframe2 = self.cpu.force(frame) assert self.cpu.get_int_value(deadframe2, 0) == 30 + def test_guard_not_forced_2_float(self): + cpu = self.cpu + if not cpu.supports_floats: + py.test.skip("requires floats") + faildescr = BasicFailDescr(1) + finaldescr = BasicFinalDescr(0) + loop = parse(""" + [f0] + f1 = float_add(f0, 2.5) + p2 = force_token() + guard_not_forced_2(descr=faildescr) [f1] + finish(p2, descr=finaldescr) + """, namespace=locals()) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + deadframe = self.cpu.execute_token(looptoken, 20.25) + fail = self.cpu.get_latest_descr(deadframe) + assert fail.identifier == 0 + frame = self.cpu.get_ref_value(deadframe, 0) + # actually, we should get the same pointer in 'frame' and 'deadframe' + # but it is not the case on LLGraph + if not getattr(self.cpu, 'is_llgraph', False): + assert frame == deadframe + deadframe2 = self.cpu.force(frame) + assert self.cpu.get_float_value(deadframe2, 0) == 22.75 + def test_call_to_c_function(self): from rpython.rlib.libffi import CDLL, types, ArgChain, FUNCFLAG_CDECL from rpython.rtyper.lltypesystem.ll2ctypes import libc_name diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -1428,6 +1428,7 @@ def consider_guard_not_forced_2(self, op): self.rm.before_call(op.getfailargs(), save_all_regs=True) + self.xrm.before_call(op.getfailargs(), save_all_regs=True) fail_locs = [self.loc(v) for v in op.getfailargs()] self.assembler.store_force_descr(op, fail_locs, self.fm.get_frame_depth()) diff --git a/rpython/jit/backend/zarch/regalloc.py b/rpython/jit/backend/zarch/regalloc.py --- a/rpython/jit/backend/zarch/regalloc.py +++ b/rpython/jit/backend/zarch/regalloc.py @@ -1138,6 +1138,7 @@ def prepare_guard_not_forced_2(self, op): self.rm.before_call(op.getfailargs(), save_all_regs=True) + self.fprm.before_call(op.getfailargs(), save_all_regs=True) arglocs = self._prepare_guard(op) return arglocs diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py --- a/rpython/jit/metainterp/optimizeopt/info.py +++ b/rpython/jit/metainterp/optimizeopt/info.py @@ -132,7 +132,6 @@ def force_box(self, op, optforce): if self.is_virtual(): - optforce.forget_numberings() # if self._is_immutable_and_filled_with_constants(optforce.optimizer): constptr = optforce.optimizer.constant_fold(op) 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 @@ -252,9 +252,6 @@ def produce_potential_short_preamble_ops(self, potential_ops): pass - def forget_numberings(self): - self.optimizer.forget_numberings() - def _can_optimize_call_pure(self, op): arg_consts = [] for i in range(op.numargs()): @@ -353,10 +350,6 @@ for opt in self.optimizations: opt.produce_potential_short_preamble_ops(sb) - def forget_numberings(self): - self.metainterp_sd.profiler.count(jitprof.Counters.OPT_FORCINGS) - self.resumedata_memo.forget_numberings() - def getinfo(self, op): if op.type == 'r': return self.getptrinfo(op) @@ -745,7 +738,7 @@ modifier = resume.ResumeDataVirtualAdder(self, descr, op, self.trace, self.resumedata_memo) try: - newboxes = modifier.finish(self, pendingfields) + newboxes = modifier.finish(pendingfields) if (newboxes is not None and len(newboxes) > self.metainterp_sd.options.failargs_limit): raise resume.TagOverflow @@ -869,92 +862,6 @@ return opinfo is not None and opinfo.is_virtual() return False - def pure_reverse(self, op): - import sys - if self.optpure is None: - return - optpure = self.optpure - if op.getopnum() == rop.INT_ADD: - arg0 = op.getarg(0) - arg1 = op.getarg(1) - optpure.pure_from_args(rop.INT_ADD, [arg1, arg0], op) - # Synthesize the reverse op for optimize_default to reuse - optpure.pure_from_args(rop.INT_SUB, [op, arg1], arg0) - optpure.pure_from_args(rop.INT_SUB, [op, arg0], arg1) - if isinstance(arg0, ConstInt): - # invert the constant - i0 = arg0.getint() - if i0 == -sys.maxint - 1: - return - inv_arg0 = ConstInt(-i0) - elif isinstance(arg1, ConstInt): - # commutative - i0 = arg1.getint() - if i0 == -sys.maxint - 1: - return - inv_arg0 = ConstInt(-i0) - arg1 = arg0 - else: - return - optpure.pure_from_args(rop.INT_SUB, [arg1, inv_arg0], op) - optpure.pure_from_args(rop.INT_SUB, [arg1, op], inv_arg0) - optpure.pure_from_args(rop.INT_ADD, [op, inv_arg0], arg1) - optpure.pure_from_args(rop.INT_ADD, [inv_arg0, op], arg1) - - elif op.getopnum() == rop.INT_SUB: - arg0 = op.getarg(0) - arg1 = op.getarg(1) - optpure.pure_from_args(rop.INT_ADD, [op, arg1], arg0) - optpure.pure_from_args(rop.INT_SUB, [arg0, op], arg1) - if isinstance(arg1, ConstInt): - # invert the constant - i1 = arg1.getint() - if i1 == -sys.maxint - 1: - return - inv_arg1 = ConstInt(-i1) - optpure.pure_from_args(rop.INT_ADD, [arg0, inv_arg1], op) - optpure.pure_from_args(rop.INT_ADD, [inv_arg1, arg0], op) - optpure.pure_from_args(rop.INT_SUB, [op, inv_arg1], arg0) - optpure.pure_from_args(rop.INT_SUB, [op, arg0], inv_arg1) - elif op.getopnum() == rop.FLOAT_MUL: - optpure.pure_from_args(rop.FLOAT_MUL, - [op.getarg(1), op.getarg(0)], op) - elif op.getopnum() == rop.FLOAT_NEG: - optpure.pure_from_args(rop.FLOAT_NEG, [op], op.getarg(0)) - elif op.getopnum() == rop.CAST_INT_TO_PTR: - optpure.pure_from_args(rop.CAST_PTR_TO_INT, [op], op.getarg(0)) - elif op.getopnum() == rop.CAST_PTR_TO_INT: - optpure.pure_from_args(rop.CAST_INT_TO_PTR, [op], op.getarg(0)) - - #def optimize_GUARD_NO_OVERFLOW(self, op): - # # otherwise the default optimizer will clear fields, which is unwanted - # # in this case - # self.emit(op) - # FIXME: Is this still needed? - - def optimize_DEBUG_MERGE_POINT(self, op): - self.emit(op) - - def optimize_JIT_DEBUG(self, op): - self.emit(op) - - def optimize_STRGETITEM(self, op): - indexb = self.getintbound(op.getarg(1)) - if indexb.is_constant(): - pass - #raise Exception("implement me") - #arrayvalue = self.getvalue(op.getarg(0)) - #arrayvalue.make_len_gt(MODE_STR, op.getdescr(), indexvalue.box.getint()) - self.optimize_default(op) - - def optimize_UNICODEGETITEM(self, op): - indexb = self.getintbound(op.getarg(1)) - if indexb.is_constant(): - #arrayvalue = self.getvalue(op.getarg(0)) - #arrayvalue.make_len_gt(MODE_UNICODE, op.getdescr(), indexvalue.box.getint()) - pass - self.optimize_default(op) - # These are typically removed already by OptRewrite, but it can be # dissabled and unrolling emits some SAME_AS ops to setup the # optimizier state. These needs to always be optimized out. diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py --- a/rpython/jit/metainterp/optimizeopt/rewrite.py +++ b/rpython/jit/metainterp/optimizeopt/rewrite.py @@ -143,7 +143,21 @@ return self.emit(op) def postprocess_INT_SUB(self, op): - self.optimizer.pure_reverse(op) + import sys + arg0 = op.getarg(0) + arg1 = op.getarg(1) + self.optimizer.pure_from_args(rop.INT_ADD, [op, arg1], arg0) + self.optimizer.pure_from_args(rop.INT_SUB, [arg0, op], arg1) + if isinstance(arg1, ConstInt): + # invert the constant + i1 = arg1.getint() + if i1 == -sys.maxint - 1: + return + inv_arg1 = ConstInt(-i1) + self.optimizer.pure_from_args(rop.INT_ADD, [arg0, inv_arg1], op) + self.optimizer.pure_from_args(rop.INT_ADD, [inv_arg1, arg0], op) + self.optimizer.pure_from_args(rop.INT_SUB, [op, inv_arg1], arg0) + self.optimizer.pure_from_args(rop.INT_SUB, [op, arg0], inv_arg1) def optimize_INT_ADD(self, op): if self.is_raw_ptr(op.getarg(0)) or self.is_raw_ptr(op.getarg(1)): @@ -162,7 +176,32 @@ return self.emit(op) def postprocess_INT_ADD(self, op): - self.optimizer.pure_reverse(op) + import sys + arg0 = op.getarg(0) + arg1 = op.getarg(1) + self.optimizer.pure_from_args(rop.INT_ADD, [arg1, arg0], op) + # Synthesize the reverse op for optimize_default to reuse + self.optimizer.pure_from_args(rop.INT_SUB, [op, arg1], arg0) + self.optimizer.pure_from_args(rop.INT_SUB, [op, arg0], arg1) + if isinstance(arg0, ConstInt): + # invert the constant + i0 = arg0.getint() + if i0 == -sys.maxint - 1: + return + inv_arg0 = ConstInt(-i0) + elif isinstance(arg1, ConstInt): + # commutative + i0 = arg1.getint() + if i0 == -sys.maxint - 1: + return + inv_arg0 = ConstInt(-i0) + arg1 = arg0 + else: + return + self.optimizer.pure_from_args(rop.INT_SUB, [arg1, inv_arg0], op) + self.optimizer.pure_from_args(rop.INT_SUB, [arg1, op], inv_arg0) + self.optimizer.pure_from_args(rop.INT_ADD, [op, inv_arg0], arg1) + self.optimizer.pure_from_args(rop.INT_ADD, [inv_arg0, op], arg1) def optimize_INT_MUL(self, op): arg1 = self.get_box_replacement(op.getarg(0)) @@ -250,7 +289,8 @@ return self.emit(op) def postprocess_FLOAT_MUL(self, op): - self.optimizer.pure_reverse(op) + self.optimizer.pure_from_args(rop.FLOAT_MUL, + [op.getarg(1), op.getarg(0)], op) def optimize_FLOAT_TRUEDIV(self, op): arg1 = op.getarg(0) @@ -277,7 +317,7 @@ return self.emit(op) def postprocess_FLOAT_NEG(self, op): - self.optimizer.pure_reverse(op) + self.optimizer.pure_from_args(rop.FLOAT_NEG, [op], op.getarg(0)) def optimize_guard(self, op, constbox): box = op.getarg(0) @@ -799,11 +839,11 @@ return True def optimize_CAST_PTR_TO_INT(self, op): - self.optimizer.pure_reverse(op) + self.optimizer.pure_from_args(rop.CAST_INT_TO_PTR, [op], op.getarg(0)) return self.emit(op) def optimize_CAST_INT_TO_PTR(self, op): - self.optimizer.pure_reverse(op) + self.optimizer.pure_from_args(rop.CAST_PTR_TO_INT, [op], op.getarg(0)) return self.emit(op) def optimize_SAME_AS_I(self, op): diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py --- a/rpython/jit/metainterp/optimizeopt/vstring.py +++ b/rpython/jit/metainterp/optimizeopt/vstring.py @@ -79,7 +79,6 @@ def force_box(self, op, optforce): if not self.is_virtual(): return op - optforce.forget_numberings() if self.mode is mode_string: s = self.get_constant_string_spec(optforce, mode_string) if s is not None: diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py --- a/rpython/jit/metainterp/resume.py +++ b/rpython/jit/metainterp/resume.py @@ -165,15 +165,23 @@ class NumberingState(object): def __init__(self, size): self.liveboxes = {} - self.current = [0] * size + self.current = [rffi.cast(rffi.SHORT, 0)] * size self._pos = 0 - self.n = 0 - self.v = 0 + self.num_boxes = 0 + self.num_virtuals = 0 - def append(self, item): + def append_short(self, item): self.current[self._pos] = item self._pos += 1 + def append_int(self, item): + short = rffi.cast(rffi.SHORT, item) + assert rffi.cast(lltype.Signed, short) == item + return self.append_short(short) + + def create_numbering(self): + return resumecode.create_numbering(self.current) + class ResumeDataLoopMemo(object): def __init__(self, metainterp_sd): @@ -182,7 +190,6 @@ self.consts = [] self.large_ints = {} self.refs = self.cpu.ts.new_ref_dict_2() - self.numberings = {} self.cached_boxes = {} self.cached_virtuals = {} @@ -225,12 +232,12 @@ # env numbering - def _number_boxes(self, iter, arr, optimizer, state): + def _number_boxes(self, iter, arr, optimizer, numb_state): """ Number boxes from one snapshot """ - n = state.n - v = state.v - liveboxes = state.liveboxes + num_boxes = numb_state.num_boxes + num_virtuals = numb_state.num_virtuals + liveboxes = numb_state.liveboxes for item in arr: box = iter.get(rffi.cast(lltype.Signed, item)) box = optimizer.get_box_replacement(box) @@ -248,45 +255,41 @@ info = optimizer.getrawptrinfo(box, create=False) is_virtual = (info is not None and info.is_virtual()) if is_virtual: - tagged = tag(v, TAGVIRTUAL) - v += 1 + tagged = tag(num_virtuals, TAGVIRTUAL) + num_virtuals += 1 else: - tagged = tag(n, TAGBOX) - n += 1 + tagged = tag(num_boxes, TAGBOX) + num_boxes += 1 liveboxes[box] = tagged - state.append(tagged) - state.n = n - state.v = v + numb_state.append_short(tagged) + numb_state.num_boxes = num_boxes + numb_state.num_virtuals = num_virtuals def number(self, optimizer, position, trace): snapshot_iter = trace.get_snapshot_iter(position) - state = NumberingState(snapshot_iter.size) + numb_state = NumberingState(snapshot_iter.size) arr = snapshot_iter.vable_array - state.append(rffi.cast(rffi.SHORT, len(arr))) - self._number_boxes(snapshot_iter, arr, optimizer, state) + numb_state.append_int(len(arr)) + self._number_boxes(snapshot_iter, arr, optimizer, numb_state) arr = snapshot_iter.vref_array n = len(arr) assert not (n & 1) - state.append(rffi.cast(rffi.SHORT, n >> 1)) + numb_state.append_int(n >> 1) - self._number_boxes(snapshot_iter, arr, optimizer, state) + self._number_boxes(snapshot_iter, arr, optimizer, numb_state) for snapshot in snapshot_iter.framestack: jitcode_index, pc = snapshot_iter.unpack_jitcode_pc(snapshot) - state.append(rffi.cast(rffi.SHORT, jitcode_index)) - state.append(rffi.cast(rffi.SHORT, pc)) - self._number_boxes(snapshot_iter, snapshot.box_array, optimizer, state) + numb_state.append_int(jitcode_index) + numb_state.append_int(pc) + self._number_boxes( + snapshot_iter, snapshot.box_array, optimizer, numb_state) - numb = resumecode.create_numbering(state.current) - return numb, state.liveboxes, state.v - - def forget_numberings(self): - # XXX ideally clear only the affected numberings - self.numberings.clear() - self.clear_box_virtual_numbers() + return numb_state + # caching for virtuals and boxes inside them @@ -418,7 +421,8 @@ _, tagbits = untag(tagged) return tagbits == TAGVIRTUAL - def finish(self, optimizer, pending_setfields=[]): + def finish(self, pending_setfields=[]): + optimizer = self.optimizer # compute the numbering storage = self.storage # make sure that nobody attached resume data to this guard yet @@ -426,14 +430,14 @@ resume_position = self.guard_op.rd_resume_position assert resume_position >= 0 # count stack depth - numb, liveboxes_from_env, v = self.memo.number(optimizer, - resume_position, self.optimizer.trace) - self.liveboxes_from_env = liveboxes_from_env + numb_state = self.memo.number(optimizer, + resume_position, optimizer.trace) + self.liveboxes_from_env = liveboxes_from_env = numb_state.liveboxes + num_virtuals = numb_state.num_virtuals self.liveboxes = {} - storage.rd_numb = numb - + # collect liveboxes and virtuals - n = len(liveboxes_from_env) - v + n = len(liveboxes_from_env) - num_virtuals liveboxes = [None] * n self.vfieldboxes = {} for box, tagged in liveboxes_from_env.iteritems(): @@ -464,9 +468,10 @@ assert info is not None and info.is_virtual() info.visitor_walk_recursive(fieldbox, self, optimizer) - self._number_virtuals(liveboxes, optimizer, v) + self._number_virtuals(liveboxes, optimizer, num_virtuals) self._add_pending_fields(optimizer, pending_setfields) + storage.rd_numb = numb_state.create_numbering() storage.rd_consts = self.memo.consts return liveboxes[:] @@ -526,7 +531,7 @@ if self._invalidation_needed(len(liveboxes), nholes): memo.clear_box_virtual_numbers() - + def _invalidation_needed(self, nliveboxes, nholes): memo = self.memo # xxx heuristic a bit out of thin air diff --git a/rpython/jit/metainterp/test/test_resume.py b/rpython/jit/metainterp/test/test_resume.py --- a/rpython/jit/metainterp/test/test_resume.py +++ b/rpython/jit/metainterp/test/test_resume.py @@ -551,8 +551,8 @@ FakeFrame("code2", 9, c3, b2)] capture_resumedata(fs, None, [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) - modifier = ResumeDataVirtualAdder(None, storage, storage, memo) - liveboxes = modifier.finish(FakeOptimizer()) + modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, memo) + liveboxes = modifier.finish() metainterp = MyMetaInterp() b1t, b2t, b3t = [BoxInt(), InputArgRef(), BoxInt()] @@ -575,8 +575,8 @@ FakeFrame("code2", 9, c3, b2)] capture_resumedata(fs, [b4], [], storage) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) - modifier = ResumeDataVirtualAdder(None, storage, memo) - liveboxes = modifier.finish(FakeOptimizer({})) + modifier = ResumeDataVirtualAdder(FakeOptimizer({}), storage, memo) + liveboxes = modifier.finish() metainterp = MyMetaInterp() b1t, b2t, b3t, b4t = [BoxInt(), InputArgRef(), BoxInt(), InputArgRef()] @@ -604,11 +604,11 @@ capture_resumedata(fs, None, [], storage2) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) - modifier = ResumeDataVirtualAdder(None, storage, memo) - liveboxes = modifier.finish(FakeOptimizer({})) + modifier = ResumeDataVirtualAdder(FakeOptimizer({}), storage, memo) + liveboxes = modifier.finish() - modifier = ResumeDataVirtualAdder(None, storage2, memo) - liveboxes2 = modifier.finish(FakeOptimizer({})) + modifier = ResumeDataVirtualAdder(FakeOptimizer({}), storage2, memo) + liveboxes2 = modifier.finish() metainterp = MyMetaInterp() @@ -668,8 +668,8 @@ memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} - modifier = ResumeDataVirtualAdder(storage, memo) - liveboxes = modifier.finish(FakeOptimizer(values)) + modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo) + liveboxes = modifier.finish() assert len(storage.rd_virtuals) == 1 assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX), tag(0, TAGCONST)] @@ -679,8 +679,8 @@ v6.setfield(LLtypeMixin.nextdescr, v6) values = {b2: virtual_value(b2, b4, v6), b6: v6} memo.clear_box_virtual_numbers() - modifier = ResumeDataVirtualAdder(storage2, memo) - liveboxes2 = modifier.finish(FakeOptimizer(values)) + modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage2, memo) + liveboxes2 = modifier.finish() assert len(storage2.rd_virtuals) == 2 assert storage2.rd_virtuals[0].fieldnums == [tag(len(liveboxes2)-1, TAGBOX), tag(-1, TAGVIRTUAL)] @@ -725,8 +725,8 @@ memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) values = {b2: virtual_value(b2, b5, c4)} - modifier = ResumeDataVirtualAdder(storage, memo) - liveboxes = modifier.finish(FakeOptimizer(values)) + modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo) + liveboxes = modifier.finish() assert len(storage.rd_virtuals) == 1 assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX), tag(0, TAGCONST)] @@ -735,8 +735,8 @@ fs = [FakeFrame("code0", 0, b1, b4, b2)] capture_resumedata(fs, None, [], storage2) values[b4] = virtual_value(b4, b6, c4) - modifier = ResumeDataVirtualAdder(storage2, memo) - liveboxes = modifier.finish(FakeOptimizer(values)) + modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage2, memo) + liveboxes = modifier.finish() assert len(storage2.rd_virtuals) == 2 assert storage2.rd_virtuals[1].fieldnums == storage.rd_virtuals[0].fieldnums assert storage2.rd_virtuals[1] is storage.rd_virtuals[0] @@ -754,8 +754,8 @@ v2 = virtual_value(b2, b3, v1) v1.setfield(LLtypeMixin.nextdescr, v2) values = {b1: v1, b2: v2} - modifier = ResumeDataVirtualAdder(storage, memo) - liveboxes = modifier.finish(FakeOptimizer(values)) + modifier = ResumeDataVirtualAdder(FakeOptimizer(values), storage, memo) + liveboxes = modifier.finish() assert liveboxes == [b3] assert len(storage.rd_virtuals) == 2 assert storage.rd_virtuals[0].fieldnums == [tag(-1, TAGBOX), @@ -849,11 +849,12 @@ iter = t.get_iter() b1, b2, b3, b4, b5 = iter.inputargs - numb, liveboxes, v = memo.number(FakeOptimizer(), 0, iter) - assert v == 0 + numb_state = memo.number(FakeOptimizer(), 0, iter) + numb = numb_state.create_numbering() + assert numb_state.num_virtuals == 0 - assert liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), - b3: tag(2, TAGBOX)} + assert numb_state.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), + b3: tag(2, TAGBOX)} base = [0, 0, tag(0, TAGBOX), tag(1, TAGINT), tag(1, TAGBOX), tag(0, TAGBOX), tag(2, TAGINT)] @@ -864,12 +865,13 @@ False, [], []) snap2.prev = snap - numb2, liveboxes2, v = memo.number(FakeOptimizer(), 1, iter) - assert v == 0 - - assert liveboxes2 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), - b3: tag(2, TAGBOX)} - assert liveboxes2 is not liveboxes + numb_state2 = memo.number(FakeOptimizer(), 1, iter) + numb2 = numb_state2.create_numbering() + assert numb_state2.num_virtuals == 0 + + assert numb_state2.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), + b3: tag(2, TAGBOX)} + assert numb_state2.liveboxes is not numb_state.liveboxes assert unpack_numbering(numb2) == [0, 0] + base + [0, 2, tag(3, TAGINT), tag(2, TAGBOX), tag(0, TAGBOX), tag(3, TAGINT)] @@ -887,10 +889,11 @@ # renamed b3.set_forwarded(c4) - numb3, liveboxes3, v = memo.number(FakeOptimizer(), 2, iter) - assert v == 0 + numb_state3 = memo.number(FakeOptimizer(), 2, iter) + numb3 = numb_state3.create_numbering() + assert numb_state3.num_virtuals == 0 - assert liveboxes3 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)} + assert numb_state3.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX)} assert unpack_numbering(numb3) == ([0, 2, tag(3, TAGINT), tag(4, TAGINT), tag(0, TAGBOX), tag(3, TAGINT)] + base + [0, 2]) @@ -902,11 +905,12 @@ snap4.prev = snap b4.set_forwarded(FakeVirtualInfo(True)) - numb4, liveboxes4, v = memo.number(FakeOptimizer(), 3, iter) - assert v == 1 + numb_state4 = memo.number(FakeOptimizer(), 3, iter) + numb4 = numb_state4.create_numbering() + assert numb_state4.num_virtuals == 1 - assert liveboxes4 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), - b4: tag(0, TAGVIRTUAL)} + assert numb_state4.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), + b4: tag(0, TAGVIRTUAL)} assert unpack_numbering(numb4) == [0, 2, tag(3, TAGINT), tag(0, TAGVIRTUAL), tag(0, TAGBOX), tag(3, TAGINT)] + base + [0, 2] @@ -920,11 +924,12 @@ b4.set_forwarded(FakeVirtualInfo(True)) b5.set_forwarded(FakeVirtualInfo(True)) - numb5, liveboxes5, v = memo.number(FakeOptimizer(), 4, iter) - assert v == 2 - - assert liveboxes5 == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), - b4: tag(0, TAGVIRTUAL), b5: tag(1, TAGVIRTUAL)} + numb_state5 = memo.number(FakeOptimizer(), 4, iter) + numb5 = numb_state5.create_numbering() + assert numb_state5.num_virtuals == 2 + + assert numb_state5.liveboxes == {b1: tag(0, TAGBOX), b2: tag(1, TAGBOX), + b4: tag(0, TAGVIRTUAL), b5: tag(1, TAGVIRTUAL)} assert unpack_numbering(numb5) == [ 3, tag(0, TAGBOX), tag(0, TAGVIRTUAL), tag(1, TAGVIRTUAL), 0] + base + [ @@ -941,8 +946,9 @@ i = t.get_iter() t.create_top_snapshot(FakeJitCode("", 0), 0, Frame(lst), False, [], []) memo = ResumeDataLoopMemo(metainterp_sd) - num, liveboxes, v = memo.number(FakeOptimizer(), 0, i) - l = unpack_numbering(num) + numb_state = memo.number(FakeOptimizer(), 0, i) + numb = numb_state.create_numbering() + l = unpack_numbering(numb) assert l[0] == 0 assert l[1] == 0 assert l[2] == 0 @@ -951,7 +957,7 @@ for i, item in enumerate(lst): v, tag = untag(l[i + 4]) if tag == TAGBOX: - assert l[i + 4] == liveboxes[mapping[item]] + assert l[i + 4] == numb_state.liveboxes[mapping[item]] elif tag == TAGCONST: assert memo.consts[v].getint() == item.getint() elif tag == TAGINT: @@ -1059,7 +1065,7 @@ memo = ResumeDataLoopMemo(metainterp_sd) i = t.get_iter() modifier = ResumeDataVirtualAdder(FakeOptimizer(i), storage, storage, i, memo) - liveboxes = modifier.finish(FakeOptimizer(i)) + liveboxes = modifier.finish() cpu = MyCPU([]) reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage, "deadframe") reader.consume_vref_and_vable(None, None, None) @@ -1077,7 +1083,7 @@ memo = ResumeDataLoopMemo(metainterp_sd) i = t.get_iter() modifier = ResumeDataVirtualAdder(FakeOptimizer(i), storage, storage, i, memo) - modifier.finish(FakeOptimizer(i)) + modifier.finish() assert len(memo.consts) == 2 assert storage.rd_consts is memo.consts @@ -1086,7 +1092,7 @@ i = t.get_iter() modifier2 = ResumeDataVirtualAdder(FakeOptimizer(i), storage2, storage2, i, memo) - modifier2.finish(FakeOptimizer(i)) + modifier2.finish() assert len(memo.consts) == 3 assert storage2.rd_consts is memo.consts @@ -1155,7 +1161,7 @@ b1s.set_forwarded(b1_2) b2s.set_forwarded(b1_2) - liveboxes = modifier.finish(FakeOptimizer()) + liveboxes = modifier.finish() assert storage.rd_snapshot is None b1t, b3t = [InputArgInt(11), InputArgInt(33)] newboxes = _resume_remap(liveboxes, [b1_2, b3s], b1t, b3t) @@ -1177,7 +1183,7 @@ storage = make_storage(b1s, b2s, b3s) memo = ResumeDataLoopMemo(FakeMetaInterpStaticData()) modifier = ResumeDataVirtualAdder(FakeOptimizer(), storage, storage, memo) - liveboxes = modifier.finish(FakeOptimizer()) + liveboxes = modifier.finish() b2t, b3t = [InputArgRef(demo55o), InputArgInt(33)] newboxes = _resume_remap(liveboxes, [b2s, b3s], b2t, b3t) metainterp = MyMetaInterp() diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -679,7 +679,7 @@ # return newgcdependencies - def get_finish_tables(self): + def enum_type_info_members(self): # We must first make sure that the type_info_group's members # are all followed. Do it repeatedly while new members show up. # Once it is really done, do finish_tables(). @@ -688,6 +688,15 @@ curtotal = len(self.layoutbuilder.type_info_group.members) yield self.layoutbuilder.type_info_group.members[seen:curtotal] seen = curtotal + + def get_finish_helpers(self): + for dep in self.enum_type_info_members(): + yield dep + yield self.finish_helpers() + + def get_finish_tables(self): + for dep in self.enum_type_info_members(): + yield dep yield self.finish_tables() def write_typeid_list(self): diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py --- a/rpython/memory/gctransform/transform.py +++ b/rpython/memory/gctransform/transform.py @@ -286,6 +286,9 @@ newgcdependencies = self.ll_finalizers_ptrs return newgcdependencies + def get_finish_helpers(self): + return self.finish_helpers + def finish_tables(self): pass diff --git a/rpython/translator/c/database.py b/rpython/translator/c/database.py --- a/rpython/translator/c/database.py +++ b/rpython/translator/c/database.py @@ -275,7 +275,7 @@ finish_callbacks = [] if self.gctransformer: finish_callbacks.append(('GC transformer: finished helpers', - self.gctransformer.finish_helpers)) + self.gctransformer.get_finish_helpers())) finish_callbacks.append(('GC transformer: finished tables', self.gctransformer.get_finish_tables())) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit