Author: Antonio Cuni <anto.c...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit