[pypy-svn] r72263 - in pypy/trunk/pypy: jit/backend/llsupport jit/backend/x86 jit/backend/x86/test translator/c

arigo at codespeak.net arigo at codespeak.net
Mon Mar 15 22:57:27 CET 2010


Author: arigo
Date: Mon Mar 15 22:57:25 2010
New Revision: 72263

Modified:
   pypy/trunk/pypy/jit/backend/llsupport/gc.py
   pypy/trunk/pypy/jit/backend/x86/assembler.py
   pypy/trunk/pypy/jit/backend/x86/regalloc.py
   pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py
   pypy/trunk/pypy/translator/c/genc.py
Log:
Fix the bug of r72259.  Simplifies a bit stuff (no more longlong result)
at the cost of a more complicated, but local, hack in 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 22:57:25 2010
@@ -14,7 +14,6 @@
 from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr
 from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr
 from pypy.jit.backend.llsupport.descr import get_call_descr
-from pypy.rlib.rarithmetic import r_ulonglong, r_uint
 
 # ____________________________________________________________
 
@@ -457,13 +456,11 @@
                                             0, size, True, False, False)
             except MemoryError:
                 fatalerror("out of memory (from JITted code)")
-                return r_ulonglong(0)
-            res = rffi.cast(lltype.Signed, gcref)
-            nurs_free = llop1.gc_adr_of_nursery_free(llmemory.Address).signed[0]
-            return r_ulonglong(nurs_free) << 32 | r_ulonglong(r_uint(res))
+                return 0
+            return rffi.cast(lltype.Signed, gcref)
         self.malloc_fixedsize_slowpath = malloc_fixedsize_slowpath
         self.MALLOC_FIXEDSIZE_SLOWPATH = lltype.FuncType([lltype.Signed],
-                                                 lltype.UnsignedLongLong)
+                                                         lltype.Signed)
 
     def get_nursery_free_addr(self):
         nurs_addr = llop.gc_adr_of_nursery_free(llmemory.Address)

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 22:57:25 2010
@@ -118,6 +118,8 @@
         self.fail_ebp = 0
         self.loc_float_const_neg = None
         self.loc_float_const_abs = None
+        self.malloc_fixedsize_slowpath1 = 0
+        self.malloc_fixedsize_slowpath2 = 0
         self.setup_failure_recovery()
 
     def leave_jitted_hook(self):
@@ -164,6 +166,8 @@
                 self._build_failure_recovery(True, withfloats=True)
                 codebuf.ensure_sse2_floats()
                 self._build_float_constants()
+            if hasattr(gc_ll_descr, 'get_malloc_fixedsize_slowpath_addr'):
+                self._build_malloc_fixedsize_slowpath()
 
     def _build_float_constants(self):
         # 11 words: 8 words for the data, and up to 3 words for alignment
@@ -184,6 +188,27 @@
         self.loc_float_const_neg = heap64(float_constants)
         self.loc_float_const_abs = heap64(float_constants + 16)
 
+    def _build_malloc_fixedsize_slowpath(self):
+        mc = self.mc2._mc
+        # ---------- first helper for the slow path of malloc ----------
+        self.malloc_fixedsize_slowpath1 = mc.tell()
+        if self.cpu.supports_floats:          # save the XMM registers in
+            for i in range(8):                # the *caller* frame, from esp+8
+                mc.MOVSD(mem64(esp, 8+8*i), xmm_registers[i])
+        mc.SUB(edx, eax)                      # compute the size we want
+        mc.MOV(mem(esp, 4), edx)              # save it as the new argument
+        addr = self.cpu.gc_ll_descr.get_malloc_fixedsize_slowpath_addr()
+        mc.JMP(rel32(addr))                   # tail call to the real malloc
+        # ---------- second helper for the slow path of malloc ----------
+        self.malloc_fixedsize_slowpath2 = mc.tell()
+        if self.cpu.supports_floats:          # restore the XMM registers
+            for i in range(8):                # from where they were saved
+                mc.MOVSD(xmm_registers[i], mem64(esp, 8+8*i))
+        nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr()
+        mc.MOV(edx, heap(nursery_free_adr))   # load this in EDX
+        mc.RET()
+        self.mc2.done()
+
     def assemble_loop(self, inputargs, operations, looptoken):
         """adds the following attributes to looptoken:
                _x86_loop_code       (an integer giving an address)
@@ -1442,7 +1467,7 @@
         self.mc.JMP(rel32(loop_token._x86_loop_code))
 
     def malloc_cond_fixedsize(self, nursery_free_adr, nursery_top_adr,
-                              size, tid, slowpath_addr):
+                              size, tid):
         # don't use self.mc
         mc = self._start_block()
         mc.MOV(eax, heap(nursery_free_adr))
@@ -1450,14 +1475,25 @@
         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)
-
-        # note that slowpath_addr returns a "long long", or more precisely
-        # two results, which end up in eax and edx.
-        # eax should contain the result of allocation, edx new value
-        # of nursery_free_adr
+
+        # See comments in _build_malloc_fixedsize_slowpath for the
+        # details of the two helper functions that we are calling below.
+        # First, we need to call two of them and not just one because we
+        # need to have a mark_gc_roots() in between.  Then the calling
+        # convention of slowpath_addr{1,2} are tweaked a lot to allow
+        # the code here to be just two CALLs: slowpath_addr1 gets the
+        # size of the object to allocate from (EDX-EAX) and returns the
+        # result in EAX; slowpath_addr2 additionally returns in EDX a
+        # copy of heap(nursery_free_adr), so that the final MOV below is
+        # a no-op.
+        slowpath_addr1 = self.malloc_fixedsize_slowpath1
+        # reserve room for the argument to the real malloc and the
+        # 8 saved XMM regs
+        self._regalloc.reserve_param(1+16)
+        mc.CALL(rel32(slowpath_addr1))
+        self.mark_gc_roots()
+        slowpath_addr2 = self.malloc_fixedsize_slowpath2
+        mc.CALL(rel32(slowpath_addr2))
 
         offset = mc.get_relative_pos() - jmp_adr
         assert 0 < offset <= 127

Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/regalloc.py	Mon Mar 15 22:57:25 2010
@@ -702,7 +702,6 @@
             gc_ll_descr.get_nursery_free_addr(),
             gc_ll_descr.get_nursery_top_addr(),
             descr.size, descr.tid,
-            gc_ll_descr.get_malloc_fixedsize_slowpath_addr(),
             )
 
     def consider_new(self, op):

Modified: pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py	(original)
+++ pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py	Mon Mar 15 22:57:25 2010
@@ -175,15 +175,13 @@
         self.addrs[1] = self.addrs[0] + 64
         # 64 bytes
         def malloc_slowpath(size):
-            from pypy.rlib.rarithmetic import r_ulonglong
             assert size == 8
             nadr = rffi.cast(lltype.Signed, self.nursery)
-            self.addrs[0] = 99999    # should be overridden by the caller
-            return ((r_ulonglong(nadr + size) << 32) |     # this part in edx
-                     r_ulonglong(nadr))                    # this part in eax
+            self.addrs[0] = nadr + size
+            return nadr
         self.malloc_slowpath = malloc_slowpath
         self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed],
-                                               lltype.UnsignedLongLong)
+                                               lltype.Signed)
         self._counter = 123
 
     def can_inline_malloc(self, descr):

Modified: pypy/trunk/pypy/translator/c/genc.py
==============================================================================
--- pypy/trunk/pypy/translator/c/genc.py	(original)
+++ pypy/trunk/pypy/translator/c/genc.py	Mon Mar 15 22:57:25 2010
@@ -437,6 +437,7 @@
         if res.returncode != 0:
             if expect_crash:
                 return res.out, res.err
+            print >> sys.stderr, res.err
             raise Exception("Returned %d" % (res.returncode,))
         if expect_crash:
             raise Exception("Program did not crash!")



More information about the Pypy-commit mailing list