[pypy-commit] pypy ppc-jit-backend: merge

hager noreply at buildbot.pypy.org
Mon Feb 13 18:38:56 CET 2012


Author: hager <sven.hager at 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


More information about the pypy-commit mailing list