[pypy-commit] pypy stm-thread-2: In-progress: the first goal will be to have a working Boehm translation.

arigo noreply at buildbot.pypy.org
Wed Sep 5 18:57:12 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread-2
Changeset: r57156:1787404cd286
Date: 2012-09-05 18:56 +0200
http://bitbucket.org/pypy/pypy/changeset/1787404cd286/

Log:	In-progress: the first goal will be to have a working Boehm
	translation.

diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -107,8 +107,8 @@
                default=False, cmdline="--thread"),
     BoolOption("stm", "enable use of Software Transactional Memory",
                default=False, cmdline="--stm",
-               requires=[("translation.gc", "stmgc"),
-                         ("translation.thread", True),
+               suggests=[("translation.gc", "stmgc")],   # Boehm works too
+               requires=[("translation.thread", True),
                          ("translation.continuation", False),  # XXX for now
                          ]),
     BoolOption("sandbox", "Produce a fully-sandboxed executable",
diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -1,79 +1,18 @@
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.translator.c.support import cdecl, c_string_constant
+from pypy.translator.c.support import c_string_constant
 
 
-def _stm_generic_get(funcgen, op, (expr_type, expr_ptr, expr_field)):
-    T = funcgen.lltypemap(op.result)
-    resulttypename = funcgen.db.gettype(T)
-    cresulttypename = cdecl(resulttypename, '')
-    newvalue = funcgen.expr(op.result, special_case_void=False)
-    #
-    assert T is not lltype.Void
-    fieldsize = rffi.sizeof(T)
-    assert fieldsize in (1, 2, 4, 8)
-    if T == lltype.Float:
-        assert fieldsize == 8
-        fieldsize = '8f'
-    elif T == lltype.SingleFloat:
-        assert fieldsize == 4
-        fieldsize = '4f'
-    if expr_type is not None:     # optimization for the common case
-        return '%s = RPY_STM_FIELD(%s, %s, %s, %s, %s);' % (
-            newvalue, cresulttypename, fieldsize,
-            expr_type, expr_ptr, expr_field)
-    else:
-        return '%s = RPY_STM_ARRAY(%s, %s, %s, %s);' % (
-            newvalue, cresulttypename, fieldsize,
-            expr_ptr, expr_field)
+def stm_barrier(funcgen, op):
+    level = op.args[0].value
+    assert type(level) is str
+    arg = funcgen.expr(op.args[1])
+    result = funcgen.expr(op.result)
+    return '%s = STM_BARRIER_%s(%s);' % (result, level, arg)
 
-
-def field_expr(funcgen, args):
-    STRUCT = funcgen.lltypemap(args[0]).TO
-    structdef = funcgen.db.gettypedefnode(STRUCT)
-    fldname = structdef.c_struct_field_name(args[1].value)
-    ptr = funcgen.expr(args[0])
-    return ('%s %s' % (structdef.typetag, structdef.name), ptr, fldname)
-
-def stm_getfield(funcgen, op):
-    access_info = field_expr(funcgen, op.args)
-    return _stm_generic_get(funcgen, op, access_info)
-
-def array_expr(funcgen, args):
-    ARRAY = funcgen.lltypemap(args[0]).TO
-    ptr = funcgen.expr(args[0])
-    index = funcgen.expr(args[1])
-    arraydef = funcgen.db.gettypedefnode(ARRAY)
-    return (None, ptr, arraydef.itemindex_access_expr(ptr, index))
-
-def stm_getarrayitem(funcgen, op):
-    access_info = array_expr(funcgen, op.args)
-    return _stm_generic_get(funcgen, op, access_info)
-
-def stm_getinteriorfield(funcgen, op):
-    ptr = funcgen.expr(op.args[0])
-    expr = funcgen.interior_expr(op.args)
-    access_info = (None, ptr, expr)
-    return _stm_generic_get(funcgen, op, access_info)
-
-def _gc_load_store_expr(funcgen, op, v_value):
-    ptr = funcgen.expr(op.args[0])
-    ofs = funcgen.expr(op.args[1])
-    T = funcgen.lltypemap(v_value)
-    resulttypename = funcgen.db.gettype(T)
-    cresulttypename_ptr = cdecl(resulttypename, ' *')
-    expr = '(*(%s)(((char *)(%s)) + (%s)))' % (cresulttypename_ptr, ptr, ofs)
-    return expr
-
-def stm_gc_load(funcgen, op):
-    ptr = funcgen.expr(op.args[0])
-    expr = _gc_load_store_expr(funcgen, op, op.result)
-    access_info = (None, ptr, expr)
-    return _stm_generic_get(funcgen, op, access_info)
-
-def stm_gc_store(funcgen, op):
-    targetexpr = _gc_load_store_expr(funcgen, op, op.args[-1])
-    return funcgen.generic_set(op, targetexpr)
-
+def stm_ptr_eq(funcgen, op):
+    arg0 = funcgen.expr(op.args[0])
+    arg1 = funcgen.expr(op.args[1])
+    result = funcgen.expr(op.result)
+    return '%s = STM_PTR_EQ(%s, %s);' % (result, arg0, arg1)
 
 def stm_become_inevitable(funcgen, op):
     try:
@@ -81,9 +20,10 @@
     except IndexError:
         info = "rstm.become_inevitable"    # cannot insert it in 'llop'
     string_literal = c_string_constant(info)
-    return 'stm_try_inevitable(STM_EXPLAIN1(%s));' % (string_literal,)
+    return 'stm_try_inevitable(%s);' % (string_literal,)
 
 def stm_jit_invoke_code(funcgen, op):
+    XXX
     return funcgen.OP_DIRECT_CALL(op)
 
 
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -37,30 +37,34 @@
 
 #define STM_BARRIER_P2R(P)                                              \
     (__builtin_expect((((gcptr)(P))->h_tid & GCFLAG_GLOBAL) == 0, 1) ?  \
-     (P) : (typeof(P))_DirectReadBarrier((gcptr)(P)))
+     (P) : (typeof(P))stm_DirectReadBarrier((gcptr)(P)))
 
 #define STM_BARRIER_G2R(G)                                          \
     (assert(((gcptr)(G))->h_tid & GCFLAG_GLOBAL),                   \
-     (typeof(G))_DirectReadBarrier((gcptr)(G)))
+     (typeof(G))stm_DirectReadBarrier((gcptr)(G)))
 
 #define STM_BARRIER_O2R(O)                                              \
     (__builtin_expect((((gcptr)(O))->h_tid & GCFLAG_POSSIBLY_OUTDATED) == 0, \
                       1) ?                                              \
-     (O) : (typeof(O))_RepeatReadBarrier((gcptr)(O)))
+     (O) : (typeof(O))stm_RepeatReadBarrier((gcptr)(O)))
 
 /*#define STM_READ_BARRIER_P_FROM_R(P, R_container, offset)             \
     (__builtin_expect((((gcptr)(P))->h_tid & GCFLAG_GLOBAL) == 0, 1) ?  \
-     (P) : (typeof(P))_DirectReadBarrierFromR((gcptr)(P),               \
+     (P) : (typeof(P))stm_DirectReadBarrierFromR((gcptr)(P),            \
                                               (gcptr)(R_container),     \
                                               offset))*/
 
 #define STM_BARRIER_P2W(P)                                                  \
     (__builtin_expect((((gcptr)(P))->h_tid & GCFLAG_NOT_WRITTEN) == 0, 1) ? \
-     (P) : (typeof(P))_WriteBarrier((gcptr)(P)))
+     (P) : (typeof(P))stm_WriteBarrier((gcptr)(P)))
 
 #define STM_BARRIER_R2W(R)                                                  \
     (__builtin_expect((((gcptr)(R))->h_tid & GCFLAG_NOT_WRITTEN) == 0, 1) ? \
-     (R) : (typeof(R))_WriteBarrierFromReady((gcptr)(R)))
+     (R) : (typeof(R))stm_WriteBarrierFromReady((gcptr)(R)))
+
+#define STM_PTR_EQ(P1, P2)                      \
+    stm_PtrEq((gcptr)(P1), (gcptr)(P2))
+
 
 void BeginTransaction(jmp_buf *);
 void BeginInevitableTransaction(void);
@@ -73,13 +77,13 @@
 int _FakeReach(gcptr P);
 
 //gcptr Allocate(size_t size, int gctid);
-_Bool PtrEq(gcptr P1, gcptr P2);
+_Bool stm_PtrEq(gcptr P1, gcptr P2);
 
-gcptr _DirectReadBarrier(gcptr);
-gcptr _DirectReadBarrierFromR(gcptr, gcptr, size_t);
-gcptr _RepeatReadBarrier(gcptr);
-gcptr _WriteBarrier(gcptr);
-gcptr _WriteBarrierFromReady(gcptr);
+gcptr stm_DirectReadBarrier(gcptr);
+gcptr stm_DirectReadBarrierFromR(gcptr, gcptr, size_t);
+gcptr stm_RepeatReadBarrier(gcptr);
+gcptr stm_WriteBarrier(gcptr);
+gcptr stm_WriteBarrierFromReady(gcptr);
 //gcptr _NonTransactionalReadBarrier(gcptr);
 
 
diff --git a/pypy/translator/stm/test/support.py b/pypy/translator/stm/test/support.py
--- a/pypy/translator/stm/test/support.py
+++ b/pypy/translator/stm/test/support.py
@@ -9,8 +9,8 @@
     def compile(self, entry_point, **kwds):
         from pypy.config.pypyoption import get_pypy_config
         self.config = get_pypy_config(translating=True)
+        self.config.translation.gc = self.gc
         self.config.translation.stm = True
-        self.config.translation.gc = self.gc
         #
         # Prevent the RaiseAnalyzer from just emitting "WARNING: Unknown
         # operation".  We want instead it to crash.
@@ -22,3 +22,7 @@
         finally:
             RaiseAnalyzer.fail_on_unknown_operation = False
         return res
+
+
+class BoehmCompiledSTMTests(CompiledSTMTests):
+    gc = "boehm"
diff --git a/pypy/translator/stm/test/test_ztranslated.py b/pypy/translator/stm/test/test_ztranslated.py
--- a/pypy/translator/stm/test/test_ztranslated.py
+++ b/pypy/translator/stm/test/test_ztranslated.py
@@ -1,9 +1,18 @@
 import py
 from pypy.rlib import rstm, rgc
+from pypy.translator.stm.test.support import BoehmCompiledSTMTests
 from pypy.translator.stm.test.support import CompiledSTMTests
 from pypy.translator.stm.test import targetdemo2
 
 
+class TestBoehmSTMTranslated(BoehmCompiledSTMTests):
+    def test_targetdemo(self):
+        t, cbuilder = self.compile(targetdemo2.entry_point)
+        data, dataerr = cbuilder.cmdexec('4 5000', err=True,
+                                         env={'PYPY_GC_DEBUG': '1'})
+        assert 'check ok!' in data
+
+
 class TestSTMTranslated(CompiledSTMTests):
 
     def test_targetdemo(self):


More information about the pypy-commit mailing list