Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: jitframe-on-heap
Changeset: r60415:2b69388c82c3
Date: 2013-01-24 12:00 +0200
http://bitbucket.org/pypy/pypy/changeset/2b69388c82c3/

Log:    a bit undertested write barrier for frames

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
@@ -1258,6 +1258,13 @@
             mc.MOV(ebp, mem(edx, -WORD))
             base_ofs = self.cpu.get_baseofs_of_frame_field()
             mc.ADD_ri(ebp.value, base_ofs)
+        wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
+        if gcrootmap and wbdescr:
+            ofs = self.cpu.get_baseofs_of_frame_field()
+            # frame never uses card marking, so we enforce this is not
+            # an array
+            self._write_barrier_fastpah(wbdescr, [ebp], array=False,
+                                        extra_ofs=-ofs)
 
     def call(self, addr, args, res):
         self._emit_call(imm(addr), args)
@@ -2311,20 +2318,18 @@
         self.mc.overwrite(jmp_location - 1, chr(offset))
         self._emit_guard_not_forced(guard_token)
 
-    def genop_discard_cond_call_gc_wb(self, op, arglocs):
+    def _write_barrier_fastpah(self, descr, arglocs, array=False, extra_ofs=0):
         # Write code equivalent to write_barrier() in the GC: it checks
         # a flag in the object at arglocs[0], and if set, it calls a
         # helper piece of assembler.  The latter saves registers as needed
         # and call the function jit_remember_young_pointer() from the GC.
-        descr = op.getdescr()
         if we_are_translated():
             cls = self.cpu.gc_ll_descr.has_write_barrier_class()
             assert cls is not None and isinstance(descr, cls)
         #
-        opnum = op.getopnum()
         card_marking = False
         mask = descr.jit_wb_if_flag_singlebyte
-        if opnum == rop.COND_CALL_GC_WB_ARRAY and descr.jit_wb_cards_set != 0:
+        if array and descr.jit_wb_cards_set != 0:
             # assumptions the rest of the function depends on:
             assert (descr.jit_wb_cards_set_byteofs ==
                     descr.jit_wb_if_flag_byteofs)
@@ -2333,7 +2338,8 @@
             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),
+        self.mc.TEST8(addr_add_const(loc_base,
+                                     descr.jit_wb_if_flag_byteofs + extra_ofs),
                       imm(mask))
         self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
         jz_location = self.mc.get_relative_pos()
@@ -2418,7 +2424,11 @@
         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
+    def genop_discard_cond_call_gc_wb(self, op, arglocs):
+        self._write_barrier_fastpah(op.getdescr(), arglocs)
+
+    def genop_discard_cond_call_gc_wb_array(self, op, arglocs):
+        self._write_barrier_fastpah(op.getdescr(), arglocs, array=True)
 
     def not_implemented_op_discard(self, op, arglocs):
         not_implemented("not implemented operation: %s" % op.getopname())
diff --git a/rpython/jit/backend/x86/test/test_gc_integration.py 
b/rpython/jit/backend/x86/test/test_gc_integration.py
--- a/rpython/jit/backend/x86/test/test_gc_integration.py
+++ b/rpython/jit/backend/x86/test/test_gc_integration.py
@@ -236,7 +236,7 @@
             assert len(x) == 1
             assert (bin(x[0]).count('1') ==
                     '0b1111100000000000000001111111011111'.count('1'))
-            # all but two
+            # all but two registers + some stuff on stack
         
         self.cpu = self.getcpu(check)
         S1 = lltype.GcStruct('S1')
@@ -328,16 +328,22 @@
     class GCClass:
         JIT_WB_IF_FLAG = 0
 
+    def __init__(self, nursery_size=100):
+        GcCache.__init__(self, False, None)
+        self.gcrootmap = MockShadowStackRootMap()
+        self.nursery = lltype.malloc(rffi.CArray(lltype.Char), nursery_size,
+                                     flavor='raw')
+        self.nursery_addr = rffi.cast(lltype.Signed, self.nursery)
+
     def get_malloc_slowpath_addr(self):
         return 0
 
     def get_nursery_free_addr(self):
         return 0
+
+    def __del__(self):
+        lltype.free(self.nursery, flavor='raw')
     
-    def __init__(self):
-        GcCache.__init__(self, False, None)
-        self.gcrootmap = MockShadowStackRootMap()
-
 def unpack_gcmap(frame):
     res = []
     val = 0
@@ -351,17 +357,20 @@
     return res
 
 class TestGcShadowstackDirect(BaseTestRegalloc):
-    
-    cpu = CPU(None, None)
-    cpu.gc_ll_descr = GCDescrShadowstackDirect()
-    cpu.setup_once()
+
+    def setup_method(self, meth):
+        cpu = CPU(None, None)
+        cpu.gc_ll_descr = GCDescrShadowstackDirect()
+        cpu.setup_once()
+        self.cpu = cpu
 
     def test_shadowstack_call(self):
-        ofs = self.cpu.get_baseofs_of_frame_field()
+        cpu = self.cpu
+        ofs = cpu.get_baseofs_of_frame_field()
         frames = []
         
         def check(i):
-            assert self.cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs
+            assert cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs
             frame = rffi.cast(jitframe.JITFRAMEPTR, i - ofs)
             assert len(frame.jf_frame) == JITFRAME_FIXED_SIZE + 4
             # we "collect"
@@ -371,13 +380,13 @@
             assert gcmap == [28, 29, 30]
             for item, s in zip(gcmap, new_items):
                 new_frame.jf_frame[item] = rffi.cast(lltype.Signed, s)
-            assert self.cpu.gc_ll_descr.gcrootmap.stack[0] == 
rffi.cast(lltype.Signed, frame)
+            assert cpu.gc_ll_descr.gcrootmap.stack[0] == 
rffi.cast(lltype.Signed, frame)
             hdrbuilder.new_header(new_frame)
             gc_ll_descr.gcrootmap.stack[0] = rffi.cast(lltype.Signed, 
new_frame)
             frames.append(new_frame)
 
         def check2(i):
-            assert self.cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs
+            assert cpu.gc_ll_descr.gcrootmap.stack[0] == i - ofs
             frame = rffi.cast(jitframe.JITFRAMEPTR, i - ofs)
             assert frame == frames[1]
             assert frame != frames[0]
@@ -385,7 +394,7 @@
         CHECK = lltype.FuncType([lltype.Signed], lltype.Void)
         checkptr = llhelper(lltype.Ptr(CHECK), check)
         check2ptr = llhelper(lltype.Ptr(CHECK), check2)
-        checkdescr = self.cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT,
+        checkdescr = cpu.calldescrof(CHECK, CHECK.ARGS, CHECK.RESULT,
                                           EffectInfo.MOST_GENERAL)
 
         S = lltype.GcForwardReference()
@@ -404,13 +413,13 @@
                         'faildescr': BasicFailDescr(),
                         'check_adr': checkptr, 'check2_adr': check2ptr,
                         'checkdescr': checkdescr,
-                        'fielddescr': self.cpu.fielddescrof(S, 'x')})
+                        'fielddescr': cpu.fielddescrof(S, 'x')})
         token = JitCellToken()
-        self.cpu.compile_loop(loop.inputargs, loop.operations, token)
-        self.cpu.register_frame = lambda frame : hdrbuilder.new_header(frame)
+        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.register_frame = lambda frame : hdrbuilder.new_header(frame)
         HDR = lltype.Struct('HDR', ('tid', lltype.Signed))
         hdrbuilder = GCHeaderBuilder(HDR)
-        gc_ll_descr = self.cpu.gc_ll_descr
+        gc_ll_descr = cpu.gc_ll_descr
         gc_ll_descr.gcheaderbuilder = hdrbuilder
         gc_ll_descr.HDRPTR = lltype.Ptr(HDR)
         p0 = lltype.malloc(S, zero=True)
@@ -421,10 +430,13 @@
         hdrbuilder.new_header(p0)
         hdrbuilder.new_header(p1)
         hdrbuilder.new_header(p2)
-        frame = self.cpu.execute_token(token, p0, p1, p2)
+        frame = cpu.execute_token(token, p0, p1, p2)
         frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame)
         gcmap = unpack_gcmap(lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, 
frame))
         assert len(gcmap) == 1
         assert gcmap[0] < 29
         item = rffi.cast(lltype.Ptr(S), frame.jf_frame[gcmap[0]])
         assert item == new_items[2]
+
+    def test_malloc_slowpath(self):
+        cpu = self.cpu
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to