[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