[pypy-commit] pypy stmgc-c7: We don't really need rstm.allocate_preexisting(), so introduce and use

arigo noreply at buildbot.pypy.org
Thu Feb 19 00:40:25 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r75988:a0212f508821
Date: 2015-02-18 20:13 +0100
http://bitbucket.org/pypy/pypy/changeset/a0212f508821/

Log:	We don't really need rstm.allocate_preexisting(), so introduce and
	use instead rstm.allocate_nonmovable(). There is an annoying rare
	bug that I've no clue about but could be related to
	allocate_preexisting().

diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -862,10 +862,7 @@
             # produce a header that takes a STM_GUARD_FAILURE and jumps
             # to the target written there
             assert IS_X86_64
-            p = lltype.malloc(STM_GUARD_FAILURE)
-            # xxx don't really need allocate_preexisting().  we only need
-            # some non-movable object
-            p = rstm.allocate_preexisting(p)
+            p = rstm.allocate_nonmovable(STM_GUARD_FAILURE)
             self.current_clt._stm_redirection = lltype.cast_opaque_ptr(
                 llmemory.GCREF, p)
             addr = rffi.cast(lltype.Signed, p)
@@ -1981,14 +1978,11 @@
 
     def _generate_quick_failure_stm(self, fail_descr, target, guardtok):
         assert IS_X86_64
-        p = lltype.malloc(STM_GUARD_FAILURE)
+        # we could maybe store the data directly on the faildescr.
+        p = rstm.allocate_nonmovable(STM_GUARD_FAILURE)
         p.fail_descr = fail_descr
         p.jump_target = target
         p.gcmap = guardtok.gcmap
-        # unclear if we really need a preexisting object here, or if we
-        # just need a regular but non-moving pointer.  In the latter case
-        # we could maybe store the data directly on the faildescr.
-        p = rstm.allocate_preexisting(p)
         guardtok.faildescr._x86_stm_guard_failure = p
         addr = rffi.cast(lltype.Signed, p)
         addr += llmemory.offsetof(STM_GUARD_FAILURE, 'jump_target')
diff --git a/rpython/memory/gctransform/stmframework.py b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -201,6 +201,23 @@
         self.default(hop)
         self.pop_roots(hop, livevars)
 
+    def gct_stm_malloc_nonmovable(self, hop):
+        op = hop.spaceop
+        PTRTYPE = op.result.concretetype
+        TYPE = PTRTYPE.TO
+        type_id = self.get_type_id(TYPE)
+
+        c_type_id = rmodel.inputconst(TYPE_ID, type_id)
+        info = self.layoutbuilder.get_info(type_id)
+        c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
+
+        livevars = self.push_roots(hop)
+        v_result = hop.genop("stm_allocate_nonmovable",
+                             [c_size, c_type_id],
+                             resulttype=llmemory.GCREF)
+        self.pop_roots(hop, livevars)
+        hop.genop("cast_opaque_ptr", [v_result], resultvar=op.result)
+
     # sync with lloperation.py
     gct_stm_become_inevitable                       = _gct_with_roots_pushed
     gct_stm_stop_all_other_threads                  = _gct_with_roots_pushed
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -173,10 +173,15 @@
     the current transaction can then proceed to change normally.  This
     initial state must not contain GC pointers to any other uncommitted
     object."""
+    # XXX is this buggy?
     TP = lltype.typeOf(p)
     size = llmemory.sizeof(TP.TO)
     return llop.stm_allocate_preexisting(TP, size, p)
 
+ at specialize.ll()
+def allocate_nonmovable(GCTYPE):
+    return llop.stm_malloc_nonmovable(lltype.Ptr(GCTYPE))
+
 # ____________________________________________________________
 
 class _Entry(ExtRegistryEntry):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -419,6 +419,8 @@
     'stm_allocate_finalizer': LLOp(sideeffects=False, canmallocgc=True),
     'stm_allocate_f_light':   LLOp(sideeffects=False, canmallocgc=True),
     'stm_allocate_preexisting':LLOp(sideeffects=False, canmallocgc=True),
+    'stm_allocate_nonmovable':LLOp(sideeffects=False, canmallocgc=True),
+    'stm_malloc_nonmovable':  LLOp(sideeffects=False, canmallocgc=True),
     'stm_get_from_obj':       LLOp(sideeffects=False),
     'stm_get_from_obj_const': LLOp(canfold=True),
     'stm_set_into_obj':       LLOp(),
diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -117,6 +117,15 @@
             ' _stm_real_address((object_t *)%s));' % (
         result, resulttype, arg_size, arg_idata))
 
+def stm_allocate_nonmovable(funcgen, op):
+    arg_size    = funcgen.expr(op.args[0])  # <- could be smaller than 16 here
+    arg_type_id = funcgen.expr(op.args[1])
+    result      = funcgen.expr(op.result)
+    # XXX NULL returns?
+    return ('%s = (rpygcchar_t *)_stm_allocate_external(%s >= 16 ? %s : 16); ' %
+                (result, arg_size, arg_size) +
+            '((rpyobj_t *)%s)->tid = %s;' % (result, arg_type_id))
+
 def stm_get_from_obj(funcgen, op):
     assert op.args[0].concretetype == llmemory.GCREF
     arg_obj = funcgen.expr(op.args[0])
diff --git a/rpython/translator/stm/test/test_ztranslated.py b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -620,3 +620,19 @@
         t, cbuilder = self.compile(main)
         data = cbuilder.cmdexec('')
         assert 'ok!\n' in data
+
+    def test_allocate_nonmovable(self):
+        S = lltype.GcStruct('S', ('n', lltype.Signed))
+
+        def main(argv):
+            s1 = rstm.allocate_nonmovable(S)
+            s1.n = 42
+            assert s1.n == 42
+            assert not rgc.can_move(s1)
+            #
+            print "ok!"
+            return 0
+
+        t, cbuilder = self.compile(main)
+        data = cbuilder.cmdexec('')
+        assert 'ok!\n' in data


More information about the pypy-commit mailing list