[pypy-commit] pypy default: merge heads
antocuni
noreply at buildbot.pypy.org
Wed Jul 27 13:24:29 CEST 2011
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch:
Changeset: r46014:7634d3a5a5b2
Date: 2011-07-27 13:24 +0200
http://bitbucket.org/pypy/pypy/changeset/7634d3a5a5b2/
Log: merge heads
diff --git a/pypy/jit/backend/x86/arch.py b/pypy/jit/backend/x86/arch.py
--- a/pypy/jit/backend/x86/arch.py
+++ b/pypy/jit/backend/x86/arch.py
@@ -27,3 +27,6 @@
# which are used in the malloc itself. They are:
# ecx, ebx, esi, edi [32 and 64 bits]
# r8, r9, r10, r12, r13, r14, r15 [64 bits only]
+#
+# Note that with asmgcc, the locations corresponding to callee-save registers
+# are never used.
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
@@ -181,6 +181,7 @@
# instructions in assembler, with a mark_gc_roots in between.
# With shadowstack, this is not needed, so we produce a single helper.
gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+ shadow_stack = (gcrootmap is not None and gcrootmap.is_shadow_stack)
#
# ---------- first helper for the slow path of malloc ----------
mc = codebuf.MachineCodeBlockWrapper()
@@ -190,10 +191,19 @@
mc.SUB_rr(edx.value, eax.value) # compute the size we want
addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
#
- if gcrootmap is not None and gcrootmap.is_shadow_stack:
+ # The registers to save in the copy area: with shadowstack, most
+ # registers need to be saved. With asmgcc, the callee-saved registers
+ # don't need to.
+ save_in_copy_area = gpr_reg_mgr_cls.REGLOC_TO_COPY_AREA_OFS.items()
+ if not shadow_stack:
+ save_in_copy_area = [(reg, ofs) for (reg, ofs) in save_in_copy_area
+ if reg not in gpr_reg_mgr_cls.REGLOC_TO_GCROOTMAP_REG_INDEX]
+ #
+ for reg, ofs in save_in_copy_area:
+ mc.MOV_br(ofs, reg.value)
+ #
+ if shadow_stack:
# ---- shadowstack ----
- for reg, ofs in gpr_reg_mgr_cls.REGLOC_TO_COPY_AREA_OFS.items():
- mc.MOV_br(ofs, reg.value)
mc.SUB_ri(esp.value, 16 - WORD) # stack alignment of 16 bytes
if IS_X86_32:
mc.MOV_sr(0, edx.value) # push argument
@@ -201,15 +211,13 @@
mc.MOV_rr(edi.value, edx.value)
mc.CALL(imm(addr))
mc.ADD_ri(esp.value, 16 - WORD)
- for reg, ofs in gpr_reg_mgr_cls.REGLOC_TO_COPY_AREA_OFS.items():
- mc.MOV_rb(reg.value, ofs)
else:
# ---- asmgcc ----
if IS_X86_32:
mc.MOV_sr(WORD, edx.value) # save it as the new argument
elif IS_X86_64:
- # rdi can be clobbered: its content was forced to the stack
- # by _fastpath_malloc(), like all other save_around_call_regs.
+ # rdi can be clobbered: its content was saved in the
+ # copy area of the stack
mc.MOV_rr(edi.value, edx.value)
mc.JMP(imm(addr)) # tail call to the real malloc
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
@@ -217,6 +225,10 @@
# ---------- second helper for the slow path of malloc ----------
mc = codebuf.MachineCodeBlockWrapper()
#
+ for reg, ofs in save_in_copy_area:
+ mc.MOV_rb(reg.value, ofs)
+ assert reg is not eax and reg is not edx
+ #
if self.cpu.supports_floats: # restore the XMM registers
for i in range(self.cpu.NUM_REGS):# from where they were saved
mc.MOVSD_xs(i, (WORD*2)+8*i)
@@ -2424,8 +2436,7 @@
# there are two helpers to call only with asmgcc
slowpath_addr1 = self.malloc_slowpath1
self.mc.CALL(imm(slowpath_addr1))
- self.mark_gc_roots(self.write_new_force_index(),
- use_copy_area=shadow_stack)
+ self.mark_gc_roots(self.write_new_force_index(), use_copy_area=True)
slowpath_addr2 = self.malloc_slowpath2
self.mc.CALL(imm(slowpath_addr2))
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
@@ -921,27 +921,13 @@
def _do_fastpath_malloc(self, op, size, tid):
gc_ll_descr = self.assembler.cpu.gc_ll_descr
self.rm.force_allocate_reg(op.result, selected_reg=eax)
-
- if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack:
- # ---- shadowstack ----
- # We need edx as a temporary, but otherwise don't save any more
- # register. See comments in _build_malloc_slowpath().
- tmp_box = TempBox()
- self.rm.force_allocate_reg(tmp_box, selected_reg=edx)
- self.rm.possibly_free_var(tmp_box)
- else:
- # ---- asmgcc ----
- # We need to force-allocate each of save_around_call_regs now.
- # The alternative would be to save and restore them around the
- # actual call to malloc(), in the rare case where we need to do
- # it; however, mark_gc_roots() would need to be adapted to know
- # where the variables end up being saved. Messy.
- for reg in self.rm.save_around_call_regs:
- if reg is not eax:
- tmp_box = TempBox()
- self.rm.force_allocate_reg(tmp_box, selected_reg=reg)
- self.rm.possibly_free_var(tmp_box)
-
+ #
+ # We need edx as a temporary, but otherwise don't save any more
+ # register. See comments in _build_malloc_slowpath().
+ tmp_box = TempBox()
+ self.rm.force_allocate_reg(tmp_box, selected_reg=edx)
+ self.rm.possibly_free_var(tmp_box)
+ #
self.assembler.malloc_cond(
gc_ll_descr.get_nursery_free_addr(),
gc_ll_descr.get_nursery_top_addr(),
@@ -1337,14 +1323,26 @@
if reg is eax:
continue # ok to ignore this one
if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
- if use_copy_area:
- assert reg in self.rm.REGLOC_TO_COPY_AREA_OFS
- area_offset = self.rm.REGLOC_TO_COPY_AREA_OFS[reg]
- gcrootmap.add_frame_offset(shape, area_offset)
- else:
- assert reg in self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX
- gcrootmap.add_callee_save_reg(
- shape, self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX[reg])
+ #
+ # The register 'reg' is alive across this call.
+ gcrootmap = self.assembler.cpu.gc_ll_descr.gcrootmap
+ if gcrootmap is None or not gcrootmap.is_shadow_stack:
+ #
+ # Asmgcc: if reg is a callee-save register, we can
+ # explicitly mark it as containing a BoxPtr.
+ if reg in self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX:
+ gcrootmap.add_callee_save_reg(
+ shape, self.rm.REGLOC_TO_GCROOTMAP_REG_INDEX[reg])
+ continue
+ #
+ # Else, 'use_copy_area' must be True (otherwise this BoxPtr
+ # should not be in a register). The copy area contains the
+ # real value of the register.
+ assert use_copy_area
+ assert reg in self.rm.REGLOC_TO_COPY_AREA_OFS
+ area_offset = self.rm.REGLOC_TO_COPY_AREA_OFS[reg]
+ gcrootmap.add_frame_offset(shape, area_offset)
+ #
return gcrootmap.compress_callshape(shape,
self.assembler.datablockwrapper)
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -1733,7 +1733,7 @@
# ----------
# id() and identityhash() support
- def id_or_identityhash(self, gcobj, special_case_prebuilt):
+ def id_or_identityhash(self, gcobj, is_hash):
"""Implement the common logic of id() and identityhash()
of an object, given as a GCREF.
"""
@@ -1776,7 +1776,7 @@
# The answer is the address of the shadow.
obj = shadow
#
- elif special_case_prebuilt:
+ elif is_hash:
if self.header(obj).tid & GCFLAG_HAS_SHADOW:
#
# For identityhash(), we need a special case for some
@@ -1785,16 +1785,20 @@
# after the object. But we cannot use it for id()
# because the stored value might clash with a real one.
size = self.get_size(obj)
- return (obj + size).signed[0]
+ i = (obj + size).signed[0]
+ # Important: the returned value is not mangle_hash()ed!
+ return i
#
- return llmemory.cast_adr_to_int(obj)
-
+ i = llmemory.cast_adr_to_int(obj)
+ if is_hash:
+ i = mangle_hash(i)
+ return i
def id(self, gcobj):
return self.id_or_identityhash(gcobj, False)
def identityhash(self, gcobj):
- return mangle_hash(self.id_or_identityhash(gcobj, True))
+ return self.id_or_identityhash(gcobj, True)
# ----------
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -932,10 +932,10 @@
def gct_gc_identityhash(self, hop):
livevars = self.push_roots(hop)
[v_ptr] = hop.spaceop.args
- v_adr = hop.genop("cast_ptr_to_adr", [v_ptr],
- resulttype=llmemory.Address)
+ v_ptr = hop.genop("cast_opaque_ptr", [v_ptr],
+ resulttype=llmemory.GCREF)
hop.genop("direct_call",
- [self.identityhash_ptr, self.c_const_gc, v_adr],
+ [self.identityhash_ptr, self.c_const_gc, v_ptr],
resultvar=hop.spaceop.result)
self.pop_roots(hop, livevars)
More information about the pypy-commit
mailing list