[pypy-commit] pypy stm-jit: in-progress. Missing tests :-(

arigo noreply at buildbot.pypy.org
Sun Aug 5 18:39:58 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-jit
Changeset: r56586:4a547da831fd
Date: 2012-08-05 16:22 +0200
http://bitbucket.org/pypy/pypy/changeset/4a547da831fd/

Log:	in-progress. Missing tests :-(

diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -22,6 +22,7 @@
 # ____________________________________________________________
 
 class GcLLDescription(GcCache):
+    stm = False
 
     def __init__(self, gcdescr, translator=None, rtyper=None):
         GcCache.__init__(self, translator is not None, rtyper)
@@ -580,11 +581,12 @@
 class WriteBarrierDescr(AbstractDescr):
     def __init__(self, gc_ll_descr):
         self.llop1 = gc_ll_descr.llop1
-        if not gc_ll_descr.stm:
+        self.returns_modified_object = gc_ll_descr.stm
+        if not self.returns_modified_object:
             self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
                 [llmemory.Address], lltype.Void))
         else:
-            self.WB_STM_FUNCPTR = lltype.Ptr(lltype.FuncType(
+            self.WB_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
                 [llmemory.Address], llmemory.Address))
         self.fielddescr_tid = gc_ll_descr.fielddescr_tid
         #
@@ -618,9 +620,16 @@
         while value[i] == '\x00': i += 1
         return (i, struct.unpack('b', value[i])[0])
 
-    def get_write_barrier_fn(self, cpu):
+    def get_write_barrier_fn(self, cpu, returns_modified_object=False):
+        # must pass in 'self.returns_modified_object', to make sure that
+        # the callers are fixed for this case
+        assert returns_modified_object == self.returns_modified_object
+        if returns_modified_object:
+            FUNCTYPE = self.WB_FUNCPTR_MOD
+        else:
+            FUNCTYPE = self.WB_FUNCPTR
         llop1 = self.llop1
-        funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
+        funcptr = llop1.get_write_barrier_failing_case(FUNCTYPE)
         funcaddr = llmemory.cast_ptr_to_adr(funcptr)
         return cpu.cast_adr_to_int(funcaddr)
 
@@ -630,6 +639,7 @@
         funcptr = llop1.get_write_barrier_from_array_failing_case(
             self.WB_FUNCPTR)
         funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+        assert not (funcaddr and self.returns_modified_object)
         return cpu.cast_adr_to_int(funcaddr)    # this may return 0
 
     def has_write_barrier_from_array(self, cpu):
@@ -646,7 +656,10 @@
         GcLLDescription.__init__(self, gcdescr, translator, rtyper)
         self.translator = translator
         self.llop1 = llop1
-        self.stm = translator.config.translation.stm
+        try:
+            self.stm = translator.config.translation.stm
+        except AttributeError:
+            pass      # keep the default of False
         if really_not_translated:
             assert not self.translate_support_code  # but half does not work
             self._initialize_for_tests()
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -274,8 +274,8 @@
             v = op.getarg(1)
             if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
                                          bool(v.value)): # store a non-NULL
+                op = self.prepare_write_barrier(op, rop.SETFIELD_RAW)
                 self.gen_write_barrier(op.getarg(0), v)
-                op = op.copy_and_change(rop.SETFIELD_RAW)
         self.newops.append(op)
 
     def handle_write_barrier_setinteriorfield(self, op):
@@ -285,8 +285,8 @@
             v = op.getarg(2)
             if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
                                          bool(v.value)): # store a non-NULL
+                op = self.prepare_write_barrier(op, rop.SETINTERIORFIELD_RAW)
                 self.gen_write_barrier(op.getarg(0), v)
-                op = op.copy_and_change(rop.SETINTERIORFIELD_RAW)
         self.newops.append(op)
 
     def handle_write_barrier_setarrayitem(self, op):
@@ -296,11 +296,21 @@
             v = op.getarg(2)
             if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
                                          bool(v.value)): # store a non-NULL
+                op = self.prepare_write_barrier(op, rop.SETARRAYITEM_RAW)
                 self.gen_write_barrier_array(op.getarg(0),
                                              op.getarg(1), v)
-                op = op.copy_and_change(rop.SETARRAYITEM_RAW)
         self.newops.append(op)
 
+    def prepare_write_barrier(self, op, newopnum):
+        write_barrier_descr = self.gc_ll_descr.write_barrier_descr
+        args = op.getarglist()
+        if (write_barrier_descr.returns_modified_object and
+                isinstance(op.getarg(0), ConstPtr)):
+            v_box = BoxPtr()
+            self.newops.append(ResOperation(rop.SAME_AS, [args[0]], v_box))
+            args[0] = v_box
+        return op.copy_and_change(opnum=newopnum, args=args)
+
     def gen_write_barrier(self, v_base, v_value):
         write_barrier_descr = self.gc_ll_descr.write_barrier_descr
         args = [v_base, v_value]
@@ -313,6 +323,7 @@
             # If we know statically the length of 'v', and it is not too
             # big, then produce a regular write_barrier.  If it's unknown or
             # too big, produce instead a write_barrier_from_array.
+            assert not write_barrier_descr.returns_modified_object
             LARGE = 130
             length = self.known_lengths.get(v_base, LARGE)
             if length >= LARGE:
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -351,12 +351,17 @@
         rawstart = mc.materialize(self.cpu.asmmemmgr, [])
         self.stack_check_slowpath = rawstart
 
+    def _wb_returns_modified_object(self):
+        descr = self.cpu.gc_ll_descr.write_barrier_descr
+        return descr.returns_modified_object
+
     def _build_wb_slowpath(self, withcards, withfloats=False):
         descr = self.cpu.gc_ll_descr.write_barrier_descr
         if descr is None:
             return
         if not withcards:
-            func = descr.get_write_barrier_fn(self.cpu)
+            func = descr.get_write_barrier_fn(self.cpu,
+                                              descr.returns_modified_object)
         else:
             if descr.jit_wb_cards_set == 0:
                 return
@@ -402,6 +407,9 @@
             mc.MOV_rs(edi.value, (frame_size - 1) * WORD)
         mc.CALL(imm(func))
         #
+        if descr.returns_modified_object:
+            mc.MOV_sr(correct_esp_by, eax.value)
+        #
         if withcards:
             # A final TEST8 before the RET, for the caller.  Careful to
             # not follow this instruction with another one that changes
@@ -422,7 +430,10 @@
         # ADD esp, correct_esp_by --- but cannot use ADD, because
         # of its effects on the CPU flags
         mc.LEA_rs(esp.value, correct_esp_by)
-        mc.RET16_i(WORD)
+        if not descr.returns_modified_object:
+            mc.RET16_i(WORD)
+        else:
+            mc.RET()     # and leave the modified object in [ESP+0]
         #
         rawstart = mc.materialize(self.cpu.asmmemmgr, [])
         self.wb_slowpath[withcards + 2 * withfloats] = rawstart
@@ -2480,6 +2491,16 @@
         self.mc.PUSH(loc_base)
         self.mc.CALL(imm(self.wb_slowpath[helper_num]))
 
+        if self._wb_returns_modified_object():
+            # the value at [ESP] is not popped in this case, but possibly
+            # updated.  We have to use it to update the register at loc_base
+            assert isinstance(loc_base, RegLoc)
+            self.mc.POP_r(loc_base.value)
+            # also update the copy of the same value in the stack, if any
+            loc_base_2 = self._regalloc.fm.get(op.getarg(0))
+            if loc_base_2 is not None:
+                self.regalloc_mov(loc_base, loc_base_2)
+
         if card_marking:
             # The helper ends again with a check of the flag in the object.
             # So here, we can simply write again a 'JNS', which will be


More information about the pypy-commit mailing list