[pypy-commit] pypy stm: setarrayitem.

arigo noreply at buildbot.pypy.org
Thu Nov 3 21:12:44 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r48720:e67329e4d516
Date: 2011-11-03 19:28 +0100
http://bitbucket.org/pypy/pypy/changeset/e67329e4d516/

Log:	setarrayitem.

diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -397,6 +397,7 @@
 
     'stm_getfield':         LLOp(sideeffects=False, canrun=True),
     'stm_setfield':         LLOp(),
+    'stm_setarrayitem':     LLOp(),
 
     'stm_begin_transaction':            LLOp(),
     'stm_commit_transaction':           LLOp(),
diff --git a/pypy/translator/stm/llstminterp.py b/pypy/translator/stm/llstminterp.py
--- a/pypy/translator/stm/llstminterp.py
+++ b/pypy/translator/stm/llstminterp.py
@@ -94,6 +94,22 @@
             self.check_stm_mode(lambda m: False)
             assert 0
 
+    def opstm_setarrayitem(self, array, index, newvalue):
+        ARRAY = lltype.typeOf(struct).TO
+        if ARRAY._immutable_field():
+            # immutable item writes (i.e. initializing writes) should
+            # always be fine, because they should occur into newly malloced
+            # arrays
+            LLFrame.op_setarrayitem(self, array, index, newvalue)
+        elif ARRAY._gckind == 'raw':
+            # raw setarrayitems are allowed outside a regular transaction
+            self.check_stm_mode(lambda m: m != "regular_transaction")
+            LLFrame.op_setarrayitem(self, array, index, newvalue)
+        else:
+            # mutable 'setarrayitems' are always forbidden for now
+            self.check_stm_mode(lambda m: False)
+            assert 0
+
     def opstm_malloc(self, TYPE, flags):
         # non-GC must not occur in a regular transaction,
         # but can occur in inevitable mode or outside a transaction
@@ -118,6 +134,10 @@
         self.check_stm_mode(lambda m: m != "not_in_transaction")
         LLFrame.op_setfield(self, struct, fieldname, value)
 
+    def opstm_stm_setarrayitem(self, array, index, value):
+        self.check_stm_mode(lambda m: m != "not_in_transaction")
+        LLFrame.op_setarrayitem(self, array, index, value)
+
     def opstm_stm_begin_transaction(self):
         self.check_stm_mode(lambda m: m == "not_in_transaction")
         self.llinterpreter.stm_mode = "regular_transaction"
diff --git a/pypy/translator/stm/test/targetdemo.py b/pypy/translator/stm/test/targetdemo.py
--- a/pypy/translator/stm/test/targetdemo.py
+++ b/pypy/translator/stm/test/targetdemo.py
@@ -24,7 +24,7 @@
     seen[-1] = NUM_THREADS
     while node is not None:
         value = node.value
-        print value
+        #print value
         if not (0 <= value < LENGTH):
             print "node.value out of bounds:", value
             raise AssertionError
diff --git a/pypy/translator/stm/test/test_transform.py b/pypy/translator/stm/test/test_transform.py
--- a/pypy/translator/stm/test/test_transform.py
+++ b/pypy/translator/stm/test/test_transform.py
@@ -56,6 +56,17 @@
     res = eval_stm_graph(interp, graph, [p], stm_mode="regular_transaction")
     assert res == 42
 
+def test_setarrayitem():
+    A = lltype.GcArray(lltype.Signed)
+    p = lltype.malloc(A, 100, immortal=True)
+    p[42] = 666
+    def func(p):
+        p[42] = 676
+    interp, graph = get_interpreter(func, [p])
+    transform_graph(graph)
+    assert summary(graph) == {'stm_setarrayitem': 1}
+    eval_stm_graph(interp, graph, [p], stm_mode="regular_transaction")
+
 def test_unsupported_operation():
     def func(n):
         n += 1
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -129,6 +129,17 @@
             op1 = SpaceOperation('stm_setfield', op.args, op.result)
         newoperations.append(op1)
 
+    def stt_setarrayitem(self, newoperations, op):
+        ARRAY = op.args[0].concretetype.TO
+        if ARRAY._immutable_field():
+            op1 = op
+        elif ARRAY._gckind == 'raw':
+            turn_inevitable(newoperations, "setarrayitem-raw")
+            op1 = op
+        else:
+            op1 = SpaceOperation('stm_setarrayitem', op.args, op.result)
+        newoperations.append(op1)
+
     def stt_stm_transaction_boundary(self, newoperations, op):
         self.seen_transaction_boundary = True
         v_result = op.result


More information about the pypy-commit mailing list