Author: hager <sven.ha...@uni-duesseldorf.de> Branch: ppc-jit-backend Changeset: r52429:68416fec227f Date: 2012-02-13 18:38 +0100 http://bitbucket.org/pypy/pypy/changeset/68416fec227f/
Log: merge diff --git a/pypy/jit/backend/ppc/ppc_assembler.py b/pypy/jit/backend/ppc/ppc_assembler.py --- a/pypy/jit/backend/ppc/ppc_assembler.py +++ b/pypy/jit/backend/ppc/ppc_assembler.py @@ -7,7 +7,7 @@ from pypy.jit.backend.ppc.assembler import Assembler from pypy.jit.backend.ppc.opassembler import OpAssembler from pypy.jit.backend.ppc.symbol_lookup import lookup -from pypy.jit.backend.ppc.codebuilder import PPCBuilder +from pypy.jit.backend.ppc.codebuilder import PPCBuilder, OverwritingBuilder from pypy.jit.backend.ppc.jump import remap_frame_layout from pypy.jit.backend.ppc.arch import (IS_PPC_32, IS_PPC_64, WORD, NONVOLATILES, MAX_REG_PARAMS, @@ -20,6 +20,7 @@ decode32, decode64, count_reg_args, Saved_Volatiles) +from pypy.jit.backend.ppc.helper.regalloc import _check_imm_arg import pypy.jit.backend.ppc.register as r import pypy.jit.backend.ppc.condition as c from pypy.jit.metainterp.history import (Const, ConstPtr, JitCellToken, @@ -279,6 +280,28 @@ locs.append(loc) return locs + def _build_malloc_slowpath(self): + mc = PPCBuilder() + with Saved_Volatiles(mc): + # Values to compute size stored in r3 and r4 + mc.subf(r.r3.value, r.r3.value, r.r4.value) + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() + mc.call(addr) + + mc.cmp_op(0, r.r3.value, 0, imm=True) + jmp_pos = mc.currpos() + mc.nop() + nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() + mc.load_imm(r.r4, nursery_free_adr) + mc.load(r.r4.value, r.r4.value, 0) + + pmc = OverwritingBuilder(mc, jmp_pos, 1) + pmc.bc(4, 2, jmp_pos) # jump if the two values are equal + pmc.overwrite() + mc.b_abs(self.propagate_exception_path) + rawstart = mc.materialize(self.cpu.asmmemmgr, []) + self.malloc_slowpath = rawstart + def _build_propagate_exception_path(self): if self.cpu.propagate_exception_v < 0: return @@ -383,8 +406,8 @@ gc_ll_descr = self.cpu.gc_ll_descr gc_ll_descr.initialize() self._build_propagate_exception_path() - #if gc_ll_descr.get_malloc_slowpath_addr is not None: - # self._build_malloc_slowpath() + if gc_ll_descr.get_malloc_slowpath_addr is not None: + self._build_malloc_slowpath() if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack: self._build_release_gil(gc_ll_descr.gcrootmap) self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn) @@ -892,6 +915,51 @@ else: self.mc.extsw(resloc.value, resloc.value) + def malloc_cond(self, nursery_free_adr, nursery_top_adr, size): + assert size & (WORD-1) == 0 # must be correctly aligned + size = max(size, self.cpu.gc_ll_descr.minimal_size_in_nursery) + size = (size + WORD - 1) & ~(WORD - 1) # round up + + self.mc.load_imm(r.r3, nursery_free_adr) + self.mc.load(r.r3.value, r.r3.value, 0) + + if _check_imm_arg(size): + self.mc.addi(r.r4.value, r.r3.value, size) + else: + self.mc.load_imm(r.r4, size) + self.mc.add(r.r4.value, r.r3.value, r.r4.value) + + # XXX maybe use an offset from the value nursery_free_addr + self.mc.load_imm(r.r3, nursery_top_adr) + self.mc.load(r.r3.value, r.r3.value, 0) + + self.mc.cmp_op(0, r.r4.value, r.r3.value, signed=False) + + fast_jmp_pos = self.mc.currpos() + self.mc.nop() + + # XXX update + # See comments in _build_malloc_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; self.malloc_slowpath additionally returns in EDX a + # copy of heap(nursery_free_adr), so that the final MOV below is + # a no-op. + self.mark_gc_roots(self.write_new_force_index(), + use_copy_area=True) + self.mc.call(self.malloc_slowpath) + + offset = self.mc.currpos() - fast_jmp_pos + pmc = OverwritingBuilder(self.mc, fast_jmp_pos, 1) + pmc.bc(4, 1, offset) # jump if LE (not GT) + + self.mc.load_imm(r.r3, nursery_free_adr) + self.mc.store(r.r4.value, r.r3.value, 0) + def mark_gc_roots(self, force_index, use_copy_area=False): if force_index < 0: return # not needed diff --git a/pypy/jit/backend/ppc/regalloc.py b/pypy/jit/backend/ppc/regalloc.py --- a/pypy/jit/backend/ppc/regalloc.py +++ b/pypy/jit/backend/ppc/regalloc.py @@ -11,8 +11,9 @@ prepare_binary_int_op, prepare_binary_int_op_with_imm, prepare_unary_cmp) -from pypy.jit.metainterp.history import (INT, REF, FLOAT, Const, ConstInt, - ConstPtr, Box) +from pypy.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr, + Box, BoxPtr, + INT, REF, FLOAT) from pypy.jit.metainterp.history import JitCellToken, TargetToken from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.ppc import locations @@ -507,17 +508,14 @@ gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap: arglocs = [] - argboxes = [] + args = op.getarglist() for i in range(op.numargs()): - loc, box = self._ensure_value_is_boxed(op.getarg(i), argboxes) + loc = self._ensure_value_is_boxed(op.getarg(i), args) arglocs.append(loc) - argboxes.append(box) self.assembler.call_release_gil(gcrootmap, arglocs) - self.possibly_free_vars(argboxes) # do the call faildescr = guard_op.getdescr() fail_index = self.cpu.get_fail_descr_number(faildescr) - self.assembler._write_fail_index(fail_index) args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))] self.assembler.emit_call(op, args, self, fail_index) # then reopen the stack @@ -778,6 +776,43 @@ args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))] return args + def prepare_call_malloc_nursery(self, op): + size_box = op.getarg(0) + assert isinstance(size_box, ConstInt) + size = size_box.getint() + + self.rm.force_allocate_reg(op.result, selected_reg=r.r3) + t = TempInt() + self.rm.force_allocate_reg(t, selected_reg=r.r4) + self.possibly_free_var(op.result) + self.possibly_free_var(t) + + gc_ll_descr = self.assembler.cpu.gc_ll_descr + self.assembler.malloc_cond( + gc_ll_descr.get_nursery_free_addr(), + gc_ll_descr.get_nursery_top_addr(), + size + ) + + def get_mark_gc_roots(self, gcrootmap, use_copy_area=False): + shape = gcrootmap.get_basic_shape(False) + for v, val in self.frame_manager.bindings.items(): + if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)): + assert val.is_stack() + gcrootmap.add_frame_offset(shape, val.position * -WORD) + for v, reg in self.rm.reg_bindings.items(): + if reg is r.r3: + continue + 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 0, 'sure??' + return gcrootmap.compress_callshape(shape, + self.assembler.datablockwrapper) + prepare_debug_merge_point = void prepare_jit_debug = void @@ -788,11 +823,10 @@ # because it will be needed anyway by the following setfield_gc # or setarrayitem_gc. It avoids loading it twice from the memory. arglocs = [] - argboxes = [] + args = op.getarglist() for i in range(N): - loc = self._ensure_value_is_boxed(op.getarg(i), argboxes) + loc = self._ensure_value_is_boxed(op.getarg(i), args) arglocs.append(loc) - self.rm.possibly_free_vars(argboxes) return arglocs prepare_cond_call_gc_wb_array = prepare_cond_call_gc_wb _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit