[pypy-svn] r72259 - in pypy/trunk/pypy/jit/backend: llsupport x86 x86/test

arigo at codespeak.net arigo at codespeak.net
Mon Mar 15 20:32:35 CET 2010


Author: arigo
Date: Mon Mar 15 20:32:33 2010
New Revision: 72259

Modified:
   pypy/trunk/pypy/jit/backend/llsupport/gc.py
   pypy/trunk/pypy/jit/backend/x86/assembler.py
   pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py
Log:
Write a test, which I think is finally failing for the reason I expect.
Document this reason as an XXX is assembler.py.


Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/trunk/pypy/jit/backend/llsupport/gc.py	Mon Mar 15 20:32:33 2010
@@ -325,6 +325,7 @@
 
 
 class GcLLDescr_framework(GcLLDescription):
+    DEBUG = False    # forced to True by x86/test/test_zrpy_gc.py
 
     def __init__(self, gcdescr, translator, llop1=llop):
         from pypy.rpython.memory.gctypelayout import _check_typeid
@@ -436,7 +437,21 @@
         self.malloc_unicode = malloc_unicode
         self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
             [lltype.Signed], llmemory.GCREF))
+        #
+        class ForTestOnly:
+            pass
+        for_test_only = ForTestOnly()
+        for_test_only.x = 1.23
+        def random_usage_of_xmm_registers():
+            x0 = for_test_only.x
+            x1 = x0 * 0.1
+            x2 = x0 * 0.2
+            x3 = x0 * 0.3
+            for_test_only.x = x0 + x1 + x2 + x3
+        #
         def malloc_fixedsize_slowpath(size):
+            if self.DEBUG:
+                random_usage_of_xmm_registers()
             try:
                 gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
                                             0, size, True, False, False)

Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/assembler.py	Mon Mar 15 20:32:33 2010
@@ -1244,7 +1244,8 @@
         # as pushed above, plus optionally in esi[-16] to esi[-1] for
         # the XMM registers.  Moreover, esi[8] is a pointer to the recovery
         # bytecode, pushed just before by the CALL instruction written by
-        # generate_quick_failure().
+        # generate_quick_failure().  XXX misaligned stack in the call, but
+        # it's ok because failure_recovery_func is not calling anything more
         mc.PUSH(esi)
         mc.CALL(rel32(failure_recovery_func))
         # returns in eax the fail_index
@@ -1395,6 +1396,9 @@
         # we choose the most compact encoding over the most efficient one.
         for i in range(len(arglocs)-1, -1, -1):
             mc.PUSH(arglocs[i])
+        # misaligned stack in the call, but it's ok because the write barrier
+        # is not going to call anything more.  Also, this assumes that the
+        # write barrier does not touch the xmm registers.
         mc.CALL(rel32(descr.get_write_barrier_fn(self.cpu)))
         for i in range(len(arglocs)):
             loc = arglocs[i]
@@ -1446,6 +1450,7 @@
         mc.CMP(edx, heap(nursery_top_adr))
         mc.write(constlistofchars('\x76\x00')) # JNA after the block
         jmp_adr = mc.get_relative_pos()
+        # XXXXXXXXXXXXXXXX must save and restore xmm registers here!!!!
         self._emit_call(rel32(slowpath_addr), [imm(size)],
                         force_mc=True, mc=mc)
 

Modified: pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py	Mon Mar 15 20:32:33 2010
@@ -12,9 +12,10 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.jit import JitDriver, OPTIMIZER_SIMPLE, dont_look_inside
-from pypy.rlib.jit import purefunction
+from pypy.rlib.jit import purefunction, unroll_safe
 from pypy.jit.backend.x86.runner import CPU386
 from pypy.jit.backend.llsupport.gc import GcRefList, GcRootMap_asmgcc
+from pypy.jit.backend.llsupport.gc import GcLLDescr_framework
 from pypy.tool.udir import udir
 
 class X(object):
@@ -162,7 +163,13 @@
                                         'x5', 'x6', 'x7', 'l', 's'])
         cls.main_allfuncs = staticmethod(main_allfuncs)
         cls.name_to_func = name_to_func
-        cls.cbuilder = compile(get_entry(allfuncs), "hybrid", gcrootfinder="asmgcc", jit=True)
+        OLD_DEBUG = GcLLDescr_framework.DEBUG
+        try:
+            GcLLDescr_framework.DEBUG = True
+            cls.cbuilder = compile(get_entry(allfuncs), "hybrid",
+                                   gcrootfinder="asmgcc", jit=True)
+        finally:
+            GcLLDescr_framework.DEBUG = OLD_DEBUG
 
     def run(self, name, n=2000):
         pypylog = udir.join('TestCompileHybrid.log')
@@ -455,3 +462,53 @@
 
     def test_compile_hybrid_vref(self):
         self.run('compile_hybrid_vref', 200)
+
+    def define_compile_hybrid_float(self):
+        # test for a bug: the fastpath_malloc does not save and restore
+        # xmm registers around the actual call to the slow path
+        class A:
+            x0 = x1 = x2 = x3 = x4 = x5 = x6 = x7 = 0
+        @dont_look_inside
+        def escape1(a):
+            a.x0 += 0
+            a.x1 += 6
+            a.x2 += 12
+            a.x3 += 18
+            a.x4 += 24
+            a.x5 += 30
+            a.x6 += 36
+            a.x7 += 42
+        @dont_look_inside
+        def escape2(n, f0, f1, f2, f3, f4, f5, f6, f7):
+            check(f0 == n + 0.0)
+            check(f1 == n + 0.125)
+            check(f2 == n + 0.25)
+            check(f3 == n + 0.375)
+            check(f4 == n + 0.5)
+            check(f5 == n + 0.625)
+            check(f6 == n + 0.75)
+            check(f7 == n + 0.875)
+        @unroll_safe
+        def f(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s):
+            i = 0
+            while i < 42:
+                m = n + i
+                f0 = m + 0.0
+                f1 = m + 0.125
+                f2 = m + 0.25
+                f3 = m + 0.375
+                f4 = m + 0.5
+                f5 = m + 0.625
+                f6 = m + 0.75
+                f7 = m + 0.875
+                a1 = A()
+                # at this point, all or most f's are still in xmm registers
+                escape1(a1)
+                escape2(m, f0, f1, f2, f3, f4, f5, f6, f7)
+                i += 1
+            n -= 1
+            return n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s
+        return None, f, None
+
+    def test_compile_hybrid_float(self):
+        self.run('compile_hybrid_float')



More information about the Pypy-commit mailing list