Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r70345:8f8d27711915
Date: 2014-03-31 14:05 +0200
http://bitbucket.org/pypy/pypy/changeset/8f8d27711915/

Log:    Test and fix: 'guard_not_forced_2' was ignored if followed by a
        'finish' that doesn't return a reference.

        Found originally with the help of:
        https://bitbucket.org/samuelgiles/naulang/

diff --git a/rpython/jit/backend/arm/opassembler.py 
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -362,11 +362,18 @@
         self.store_reg(self.mc, r.ip, r.fp, ofs, helper=r.lr)
         if op.numargs() > 0 and op.getarg(0).type == REF:
             if self._finish_gcmap:
-                self._finish_gcmap[0] |= r_uint(0) # r0
+                # we're returning with a guard_not_forced_2, and
+                # additionally we need to say that r0 contains
+                # a reference too:
+                self._finish_gcmap[0] |= r_uint(0)
                 gcmap = self._finish_gcmap
             else:
                 gcmap = self.gcmap_for_finish
             self.push_gcmap(self.mc, gcmap, store=True)
+        elif self._finish_gcmap:
+            # we're returning with a guard_not_forced_2
+            gcmap = self._finish_gcmap
+            self.push_gcmap(self.mc, gcmap, store=True)
         else:
             # note that the 0 here is redundant, but I would rather
             # keep that one and kill all the others
diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py 
b/rpython/jit/backend/llsupport/test/test_gc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_gc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py
@@ -916,3 +916,73 @@
                                        cpu.execute_token(token, 1, a))
         assert getmap(frame).count('1') == 4
 
+    def test_finish_without_gcmap(self):
+        cpu = self.cpu
+
+        loop = self.parse("""
+        [i0]
+        finish(i0, descr=finaldescr)
+        """, namespace={'finaldescr': BasicFinalDescr(2)})
+
+        token = JitCellToken()
+        cpu.gc_ll_descr.init_nursery(100)
+        cpu.setup_once()
+        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
+                                       cpu.execute_token(token, 10))
+        assert not frame.jf_gcmap
+
+    def test_finish_with_trivial_gcmap(self):
+        cpu = self.cpu
+
+        loop = self.parse("""
+        [p0]
+        finish(p0, descr=finaldescr)
+        """, namespace={'finaldescr': BasicFinalDescr(2)})
+
+        token = JitCellToken()
+        cpu.gc_ll_descr.init_nursery(100)
+        cpu.setup_once()
+        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        n = lltype.nullptr(llmemory.GCREF.TO)
+        frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
+                                       cpu.execute_token(token, n))
+        assert getmap(frame) == '1'
+
+    def test_finish_with_guard_not_forced_2_ref(self):
+        cpu = self.cpu
+
+        loop = self.parse("""
+        [p0, p1]
+        guard_not_forced_2(descr=faildescr) [p1]
+        finish(p0, descr=finaldescr)
+        """, namespace={'faildescr': BasicFailDescr(1),
+                        'finaldescr': BasicFinalDescr(2)})
+
+        token = JitCellToken()
+        cpu.gc_ll_descr.init_nursery(100)
+        cpu.setup_once()
+        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        n = lltype.nullptr(llmemory.GCREF.TO)
+        frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
+                                       cpu.execute_token(token, n, n))
+        assert getmap(frame).count('1') == 2
+
+    def test_finish_with_guard_not_forced_2_int(self):
+        cpu = self.cpu
+
+        loop = self.parse("""
+        [i0, p1]
+        guard_not_forced_2(descr=faildescr) [p1]
+        finish(i0, descr=finaldescr)
+        """, namespace={'faildescr': BasicFailDescr(1),
+                        'finaldescr': BasicFinalDescr(2)})
+
+        token = JitCellToken()
+        cpu.gc_ll_descr.init_nursery(100)
+        cpu.setup_once()
+        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        n = lltype.nullptr(llmemory.GCREF.TO)
+        frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
+                                       cpu.execute_token(token, 10, n))
+        assert getmap(frame).count('1') == 1
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
@@ -1857,11 +1857,18 @@
         arglist = op.getarglist()
         if arglist and arglist[0].type == REF:
             if self._finish_gcmap:
-                self._finish_gcmap[0] |= r_uint(1) # rax
+                # we're returning with a guard_not_forced_2, and
+                # additionally we need to say that eax/rax contains
+                # a reference too:
+                self._finish_gcmap[0] |= r_uint(1)
                 gcmap = self._finish_gcmap
             else:
                 gcmap = self.gcmap_for_finish
             self.push_gcmap(self.mc, gcmap, store=True)
+        elif self._finish_gcmap:
+            # we're returning with a guard_not_forced_2
+            gcmap = self._finish_gcmap
+            self.push_gcmap(self.mc, gcmap, store=True)
         else:
             # note that the 0 here is redundant, but I would rather
             # keep that one and kill all the others
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to