Author: Antonio Cuni <[email protected]>
Branch: virtual-raw-mallocs
Changeset: r59489:27446ea92191
Date: 2012-12-18 18:21 +0100
http://bitbucket.org/pypy/pypy/changeset/27446ea92191/
Log: force the raw buffer if we detect an invalid write
diff --git a/pypy/jit/backend/llgraph/runner.py
b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -3,9 +3,9 @@
"""
from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import we_are_translated, Symbolic
from pypy.rlib.jit_hooks import LOOP_RUN_CONTAINER
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rffi
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.llinterp import LLInterpreter
from pypy.jit.metainterp import history
@@ -397,13 +397,18 @@
token = 's'
else:
token = '?'
- return self.getdescr(size, token)
+ # so that unpack_arraydescr_size returns something sensible
+ width = rffi.sizeof(A.OF)
+ if isinstance(width, Symbolic):
+ # we cannot compute anything reasonable, so we just make up a size
+ width = 8 * len(A.OF._flds)
+ return self.getdescr(size, token, width=width)
def unpack_arraydescr_size(self, arraydescr):
# so far this is used only by optimizeopt.virtualize for
- # {GET,SET}ARRAYITEM_RAW: it's hard (if not impossible) to compute
- # precise values, so we just return dummy ones for now
- return 0, 8, True
+ # {GET,SET}ARRAYITEM_RAW: for now we just return dummy values for
+ # basesize and is_signed
+ return 0, arraydescr.width, True
# ---------- the backend-dependent operations ----------
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
@@ -1784,6 +1784,27 @@
"""
self.optimize_loop(ops, expected)
+ def test_virtual_raw_malloc_invalid_write_force(self):
+ ops = """
+ [i1]
+ i2 = call('malloc', 10, descr=raw_malloc_descr)
+ setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
+ label('foo') # we expect the buffer to be forced *after* the label
+ setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char) # overlap!
+ call('free', i2, descr=raw_free_descr)
+ jump(i1)
+ """
+ expected = """
+ [i1]
+ label('foo')
+ i2 = call('malloc', 10, descr=raw_malloc_descr)
+ setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
+ setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
+ call('free', i2, descr=raw_free_descr)
+ jump(i1)
+ """
+ self.optimize_loop(ops, expected)
+
def test_duplicate_getfield_1(self):
ops = """
[p1, p2]
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py
b/pypy/jit/metainterp/optimizeopt/test/test_util.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_util.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py
@@ -219,6 +219,9 @@
rawarraydescr = cpu.arraydescrof(lltype.Array(lltype.Signed,
hints={'nolength': True}))
+ rawarraydescr_char = cpu.arraydescrof(lltype.Array(lltype.Char,
+ hints={'nolength':
True}))
+
for _name, _os in [
('strconcatdescr', 'OS_STR_CONCAT'),
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py
b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -403,10 +403,7 @@
optforce.emit_operation(op)
def setitem_raw(self, offset, length, descr, value):
- try:
- self.buffer.write_value(offset, length, descr, value)
- except InvalidRawOperation:
- XXX
+ self.buffer.write_value(offset, length, descr, value)
def getitem_raw(self, offset, length, descr):
try:
@@ -633,7 +630,12 @@
if indexbox is not None:
offset, itemsize, descr = self._unpack_arrayitem_raw_op(op,
indexbox)
itemvalue = self.getvalue(op.getarg(2))
- value.setitem_raw(offset, itemsize, descr, itemvalue)
+ try:
+ value.setitem_raw(offset, itemsize, descr, itemvalue)
+ except InvalidRawOperation:
+ box = value.force_box(self)
+ op.setarg(0, box)
+ self.emit_operation(op)
return
value.ensure_nonnull()
self.emit_operation(op)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit