[pypy-commit] pypy py3.5: hg merge default
arigo
pypy.commits at gmail.com
Wed Oct 12 15:27:34 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
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
+ reubano at gmail.com
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()))
More information about the pypy-commit
mailing list