Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: jitframe-on-heap
Changeset: r60422:019db8f1e708
Date: 2013-01-24 17:41 +0200
http://bitbucket.org/pypy/pypy/changeset/019db8f1e708/

Log:    a fix and a failing test

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
@@ -151,6 +151,7 @@
         self.newops.append(op0)
         # XXX for now it generates call_malloc_gc, instead of
         # call_malloc_nursery, because the array is strange
+
         op1 = ResOperation(rop.NEW_ARRAY, [lgt_box], frame,
                            descr=descrs.arraydescr)
         self.handle_new_array(descrs.arraydescr, op1)
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
@@ -866,6 +866,10 @@
         self.mc.RET()
 
     def _call_header_shadowstack(self, gcrootmap):
+        # we don't *really* have to do it, since we have the frame
+        # being referenced by the caller. However, we still do it
+        # to provide a place where we can read the frame from, in case
+        # we need to reload it after a collection
         rst = gcrootmap.get_root_stack_top_addr()
         if rx86.fits_in_32bits(rst):
             self.mc.MOV_rj(eax.value, rst)            # MOV eax, [rootstacktop]
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -891,6 +891,8 @@
         size_box = op.getarg(0)
         assert isinstance(size_box, ConstInt)
         size = size_box.getint()
+        gcmap = self.get_gcmap() # allocate the gcmap *before*
+        # looking at the result
         self.rm.force_allocate_reg(op.result, selected_reg=eax)
         #
         # We need edx as a temporary, but otherwise don't save any more
@@ -899,7 +901,6 @@
         self.rm.force_allocate_reg(tmp_box, selected_reg=edi)
         self.rm.possibly_free_var(tmp_box)
         #
-        gcmap = self.get_gcmap()
         gc_ll_descr = self.assembler.cpu.gc_ll_descr
         self.assembler.malloc_cond(
             gc_ll_descr.get_nursery_free_addr(),
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
@@ -342,25 +342,54 @@
     class GCClass:
         JIT_WB_IF_FLAG = 0
 
-    def __init__(self, nursery_size=100):
+    def __init__(self):
         GcCache.__init__(self, False, None)
         self._generated_functions = []
         self.gcrootmap = MockShadowStackRootMap()
+        self.write_barrier_descr = WriteBarrierDescr(self)
+        self._initialize_for_tests()
+        self.frames = []
+
+        def malloc_slowpath(size):
+            self._collect()
+
+        self.malloc_slowpath_fnptr = llhelper_args(malloc_slowpath,
+                                                   [lltype.Signed],
+                                                   llmemory.GCREF)
+        self.all_nurseries = []
+
+    def init_nursery(self, nursery_size):
         self.nursery = lltype.malloc(rffi.CArray(lltype.Char), nursery_size,
-                                     flavor='raw')
+                                     flavor='raw', zero=True)
         self.nursery_ptrs = lltype.malloc(rffi.CArray(lltype.Signed), 2,
                                           flavor='raw')
         self.nursery_ptrs[0] = rffi.cast(lltype.Signed, self.nursery)
         self.nursery_ptrs[1] = self.nursery_ptrs[0] + nursery_size
         self.nursery_addr = rffi.cast(lltype.Signed, self.nursery_ptrs)
-        self.write_barrier_descr = WriteBarrierDescr(self)
-        self._initialize_for_tests()
+        self.all_nurseries.append(self.nursery)
+        self.collections.reverse()
+
+    def _collect(self):
+        gcmap = unpack_gcmap(self.frames[-1])
+        col = self.collections.pop()
+        frame = self.frames[-1].jf_frame
+        start = self.nursery_ptrs[0]
+        assert len(gcmap) == len(col)
+        for i in range(len(gcmap)):
+            assert col[i] + start == frame[gcmap[i]]
+
+    def malloc_jitframe(self, frame_info):
+        """ Allocate a new frame, overwritten by tests
+        """
+        frame = jitframe.JITFRAME.allocate(frame_info)
+        self.frames.append(frame)
+        return frame
 
     def do_write_barrier(self, gcref_struct, gcref_newptr):
         pass
 
     def get_malloc_slowpath_addr(self):
-        return 0
+        return self.malloc_slowpath_fnptr
 
     def get_nursery_free_addr(self):
         return self.nursery_addr
@@ -369,7 +398,8 @@
         return self.nursery_addr + rffi.sizeof(lltype.Signed)
 
     def __del__(self):
-        lltype.free(self.nursery, flavor='raw')
+        for nursery in self.all_nurseries:
+            lltype.free(nursery, flavor='raw')
         lltype.free(self.nursery_ptrs, flavor='raw')
     
 def unpack_gcmap(frame):
@@ -391,7 +421,6 @@
         cpu.gc_ll_descr = GCDescrShadowstackDirect()
         wbd = cpu.gc_ll_descr.write_barrier_descr
         wbd.jit_wb_if_flag_byteofs = 0 # directly into 'hdr' field
-        cpu.setup_once() 
         S = lltype.GcForwardReference()
         S.become(lltype.GcStruct('S',
                                  ('hdr', lltype.Signed),
@@ -402,6 +431,8 @@
 
     def test_shadowstack_call(self):
         cpu = self.cpu
+        cpu.gc_ll_descr.init_nursery(100)
+        cpu.setup_once() 
         S = self.S
         ofs = cpu.get_baseofs_of_frame_field()
         frames = []
@@ -466,13 +497,21 @@
         cpu = self.cpu
         sizeof = cpu.sizeof(self.S)
         sizeof.tid = 0
+        size = sizeof.size
         loop = self.parse("""
         []
-        p0 = new(descr=sizedescr)
+        p0 = call_malloc_nursery(%d)
+        p1 = call_malloc_nursery(%d)
+        p2 = call_malloc_nursery(%d) # this overflows
+        guard_nonnull(p2, descr=faildescr) [p0, p1, p2]
         finish(p0, descr=finaldescr)
-        """, namespace={'sizedescr': sizeof,
-                        'finaldescr': BasicFinalDescr()})
+        """ % (size, size, size), namespace={'sizedescr': sizeof,
+                        'finaldescr': BasicFinalDescr(),
+                        'faildescr': BasicFailDescr()})
         token = JitCellToken()
+        cpu.gc_ll_descr.collections = [[0, sizeof.size]]
+        cpu.gc_ll_descr.init_nursery(2 * sizeof.size)
+        cpu.setup_once()
         cpu.compile_loop(loop.inputargs, loop.operations, token)
         frame = cpu.execute_token(token)
         # now we should be able to track everything from the frame
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to