[pypy-commit] pypy stm: (antocuni, arigo)

arigo noreply at buildbot.pypy.org
Mon Jan 16 15:43:48 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r51344:7dc69a93d5be
Date: 2012-01-16 15:43 +0100
http://bitbucket.org/pypy/pypy/changeset/7dc69a93d5be/

Log:	(antocuni, arigo)

	Fix the llstminterp. Wondering a bit what is its purpose...

diff --git a/pypy/translator/stm/TODO.txt b/pypy/translator/stm/TODO.txt
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/TODO.txt
@@ -0,0 +1,9 @@
+
+
+* turn calls to stm_read_word() to:
+    if (d) x = stm_read_word(a); else x = *a;
+
+  this way, gcc will optimize:
+    if (d) x = stm_read_word(a); else x = *a;
+    if (d) y = stm_read_word(b); else y = *b;
+  to check !d only once if it is null
diff --git a/pypy/translator/stm/llstm.py b/pypy/translator/stm/llstm.py
--- a/pypy/translator/stm/llstm.py
+++ b/pypy/translator/stm/llstm.py
@@ -92,9 +92,13 @@
     "NOT_RPYTHON"
     raise NotImplementedError("sorry")
 
-##def stm_setarrayitem(arrayptr, index, value):
-##    "NOT_RPYTHON"
-##    raise NotImplementedError("sorry")
+def stm_setarrayitem(arrayptr, index, value):
+    "NOT_RPYTHON"
+    raise NotImplementedError("sorry")
+
+def stm_become_inevitable(why):
+    "NOT_RPYTHON"
+    raise NotImplementedError("sorry")
 
 # ____________________________________________________________
 
@@ -146,13 +150,28 @@
                          resulttype = hop.r_result)
 
 
-##class ExtEntry(ExtRegistryEntry):
-##    _about_ = (begin_transaction, commit_transaction,
-##               begin_inevitable_transaction, transaction_boundary)
+class ExtEntry(ExtRegistryEntry):
+    _about_ = stm_setarrayitem
 
-##    def compute_result_annotation(self):
-##        return None
+    def compute_result_annotation(self, s_arrayptr, s_index, s_newvalue):
+        return None
 
-##    def specialize_call(self, hop):
-##        hop.exception_cannot_occur()
-##        hop.genop("stm_" + self.instance.__name__, [])
+    def specialize_call(self, hop):
+        r_arrayptr = hop.args_r[0]
+        v_arrayptr, v_index, v_newvalue = hop.inputargs(r_arrayptr,
+                                                        lltype.Signed,
+                                                        hop.args_r[2])
+        hop.exception_cannot_occur()
+        hop.genop('stm_setarrayitem', [v_arrayptr, v_index, v_newvalue])
+
+
+class ExtEntry(ExtRegistryEntry):
+    _about_ = stm_become_inevitable
+
+    def compute_result_annotation(self, s_why):
+        return None
+
+    def specialize_call(self, hop):
+        hop.exception_cannot_occur()
+        c_why = hop.inputconst(lltype.Signed, 42)    # XXX
+        hop.genop("stm_become_inevitable", [c_why])
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
@@ -146,44 +146,38 @@
             raise ForbiddenInstructionInSTMMode(stm_mode, self.graph)
 
     def opstm_stm_getfield(self, struct, fieldname):
-        self.check_stm_mode(lambda m: m != "not_in_transaction")
         return LLFrame.op_getfield(self, struct, fieldname)
 
     def opstm_stm_setfield(self, struct, fieldname, value):
-        self.check_stm_mode(lambda m: m != "not_in_transaction")
         LLFrame.op_setfield(self, struct, fieldname, value)
 
     def opstm_stm_getarrayitem(self, array, index):
-        self.check_stm_mode(lambda m: m != "not_in_transaction")
         return LLFrame.op_getarrayitem(self, array, index)
 
     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_getinteriorfield(self, obj, *offsets):
-        self.check_stm_mode(lambda m: m != "not_in_transaction")
         return LLFrame.op_getinteriorfield(self, obj, *offsets)
 
     def opstm_stm_setinteriorfield(self, obj, *fieldnamesval):
-        self.check_stm_mode(lambda m: m != "not_in_transaction")
         LLFrame.op_setinteriorfield(self, obj, *fieldnamesval)
 
-    def opstm_stm_begin_transaction(self):
-        self.check_stm_mode(lambda m: m == "not_in_transaction")
-        self.llinterpreter.stm_mode = "regular_transaction"
-        self.llinterpreter.last_transaction_started_in_frame = self
+##    def opstm_stm_begin_transaction(self):
+##        self.check_stm_mode(lambda m: m == "not_in_transaction")
+##        self.llinterpreter.stm_mode = "regular_transaction"
+##        self.llinterpreter.last_transaction_started_in_frame = self
 
-    def opstm_stm_commit_transaction(self):
-        self.check_stm_mode(lambda m: m != "not_in_transaction")
-        self.llinterpreter.stm_mode = "not_in_transaction"
+##    def opstm_stm_commit_transaction(self):
+##        self.check_stm_mode(lambda m: m != "not_in_transaction")
+##        self.llinterpreter.stm_mode = "not_in_transaction"
 
-    def opstm_stm_transaction_boundary(self):
-        self.check_stm_mode(lambda m: m != "not_in_transaction")
-        self.llinterpreter.stm_mode = "regular_transaction"
-        self.llinterpreter.last_transaction_started_in_frame = self
+##    def opstm_stm_transaction_boundary(self):
+##        self.check_stm_mode(lambda m: m != "not_in_transaction")
+##        self.llinterpreter.stm_mode = "regular_transaction"
+##        self.llinterpreter.last_transaction_started_in_frame = self
 
-    def opstm_stm_try_inevitable(self, why):
+    def opstm_stm_become_inevitable(self, why):
         self.check_stm_mode(lambda m: m != "not_in_transaction")
         self.llinterpreter.stm_mode = "inevitable_transaction"
         print why
diff --git a/pypy/translator/stm/test/test_llstminterp.py b/pypy/translator/stm/test/test_llstminterp.py
--- a/pypy/translator/stm/test/test_llstminterp.py
+++ b/pypy/translator/stm/test/test_llstminterp.py
@@ -4,7 +4,7 @@
 from pypy.translator.stm.llstminterp import eval_stm_graph
 from pypy.translator.stm.llstminterp import ForbiddenInstructionInSTMMode
 from pypy.translator.stm.llstminterp import ReturnWithTransactionActive
-from pypy.translator.stm import rstm
+from pypy.translator.stm import llstm
 
 ALL_STM_MODES = ["not_in_transaction",
                  "regular_transaction",
@@ -14,55 +14,59 @@
     def func(n):
         return (n+1) * (n+2)
     interp, graph = get_interpreter(func, [5])
-    res = eval_stm_graph(interp, graph, [5])
+    res = eval_stm_graph(interp, graph, [5],
+                         stm_mode="not_in_transaction",
+                         final_stm_mode="not_in_transaction")
     assert res == 42
 
 def test_forbidden():
     S = lltype.GcStruct('S', ('x', lltype.Signed))
     p = lltype.malloc(S, immortal=True)
     p.x = 42
-    def func(p):
+    #
+    def funcget(p):
         return p.x
-    interp, graph = get_interpreter(func, [p])
+    interp, graph = get_interpreter(funcget, [p])
+    py.test.raises(ForbiddenInstructionInSTMMode,
+                   eval_stm_graph, interp, graph, [p],
+                   stm_mode="regular_transaction")
+    #
+    def funcset(p):
+        p.x = 43
+    interp, graph = get_interpreter(funcset, [p])
     py.test.raises(ForbiddenInstructionInSTMMode,
                    eval_stm_graph, interp, graph, [p],
                    stm_mode="regular_transaction")
 
-def test_stm_getfield():
-    S = lltype.GcStruct('S', ('x', lltype.Signed))
+def test_stm_getfield_stm_setfield():
+    S = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed))
     p = lltype.malloc(S, immortal=True)
     p.x = 42
     def func(p):
-        return rstm.stm_getfield(p, 'x')
+        llstm.stm_setfield(p, 'y', 43)
+        return llstm.stm_getfield(p, 'x')
     interp, graph = get_interpreter(func, [p])
-    # forbidden in "not_in_transaction" mode
-    py.test.raises(ForbiddenInstructionInSTMMode,
-                   eval_stm_graph, interp, graph, [p],
-                   stm_mode="not_in_transaction")
-    # works in "regular_transaction" mode
-    res = eval_stm_graph(interp, graph, [p], stm_mode="regular_transaction")
-    assert res == 42
-    # works in "inevitable_transaction" mode
-    res = eval_stm_graph(interp, graph, [p], stm_mode="inevitable_transaction")
-    assert res == 42
+    # works in all modes
+    for mode in ALL_STM_MODES:
+        p.y = 0
+        res = eval_stm_graph(interp, graph, [p], stm_mode=mode)
+        assert res == 42
+        assert p.y == 43
 
-def test_stm_getarrayitem():
+def test_stm_getarrayitem_stm_setarrayitem():
     A = lltype.GcArray(lltype.Signed)
     p = lltype.malloc(A, 5, immortal=True)
     p[3] = 42
     def func(p):
-        return rstm.stm_getarrayitem(p, 3)
+        llstm.stm_setarrayitem(p, 2, 43)
+        return llstm.stm_getarrayitem(p, 3)
     interp, graph = get_interpreter(func, [p])
-    # forbidden in "not_in_transaction" mode
-    py.test.raises(ForbiddenInstructionInSTMMode,
-                   eval_stm_graph, interp, graph, [p],
-                   stm_mode="not_in_transaction")
-    # works in "regular_transaction" mode
-    res = eval_stm_graph(interp, graph, [p], stm_mode="regular_transaction")
-    assert res == 42
-    # works in "inevitable_transaction" mode
-    res = eval_stm_graph(interp, graph, [p], stm_mode="inevitable_transaction")
-    assert res == 42
+    # works in all modes
+    for mode in ALL_STM_MODES:
+        p[2] = 0
+        res = eval_stm_graph(interp, graph, [p], stm_mode=mode)
+        assert res == 42
+        assert p[2] == 43
 
 def test_getfield_immutable():
     S = lltype.GcStruct('S', ('x', lltype.Signed), hints = {'immutable': True})
@@ -76,66 +80,13 @@
         res = eval_stm_graph(interp, graph, [p], stm_mode=mode)
         assert res == 42
 
-def test_begin_commit_transaction():
-    S = lltype.GcStruct('S', ('x', lltype.Signed))
-    p = lltype.malloc(S, immortal=True)
-    p.x = 42
-    def func(p):
-        rstm.begin_transaction()
-        res = rstm.stm_getfield(p, 'x')
-        rstm.commit_transaction()
-        return res
-    interp, graph = get_interpreter(func, [p])
-    res = eval_stm_graph(interp, graph, [p])
-    assert res == 42
-
-def test_call_and_return_with_regular_transaction():
-    def g():
-        pass
-    g._dont_inline_ = True
+def test_become_inevitable():
     def func():
-        rstm.begin_transaction()
-        g()
-        rstm.commit_transaction()
+        llstm.stm_become_inevitable("foobar!")
     interp, graph = get_interpreter(func, [])
-    eval_stm_graph(interp, graph, [])
-
-def test_cannot_return_with_regular_transaction():
-    def g():
-        rstm.begin_transaction()
-    g._dont_inline_ = True
-    def func():
-        g()
-        rstm.commit_transaction()
-    interp, graph = get_interpreter(func, [])
-    py.test.raises(ReturnWithTransactionActive,
-                   eval_stm_graph, interp, graph, [])
-
-def test_cannot_raise_with_regular_transaction():
-    def g():
-        rstm.begin_transaction()
-        raise ValueError
-    g._dont_inline_ = True
-    def func():
-        try:
-            g()
-        except ValueError:
-            pass
-        rstm.commit_transaction()
-    interp, graph = get_interpreter(func, [])
-    py.test.raises(ReturnWithTransactionActive,
-                   eval_stm_graph, interp, graph, [])
-
-def test_transaction_boundary():
-    def func(n):
-        if n > 5:
-            rstm.transaction_boundary()
-    interp, graph = get_interpreter(func, [2])
-    eval_stm_graph(interp, graph, [10],
-                   stm_mode="regular_transaction",
-                   final_stm_mode="inevitable_transaction",
-                   automatic_promotion=True)
-    eval_stm_graph(interp, graph, [1],
-                   stm_mode="regular_transaction",
-                   final_stm_mode="regular_transaction",
-                   automatic_promotion=True)
+    py.test.raises(ForbiddenInstructionInSTMMode,
+                   eval_stm_graph, interp, graph, [],
+                   stm_mode="not_in_transaction")
+    eval_stm_graph(interp, graph, [], stm_mode="regular_transaction",
+                   final_stm_mode="inevitable_transaction")
+    eval_stm_graph(interp, graph, [], stm_mode="inevitable_transaction")


More information about the pypy-commit mailing list