Author: Armin Rigo <[email protected]> Branch: py3.5 Changeset: r87737:c3484752b4b2 Date: 2016-10-12 11:58 +0200 http://bitbucket.org/pypy/pypy/changeset/c3484752b4b2/
Log: hg merge default diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -1,10 +1,3 @@ -Contributors to PyPy -==================== - -Here is a list of developers who have committed to the PyPy source -code base, ordered by number of commits (which is certainly not a very -appropriate measure but it's something):: - Armin Rigo Maciej Fijalkowski Carl Friedrich Bolz @@ -14,15 +7,15 @@ Matti Picus Alex Gaynor Philip Jenvey + Ronan Lamy Brian Kearns - Ronan Lamy Michael Hudson + Richard Plangger Manuel Jacob David Schneider Holger Krekel Christian Tismer Hakan Ardo - Richard Plangger Benjamin Peterson Anders Chrigstrom Eric van Riet Paap @@ -38,8 +31,8 @@ Niklaus Haldimann Camillo Bruni Laura Creighton + Romain Guillebert Toon Verwaest - Romain Guillebert Leonardo Santagada Seo Sanghyeon Ronny Pfannschmidt @@ -59,10 +52,12 @@ Ludovic Aubry Jacob Hallen Jason Creighton + Mark Young Alex Martelli Michal Bendowski stian Jan de Mooij + Spenser Bauman Tyler Wade Vincent Legoll Michael Foord @@ -71,19 +66,20 @@ Valentino Volonghi Tomek Meka Patrick Maupin + Devin Jeanpierre Bob Ippolito Bruno Gola David Malcolm Jean-Paul Calderone - Mark Young + Stefano Rivera Timo Paulssen + Edd Barrett Squeaky - Devin Jeanpierre Marius Gedminas Alexandre Fayolle Simon Burton - Stefano Rivera Martin Matusiak + Nicolas Truessel Konstantin Lopuhin Wenzhu Man John Witulski @@ -93,13 +89,11 @@ Dario Bertini Mark Pearse Simon Cross - Edd Barrett Andreas Stührk Tobias Pape Jean-Philippe St. Pierre Guido van Rossum Pavel Vinogradov - Spenser Bauman Jeremy Thurgood Paweł Piotr Przeradowski Paul deGrandis @@ -111,7 +105,6 @@ tav Taavi Burns Georg Brandl - Nicolas Truessel Bert Freudenberg Stian Andreassen Wanja Saatkamp @@ -126,12 +119,12 @@ Preston Timmons David Ripton Jeff Terrace + Tim Felgentreff Dusty Phillips Lukas Renggli Guenter Jantzen William Leslie Ned Batchelder - Tim Felgentreff Anton Gulenko Amit Regmi Ben Young @@ -159,6 +152,7 @@ Victor Stinner Andrews Medina Stuart Williams + Daniel Patrick Jasper Schulz Christian Hudon Toby Watson @@ -283,6 +277,7 @@ Daniel Neuhäuser Ben Mather Niclas Olofsson + "Aaron Gallagher halgari Boglarka Vezer Chris Pressey @@ -311,8 +306,10 @@ jiaaro Mads Kiilerich opassembler.py + JohnDoe Antony Lee Jason Madden + [email protected] Yaroslav Fedevych Jim Hunziker Markus Unterwaditzer @@ -331,6 +328,7 @@ Michael Chermside Anna Ravencroft pizi + remarkablerocket Andrey Churin Dan Crosta Eli Stevens @@ -339,3 +337,4 @@ Roman Podoliaka Dan Loewenherz werat + hgattic 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 @@ -27,7 +27,12 @@ whatsnew-2.0.0-beta1.rst whatsnew-1.9.rst +CPython 3.3 compatible versions +------------------------------- +.. toctree:: + + whatsnew-pypy3-5.5.0.rst CPython 3.2 compatible versions ------------------------------- 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/opassembler.py b/rpython/jit/backend/arm/opassembler.py --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -31,6 +31,7 @@ from rpython.rtyper import rclass from rpython.jit.backend.arm import callbuilder from rpython.rlib.rarithmetic import r_uint +from rpython.rlib.rjitlog import rjitlog as jl class ArmGuardToken(GuardToken): @@ -1012,6 +1013,8 @@ mc = InstrBuilder(self.cpu.cpuinfo.arch_version) mc.B(target) mc.copy_to_raw_memory(oldadr) + # + jl.redirect_assembler(oldlooptoken, newlooptoken, newlooptoken.number) def emit_op_guard_not_forced(self, op, arglocs, regalloc, fcond): ofs = self.cpu.get_ofs_of_frame_field('jf_descr') 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/opassembler.py b/rpython/jit/backend/ppc/opassembler.py --- a/rpython/jit/backend/ppc/opassembler.py +++ b/rpython/jit/backend/ppc/opassembler.py @@ -29,6 +29,7 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.backend.ppc import callbuilder from rpython.rlib.rarithmetic import r_uint +from rpython.rlib.rjitlog import rjitlog as jl class IntOpAssembler(object): @@ -1321,6 +1322,7 @@ mc = PPCBuilder() mc.b_abs(target) mc.copy_to_raw_memory(oldadr) + jl.redirect_assembler(oldlooptoken, newlooptoken, newlooptoken.number) class OpAssembler(IntOpAssembler, GuardOpAssembler, 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/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -466,6 +466,7 @@ operations, looptoken, log): '''adds the following attributes to looptoken: _ll_function_addr (address of the generated func, as an int) + _ll_raw_start (jitlog: address of the first byte to asm memory) _ll_loop_code (debug: addr of the start of the ResOps) _x86_fullsize (debug: full size including failure) ''' @@ -539,10 +540,11 @@ looptoken._x86_fullsize = full_size looptoken._x86_ops_offset = ops_offset looptoken._ll_function_addr = rawstart + functionpos + looptoken._ll_raw_start = rawstart - if logger: - log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc) - log.write(inputargs, operations, ops_offset=ops_offset) + if log and logger: + l = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc) + l.write(inputargs, operations, ops_offset=ops_offset) # legacy if logger.logger_ops: @@ -594,6 +596,7 @@ fullsize = self.mc.get_relative_pos() # rawstart = self.materialize_loop(original_loop_token) + original_loop_token._ll_raw_start = rawstart self.patch_gcref_table(original_loop_token, rawstart) self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, rawstart) @@ -1065,7 +1068,8 @@ assert mc.get_relative_pos() <= 13 mc.copy_to_raw_memory(oldadr) # log the redirection of the call_assembler_* operation - jl.redirect_assembler(oldlooptoken, newlooptoken, target) + asm_adr = newlooptoken._ll_raw_start + jl.redirect_assembler(oldlooptoken, newlooptoken, asm_adr) def dump(self, text): if not self.verbose: 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/opassembler.py b/rpython/jit/backend/zarch/opassembler.py --- a/rpython/jit/backend/zarch/opassembler.py +++ b/rpython/jit/backend/zarch/opassembler.py @@ -9,6 +9,7 @@ from rpython.jit.metainterp.history import (ConstInt) from rpython.jit.backend.zarch.codebuilder import ZARCHGuardToken, InstrBuilder from rpython.jit.backend.llsupport import symbolic, jitframe +from rpython.rlib.rjitlog import rjitlog as jl import rpython.jit.backend.zarch.conditions as c import rpython.jit.backend.zarch.registers as r import rpython.jit.backend.zarch.locations as l @@ -1155,6 +1156,8 @@ mc.load_imm(r.SCRATCH, target) mc.BCR(c.ANY, r.SCRATCH) mc.copy_to_raw_memory(oldadr) + # + jl.redirect_assembler(oldlooptoken, newlooptoken, newlooptoken.number) class MiscOpAssembler(object): 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/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -7,6 +7,7 @@ from rpython.rlib import rstack from rpython.rlib.jit import JitDebugInfo, Counters, dont_look_inside from rpython.rlib.rjitlog import rjitlog as jl +from rpython.rlib.objectmodel import compute_unique_id from rpython.conftest import option from rpython.jit.metainterp.resoperation import ResOperation, rop,\ @@ -1121,6 +1122,10 @@ version of the code may end up replacing it. """ jitcell_token = make_jitcell_token(jitdriver_sd) + # + # record the target of a temporary callback to the interpreter + jl.tmp_callback(jitcell_token) + # nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args inputargs = [] @@ -1156,6 +1161,7 @@ operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, jitcell_token, log=False) + if memory_manager is not None: # for tests memory_manager.keep_loop_alive(jitcell_token) return jitcell_token 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 @@ -249,9 +249,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()): @@ -350,10 +347,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) @@ -865,92 +858,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 @@ -167,13 +167,18 @@ self.liveboxes = {} self.current = [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) + class ResumeDataLoopMemo(object): def __init__(self, metainterp_sd): @@ -182,7 +187,6 @@ self.consts = [] self.large_ints = {} self.refs = self.cpu.ts.new_ref_dict_2() - self.numberings = {} self.cached_boxes = {} self.cached_virtuals = {} @@ -228,8 +232,8 @@ def _number_boxes(self, iter, arr, optimizer, state): """ Number boxes from one snapshot """ - n = state.n - v = state.v + num_boxes = state.num_boxes + num_virtuals = state.num_virtuals liveboxes = state.liveboxes for item in arr: box = iter.get(rffi.cast(lltype.Signed, item)) @@ -248,15 +252,15 @@ 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 + state.append_short(tagged) + state.num_boxes = num_boxes + state.num_virtuals = num_virtuals def number(self, optimizer, position, trace): snapshot_iter = trace.get_snapshot_iter(position) @@ -264,29 +268,25 @@ arr = snapshot_iter.vable_array - state.append(rffi.cast(rffi.SHORT, len(arr))) + state.append_int(len(arr)) self._number_boxes(snapshot_iter, arr, optimizer, state) arr = snapshot_iter.vref_array n = len(arr) assert not (n & 1) - state.append(rffi.cast(rffi.SHORT, n >> 1)) + state.append_int(n >> 1) self._number_boxes(snapshot_iter, arr, optimizer, 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)) + state.append_int(jitcode_index) + state.append_int(pc) self._number_boxes(snapshot_iter, snapshot.box_array, optimizer, 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.liveboxes, state.num_virtuals + # caching for virtuals and boxes inside them @@ -426,14 +426,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, + numb, liveboxes_from_env, num_virtuals = self.memo.number(optimizer, resume_position, self.optimizer.trace) self.liveboxes_from_env = liveboxes_from_env 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,7 +464,7 @@ 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_consts = self.memo.consts @@ -526,7 +526,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/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/rlib/rjitlog/rjitlog.py b/rpython/rlib/rjitlog/rjitlog.py --- a/rpython/rlib/rjitlog/rjitlog.py +++ b/rpython/rlib/rjitlog/rjitlog.py @@ -212,7 +212,7 @@ return method return decor -JITLOG_VERSION = 3 +JITLOG_VERSION = 4 JITLOG_VERSION_16BIT_LE = struct.pack("<H", JITLOG_VERSION) marks = [ @@ -245,6 +245,7 @@ ('ABORT_TRACE',), ('SOURCE_CODE',), ('REDIRECT_ASSEMBLER',), + ('TMP_CALLBACK',), ] start = 0x11 @@ -254,12 +255,13 @@ if __name__ == "__main__": print("# generated constants from rpython/rlib/jitlog.py") - print 'MARK_JITLOG_START = struct.pack("b", "%s")' % hex(0x10) + print('import struct') + print('MARK_JITLOG_START = struct.pack("b", %s)' % hex(0x10)) for mark, in marks: nmr = globals()['MARK_' + mark] h = hex(ord(nmr)) - print '%s = struct.pack("b", "%s")' % ('MARK_' + mark, h) - print 'MARK_JITLOG_END = struct.pack("b", "%s")' % hex(start) + print '%s = struct.pack("b", %s)' % ('MARK_' + mark, h) + print 'MARK_JITLOG_END = struct.pack("b", %s)' % hex(start) for key,value in locals().items(): if key.startswith("MP_"): print '%s = (%s,"%s")' % (key, hex(value[0]), value[1]) @@ -310,16 +312,22 @@ content = ''.join(list) jitlog_write_marked(content, len(content)) -def redirect_assembler(oldtoken, newtoken, target): +def redirect_assembler(oldtoken, newtoken, asm_adr): if not jitlog_enabled(): return descr_nmr = compute_unique_id(oldtoken) new_descr_nmr = compute_unique_id(newtoken) list = [MARK_REDIRECT_ASSEMBLER, encode_le_addr(descr_nmr), - encode_le_addr(new_descr_nmr), encode_le_addr(target)] + encode_le_addr(new_descr_nmr), encode_le_addr(asm_adr)] content = ''.join(list) jitlog_write_marked(content, len(content)) +def tmp_callback(looptoken): + mark_tmp_callback = ''.join([ + MARK_TMP_CALLBACK, + encode_le_addr(compute_unique_id(looptoken)), + encode_le_64bit(looptoken.number)]) + jitlog_write_marked(mark_tmp_callback, len(mark_tmp_callback)) class JitLogger(object): def __init__(self, cpu=None): @@ -343,6 +351,10 @@ def finish(self): jitlog_teardown() + def next_id(self): + self.trace_id += 1 + return self.trace_id + def start_new_trace(self, metainterp_sd, faildescr=None, entry_bridge=False, jd_name=""): # even if the logger is not enabled, increment the trace id self.trace_id += 1 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 [email protected] https://mail.python.org/mailman/listinfo/pypy-commit
