[pypy-commit] pypy default: merge heads

mattip noreply at buildbot.pypy.org
Sun Nov 8 13:11:09 EST 2015


Author: mattip <matti.picus at gmail.com>
Branch: 
Changeset: r80594:b2a2f75dc940
Date: 2015-11-08 20:11 +0200
http://bitbucket.org/pypy/pypy/changeset/b2a2f75dc940/

Log:	merge heads

diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py b/pypy/interpreter/test/test_zzpickle_and_slow.py
--- a/pypy/interpreter/test/test_zzpickle_and_slow.py
+++ b/pypy/interpreter/test/test_zzpickle_and_slow.py
@@ -390,15 +390,20 @@
 
     def test_pickle_enum(self):
         import pickle
-        e      = enumerate(range(10))
+        e = enumerate(range(100, 106))
         e.next()
         e.next()
         pckl   = pickle.dumps(e)
         result = pickle.loads(pckl)
-        e.next()
-        result.next()
+        res = e.next()
+        assert res == (2, 102)
+        res = result.next()
+        assert res == (2, 102)
         assert type(e) is type(result)
-        assert list(e) == list(result)
+        res = list(e)
+        assert res == [(3, 103), (4, 104), (5, 105)]
+        res = list(result)
+        assert res == [(3, 103), (4, 104), (5, 105)]
 
     def test_pickle_xrangeiter(self):
         import pickle
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -231,28 +231,33 @@
 
 
 class W_Enumerate(W_Root):
-    def __init__(self, space, w_iterable, w_start):
-        from pypy.objspace.std.listobject import W_ListObject
-        w_iter = space.iter(w_iterable)
-        if space.is_w(space.type(w_start), space.w_int):
-            self.index = space.int_w(w_start)
-            self.w_index = None
-            if self.index == 0 and type(w_iterable) is W_ListObject:
-                w_iter = w_iterable
-        else:
-            self.index = -1
-            self.w_index = w_start
-        self.w_iter_or_list = w_iter
-        if self.w_index is not None:
-            assert not type(self.w_iter_or_list) is W_ListObject
+    def __init__(self, w_iter_or_list, start, w_start):
+        # 'w_index' should never be a wrapped int here; if it would be,
+        # then it is actually None and the unwrapped int is in 'index'.
+        self.w_iter_or_list = w_iter_or_list
+        self.index = start
+        self.w_index = w_start
 
     def descr___new__(space, w_subtype, w_iterable, w_start=None):
-        self = space.allocate_instance(W_Enumerate, w_subtype)
+        from pypy.objspace.std.listobject import W_ListObject
+
         if w_start is None:
-            w_start = space.wrap(0)
+            start = 0
         else:
             w_start = space.index(w_start)
-        self.__init__(space, w_iterable, w_start)
+            if space.is_w(space.type(w_start), space.w_int):
+                start = space.int_w(w_start)
+                w_start = None
+            else:
+                start = -1
+
+        if start == 0 and type(w_iterable) is W_ListObject:
+            w_iter = w_iterable
+        else:
+            w_iter = space.iter(w_iterable)
+
+        self = space.allocate_instance(W_Enumerate, w_subtype)
+        self.__init__(w_iter, start, w_start)
         return space.wrap(self)
 
     def descr___iter__(self, space):
@@ -298,14 +303,17 @@
         w_index = self.w_index
         if w_index is None:
             w_index = space.wrap(self.index)
-        else:
-            w_index = self.w_index
         w_info = space.newtuple([self.w_iter_or_list, w_index])
         return space.newtuple([w_new_inst, w_info])
 
 # exported through _pickle_support
-def _make_enumerate(space, w_iter, w_index):
-    return space.wrap(W_Enumerate(space, w_iter, w_index))
+def _make_enumerate(space, w_iter_or_list, w_index):
+    if space.is_w(space.type(w_index), space.w_int):
+        index = space.int_w(w_index)
+        w_index = None
+    else:
+        index = -1
+    return space.wrap(W_Enumerate(w_iter_or_list, index, w_index))
 
 W_Enumerate.typedef = TypeDef("enumerate",
     __new__=interp2app(W_Enumerate.descr___new__.im_func),
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
@@ -680,8 +680,6 @@
     emit_op_getfield_gc_pure_f = _genop_getfield
     emit_op_getfield_raw_i = _genop_getfield
     emit_op_getfield_raw_f = _genop_getfield
-    emit_op_getfield_raw_pure_i = _genop_getfield
-    emit_op_getfield_raw_pure_f = _genop_getfield
 
     def emit_op_increment_debug_counter(self, op, arglocs, regalloc, fcond):
         base_loc, value_loc = arglocs
@@ -825,8 +823,6 @@
     emit_op_getarrayitem_gc_pure_f = _genop_getarrayitem
     emit_op_getarrayitem_raw_i = _genop_getarrayitem
     emit_op_getarrayitem_raw_f = _genop_getarrayitem
-    emit_op_getarrayitem_raw_pure_i = _genop_getarrayitem
-    emit_op_getarrayitem_raw_pure_f = _genop_getarrayitem
 
     def _load_from_mem(self, res_loc, base_loc, ofs_loc, scale,
                                             signed=False, fcond=c.AL):
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
@@ -847,8 +847,6 @@
     prepare_op_getfield_gc_f = _prepare_op_getfield
     prepare_op_getfield_raw_i = _prepare_op_getfield
     prepare_op_getfield_raw_f = _prepare_op_getfield
-    prepare_op_getfield_raw_pure_i = _prepare_op_getfield
-    prepare_op_getfield_raw_pure_f = _prepare_op_getfield
     prepare_op_getfield_gc_pure_i = _prepare_op_getfield
     prepare_op_getfield_gc_pure_r = _prepare_op_getfield
     prepare_op_getfield_gc_pure_f = _prepare_op_getfield
@@ -942,8 +940,6 @@
     prepare_op_getarrayitem_gc_f = _prepare_op_getarrayitem
     prepare_op_getarrayitem_raw_i = _prepare_op_getarrayitem
     prepare_op_getarrayitem_raw_f = _prepare_op_getarrayitem
-    prepare_op_getarrayitem_raw_pure_i = _prepare_op_getarrayitem
-    prepare_op_getarrayitem_raw_pure_f = _prepare_op_getarrayitem
     prepare_op_getarrayitem_gc_pure_i = _prepare_op_getarrayitem
     prepare_op_getarrayitem_gc_pure_r = _prepare_op_getarrayitem
     prepare_op_getarrayitem_gc_pure_f = _prepare_op_getarrayitem
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -613,9 +613,6 @@
     bh_getfield_gc_f = bh_getfield_gc
 
     bh_getfield_raw = bh_getfield_gc
-    bh_getfield_raw_pure_i = bh_getfield_raw
-    bh_getfield_raw_pure_r = bh_getfield_raw
-    bh_getfield_raw_pure_f = bh_getfield_raw
     bh_getfield_raw_i = bh_getfield_raw
     bh_getfield_raw_r = bh_getfield_raw
     bh_getfield_raw_f = bh_getfield_raw
@@ -641,6 +638,7 @@
     def bh_getarrayitem_gc(self, a, index, descr):
         a = support.cast_arg(lltype.Ptr(descr.A), a)
         array = a._obj
+        assert index >= 0
         return support.cast_result(descr.A.OF, array.getitem(index))
 
     bh_getarrayitem_gc_pure_i = bh_getarrayitem_gc
@@ -651,9 +649,6 @@
     bh_getarrayitem_gc_f = bh_getarrayitem_gc
 
     bh_getarrayitem_raw = bh_getarrayitem_gc
-    bh_getarrayitem_raw_pure_i = bh_getarrayitem_raw
-    bh_getarrayitem_raw_pure_r = bh_getarrayitem_raw
-    bh_getarrayitem_raw_pure_f = bh_getarrayitem_raw
     bh_getarrayitem_raw_i = bh_getarrayitem_raw
     bh_getarrayitem_raw_r = bh_getarrayitem_raw
     bh_getarrayitem_raw_f = bh_getarrayitem_raw
@@ -749,6 +744,7 @@
         return s._obj.container.chars.getlength()
 
     def bh_strgetitem(self, s, item):
+        assert item >= 0
         return ord(s._obj.container.chars.getitem(item))
 
     def bh_strsetitem(self, s, item, v):
@@ -770,6 +766,7 @@
         return string._obj.container.chars.getlength()
 
     def bh_unicodegetitem(self, string, index):
+        assert index >= 0
         return ord(string._obj.container.chars.getitem(index))
 
     def bh_unicodesetitem(self, string, index, newvalue):
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
@@ -803,8 +803,6 @@
     emit_getfield_gc_pure_f = _genop_getfield
     emit_getfield_raw_i = _genop_getfield
     emit_getfield_raw_f = _genop_getfield
-    emit_getfield_raw_pure_i = _genop_getfield
-    emit_getfield_raw_pure_f = _genop_getfield
 
     SIZE2SCALE = dict([(1<<_i, _i) for _i in range(32)])
 
@@ -893,8 +891,6 @@
     emit_getarrayitem_gc_pure_f = _genop_getarray_or_interiorfield
     emit_getarrayitem_raw_i = _genop_getarray_or_interiorfield
     emit_getarrayitem_raw_f = _genop_getarray_or_interiorfield
-    emit_getarrayitem_raw_pure_i = _genop_getarray_or_interiorfield
-    emit_getarrayitem_raw_pure_f = _genop_getarray_or_interiorfield
 
     emit_raw_store = emit_setarrayitem_gc
     emit_raw_load_i = _genop_getarray_or_interiorfield
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
@@ -711,8 +711,6 @@
     prepare_getfield_gc_f = _prepare_getfield
     prepare_getfield_raw_i = _prepare_getfield
     prepare_getfield_raw_f = _prepare_getfield
-    prepare_getfield_raw_pure_i = _prepare_getfield
-    prepare_getfield_raw_pure_f = _prepare_getfield
     prepare_getfield_gc_pure_i = _prepare_getfield
     prepare_getfield_gc_pure_r = _prepare_getfield
     prepare_getfield_gc_pure_f = _prepare_getfield
@@ -796,8 +794,6 @@
     prepare_getarrayitem_gc_f = _prepare_getarrayitem
     prepare_getarrayitem_raw_i = _prepare_getarrayitem
     prepare_getarrayitem_raw_f = _prepare_getarrayitem
-    prepare_getarrayitem_raw_pure_i = _prepare_getarrayitem
-    prepare_getarrayitem_raw_pure_f = _prepare_getarrayitem
     prepare_getarrayitem_gc_pure_i = _prepare_getarrayitem
     prepare_getarrayitem_gc_pure_r = _prepare_getarrayitem
     prepare_getarrayitem_gc_pure_f = _prepare_getarrayitem
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
@@ -1477,8 +1477,6 @@
     genop_getfield_gc_f = _genop_getfield
     genop_getfield_raw_i = _genop_getfield
     genop_getfield_raw_f = _genop_getfield
-    genop_getfield_raw_pure_i = _genop_getfield
-    genop_getfield_raw_pure_f = _genop_getfield
     genop_getfield_gc_pure_i = _genop_getfield
     genop_getfield_gc_pure_r = _genop_getfield
     genop_getfield_gc_pure_f = _genop_getfield
@@ -1499,8 +1497,6 @@
     genop_getarrayitem_gc_pure_f = _genop_getarrayitem
     genop_getarrayitem_raw_i = _genop_getarrayitem
     genop_getarrayitem_raw_f = _genop_getarrayitem
-    genop_getarrayitem_raw_pure_i = _genop_getarrayitem
-    genop_getarrayitem_raw_pure_f = _genop_getarrayitem
 
     def _genop_raw_load(self, op, arglocs, resloc):
         base_loc, ofs_loc, size_loc, ofs, sign_loc = arglocs
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
@@ -1141,8 +1141,6 @@
     consider_getfield_gc_f = _consider_getfield
     consider_getfield_raw_i = _consider_getfield
     consider_getfield_raw_f = _consider_getfield
-    consider_getfield_raw_pure_i = _consider_getfield
-    consider_getfield_raw_pure_f = _consider_getfield
     consider_getfield_gc_pure_i = _consider_getfield
     consider_getfield_gc_pure_r = _consider_getfield
     consider_getfield_gc_pure_f = _consider_getfield
@@ -1172,8 +1170,6 @@
     consider_getarrayitem_gc_pure_i = _consider_getarrayitem
     consider_getarrayitem_gc_pure_r = _consider_getarrayitem
     consider_getarrayitem_gc_pure_f = _consider_getarrayitem
-    consider_getarrayitem_raw_pure_i = _consider_getarrayitem
-    consider_getarrayitem_raw_pure_f = _consider_getarrayitem
     consider_raw_load_i = _consider_getarrayitem
     consider_raw_load_f = _consider_getarrayitem
 
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -703,6 +703,12 @@
             pure = '_pure'
         arraydescr = self.cpu.arraydescrof(ARRAY)
         kind = getkind(op.result.concretetype)
+        if ARRAY._gckind != 'gc':
+            assert ARRAY._gckind == 'raw'
+            if kind == 'r':
+                raise Exception("getarrayitem_raw_r not supported")
+            pure = ''   # always redetected from pyjitpl.py: we don't need
+                        # a '_pure' version of getarrayitem_raw
         return SpaceOperation('getarrayitem_%s_%s%s' % (ARRAY._gckind,
                                                         kind[0], pure),
                               [op.args[0], op.args[1], arraydescr],
@@ -792,12 +798,17 @@
         descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
                                       c_fieldname.value)
         kind = getkind(RESULT)[0]
+        if argname != 'gc':
+            assert argname == 'raw'
+            if (kind, pure) == ('r', ''):
+                # note: a pure 'getfield_raw_r' is used e.g. to load class
+                # attributes that are GC objects, so that one is supported.
+                raise Exception("getfield_raw_r (without _pure) not supported")
+            pure = ''   # always redetected from pyjitpl.py: we don't need
+                        # a '_pure' version of getfield_raw
+        #
         op1 = SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure),
                              [v_inst, descr], op.result)
-        if op1.opname == 'getfield_raw_r':
-            # note: 'getfield_raw_r_pure' is used e.g. to load class
-            # attributes that are GC objects, so that one is supported.
-            raise Exception("getfield_raw_r (without _pure) not supported")
         #
         if immut in (IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY):
             op1.opname += "_pure"
diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1266,9 +1266,6 @@
     def bhimpl_getarrayitem_raw_f(cpu, array, index, arraydescr):
         return cpu.bh_getarrayitem_raw_f(array, index, arraydescr)
 
-    bhimpl_getarrayitem_raw_i_pure = bhimpl_getarrayitem_raw_i
-    bhimpl_getarrayitem_raw_f_pure = bhimpl_getarrayitem_raw_f
-
     @arguments("cpu", "r", "i", "i", "d")
     def bhimpl_setarrayitem_gc_i(cpu, array, index, newvalue, arraydescr):
         cpu.bh_setarrayitem_gc_i(array, index, newvalue, arraydescr)
@@ -1387,17 +1384,12 @@
     def bhimpl_getfield_raw_i(cpu, struct, fielddescr):
         return cpu.bh_getfield_raw_i(struct, fielddescr)
     @arguments("cpu", "i", "d", returns="r")
-    def _bhimpl_getfield_raw_r(cpu, struct, fielddescr):
-        # only for 'getfield_raw_r_pure'
+    def bhimpl_getfield_raw_r(cpu, struct, fielddescr):   # for pure only
         return cpu.bh_getfield_raw_r(struct, fielddescr)
     @arguments("cpu", "i", "d", returns="f")
     def bhimpl_getfield_raw_f(cpu, struct, fielddescr):
         return cpu.bh_getfield_raw_f(struct, fielddescr)
 
-    bhimpl_getfield_raw_i_pure = bhimpl_getfield_raw_i
-    bhimpl_getfield_raw_r_pure = _bhimpl_getfield_raw_r
-    bhimpl_getfield_raw_f_pure = bhimpl_getfield_raw_f
-
     @arguments("cpu", "r", "i", "d")
     def bhimpl_setfield_gc_i(cpu, struct, newvalue, fielddescr):
         cpu.bh_setfield_gc_i(struct, newvalue, fielddescr)
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -409,7 +409,7 @@
 def make_execute_function(name, func):
     # Make a wrapper for 'func'.  The func is a simple bhimpl_xxx function
     # from the BlackholeInterpreter class.  The wrapper is a new function
-    # that receives and returns boxed values.
+    # that receives boxed values (but returns a non-boxed value).
     for argtype in func.argtypes:
         if argtype not in ('i', 'r', 'f', 'd', 'cpu'):
             return None
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
@@ -6,6 +6,7 @@
 from rpython.rtyper.lltypesystem import lltype
 from rpython.jit.metainterp.optimizeopt.rawbuffer import RawBuffer, InvalidRawOperation
 from rpython.jit.metainterp.executor import execute
+from rpython.jit.metainterp.optimize import InvalidLoop
 
 
 INFO_NULL = 0
@@ -674,6 +675,7 @@
 
     def _get_info(self, descr, optheap):
         ref = self._const.getref_base()
+        if not ref: raise InvalidLoop   # null protection
         info = optheap.const_infos.get(ref, None)
         if info is None:
             info = StructPtrInfo(descr)
@@ -682,6 +684,7 @@
 
     def _get_array_info(self, descr, optheap):
         ref = self._const.getref_base()
+        if not ref: raise InvalidLoop   # null protection
         info = optheap.const_infos.get(ref, None)
         if info is None:
             info = ArrayPtrInfo(descr)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -8939,6 +8939,226 @@
         # (this test was written to show it would previously crash)
         self.optimize_loop(ops, ops)
 
+    def test_unroll_constant_null_1(self):
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = getfield_gc_i(p0, descr=valuedescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        # may either raise InvalidLoop or compile; it's a rare case
+        self.raises(InvalidLoop, self.optimize_loop, ops, ops)
+
+    def test_unroll_constant_null_2(self):
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        setfield_gc(p0, i1, descr=valuedescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        # may either raise InvalidLoop or compile; it's a rare case
+        self.raises(InvalidLoop, self.optimize_loop, ops, ops)
+
+    def test_unroll_constant_null_3(self):
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = getarrayitem_gc_i(p0, 5, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        # may either raise InvalidLoop or compile; it's a rare case
+        self.raises(InvalidLoop, self.optimize_loop, ops, ops)
+
+    def test_unroll_constant_null_4(self):
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        setarrayitem_gc(p0, 5, i1, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        # may either raise InvalidLoop or compile; it's a rare case
+        self.raises(InvalidLoop, self.optimize_loop, ops, ops)
+
+    def test_unroll_constant_null_5(self):
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = getarrayitem_gc_i(p0, i1, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        expected = """
+        [i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = getarrayitem_gc_i(NULL, i1, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(i3)
+        """
+        # may either raise InvalidLoop or compile; it's a rare case
+        self.optimize_loop(ops, expected)
+
+    def test_unroll_constant_null_6(self):
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        setarrayitem_gc(p0, i1, i1, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        expected = """
+        [i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        setarrayitem_gc(NULL, i1, i1, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(i3)
+        """
+        # may either raise InvalidLoop or compile; it's a rare case
+        self.optimize_loop(ops, expected)
+
+    def test_unroll_pure_on_bogus_object_1(self):
+        py.test.skip("FIXME")
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        getfield_gc_pure_i(p0, descr=valuedescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_2(self):
+        py.test.skip("FIXME")
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        getfield_gc_pure_i(p0, descr=valuedescr)
+        i3 = int_sub(i1, 1)
+        jump(ConstPtr(myptr3), i3)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_3(self):
+        py.test.skip("FIXME")
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        getarrayitem_gc_pure_i(p0, 5, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_4(self):
+        py.test.skip("FIXME")
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        getarrayitem_gc_pure_i(p0, 5, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(ConstPtr(myptr3), i3)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_5(self):
+        py.test.skip("FIXME")
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        getarrayitem_gc_pure_i(p0, 125, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(ConstPtr(arrayref), i3)     # too short, length < 126!
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_6(self):
+        py.test.skip("FIXME")
+        ops = """
+        [i0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        getarrayitem_gc_pure_i(ConstPtr(arrayref), i0, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(125, i3)     # arrayref is too short, length < 126!
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_7(self):
+        py.test.skip("FIXME")
+        ops = """
+        [i0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        getarrayitem_gc_pure_i(ConstPtr(arrayref), i0, descr=arraydescr)
+        i3 = int_sub(i1, 1)
+        jump(-1, i3)     # cannot access array item -1!
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_8(self):
+        py.test.skip("FIXME")
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = strgetitem(p0, 125)
+        i3 = int_sub(i1, 1)
+        jump(NULL, i3)
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_9(self):
+        py.test.skip("FIXME")
+        ops = """
+        [p0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = strgetitem(p0, 125)
+        i3 = int_sub(i1, 1)
+        jump(ConstPtr(myptr), i3)    # not a string at all
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_10(self):
+        py.test.skip("FIXME")
+        ops = """
+        [i0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = strgetitem("foobar", i0)
+        i3 = int_sub(i1, 1)
+        jump(125, i3)    # string is too short!
+        """
+        self.optimize_loop(ops, ops)
+
+    def test_unroll_pure_on_bogus_object_11(self):
+        py.test.skip("FIXME")
+        ops = """
+        [i0, i1]
+        i2 = int_gt(i1, 0)
+        guard_true(i2) []
+        i4 = strgetitem("foobar", i0)
+        i3 = int_sub(i1, 1)
+        jump(-1, i3)    # cannot access character -1!
+        """
+        self.optimize_loop(ops, ops)
+
 
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
     pass
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -500,16 +500,6 @@
                                        arraydescr, arraybox, indexbox)
 
     @arguments("box", "box", "descr")
-    def opimpl_getarrayitem_raw_i_pure(self, arraybox, indexbox, arraydescr):
-        return self.execute_with_descr(rop.GETARRAYITEM_RAW_PURE_I,
-                                       arraydescr, arraybox, indexbox)
-
-    @arguments("box", "box", "descr")
-    def opimpl_getarrayitem_raw_f_pure(self, arraybox, indexbox, arraydescr):
-        return self.execute_with_descr(rop.GETARRAYITEM_RAW_PURE_F,
-                                       arraydescr, arraybox, indexbox)
-
-    @arguments("box", "box", "descr")
     def opimpl_getarrayitem_gc_i_pure(self, arraybox, indexbox, arraydescr):
         if isinstance(arraybox, ConstPtr) and isinstance(indexbox, ConstInt):
             # if the arguments are directly constants, bypass the heapcache
@@ -792,19 +782,12 @@
     def opimpl_getfield_raw_i(self, box, fielddescr):
         return self.execute_with_descr(rop.GETFIELD_RAW_I, fielddescr, box)
     @arguments("box", "descr")
+    def opimpl_getfield_raw_r(self, box, fielddescr):   # for pure only
+        return self.execute_with_descr(rop.GETFIELD_RAW_R, fielddescr, box)
+    @arguments("box", "descr")
     def opimpl_getfield_raw_f(self, box, fielddescr):
         return self.execute_with_descr(rop.GETFIELD_RAW_F, fielddescr, box)
 
-    @arguments("box", "descr")
-    def opimpl_getfield_raw_i_pure(self, box, fielddescr):
-        return self.execute_with_descr(rop.GETFIELD_RAW_PURE_I, fielddescr, box)
-    @arguments("box", "descr")
-    def opimpl_getfield_raw_r_pure(self, box, fielddescr):
-        return self.execute_with_descr(rop.GETFIELD_RAW_PURE_R, fielddescr, box)
-    @arguments("box", "descr")
-    def opimpl_getfield_raw_f_pure(self, box, fielddescr):
-        return self.execute_with_descr(rop.GETFIELD_RAW_PURE_F, fielddescr, box)
-
     @arguments("box", "box", "descr")
     def _opimpl_setfield_raw_any(self, box, valuebox, fielddescr):
         self.execute_with_descr(rop.SETFIELD_RAW, fielddescr, box, valuebox)
@@ -2093,7 +2076,17 @@
         profiler = self.staticdata.profiler
         profiler.count_ops(opnum)
         resvalue = executor.execute(self.cpu, self, opnum, descr, *argboxes)
-        if rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST:
+        #
+        is_pure = rop._ALWAYS_PURE_FIRST <= opnum <= rop._ALWAYS_PURE_LAST
+        if not is_pure:
+            if (opnum == rop.GETFIELD_RAW_I or
+                opnum == rop.GETFIELD_RAW_R or
+                opnum == rop.GETFIELD_RAW_F or
+                opnum == rop.GETARRAYITEM_RAW_I or
+                opnum == rop.GETARRAYITEM_RAW_F):
+                is_pure = descr.is_always_pure()
+        #
+        if is_pure:
             return self._record_helper_pure(opnum, resvalue, descr, *argboxes)
         if rop._OVF_FIRST <= opnum <= rop._OVF_LAST:
             return self._record_helper_ovf(opnum, resvalue, descr, *argboxes)
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -1091,9 +1091,9 @@
     'STRLEN/1/i',
     'STRGETITEM/2/i',
     'GETFIELD_GC_PURE/1d/rfi',
-    'GETFIELD_RAW_PURE/1d/rfi',
     'GETARRAYITEM_GC_PURE/2d/rfi',
-    'GETARRAYITEM_RAW_PURE/2d/fi',
+    #'GETFIELD_RAW_PURE/1d/rfi',     these two operations not useful and
+    #'GETARRAYITEM_RAW_PURE/2d/fi',  dangerous when unrolling speculatively
     'UNICODELEN/1/i',
     'UNICODEGETITEM/2/i',
     #
@@ -1371,8 +1371,6 @@
     rop.GETARRAYITEM_GC_F: rop.VEC_GETARRAYITEM_GC_F,
     # note that there is no _PURE operation for vector operations.
     # reason: currently we do not care if it is pure or not!
-    rop.GETARRAYITEM_RAW_PURE_I: rop.VEC_GETARRAYITEM_RAW_I,
-    rop.GETARRAYITEM_RAW_PURE_F: rop.VEC_GETARRAYITEM_RAW_F,
     rop.GETARRAYITEM_GC_PURE_I: rop.VEC_GETARRAYITEM_GC_I,
     rop.GETARRAYITEM_GC_PURE_F: rop.VEC_GETARRAYITEM_GC_F,
     rop.RAW_STORE:        rop.VEC_RAW_STORE,
diff --git a/rpython/jit/metainterp/test/test_immutable.py b/rpython/jit/metainterp/test/test_immutable.py
--- a/rpython/jit/metainterp/test/test_immutable.py
+++ b/rpython/jit/metainterp/test/test_immutable.py
@@ -136,15 +136,15 @@
         #
         res = self.interp_operations(f, [0], disable_optimizations=True)
         assert res == 42
-        self.check_operations_history(getfield_raw_pure_i=1,
-                                      getarrayitem_raw_pure_i=1,
+        self.check_operations_history(getfield_raw_i=1,
+                                      getarrayitem_raw_i=1,
                                       int_mul=1)
         #
         # second try, in which we get num=0 constant-folded through f()
         res = self.interp_operations(f, [-1], disable_optimizations=True)
         assert res == 42
-        self.check_operations_history(getfield_raw_pure_i=0,
-                                      getarrayitem_raw_pure_i=0,
+        self.check_operations_history(getfield_raw_i=0,
+                                      getarrayitem_raw_i=0,
                                       int_mul=0)
 
     def test_read_on_promoted(self):


More information about the pypy-commit mailing list