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

Reply via email to