[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