Author: Remi Meier <remi.me...@gmail.com>
Branch: stmgc-c4
Changeset: r66116:49e406509329
Date: 2013-08-13 15:31 +0200
http://bitbucket.org/pypy/pypy/changeset/49e406509329/

Log:    fix forgotten jitframe allocation before call_assembler

diff --git a/pypy/tool/jitlogparser/parser.py b/pypy/tool/jitlogparser/parser.py
--- a/pypy/tool/jitlogparser/parser.py
+++ b/pypy/tool/jitlogparser/parser.py
@@ -100,7 +100,7 @@
                 if ofs >= 0:
                     asm.append((ofs, v.strip("\n")))
             #
-            prefix = hex(dump_start)[:-8]
+            prefix = hex(dump_start)[:-9]
             asm_index = 0
             for i, op in enumerate(loop.operations):
                 end = 0
diff --git a/rpython/jit/backend/llsupport/assembler.py 
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -226,7 +226,6 @@
             else:
                 raise AssertionError(kind)
 
-        import pdb;pdb.set_trace()
         gcref = cast_instance_to_gcref(value)
         gcref = rgc._make_sure_does_not_move(gcref)
         value = rffi.cast(lltype.Signed, gcref)
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -172,8 +172,8 @@
                                size_box,
                                descr=descrs.jfi_frame_size)
             self.newops.append(op0)
-            self.gen_malloc_nursery_varsize_frame(size_box, frame)
-            self.gen_initialize_tid(frame, descrs.arraydescr.tid)
+            self.gen_malloc_nursery_varsize_frame(size_box, frame,
+                                                  descrs.arraydescr.tid)
             length_box = history.BoxInt()
             op1 = ResOperation(rop.GETFIELD_GC, [history.ConstInt(frame_info)],
                                length_box,
@@ -321,7 +321,7 @@
         self.recent_mallocs[v_result] = None
         return True
 
-    def gen_malloc_nursery_varsize_frame(self, sizebox, v_result):
+    def gen_malloc_nursery_varsize_frame(self, sizebox, v_result, tid):
         """ Generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
         """
         self.emitting_an_operation_that_can_collect()
@@ -332,6 +332,8 @@
         self.newops.append(op)
         self.recent_mallocs[v_result] = None
 
+        self.gen_initialize_tid(v_result, tid)
+
     def gen_malloc_nursery(self, size, v_result):
         """Try to generate or update a CALL_MALLOC_NURSERY.
         If that fails, generate a plain CALL_MALLOC_GC instead.
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py 
b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -3,6 +3,7 @@
 from rpython.jit.metainterp.history import BoxPtr, ConstPtr, ConstInt
 from rpython.rlib.objectmodel import specialize
 from rpython.rlib.objectmodel import we_are_translated
+from rpython.jit.metainterp import history
 
 #
 # STM Support
@@ -92,11 +93,13 @@
                 continue
             # ----------  calls  ----------
             if op.is_call():
-                self.known_category.clear()
                 if op.getopnum() == rop.CALL_RELEASE_GIL:
                     self.fallback_inevitable(op)
+                elif op.getopnum() == rop.CALL_ASSEMBLER:
+                    self.handle_call_assembler(op)
                 else:
                     self.newops.append(op)
+                self.known_category.clear()
                 continue
             # ----------  copystrcontent  ----------
             if op.getopnum() in (rop.COPYSTRCONTENT,
@@ -138,8 +141,15 @@
         for v, c in self.known_category.items():
             if c == 'R':
                 self.known_category[v] = 'P'
-        
-        
+
+    def gen_malloc_nursery_varsize_frame(self, sizebox, v_result, tid):
+        """ Generate CALL_MALLOC_NURSERY_VARSIZE_FRAME
+        """
+        addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_big_fixedsize')
+        args = [ConstInt(addr), sizebox, ConstInt(tid)]
+        descr = self.gc_ll_descr.malloc_big_fixedsize_descr
+        self._gen_call_malloc_gc(args, v_result, descr)
+                
     def gen_write_barrier(self, v):
         raise NotImplementedError
 
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
@@ -876,6 +876,19 @@
         return rst
 
     def _call_header_shadowstack(self, gcrootmap):
+        # do a write-barrier on ebp / frame for stm
+        # XXX: may not be necessary if we are sure that we only get
+        #      freshly allocated frames or already write-ready frames
+        #      from the caller...
+        gc_ll_descr = self.cpu.gc_ll_descr
+        gcrootmap = gc_ll_descr.gcrootmap
+        if gcrootmap and gcrootmap.is_stm:
+            if not hasattr(gc_ll_descr, 'P2Wdescr'):
+                raise Exception("unreachable code")
+            wbdescr = gc_ll_descr.P2Wdescr
+            self._stm_barrier_fastpath(self.mc, wbdescr, [ebp], is_frame=True)
+
+        # put the frame in ebp on the shadowstack for the GC to find
         rst = self._load_shadowstack_top_in_ebx(self.mc, gcrootmap)
         self.mc.MOV_mr((ebx.value, 0), ebp.value)      # MOV [ebx], ebp
         self.mc.ADD_ri(ebx.value, WORD)
diff --git a/rpython/jit/backend/x86/test/test_stm_integration.py 
b/rpython/jit/backend/x86/test/test_stm_integration.py
--- a/rpython/jit/backend/x86/test/test_stm_integration.py
+++ b/rpython/jit/backend/x86/test/test_stm_integration.py
@@ -20,6 +20,7 @@
 from rpython.jit.backend.llsupport import jitframe
 from rpython.memory.gc.stmgc import StmGC
 from rpython.jit.metainterp import history
+from rpython.jit.codewriter.effectinfo import EffectInfo
 import itertools, sys
 import ctypes
 
@@ -101,6 +102,11 @@
 class FakeGCHeaderBuilder:
     size_gc_header = WORD
 
+GCPTR = lltype.Ptr(lltype.GcStruct(
+            'GCPTR', ('h_tid', lltype.Unsigned),
+            ('h_revision', lltype.Signed),
+            ('h_original', lltype.Unsigned)))
+HDRSIZE = 3 * WORD
 
 class GCDescrStm(GCDescrShadowstackDirect):
     def __init__(self):
@@ -147,6 +153,21 @@
         self.generate_function('stm_ptr_eq', ptr_eq, [llmemory.GCREF] * 2,
                                RESULT=lltype.Bool)
 
+        def malloc_big_fixedsize(size, tid):
+            entries = size + HDRSIZE
+            TP = rffi.CArray(lltype.Char)
+            obj = lltype.malloc(TP, n=entries, flavor='raw',
+                                            track_allocation=False, zero=True)
+            objptr = rffi.cast(GCPTR, obj)
+            objptr.h_tid = rffi.cast(lltype.Unsigned,
+                                  StmGC.GCFLAG_OLD|StmGC.GCFLAG_WRITE_BARRIER
+                                  | tid)
+            objptr.h_revision = rffi.cast(lltype.Signed, -sys.maxint)
+            return rffi.cast(llmemory.GCREF, objptr)
+        self.generate_function('malloc_big_fixedsize', malloc_big_fixedsize,
+                               [lltype.Signed] * 2)
+
+        
     def malloc_jitframe(self, frame_info):
         """ Allocate a new frame, overwritten by tests
         """
@@ -180,6 +201,7 @@
     def setup_method(self, meth):
         cpu = CPU(None, None)
         cpu.gc_ll_descr = GCDescrStm()
+
         self.p2wd = cpu.gc_ll_descr.P2Wdescr
         self.p2rd = cpu.gc_ll_descr.P2Rdescr
 
@@ -205,7 +227,7 @@
         
     def assert_in(self, called_on, args):
         for i, ref in enumerate(args):
-            assert rffi.cast_ptr_to_adr(ref) == called_on[i]
+            assert rffi.cast_ptr_to_adr(ref) in called_on
             
     def assert_not_in(self, called_on, args):
         for ref in args:
@@ -267,7 +289,7 @@
             # check if rev-fastpath worked
             if rev == PRIV_REV:
                 # fastpath
-                assert not called_on
+                self.assert_not_in(called_on, [sgcref])
             else:
                 self.assert_in(called_on, [sgcref])
 
@@ -310,7 +332,7 @@
             # check if rev-fastpath worked
             if rev == PRIV_REV:
                 # fastpath and WRITE_BARRIER not set
-                assert not called_on
+                self.assert_not_in(called_on, [sgcref])
             else:
                 self.assert_in(called_on, [sgcref])
 
@@ -412,6 +434,70 @@
                             assert guard_failed
 
 
+    
+        
+    def test_assembler_call(self):
+        cpu = self.cpu
+        cpu.gc_ll_descr.init_nursery(100)
+        cpu.setup_once()
+        
+        called = []
+        def assembler_helper(deadframe, virtualizable):
+            frame = rffi.cast(JITFRAMEPTR, deadframe)
+            frame_adr = rffi.cast(lltype.Signed, frame.jf_descr)
+            called.append(frame_adr)
+            return 4 + 9
+
+        FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF,
+                                              llmemory.GCREF],
+                                             lltype.Signed))
+        class FakeJitDriverSD:
+            index_of_virtualizable = -1
+            _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper)
+            assembler_helper_adr = llmemory.cast_ptr_to_adr(
+                _assembler_helper_ptr)
+
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+        i10 = int_add(i0, i1)
+        i11 = int_add(i10, i2)
+        i12 = int_add(i11, i3)
+        i13 = int_add(i12, i4)
+        i14 = int_add(i13, i5)
+        i15 = int_add(i14, i6)
+        i16 = int_add(i15, i7)
+        i17 = int_add(i16, i8)
+        i18 = int_add(i17, i9)
+        finish(i18)'''
+        loop = parse(ops)
+        looptoken = JitCellToken()
+        looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
+        finish_descr = loop.operations[-1].getdescr()
+        self.cpu.done_with_this_frame_descr_int = BasicFinalDescr()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        ARGS = [lltype.Signed] * 10
+        RES = lltype.Signed
+        FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
+            lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
+            EffectInfo.MOST_GENERAL)
+        args = [i+1 for i in range(10)]
+        deadframe = self.cpu.execute_token(looptoken, *args)
+        
+        ops = '''
+        [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+        i10 = int_add(i0, 42)
+        i11 = call_assembler(i10, i1, i2, i3, i4, i5, i6, i7, i8, i9, 
descr=looptoken)
+        guard_not_forced()[]
+        finish(i11)
+        '''
+        loop = parse(ops, namespace=locals())
+        othertoken = JitCellToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
+        args = [i+1 for i in range(10)]
+        deadframe = self.cpu.execute_token(othertoken, *args)
+        assert called == [id(finish_descr)]
+
+
                         
 
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to