Author: Antonio Cuni <[email protected]>
Branch: faster-rstruct
Changeset: r80762:4fb804c3e5fe
Date: 2015-11-18 17:33 +0100
http://bitbucket.org/pypy/pypy/changeset/4fb804c3e5fe/
Log: fix the optimizer, which gets confused when we pass a virtual string
to getarrayitem_gc
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -535,10 +535,14 @@
cf.do_setfield(self, op)
def optimize_GETARRAYITEM_GC_I(self, op):
+ # When using str_storage_getitem we op.getarg(0) is a string, NOT an
+ # array. That's why we need to check for .is_array() before
+ # remembering the reads. There is no point in remembering it, as the
+ # box will be forced anyway by the optimizer
arrayinfo = self.ensure_ptr_info_arg0(op)
indexb = self.getintbound(op.getarg(1))
cf = None
- if indexb.is_constant():
+ if indexb.is_constant() and arrayinfo.is_array():
index = indexb.getint()
arrayinfo.getlenbound(None).make_gt_const(index)
# use the cache on (arraydescr, index), which is a constant
@@ -555,7 +559,7 @@
self.make_nonnull(op.getarg(0))
self.emit_operation(op)
# the remember the result of reading the array item
- if cf is not None:
+ if cf is not None and arrayinfo.is_array():
arrayinfo.setitem(op.getdescr(), indexb.getint(),
self.get_box_replacement(op.getarg(0)),
self.get_box_replacement(op), cf,
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
@@ -49,6 +49,9 @@
def is_null(self):
return False
+ def is_array(self):
+ return False
+
def force_at_the_end_of_preamble(self, op, optforce, rec):
if not self.is_virtual():
return optforce.get_box_replacement(op)
@@ -478,6 +481,9 @@
self.lenbound = intutils.ConstIntBound(size)
self._clear = clear
+ def is_array(self):
+ return True
+
def getlenbound(self, mode):
from rpython.jit.metainterp.optimizeopt import intutils
@@ -716,6 +722,9 @@
def is_virtual(self):
return False
+ def is_array(self):
+ return True
+
def get_known_class(self, cpu):
if not self._const.nonnull():
return None
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py
b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -271,8 +271,11 @@
self.emit_operation(op)
def optimize_GETARRAYITEM_GC_I(self, op):
+ # When using str_storage_getitem we op.getarg(0) is a string, NOT an
+ # array, hence the check for is_array(). If it's a virtual but not an
+ # array (i.e., if it's a string) it will be forced.
opinfo = self.getptrinfo(op.getarg(0))
- if opinfo and opinfo.is_virtual():
+ if opinfo and opinfo.is_virtual() and opinfo.is_array():
indexbox = self.get_constant_box(op.getarg(1))
if indexbox is not None:
item = opinfo.getitem(op.getdescr(), indexbox.getint())
diff --git a/rpython/jit/metainterp/test/test_strstorage.py
b/rpython/jit/metainterp/test/test_strstorage.py
--- a/rpython/jit/metainterp/test/test_strstorage.py
+++ b/rpython/jit/metainterp/test/test_strstorage.py
@@ -1,5 +1,6 @@
import py
-from rpython.rtyper.lltypesystem import lltype
+import struct
+from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.strstorage import str_storage_getitem
from rpython.rlib.test.test_strstorage import BaseStrStorageTest
from rpython.jit.codewriter import longlong
@@ -26,3 +27,20 @@
# back!
return longlong.int2singlefloat(res)
return res
+
+
+ def test_force_virtual_str_storage(self):
+ size = rffi.sizeof(lltype.Signed)
+ def f(val):
+ x = chr(val) + '\x00'*(size-1)
+ return str_storage_getitem(lltype.Signed, x, 0)
+ res = self.interp_operations(f, [42], supports_singlefloats=True)
+ assert res == 42
+ self.check_operations_history({
+ 'newstr': 1, # str forcing
+ 'strsetitem': 1, # str forcing
+ 'call_pure_r': 1, # str forcing (copystrcontent)
+ 'guard_no_exception': 1, # str forcing
+ 'getarrayitem_gc_i': 1, # str_storage_getitem
+ 'finish': 1
+ })
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit