[pypy-commit] pypy continulet-jit-2: Bug, test and fix.

arigo noreply at buildbot.pypy.org
Sat Mar 3 12:39:28 CET 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: continulet-jit-2
Changeset: r53138:7fd428833b06
Date: 2012-03-03 12:35 +0100
http://bitbucket.org/pypy/pypy/changeset/7fd428833b06/

Log:	Bug, test and fix.

diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -337,13 +337,15 @@
             self._gcmap_deadentries += 1
             item += asmgcroot.arrayitemsize
 
-    def get_basic_shape(self, return_addr_words_from_esp=0):
+    def get_basic_shape(self, return_addr_from_esp=0):
         # XXX: Should this code even really know about stack frame layout of
         # the JIT?
-        if return_addr_words_from_esp == 0:
+        if return_addr_from_esp == 0:
             retaddr = chr(self.LOC_EBP_PLUS | 4)   # return addr: at WORD(%rbp)
         else:
-            x = return_addr_words_from_esp * 4
+            x = return_addr_from_esp
+            if self.is_64_bit:
+                x >>= 1
             assert 0 < x < 128
             retaddr = chr(self.LOC_ESP_PLUS | x)
         #
@@ -530,7 +532,7 @@
     def initialize(self):
         pass
 
-    def get_basic_shape(self, return_addr_words_from_esp=0):
+    def get_basic_shape(self, return_addr_from_esp=0):
         return []
 
     def add_frame_offset(self, shape, offset):
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -1140,9 +1140,10 @@
         for i in range(start, n):
             loc = arglocs[i]
             p += loc.get_width()
-        extra_esp = p//WORD - OFFSTACK_REAL_FRAME
-        if extra_esp > 0:
-            extra_esp = align_stack_words(extra_esp) * WORD
+        extra_esp = 0
+        if p > OFFSTACK_REAL_FRAME * WORD:
+            extra_esp = WORD * align_stack_words(p // WORD -
+                                                 OFFSTACK_REAL_FRAME)
             self.mc.SUB_ri(esp.value, extra_esp)
 
         p = 0
@@ -1169,7 +1170,7 @@
         #self._regalloc.reserve_param(p//WORD)
         # x is a location
         self.mc.CALL(x)
-        self.mark_gc_roots(force_index)
+        self.mark_gc_roots(force_index, extra_esp=extra_esp)
         #
         if callconv != FFI_DEFAULT_ABI:
             self._fix_stdcall(callconv, p)
@@ -1266,7 +1267,7 @@
 
         #self._regalloc.reserve_param(len(pass_on_stack))
         self.mc.CALL(x)
-        self.mark_gc_roots(force_index)
+        self.mark_gc_roots(force_index, extra_esp=extra_esp)
 
         if extra_esp > 0:
             self.mc.ADD_ri(esp.value, extra_esp)
@@ -2586,12 +2587,13 @@
         not_implemented("not implemented operation (guard): %s" %
                         op.getopname())
 
-    def mark_gc_roots(self, force_index, use_copy_area=False):
+    def mark_gc_roots(self, force_index, use_copy_area=False, extra_esp=0):
         if force_index < 0:
             return     # not needed
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if gcrootmap:
-            mark = self._regalloc.get_mark_gc_roots(gcrootmap, use_copy_area)
+            mark = self._regalloc.get_mark_gc_roots(gcrootmap, use_copy_area,
+                                orf = OFFSTACK_REAL_FRAME * WORD + extra_esp)
             if gcrootmap.is_shadow_stack:
                 gcrootmap.write_callshape(mark, force_index)
             else:
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -207,7 +207,8 @@
         self.min_bytes_before_label = max(self.min_bytes_before_label,
                                           at_least_position)
 
-    def reserve_param(self, n):
+    @staticmethod
+    def reserve_param(n):
         assert n <= OFFSTACK_REAL_FRAME
         #self.param_depth = max(self.param_depth, n)
 
@@ -1417,9 +1418,9 @@
         # This operation is used only for testing
         self.force_spill_var(op.getarg(0))
 
-    def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
-        orf = OFFSTACK_REAL_FRAME
-        shape = gcrootmap.get_basic_shape(return_addr_words_from_esp=orf)
+    def get_mark_gc_roots(self, gcrootmap, use_copy_area=False,
+                          orf=OFFSTACK_REAL_FRAME*WORD):
+        shape = gcrootmap.get_basic_shape(return_addr_from_esp=orf)
         for v, val in self.fm.bindings.items():
             if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
                 assert isinstance(val, StackLoc)
diff --git a/pypy/jit/backend/x86/test/test_zrpy_gc.py b/pypy/jit/backend/x86/test/test_zrpy_gc.py
--- a/pypy/jit/backend/x86/test/test_zrpy_gc.py
+++ b/pypy/jit/backend/x86/test/test_zrpy_gc.py
@@ -789,6 +789,49 @@
     def test_compile_framework_minimal_size_in_nursery(self):
         self.run('compile_framework_minimal_size_in_nursery')
 
+    def define_compile_framework_big_call(self):
+        class A:
+            pass
+        @dont_look_inside
+        def bigcall(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+                    b0, b1, b2, b3, b4, b5, b6, b7, b8, b9):
+            check(a0 == 100)
+            check(a1 == 110)
+            check(a2 == 120)
+            check(a3 == 130)
+            check(a4 == 140)
+            check(a5 == 150)
+            check(a6 == 160)
+            check(a7 == 170)
+            check(a8 == 180)
+            check(a9 == 190)
+            check(b0 == -60)
+            check(b1 == -61)
+            check(b2 == -62)
+            check(b3 == -63)
+            check(b4 == -64)
+            check(b5 == -65)
+            check(b6 == -66)
+            check(b7 == -67)
+            check(b8 == -68)
+            check(b9 == -69)
+            return [A(), A(), A()]
+        @unroll_safe
+        def f42(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s):
+            lst = []
+            i = 0
+            while i < 42:
+                lst = bigcall(100, 110, 120, 130, 140, 150, 160, 170, 180, 190,
+                              -60, -61, -62, -63, -64, -65, -66, -67, -68, -69)
+                i += 1
+            check(len(lst) == 3)
+            n -= 1
+            return n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s
+        return None, f42, None
+
+    def test_compile_framework_big_call(self):
+        self.run('compile_framework_big_call')
+
 
 class TestShadowStack(CompileFrameworkTests):
     gcrootfinder = "shadowstack"


More information about the pypy-commit mailing list