[pypy-commit] pypy clean-exported-state: Merge with default

sbauman pypy.commits at gmail.com
Wed Oct 12 21:04:59 EDT 2016


Author: Spenser Bauman <sabauma at 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()))
 


More information about the pypy-commit mailing list