[pypy-commit] pypy default: Add null protection at one place. I think that non-pure

arigo noreply at buildbot.pypy.org
Sun Nov 8 04:37:45 EST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r80583:81f34fcd3105
Date: 2015-11-08 10:21 +0100
http://bitbucket.org/pypy/pypy/changeset/81f34fcd3105/

Log:	Add null protection at one place. I think that non-pure
	{get,set}{field,arrayitem}_gc can always go forward, even if they
	are done on a GC object of a wrong type. It will make caches to
	record these "reads" and "writes" that would never actually occur
	anyway. I think the only bad thing that occurred is the
	AssertionError when the GC object is NULL (now turned into
	InvalidLoop).

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,94 @@
         # (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)
+
 
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
     pass


More information about the pypy-commit mailing list