[pypy-commit] pypy stm-gc: In-progress: hack at all files until targetdemo.py at least compiles.

arigo noreply at buildbot.pypy.org
Thu Feb 9 16:19:24 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r52301:c14db797e8a3
Date: 2012-02-09 16:17 +0100
http://bitbucket.org/pypy/pypy/changeset/c14db797e8a3/

Log:	In-progress: hack at all files until targetdemo.py at least
	compiles. Doesn't run at all so far.

diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -75,7 +75,7 @@
                      "markcompact": [("translation.gctransformer", "framework")],
                      "minimark": [("translation.gctransformer", "framework")],
                      "stmgc": [("translation.gctransformer", "framework"),
-                               ("translation.gcrootfinder", "none")],   # XXX
+                               ("translation.gcrootfinder", "stm")],
                      },
                   cmdline="--gc"),
     ChoiceOption("gctransformer", "GC transformer that is used - internal",
@@ -93,7 +93,7 @@
                default=IS_64_BITS, cmdline="--gcremovetypeptr"),
     ChoiceOption("gcrootfinder",
                  "Strategy for finding GC Roots (framework GCs only)",
-                 ["n/a", "shadowstack", "asmgcc", "none"],
+                 ["n/a", "shadowstack", "asmgcc", "stm"],
                  "shadowstack",
                  cmdline="--gcrootfinder",
                  requires={
diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py
--- a/pypy/objspace/flow/model.py
+++ b/pypy/objspace/flow/model.py
@@ -166,7 +166,7 @@
 
     def show(self):
         from pypy.translator.tool.graphpage import try_show
-        try_show(self)
+        return try_show(self)
 
 
 class Block(object):
@@ -241,7 +241,7 @@
 
     def show(self):
         from pypy.translator.tool.graphpage import try_show
-        try_show(self)
+        return try_show(self)
 
 
 class Variable(object):
diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -1,6 +1,7 @@
 import thread
 from pypy.rlib.objectmodel import specialize, we_are_translated, keepalive_until_here
 from pypy.rpython.lltypesystem import rffi, lltype, rclass
+from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.annlowlevel import (cast_base_ptr_to_instance,
                                       cast_instance_to_base_ptr,
                                       llhelper)
@@ -45,12 +46,12 @@
 
 def descriptor_init():
     if not we_are_translated(): _global_lock.acquire()
-    _rffi_stm.stm_descriptor_init()
+    llop.stm_descriptor_init(lltype.Void)
     if not we_are_translated(): _global_lock.release()
 
 def descriptor_done():
     if not we_are_translated(): _global_lock.acquire()
-    _rffi_stm.stm_descriptor_done()
+    llop.stm_descriptor_done(lltype.Void)
     if not we_are_translated(): _global_lock.release()
 
 def debug_get_state():
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
@@ -396,12 +396,11 @@
     # to keep them as operations until the genc stage)
 
     'stm_getfield':         LLOp(sideeffects=False, canrun=True),
-    'stm_setfield':         LLOp(),
     'stm_getarrayitem':     LLOp(sideeffects=False, canrun=True),
-    'stm_setarrayitem':     LLOp(),
     'stm_getinteriorfield': LLOp(sideeffects=False, canrun=True),
-    'stm_setinteriorfield': LLOp(),
     'stm_become_inevitable':LLOp(),
+    'stm_descriptor_init':  LLOp(),
+    'stm_descriptor_done':  LLOp(),
 
     # __________ address operations __________
 
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -77,8 +77,8 @@
             return self.get_size(obj)
         self._getsize_fn = _get_size
         #
-        for size, TYPE in PRIMITIVE_SIZES.items():
-            self.declare_reader(size, TYPE)
+        ##for size, TYPE in PRIMITIVE_SIZES.items():
+        ##    self.declare_reader(size, TYPE)
         self.declare_write_barrier()
 
     GETSIZE = lltype.Ptr(lltype.FuncType([llmemory.Address], lltype.Signed))
@@ -121,6 +121,9 @@
             tls.malloc_flags = 0
         return tls
 
+    def _setup_secondary_thread(self):
+        self.setup_thread(False)
+
     @staticmethod
     def reset_nursery(tls):
         """Clear and forget all locally allocated objects."""
@@ -222,23 +225,25 @@
 
     # ----------
 
-    def declare_reader(self, size, TYPE):
-        # Reading functions.  Defined here to avoid the extra burden of
-        # passing 'self' explicitly.
-        assert rffi.sizeof(TYPE) == size
-        PTYPE = rffi.CArrayPtr(TYPE)
-        stm_read_int = getattr(self.stm_operations, 'stm_read_int%d' % size)
-        #
-        @always_inline
-        def reader(obj, offset):
-            if self.header(obj).tid & GCFLAG_GLOBAL == 0:
-                adr = rffi.cast(PTYPE, obj + offset)
-                return adr[0]                      # local obj: read directly
-            else:
-                return stm_read_int(obj, offset)   # else: call a helper
-        setattr(self, 'read_int%d' % size, reader)
-        #
-        # the following logic was moved to et.c to avoid a double call
+##    TURNED OFF, maybe temporarily: the following logic is now entirely
+##    done by C macros and functions.
+##
+##    def declare_reader(self, size, TYPE):
+##        # Reading functions.  Defined here to avoid the extra burden of
+##        # passing 'self' explicitly.
+##        assert rffi.sizeof(TYPE) == size
+##        PTYPE = rffi.CArrayPtr(TYPE)
+##        stm_read_int = getattr(self.stm_operations, 'stm_read_int%d' % size)
+##        #
+##        @always_inline
+##        def reader(obj, offset):
+##            if self.header(obj).tid & GCFLAG_GLOBAL == 0:
+##                adr = rffi.cast(PTYPE, obj + offset)
+##                return adr[0]                      # local obj: read directly
+##            else:
+##                return stm_read_int(obj, offset)   # else: call a helper
+##        setattr(self, 'read_int%d' % size, reader)
+##        #
 ##        @dont_inline
 ##        def _read_word_global(obj, offset):
 ##            hdr = self.header(obj)
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -138,7 +138,6 @@
     def __init__(self, translator):
         from pypy.rpython.memory.gc.base import choose_gc_from_config
         from pypy.rpython.memory.gc.base import ARRAY_TYPEID_MAP
-        from pypy.rpython.memory.gc import inspector
 
         super(FrameworkGCTransformer, self).__init__(translator, inline=True)
         if hasattr(self, 'GC_PARAMS'):
@@ -251,7 +250,47 @@
         
         classdef = bk.getuniqueclassdef(GCClass)
         s_gc = annmodel.SomeInstance(classdef)
+
+        self._declare_functions(GCClass, getfn, s_gc, s_typeid16)
+
+        # thread support
+        if translator.config.translation.continuation:
+            root_walker.need_stacklet_support(self, getfn)
+        if translator.config.translation.thread:
+            root_walker.need_thread_support(self, getfn)
+
+        self.layoutbuilder.encode_type_shapes_now()
+
+        annhelper.finish()   # at this point, annotate all mix-level helpers
+        annhelper.backend_optimize()
+
+        self.collect_analyzer = CollectAnalyzer(self.translator)
+        self.collect_analyzer.analyze_all()
+
+        s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass)
+        r_gc = self.translator.rtyper.getrepr(s_gc)
+        self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
+        s_gc_data = self.translator.annotator.bookkeeper.valueoftype(
+            gctypelayout.GCData)
+        r_gc_data = self.translator.rtyper.getrepr(s_gc_data)
+        self.c_const_gcdata = rmodel.inputconst(r_gc_data, self.gcdata)
+        self.malloc_zero_filled = GCClass.malloc_zero_filled
+
+        HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR
+
+        size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header
+        vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field)
+        self.c_vtableinfo = rmodel.inputconst(lltype.Void, vtableinfo)
+        tig = self.layoutbuilder.type_info_group._as_ptr()
+        self.c_type_info_group = rmodel.inputconst(lltype.typeOf(tig), tig)
+        sko = llmemory.sizeof(gcdata.TYPE_INFO)
+        self.c_vtinfo_skip_offset = rmodel.inputconst(lltype.typeOf(sko), sko)
+
+
+    def _declare_functions(self, GCClass, getfn, s_gc, s_typeid16):
         s_gcref = annmodel.SomePtr(llmemory.GCREF)
+        gcdata = self.gcdata
+        translator = self.translator
 
         malloc_fixedsize_clear_meth = GCClass.malloc_fixedsize_clear.im_func
         self.malloc_fixedsize_clear_ptr = getfn(
@@ -412,6 +451,7 @@
         else:
             self.id_ptr = None
 
+        from pypy.rpython.memory.gc import inspector
         self.get_rpy_roots_ptr = getfn(inspector.get_rpy_roots,
                                        [s_gc],
                                        rgc.s_list_of_gcrefs(),
@@ -488,39 +528,6 @@
                                     [s_gc, annmodel.SomeInteger()],
                                     annmodel.SomeInteger())
 
-        # thread support
-        if translator.config.translation.continuation:
-            root_walker.need_stacklet_support(self, getfn)
-        if translator.config.translation.thread:
-            root_walker.need_thread_support(self, getfn)
-
-        self.layoutbuilder.encode_type_shapes_now()
-
-        annhelper.finish()   # at this point, annotate all mix-level helpers
-        annhelper.backend_optimize()
-
-        self.collect_analyzer = CollectAnalyzer(self.translator)
-        self.collect_analyzer.analyze_all()
-
-        s_gc = self.translator.annotator.bookkeeper.valueoftype(GCClass)
-        r_gc = self.translator.rtyper.getrepr(s_gc)
-        self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
-        s_gc_data = self.translator.annotator.bookkeeper.valueoftype(
-            gctypelayout.GCData)
-        r_gc_data = self.translator.rtyper.getrepr(s_gc_data)
-        self.c_const_gcdata = rmodel.inputconst(r_gc_data, self.gcdata)
-        self.malloc_zero_filled = GCClass.malloc_zero_filled
-
-        HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR
-
-        size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header
-        vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field)
-        self.c_vtableinfo = rmodel.inputconst(lltype.Void, vtableinfo)
-        tig = self.layoutbuilder.type_info_group._as_ptr()
-        self.c_type_info_group = rmodel.inputconst(lltype.typeOf(tig), tig)
-        sko = llmemory.sizeof(gcdata.TYPE_INFO)
-        self.c_vtinfo_skip_offset = rmodel.inputconst(lltype.typeOf(sko), sko)
-
     def build_root_walker(self):
         from pypy.rpython.memory.gctransform import shadowstack
         return shadowstack.ShadowStackRootWalker(self)
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
new file mode 100644
--- /dev/null
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -0,0 +1,38 @@
+from pypy.rpython.memory.gctransform.framework import FrameworkGCTransformer
+from pypy.rpython.memory.gctransform.framework import BaseRootWalker
+from pypy.annotation import model as annmodel
+
+
+class StmFrameworkGCTransformer(FrameworkGCTransformer):
+
+    def _declare_functions(self, GCClass, getfn, s_gc, *args):
+        super(StmFrameworkGCTransformer, self)._declare_functions(
+            GCClass, getfn, s_gc, *args)
+        self.setup_secondary_thread_ptr = getfn(
+            GCClass._setup_secondary_thread.im_func,
+            [s_gc], annmodel.s_None)
+        self.teardown_thread_ptr = getfn(
+            GCClass.teardown_thread.im_func,
+            [s_gc], annmodel.s_None)
+
+    def push_roots(self, hop, keep_current_args=False):
+        pass
+
+    def pop_roots(self, hop, livevars):
+        pass
+
+    def build_root_walker(self):
+        return StmStackRootWalker(self)
+
+    def gct_stm_descriptor_init(self, hop):
+        hop.genop("direct_call", [self.setup_secondary_thread_ptr,
+                                  self.c_const_gc])
+
+    def gct_stm_descriptor_done(self, hop):
+        hop.genop("direct_call", [self.teardown_thread_ptr, self.c_const_gc])
+
+
+class StmStackRootWalker(BaseRootWalker):
+
+    def walk_stack_roots(self, collect_stack_root):
+        raise NotImplementedError
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -6,7 +6,7 @@
      typeOf, Ptr, ContainerType, RttiStruct, \
      RuntimeTypeInfo, getRuntimeTypeInfo, top_container
 from pypy.rpython.memory.gctransform import \
-     refcounting, boehm, framework, asmgcroot
+     refcounting, boehm, framework, asmgcroot, stmframework
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
@@ -404,6 +404,9 @@
     def OP_GC_STACK_BOTTOM(self, funcgen, op):
         return 'pypy_asm_stack_bottom();'
 
+class StmFrameworkGcPolicy(FrameworkGcPolicy):
+    transformerclass = stmframework.StmFrameworkGCTransformer
+
 
 name_to_gcpolicy = {
     'boehm': BoehmGcPolicy,
@@ -411,6 +414,5 @@
     'none': NoneGcPolicy,
     'framework': FrameworkGcPolicy,
     'framework+asmgcroot': AsmGcRootFrameworkGcPolicy,
+    'framework+stm': StmFrameworkGcPolicy,
 }
-
-
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -199,8 +199,10 @@
     def get_gcpolicyclass(self):
         if self.gcpolicy is None:
             name = self.config.translation.gctransformer
-            if self.config.translation.gcrootfinder == "asmgcc":
-                name = "%s+asmgcroot" % (name,)
+            extended_name = "%s+%s" % (
+                name, self.config.translation.gcrootfinder)
+            if extended_name in gc.name_to_gcpolicy:
+                name = extended_name
             return gc.name_to_gcpolicy[name]
         return self.gcpolicy
 
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
@@ -4,7 +4,7 @@
 from pypy.translator.stm.llstm import size_of_voidp
 
 
-def _stm_generic_get(funcgen, op, expr, simple_struct=False):
+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, '')
@@ -12,117 +12,50 @@
     #
     assert T is not lltype.Void     # XXX
     fieldsize = rffi.sizeof(T)
-    if fieldsize >= size_of_voidp or T == lltype.SingleFloat:
-        assert 1      # xxx assert somehow that the field is aligned
-        if T == lltype.Float:
-            funcname = 'stm_read_double'
-        elif T == lltype.SingleFloat:
-            funcname = 'stm_read_float'
-        elif fieldsize == size_of_voidp:
-            funcname = 'stm_read_word'
-        elif fieldsize == 8:    # 32-bit only: read a 64-bit field
-            funcname = 'stm_read_doubleword'
-        else:
-            raise NotImplementedError(fieldsize)
-        return '%s = (%s)%s((long*)&%s);' % (
-            newvalue, cresulttypename, funcname, expr)
+    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:
-        assert fieldsize in (1, 2, 4)
-        if simple_struct:
-            # assume that the object is aligned, and any possible misalignment
-            # comes from the field offset, so that it can be resolved at
-            # compile-time (by using C macros)
-            STRUCT = funcgen.lltypemap(op.args[0]).TO
-            structdef = funcgen.db.gettypedefnode(STRUCT)
-            basename = funcgen.expr(op.args[0])
-            fieldname = op.args[1].value
-            trailing = ''
-            if T == lltype.Bool:
-                trailing = ' & 1'    # needed in this case, otherwise casting
-                                     # a several-bytes value to bool_t would
-                                     # take into account all the several bytes
-            return '%s = (%s)(stm_fx_read_partial(%s, offsetof(%s, %s))%s);'% (
-                newvalue, cresulttypename, basename,
-                cdecl(funcgen.db.gettype(STRUCT), ''),
-                structdef.c_struct_field_name(fieldname),
-                trailing)
-        #
-        else:
-            return '%s = (%s)stm_read_partial_%d(&%s);' % (
-                newvalue, cresulttypename, fieldsize, expr)
-
-def _stm_generic_set(funcgen, op, targetexpr, T):
-    basename = funcgen.expr(op.args[0])
-    newvalue = funcgen.expr(op.args[-1], special_case_void=False)
-    #
-    assert T is not lltype.Void     # XXX
-    fieldsize = rffi.sizeof(T)
-    if fieldsize >= size_of_voidp or T == lltype.SingleFloat:
-        assert 1      # xxx assert somehow that the field is aligned
-        if T == lltype.Float:
-            funcname = 'stm_write_double'
-            newtype = 'double'
-        elif T == lltype.SingleFloat:
-            funcname = 'stm_write_float'
-            newtype = 'float'
-        elif fieldsize == size_of_voidp:
-            funcname = 'stm_write_word'
-            newtype = 'long'
-        elif fieldsize == 8:    # 32-bit only: read a 64-bit field
-            funcname = 'stm_write_doubleword'
-            newtype = 'long long'
-        else:
-            raise NotImplementedError(fieldsize)
-        return '%s((long*)&%s, (%s)%s);' % (
-            funcname, targetexpr, newtype, newvalue)
-    else:
-        assert fieldsize in (1, 2, 4)
-        return ('stm_write_partial_%d(&%s, (unsigned long)%s);' % (
-            fieldsize, targetexpr, newvalue))
+        return '%s = RPY_STM_ARRAY(%s, %s, %s, %s);' % (
+            newvalue, cresulttypename, fieldsize,
+            expr_ptr, expr_field)
 
 
 def field_expr(funcgen, args):
     STRUCT = funcgen.lltypemap(args[0]).TO
     structdef = funcgen.db.gettypedefnode(STRUCT)
-    baseexpr_is_const = isinstance(args[0], Constant)
-    return structdef.ptr_access_expr(funcgen.expr(args[0]),
-                                     args[1].value,
-                                     baseexpr_is_const)
+    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):
-    expr = field_expr(funcgen, op.args)
-    return _stm_generic_get(funcgen, op, expr, simple_struct=True)
-
-def stm_setfield(funcgen, op):
-    expr = field_expr(funcgen, op.args)
-    T = op.args[2].concretetype
-    return _stm_generic_set(funcgen, op, expr, T)
+    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 arraydef.itemindex_access_expr(ptr, index)
+    return (None, ptr, arraydef.itemindex_access_expr(ptr, index))
 
 def stm_getarrayitem(funcgen, op):
-    expr = array_expr(funcgen, op.args)
-    return _stm_generic_get(funcgen, op, expr)
-
-def stm_setarrayitem(funcgen, op):
-    expr = array_expr(funcgen, op.args)
-    T = op.args[2].concretetype
-    return _stm_generic_set(funcgen, op, expr, T)
+    access_info = array_expr(funcgen, op.args)
+    return _stm_generic_get(funcgen, op, access_info)
 
 def stm_getinteriorfield(funcgen, op):
+    xxx
     expr = funcgen.interior_expr(op.args)
     return _stm_generic_get(funcgen, op, expr)
 
-def stm_setinteriorfield(funcgen, op):
-    expr = funcgen.interior_expr(op.args[:-1])
-    T = op.args[-1].concretetype
-    return _stm_generic_set(funcgen, op, expr, T)
-
 
 def stm_become_inevitable(funcgen, op):
     info = op.args[0].value
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -38,19 +38,13 @@
 /************************************************************/
 
 /* This is the same as the object header structure HDR
- * declared in stmgc.py, and the same two flags */
+ * declared in stmgc.py */
 
 typedef struct {
   long tid;
   long version;
 } orec_t;
 
-enum {
-  first_gcflag      = 1L << (PYPY_LONG_BIT / 2),
-  GCFLAG_GLOBAL     = first_gcflag << 0,
-  GCFLAG_WAS_COPIED = first_gcflag << 1
-};
-
 /************************************************************/
 
 #define IS_LOCKED(num)  ((num) < 0)
@@ -681,7 +675,6 @@
   return result;
 }
 
-#if 0
 void stm_try_inevitable(STM_CCHARP1(why))
 {
   /* when a transaction is inevitable, its start_time is equal to
@@ -689,7 +682,7 @@
      by another thread.  We set the lowest bit in global_timestamp
      to 1. */
   struct tx_descriptor *d = thread_descriptor;
-  if (!d->transaction_active)
+  if (is_main_thread(d))
     return;
 
 #ifdef RPY_STM_ASSERT
@@ -697,17 +690,16 @@
   if (PYPY_HAVE_DEBUG_PRINTS)
     {
       fprintf(PYPY_DEBUG_FILE, "%s%s\n", why,
-              (!d->transaction_active) ? " (inactive)" :
-              is_inevitable(d) ? " (already inevitable)" : "");
+              is_inevitable(d) ? "" : " <====");
     }
 #endif
 
-  if (is_inevitable_or_inactive(d))
+  if (is_inevitable(d))
     {
 #ifdef RPY_STM_ASSERT
       PYPY_DEBUG_STOP("stm-inevitable");
 #endif
-      return;  /* I am already inevitable, or not in a transaction at all */
+      return;  /* I am already inevitable */
     }
 
   while (1)
@@ -738,7 +730,6 @@
   PYPY_DEBUG_STOP("stm-inevitable");
 #endif
 }
-#endif
 
 void stm_abort_and_retry(void)
 {
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
@@ -22,11 +22,12 @@
 void stm_tldict_add(void *, void *);
 void stm_tlidct_enum(void(*)(void*, void*));
 
-long stm_read_word(void *, long);
+char      stm_read_int1(void *, long);
+short     stm_read_int2(void *, long);
+int       stm_read_int4(void *, long);
+long long stm_read_int8(void *, long);
 
 
-#if 0
-
 #ifdef RPY_STM_ASSERT
 #  define STM_CCHARP1(arg)    char* arg
 #  define STM_EXPLAIN1(info)  info
@@ -37,8 +38,6 @@
 
 
 void* stm_perform_transaction(void*(*)(void*, long), void*);
-long stm_read_word(long* addr);
-void stm_write_word(long* addr, long val);
 void stm_try_inevitable(STM_CCHARP1(why));
 void stm_abort_and_retry(void);
 long stm_debug_get_state(void);  /* -1: descriptor_init() was not called
@@ -48,33 +47,27 @@
 long stm_thread_id(void);  /* returns a unique thread id,
                               or 0 if descriptor_init() was not called */
 
-// XXX little-endian only!
-/* this macro is used if 'base' is a word-aligned pointer and 'offset'
-   is a compile-time constant */
-#define stm_fx_read_partial(base, offset)                               \
-       (stm_read_word(                                                  \
-           (long*)(((char*)(base)) + ((offset) & ~(sizeof(void*)-1))))  \
-        >> (8 * ((offset) & (sizeof(void*)-1))))
 
-unsigned char stm_read_partial_1(void *addr);
-unsigned short stm_read_partial_2(void *addr);
-void stm_write_partial_1(void *addr, unsigned char nval);
-void stm_write_partial_2(void *addr, unsigned short nval);
-#if PYPY_LONG_BIT == 64
-unsigned int stm_read_partial_4(void *addr);
-void stm_write_partial_4(void *addr, unsigned int nval);
-#endif
+/************************************************************/
 
-double stm_read_double(long *addr);
-void stm_write_double(long *addr, double val);
-float stm_read_float(long *addr);
-void stm_write_float(long *addr, float val);
-#if PYPY_LONG_BIT == 32
-long long stm_read_doubleword(long *addr);
-void stm_write_doubleword(long *addr, long long val);
-#endif
+/* These are the same two flags as defined in stmgc.py */
 
-#endif  /* 0 */
+enum {
+  first_gcflag      = 1L << (PYPY_LONG_BIT / 2),
+  GCFLAG_GLOBAL     = first_gcflag << 0,
+  GCFLAG_WAS_COPIED = first_gcflag << 1
+};
+
+
+#define RPY_STM_ARRAY(T, size, ptr, field)                      \
+    _RPY_STM(T, size, ptr, ((char*)&field)-((char*)ptr), field)
+
+#define RPY_STM_FIELD(T, size, STRUCT, ptr, field)              \
+    _RPY_STM(T, size, ptr, offsetof(STRUCT, field), ptr->field)
+
+#define _RPY_STM(T, size, ptr, offset, field)   \
+    (*(long*)ptr & GCFLAG_GLOBAL ? field :      \
+     (T)stm_read_int##size(ptr, offset))
 
 
 #endif  /* _ET_H */
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
@@ -141,11 +141,9 @@
         elif (STRUCT._immutable_field(op.args[1].value) or
               'stm_access_directly' in STRUCT._hints):
             op1 = op
-        elif STRUCT._gckind == 'raw':
+        else:
             turn_inevitable(newoperations, "setfield-raw")
             op1 = op
-        else:
-            op1 = SpaceOperation('stm_setfield', op.args, op.result)
         newoperations.append(op1)
 
     def stt_getarrayitem(self, newoperations, op):
@@ -171,11 +169,9 @@
             op1 = op
         #elif op.args[0] in self.access_directly:
         #    op1 = op
-        elif ARRAY._gckind == 'raw':
+        else:
             turn_inevitable(newoperations, "setarrayitem-raw")
             op1 = op
-        else:
-            op1 = SpaceOperation('stm_setarrayitem', op.args, op.result)
         newoperations.append(op1)
 
     def stt_getinteriorfield(self, newoperations, op):
diff --git a/pypy/translator/tool/graphpage.py b/pypy/translator/tool/graphpage.py
--- a/pypy/translator/tool/graphpage.py
+++ b/pypy/translator/tool/graphpage.py
@@ -439,7 +439,7 @@
             for y in gc.get_referrers(x):
                 if isinstance(y, FunctionGraph):
                     y.show()
-                    return
+                    return y
                 elif isinstance(y, Link):
                     block = y.prevblock
                     if block not in seen:


More information about the pypy-commit mailing list