Author: Armin Rigo <[email protected]>
Branch: stm-thread-2
Changeset: r57286:4dafba14cb5e
Date: 2012-09-11 15:46 +0200
http://bitbucket.org/pypy/pypy/changeset/4dafba14cb5e/

Log:    in-progress: remove more leftovers, and start to add a test for the
        barrier that returns modified objects.

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
@@ -617,6 +617,8 @@
             assert self.jit_wb_cards_set_singlebyte == -0x80
         else:
             self.jit_wb_cards_set = 0
+        #
+        self.wb_slowpath = [0, 0, 0, 0]
 
     def repr_of_descr(self):
         if self.stmcat is None:
@@ -671,6 +673,12 @@
             return False
         return self.get_write_barrier_from_array_fn(cpu) != 0
 
+    def get_wb_slowpath(self, withcards, withfloats):
+        return self.wb_slowpath[withcards + 2 * withfloats]
+
+    def set_wb_slowpath(self, withcards, withfloats, addr):
+        self.wb_slowpath[withcards + 2 * withfloats] = addr
+
 
 class GcLLDescr_framework(GcLLDescription):
     DEBUG = False    # forced to True by x86/test/test_zrpy_gc.py
diff --git a/pypy/jit/backend/test/runner_test.py 
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -2045,11 +2045,12 @@
         FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
         func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
         funcbox = self.get_funcbox(self.cpu, func_ptr)
-        class WriteBarrierDescr(AbstractDescr):
+        class WriteBarrierDescr(WBDescrForTests):
             jit_wb_if_flag = 4096
             jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
             jit_wb_if_flag_singlebyte = 0x10
-            def get_write_barrier_fn(self, cpu):
+            def get_write_barrier_fn(self, cpu, returns_modified_object):
+                assert self.returns_modified_object == returns_modified_object
                 return funcbox.getint()
         #
         for cond in [False, True]:
@@ -2072,6 +2073,56 @@
             else:
                 assert record == []
 
+    def test_cond_call_gc_wb_stm_returns_modified_object(self):
+        def func_void(a):
+            record.append(a)
+            return t
+        record = []
+        #
+        S = lltype.GcStruct('S', ('tid', lltype.Signed))
+        FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
+        func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
+        funcbox = self.get_funcbox(self.cpu, func_ptr)
+        class WriteBarrierDescr(WBDescrForTests):
+            returns_modified_object = True
+            jit_wb_if_flag = 4096
+            jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
+            jit_wb_if_flag_singlebyte = 0x10
+            def get_write_barrier_fn(self, cpu, returns_modified_object):
+                assert self.returns_modified_object == returns_modified_object
+                return funcbox.getint()
+        #
+        for cond in [False, True]:
+            value = random.randrange(-sys.maxint, sys.maxint)
+            if cond:
+                value |= 4096
+            else:
+                value &= ~4096
+            s = lltype.malloc(S)
+            s.tid = value
+            sgcref = lltype.cast_opaque_ptr(llmemory.GCREF, s)
+            t = lltype.malloc(S)
+            tgcref = lltype.cast_opaque_ptr(llmemory.GCREF, t)
+            del record[:]
+            p0 = BoxPtr()
+            operations = [
+                ResOperation(rop.COND_CALL_GC_WB, [p0, ConstInt(0)], None,
+                             descr=WriteBarrierDescr()),
+                ResOperation(rop.FINISH, [p0], None, descr=BasicFailDescr(1))
+                ]
+            inputargs = [p0]
+            looptoken = JitCellToken()
+            self.cpu.compile_loop(inputargs, operations, looptoken)
+            fail = self.cpu.execute_token(looptoken, sgcref)
+            assert fail.identifier == 1
+            res = self.cpu.get_latest_value_ref(0)
+            if cond:
+                assert record == [s]
+                assert res == tgcref
+            else:
+                assert record == []
+                assert res == sgcref
+
     def test_cond_call_gc_wb_array(self):
         def func_void(a):
             record.append(a)
@@ -2081,12 +2132,13 @@
         FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
         func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
         funcbox = self.get_funcbox(self.cpu, func_ptr)
-        class WriteBarrierDescr(AbstractDescr):
+        class WriteBarrierDescr(WBDescrForTests):
             jit_wb_if_flag = 4096
             jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
             jit_wb_if_flag_singlebyte = 0x10
             jit_wb_cards_set = 0       # <= without card marking
-            def get_write_barrier_fn(self, cpu):
+            def get_write_barrier_fn(self, cpu, returns_modified_object):
+                assert self.returns_modified_object == returns_modified_object
                 return funcbox.getint()
         #
         for cond in [False, True]:
@@ -2128,7 +2180,7 @@
         FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
         func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
         funcbox = self.get_funcbox(self.cpu, func_ptr)
-        class WriteBarrierDescr(AbstractDescr):
+        class WriteBarrierDescr(WBDescrForTests):
             jit_wb_if_flag = 4096
             jit_wb_if_flag_byteofs = struct.pack("i", 4096).index('\x10')
             jit_wb_if_flag_singlebyte = 0x10
@@ -3728,3 +3780,13 @@
     def alloc_unicode(self, unicode):
         py.test.skip("implement me")
 
+
+class WBDescrForTests(AbstractDescr):
+    returns_modified_object = False
+    wb_slowpath = (0, 0, 0, 0)
+    def get_wb_slowpath(self, c1, c2):
+        return self.wb_slowpath[c1+2*c2]
+    def set_wb_slowpath(self, c1, c2, addr):
+        i = c1+2*c2
+        self.wb_slowpath = (self.wb_slowpath[:i] + (addr,) +
+                            self.wb_slowpath[i+1:])
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
@@ -83,7 +83,6 @@
         self.float_const_abs_addr = 0
         self.malloc_slowpath1 = 0
         self.malloc_slowpath2 = 0
-        self.wb_slowpath = [0, 0, 0, 0]
         self.memcpy_addr = 0
         self.setup_failure_recovery()
         self._debug = False
@@ -112,13 +111,9 @@
         self.memcpy_addr = self.cpu.cast_ptr_to_int(support.memcpy_fn)
         self._build_failure_recovery(False)
         self._build_failure_recovery(True)
-        self._build_wb_slowpath(False)
-        self._build_wb_slowpath(True)
         if self.cpu.supports_floats:
             self._build_failure_recovery(False, withfloats=True)
             self._build_failure_recovery(True, withfloats=True)
-            self._build_wb_slowpath(False, withfloats=True)
-            self._build_wb_slowpath(True, withfloats=True)
             support.ensure_sse2_floats()
             self._build_float_constants()
         self._build_propagate_exception_path()
@@ -355,23 +350,14 @@
         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
+    def _build_wb_slowpath(self, descr, withcards, withfloats):
         if not withcards:
             func = descr.get_write_barrier_fn(self.cpu,
                                               descr.returns_modified_object)
         else:
-            if descr.jit_wb_cards_set == 0:
-                return
+            assert descr.jit_wb_cards_set != 0
             func = descr.get_write_barrier_from_array_fn(self.cpu)
-            if func == 0:
-                return
+            assert func != 0
         #
         # This builds a helper function called from the slow path of
         # write barriers.  It must save all registers, and optionally
@@ -440,7 +426,7 @@
             mc.RET()     # and leave the modified object in [ESP+0]
         #
         rawstart = mc.materialize(self.cpu.asmmemmgr, [])
-        self.wb_slowpath[withcards + 2 * withfloats] = rawstart
+        descr.set_wb_slowpath(withcards, withfloats, rawstart)
 
     @staticmethod
     @rgc.no_collect
@@ -2478,11 +2464,18 @@
             card_marking = True
             mask = descr.jit_wb_if_flag_singlebyte | -0x80
         #
-        loc_base = arglocs[0]
-        self.mc.TEST8(addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs),
-                      imm(mask))
-        self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
-        jz_location = self.mc.get_relative_pos()
+        # If the 'descr' is for a conditional barrier (common case),
+        # then produce the condition here.  The fast-path that does not
+        # require any call is if some bit in the header of the object is
+        # *cleared*.
+        if mask != 0:
+            loc_base = arglocs[0]
+            byteaddr = addr_add_const(loc_base, descr.jit_wb_if_flag_byteofs)
+            self.mc.TEST8(byteaddr, imm(mask))
+            self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
+            jz_location = self.mc.get_relative_pos()
+        else:
+            jz_location = -1
 
         # for cond_call_gc_wb_array, also add another fast path:
         # if GCFLAG_CARDS_SET, then we can just set one bit and be done
@@ -2492,25 +2485,26 @@
             self.mc.J_il8(rx86.Conditions['S'], 0) # patched later
             js_location = self.mc.get_relative_pos()
         else:
-            js_location = 0
+            js_location = -1
 
         # Write only a CALL to the helper prepared in advance, passing it as
         # argument the address of the structure we are writing into
         # (the first argument to COND_CALL_GC_WB).
-        helper_num = card_marking
         if self._regalloc.xrm.reg_bindings:
-            helper_num += 2
-        if self.wb_slowpath[helper_num] == 0:    # tests only
-            assert not we_are_translated()
-            self.cpu.gc_ll_descr.write_barrier_descr = descr
-            self._build_wb_slowpath(card_marking,
-                                    bool(self._regalloc.xrm.reg_bindings))
-            assert self.wb_slowpath[helper_num] != 0
+            withfloats = True
+        else:
+            withfloats = False
+        wb_slowpath = descr.get_wb_slowpath(card_marking, withfloats)
+        if wb_slowpath == 0:
+            # must build the barrier's slow path
+            self._build_wb_slowpath(descr, card_marking, withfloats)
+            wb_slowpath = descr.get_wb_slowpath(card_marking, withfloats)
+            assert wb_slowpath != 0 
         #
         self.mc.PUSH(loc_base)
-        self.mc.CALL(imm(self.wb_slowpath[helper_num]))
+        self.mc.CALL(imm(wb_slowpath))
 
-        if self._wb_returns_modified_object():
+        if descr.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)
@@ -2570,9 +2564,10 @@
             self.mc.overwrite(jns_location-1, chr(offset))
 
         # patch the JZ above
-        offset = self.mc.get_relative_pos() - jz_location
-        assert 0 < offset <= 127
-        self.mc.overwrite(jz_location-1, chr(offset))
+        if jz_location != -1:
+            offset = self.mc.get_relative_pos() - jz_location
+            assert 0 < offset <= 127
+            self.mc.overwrite(jz_location-1, chr(offset))
 
     genop_discard_cond_call_gc_wb_array = genop_discard_cond_call_gc_wb
 
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -444,13 +444,8 @@
             if self.can_merge_with_next_guard(op, i, operations):
                 oplist_with_guard[op.getopnum()](self, op, operations[i + 1])
                 i += 1
-            elif not we_are_translated() and op.getopnum() < 0:
-                if op.getopnum() == -124:
-                    self._consider_force_spill(op)
-                elif op.getopnum() == -123:
-                    self._consider_escape(op)
-                else:
-                    assert 0, op
+            elif not we_are_translated() and op.getopnum() == -124:
+                self._consider_force_spill(op)
             else:
                 oplist[op.getopnum()](self, op)
             if op.result is not None:
@@ -1358,12 +1353,6 @@
         # This operation is used only for testing
         self.force_spill_var(op.getarg(0))
 
-    def _consider_escape(self, op):
-        # This operation is used only for testing:
-        # it checks that op.getarg(0) is currently not in a reg
-        loc = self.loc(op.getarg(0))
-        assert not isinstance(loc, RegLoc)
-
     def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
         shape = gcrootmap.get_basic_shape()
         for v, val in self.fm.bindings.items():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to