[pypy-commit] pypy default: Don't create VStringPlainValues corresponding to long strings:

arigo noreply at buildbot.pypy.org
Sat Nov 3 18:21:52 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r58701:19329dd72849
Date: 2012-11-03 18:21 +0100
http://bitbucket.org/pypy/pypy/changeset/19329dd72849/

Log:	Don't create VStringPlainValues corresponding to long strings: limit
	them to, arbitrarily, 100 characters. This may fix a MemoryError
	issue in test_pypy_c/test_alloc.py

diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -5646,6 +5646,16 @@
         """
         self.optimize_strunicode_loop(ops, expected, expected)
 
+    def test_newstr_toobig(self):
+        ops = """
+        [i0]
+        p1 = newstr(101)
+        strsetitem(p1, 0, i0)
+        i3 = strgetitem(p1, 0)
+        jump(i3)
+        """
+        self.optimize_strunicode_loop(ops, ops, ops)
+
     # XXX Should some of the call's below now be call_pure?
 
     def test_str_concat_1(self):
diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py
--- a/pypy/jit/metainterp/optimizeopt/vstring.py
+++ b/pypy/jit/metainterp/optimizeopt/vstring.py
@@ -13,6 +13,8 @@
 from pypy.rlib.rarithmetic import is_valid_int
 
 
+MAX_CONST_LEN = 100
+
 
 class StrOrUnicode(object):
     def __init__(self, LLTYPE, hlstr, emptystr, chr,
@@ -131,6 +133,7 @@
         # Also, as long as self.is_virtual(), then we know that no-one else
         # could have written to the string, so we know that in this case
         # "None" corresponds to "really uninitialized".
+        assert size <= MAX_CONST_LEN
         self._chars = [None] * size
 
     def setup_slice(self, longerlist, start, stop):
@@ -405,7 +408,7 @@
 
     def _optimize_NEWSTR(self, op, mode):
         length_box = self.get_constant_box(op.getarg(0))
-        if length_box:
+        if length_box and length_box.getint() <= MAX_CONST_LEN:
             # if the original 'op' did not have a ConstInt as argument,
             # build a new one with the ConstInt argument
             if not isinstance(op.getarg(0), ConstInt):
@@ -508,12 +511,17 @@
 
         if length.is_constant() and length.box.getint() == 0:
             return
-        elif ((src.is_virtual() or src.is_constant()) and dst.is_virtual() and
-            srcstart.is_constant() and dststart.is_constant() and length.is_constant()):
-
+        elif ((src.is_virtual() or src.is_constant()) and
+              isinstance(dst, VStringPlainValue) and dst.is_virtual() and
+              srcstart.is_constant() and dststart.is_constant() and
+              length.is_constant()):
             src_start = srcstart.force_box(self).getint()
             dst_start = dststart.force_box(self).getint()
-            for index in range(length.force_box(self).getint()):
+            # 'length' must be <= MAX_CONST_LEN here, because 'dst' is a
+            # VStringPlainValue, which is limited to MAX_CONST_LEN.
+            actual_length = length.force_box(self).getint()
+            assert actual_length <= MAX_CONST_LEN
+            for index in range(actual_length):
                 vresult = self.strgetitem(src, optimizer.ConstantValue(ConstInt(index + src_start)), mode)
                 dst.setitem(index + dst_start, vresult)
         else:


More information about the pypy-commit mailing list