[pypy-commit] pypy stm: Test that the stm mode falls back to "inevitable_transaction" when

arigo noreply at buildbot.pypy.org
Fri Oct 28 18:30:59 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r48578:3126dbb549ce
Date: 2011-10-28 18:30 +0200
http://bitbucket.org/pypy/pypy/changeset/3126dbb549ce/

Log:	Test that the stm mode falls back to "inevitable_transaction" when
	we see an unsupported operation like raw_malloc.

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
@@ -51,16 +51,18 @@
     def getoperationhandler(self, opname):
         ophandler = getattr(self, 'opstm_' + opname, None)
         if ophandler is None:
-            self._validate_stmoperation_handler(opname)
             ophandler = LLFrame.getoperationhandler(self, opname)
-            setattr(self, 'opstm_' + opname, ophandler)
+            if op_in_set(opname, ALWAYS_ALLOW_OPERATIONS):
+                # always allow this, so store it back on self.__class__
+                setattr(self.__class__, 'opstm_' + opname,
+                        staticmethod(ophandler))
+            else:
+                # only allow this if we're not in the "regular_transaction"
+                # mode; check every time, so don't store it on self.__class__
+                if self.llinterpreter.stm_mode == "regular_transaction":
+                    raise ForbiddenInstructionInSTMMode(opname, self.graph)
         return ophandler
 
-    def _validate_stmoperation_handler(self, opname):
-        if op_in_set(opname, ALWAYS_ALLOW_OPERATIONS):
-            return
-        raise ForbiddenInstructionInSTMMode(opname, self.graph)
-
     # ---------- operations that are sometimes safe ----------
 
     def opstm_getfield(self, struct, fieldname):
@@ -103,3 +105,7 @@
         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):
+        self.check_stm_mode(lambda m: m != "not_in_transaction")
+        self.llinterpreter.stm_mode = "inevitable_transaction"
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
@@ -1,4 +1,4 @@
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.test.test_llinterp import get_interpreter
 from pypy.objspace.flow.model import summary
 from pypy.translator.stm.llstminterp import eval_stm_graph
@@ -6,8 +6,21 @@
 from pypy.translator.stm import rstm
 from pypy.translator.c.test.test_standalone import StandaloneTests
 from pypy.rlib.debug import debug_print
+from pypy.conftest import option
 
 
+def eval_stm_func(func, arguments, stm_mode="regular_transaction",
+                  final_stm_mode="regular_transaction"):
+    interp, graph = get_interpreter(func, arguments)
+    transform_graph(graph)
+    #if option.view:
+    #    graph.show()
+    return eval_stm_graph(interp, graph, arguments, stm_mode=stm_mode,
+                          final_stm_mode=final_stm_mode,
+                          automatic_promotion=True)
+
+# ____________________________________________________________
+
 def test_simple():
     S = lltype.GcStruct('S', ('x', lltype.Signed))
     p = lltype.malloc(S, immortal=True)
@@ -32,6 +45,19 @@
     res = eval_stm_graph(interp, graph, [p], stm_mode="regular_transaction")
     assert res == 42
 
+def test_unsupported_operation():
+    def func(n):
+        n += 1
+        if n > 5:
+            p = llmemory.raw_malloc(llmemory.sizeof(lltype.Signed))
+            llmemory.raw_free(p)
+        return n
+    res = eval_stm_func(func, [3], final_stm_mode="regular_transaction")
+    assert res == 4
+    res = eval_stm_func(func, [13], final_stm_mode="inevitable_transaction")
+    assert res == 14
+
+# ____________________________________________________________
 
 class TestTransformSingleThread(StandaloneTests):
 
@@ -91,3 +117,12 @@
             return 0
         t, cbuilder = self.compile(simplefunc)
         cbuilder.cmdexec('')
+
+    def test_transaction_boundary_2(self):
+        def simplefunc(argv):
+            rstm.transaction_boundary()
+            rstm.transaction_boundary()
+            rstm.transaction_boundary()
+            return 0
+        t, cbuilder = self.compile(simplefunc)
+        cbuilder.cmdexec('')
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
@@ -5,9 +5,11 @@
 
 
 ALWAYS_ALLOW_OPERATIONS = set([
-    'int_*', 'same_as', 'cast_*',
+    'int_*', 'uint_*', 'llong_*', 'ullong_*',
+    'same_as', 'cast_*',
     'direct_call',
-    'debug_print',
+    'debug_print', 'debug_assert',
+    'malloc', 'malloc_varsize',
     ])
 
 def op_in_set(opname, set):


More information about the pypy-commit mailing list