[pypy-commit] pypy ppc-jit-backend: (bivab, hager): implement card marking

hager noreply at buildbot.pypy.org
Thu Mar 1 13:08:42 CET 2012


Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r53043:e55880d705f1
Date: 2012-03-01 03:18 -0800
http://bitbucket.org/pypy/pypy/changeset/e55880d705f1/

Log:	(bivab, hager): implement card marking

diff --git a/pypy/jit/backend/ppc/opassembler.py b/pypy/jit/backend/ppc/opassembler.py
--- a/pypy/jit/backend/ppc/opassembler.py
+++ b/pypy/jit/backend/ppc/opassembler.py
@@ -892,14 +892,15 @@
         if opnum == rop.COND_CALL_GC_WB:
             N = 2
             addr = descr.get_write_barrier_fn(self.cpu)
+            card_marking = False
         elif opnum == rop.COND_CALL_GC_WB_ARRAY:
             N = 3
             addr = descr.get_write_barrier_from_array_fn(self.cpu)
             assert addr != 0
+            card_marking = descr.jit_wb_cards_set != 0
         else:
             raise AssertionError(opnum)
         loc_base = arglocs[0]
-
         with scratch_reg(self.mc):
             self.mc.load(r.SCRATCH.value, loc_base.value, 0)
 
@@ -922,6 +923,33 @@
         jz_location = self.mc.currpos()
         self.mc.nop()
 
+        # 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
+        if card_marking:
+            with scratch_reg(self.mc):
+                self.mc.load(r.SCRATCH.value, loc_base.value, 0)
+
+                # get the position of the bit we want to test
+                bitpos = descr.jit_wb_cards_set_bitpos
+
+                if IS_PPC_32:
+                    # put this bit to the rightmost bitposition of r0
+                    if bitpos > 0:
+                        self.mc.rlwinm(r.SCRATCH.value, r.SCRATCH.value,
+                                       32 - bitpos, 31, 31)
+                else:
+                    if bitpos > 0:
+                        self.mc.rldicl(r.SCRATCH.value, r.SCRATCH.value,
+                                       64 - bitpos, 63)
+
+                # test whether this bit is set
+                self.mc.cmp_op(0, r.SCRATCH.value, 1, imm=True)
+
+                jnz_location = self.mc.currpos()
+                self.mc.nop()
+        else:
+            jnz_location = 0
+
         # the following is supposed to be the slow path, so whenever possible
         # we choose the most compact encoding over the most efficient one.
         with Saved_Volatiles(self.mc):
@@ -936,6 +964,57 @@
             # is not going to call anything more.  
             self.mc.call(func)
 
+        # if GCFLAG_CARDS_SET, then we can do the whole thing that would
+        # be done in the CALL above with just four instructions, so here
+        # is an inline copy of them
+        if card_marking:
+            with scratch_reg(self.mc):
+                jmp_location = self.mc.currpos()
+                self.mc.nop()  # jump to the exit, patched later
+                # patch the JNZ above
+                offset = self.mc.currpos()
+                pmc = OverwritingBuilder(self.mc, jnz_location, 1)
+                pmc.bc(12, 2, offset - jnz_location)     # jump on equality
+                pmc.overwrite()
+                #
+                loc_index = arglocs[1]
+                assert loc_index.is_reg()
+                tmp1 = arglocs[-2]
+                tmp2 = arglocs[-1]
+                #byteofs
+                s = 3 + descr.jit_wb_card_page_shift
+
+                # use r20 as temporay register, save it in FORCE INDEX slot
+                temp_reg = r.r20
+                ENCODING_AREA = len(r.MANAGED_REGS) * WORD
+                self.mc.store(temp_reg.value, r.SPP.value, ENCODING_AREA)
+
+                self.mc.srli_op(temp_reg.value, loc_index.value, s)
+                self.mc.not_(temp_reg.value, temp_reg.value)
+
+                # byte_index
+                self.mc.li(r.SCRATCH.value, 7)
+                self.mc.srli_op(loc_index.value, loc_index.value,
+                                descr.jit_wb_card_page_shift)
+                self.mc.and_(tmp1.value, r.SCRATCH.value, loc_index.value)
+
+                # set the bit
+                self.mc.li(tmp2.value, 1)
+                self.mc.lbzx(r.SCRATCH.value, loc_base.value, temp_reg.value)
+                self.mc.sl_op(tmp2.value, tmp2.value, tmp1.value)
+                self.mc.or_(r.SCRATCH.value, r.SCRATCH.value, tmp2.value)
+                self.mc.stbx(r.SCRATCH.value, loc_base.value, temp_reg.value)
+                # done
+
+                # patch the JMP above
+                offset = self.mc.currpos()
+                pmc = OverwritingBuilder(self.mc, jmp_location, 1)
+                pmc.b(offset - jmp_location)
+                pmc.overwrite()
+
+                # restore temporary register r20
+                self.mc.load(temp_reg.value, r.SPP.value, ENCODING_AREA)
+
         # patch the JZ above
         offset = self.mc.currpos() - jz_location
         pmc = OverwritingBuilder(self.mc, jz_location, 1)


More information about the pypy-commit mailing list