[pypy-svn] r68380 - in pypy/branch/inline-fastpath-malloc/pypy/jit/backend: llsupport x86 x86/test

fijal at codespeak.net fijal at codespeak.net
Tue Oct 13 16:25:18 CEST 2009


Author: fijal
Date: Tue Oct 13 16:25:17 2009
New Revision: 68380

Modified:
   pypy/branch/inline-fastpath-malloc/pypy/jit/backend/llsupport/gc.py
   pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/assembler.py
   pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/regalloc.py
   pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/test/test_gc_integration.py
Log:
IN-PROGRESS
Start writing direct tests for gc integration, by providing a custom
GcLLDescr. Update regalloc and assembler, test fails so far, but it's
a first step


Modified: pypy/branch/inline-fastpath-malloc/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/inline-fastpath-malloc/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/branch/inline-fastpath-malloc/pypy/jit/backend/llsupport/gc.py	Tue Oct 13 16:25:17 2009
@@ -27,6 +27,8 @@
         pass
     def rewrite_assembler(self, cpu, operations):
         pass
+    def can_inline_malloc(self, descr):
+        return False
 
 # ____________________________________________________________
 

Modified: pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/assembler.py	Tue Oct 13 16:25:17 2009
@@ -902,7 +902,27 @@
 
     def closing_jump(self, loop_token):
         self.mc.JMP(rel32(loop_token._x86_loop_code))
-        
+
+    def malloc_cond_fixedsize(self, nursery_free_adr, nursery_top_adr,
+                              size, tid, push_arg, slowpath_addr):
+        # don't use self.mc
+        mc = self.mc._mc
+        mc.MOV(eax, heap(nursery_free_adr))
+        mc.LEA(edx, addr_add(eax, imm(size)))
+        mc.CMP(edx, heap(nursery_top_adr))
+        mc.write('\x76\x00') # JNA after the block
+        jmp_adr = mc.get_relative_pos()
+        if push_arg is not None:
+            assert push_arg is ecx
+            mc.PUSH(ecx)
+        mc.CALL(rel32(slowpath_addr))
+        if push_arg is not None:
+            mc.POP(ecx)
+        mc.MOV(addr_add(eax, imm(0)), imm(tid))
+        mc.MOV(heap(nursery_free_adr), edx)
+        offset = mc.get_relative_pos() - jmp_adr
+        assert 0 < offset <= 127
+        mc.overwrite(jmp_adr-1, chr(offset))
 
 genop_discard_list = [Assembler386.not_implemented_op_discard] * rop._LAST
 genop_list = [Assembler386.not_implemented_op] * rop._LAST

Modified: pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/regalloc.py	Tue Oct 13 16:25:17 2009
@@ -624,7 +624,29 @@
         self.rm.possibly_free_vars(op.args)
 
     def consider_new(self, op, ignored):
-        args = self.assembler.cpu.gc_ll_descr.args_for_new(op.descr)
+        gc_ll_descr = self.assembler.cpu.gc_ll_descr
+        if gc_ll_descr.can_inline_malloc(op.descr):
+            descr = op.descr
+            # since we're in a very hand-crafted code, we can assume things
+            # about descr
+            tmp0 = TempBox()
+            self.rm.force_allocate_reg(op.result, selected_reg=eax)
+            self.rm.force_allocate_reg(tmp0, selected_reg=edx)
+            for k, v in self.rm.reg_bindings.items():
+                if v is ecx:
+                    push_reg = ecx
+                    break
+            else:
+                push_reg = None
+            self.assembler.malloc_cond_fixedsize(
+                gc_ll_descr.get_nursery_free_addr(),
+                gc_ll_descr.get_nursery_top_addr(),
+                op.descr.size, op.descr.type_id, push_reg,
+                gc_ll_descr.get_malloc_fixedsize_slowpath_addr(),
+                )
+            self.rm.possibly_free_var(tmp0)
+            return
+        args = gc_ll_descr.args_for_new(op.descr)
         arglocs = [imm(x) for x in args]
         return self._call(op, arglocs)
 

Modified: pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/test/test_gc_integration.py
==============================================================================
--- pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/test/test_gc_integration.py	(original)
+++ pypy/branch/inline-fastpath-malloc/pypy/jit/backend/x86/test/test_gc_integration.py	Tue Oct 13 16:25:17 2009
@@ -7,6 +7,7 @@
      BoxPtr, ConstPtr, TreeLoop
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.backend.llsupport.descr import GcCache
+from pypy.jit.backend.llsupport.gc import GcLLDescription
 from pypy.jit.backend.x86.runner import CPU
 from pypy.jit.backend.x86.regalloc import RegAlloc, WORD
 from pypy.jit.metainterp.test.oparser import parse
@@ -20,6 +21,7 @@
 from pypy.jit.backend.x86.test.test_regalloc import BaseTestRegalloc
 from pypy.jit.backend.x86.regalloc import X86RegisterManager, X86StackManager,\
      X86XMMRegisterManager
+from pypy.rpython.annlowlevel import llhelper
 
 class MockGcRootMap(object):
     def get_basic_shape(self):
@@ -159,3 +161,70 @@
         jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24)
         '''
         self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False)
+
+class GCDescrFastpathMalloc(GcLLDescription):
+    def __init__(self):
+        GcCache.__init__(self, False)
+        # create a nursery
+        NTP = rffi.CArray(lltype.Signed)
+        self.nursery = lltype.malloc(NTP, 100, flavor='raw')
+        self.addrs = lltype.malloc(rffi.CArray(lltype.Signed), 2,
+                                   flavor='raw')
+        self.addrs[0] = rffi.cast(lltype.Signed, self.nursery)
+        self.addrs[1] = self.addrs[0] + 400
+        # 400 bytes
+        def new(size):
+            xxx
+        self.new = new
+        self.NEW_TP = lltype.FuncType([lltype.Signed],
+                                      llmemory.GCREF)
+        self._counter = 123
+
+    def can_inline_malloc(self, descr):
+        return True
+
+    def get_funcptr_for_new(self):
+        return llhelper(lltype.Ptr(self.NEW_TP), self.new)
+
+    def init_size_descr(self, S, descr):
+        descr.type_id = self._counter
+        self._counter += 1
+
+    def get_nursery_free_addr(self):
+        return rffi.cast(lltype.Signed, self.addrs)
+
+    def get_nursery_top_addr(self):
+        return rffi.cast(lltype.Signed, self.addrs) + 4
+
+    def get_malloc_fixedsize_slowpath_addr(self):
+        return 123
+
+    get_funcptr_for_newarray = None
+    get_funcptr_for_newstr = None
+    get_funcptr_for_newunicode = None
+
+class TestMallocFastpath(BaseTestRegalloc):
+    cpu = CPU(None, None)
+    cpu.gc_ll_descr = GCDescrFastpathMalloc()
+
+    NODE = lltype.GcStruct('node', ('tid', lltype.Signed),
+                           ('value', lltype.Signed))
+    nodedescr = cpu.sizeof(NODE)
+    valuedescr = cpu.fielddescrof(NODE, 'value')
+
+    namespace = locals().copy()
+    
+    def test_malloc_fastpath(self):
+        ops = '''
+        [i0]
+        p0 = new(descr=nodedescr)
+        setfield_gc(p0, i0, descr=valuedescr)
+        finish(p0)
+        '''
+        self.interpret(ops, [42])
+        # check the nursery
+        gc_ll_descr = self.cpu.gc_ll_descr
+        assert gc_ll_descr.nursery[0] == self.nodedescr.type_id
+        assert gc_ll_descr.nursery[1] == 42
+        assert gc_ll_descr.addrs[0] == gc_ll_descr.nursery + 8
+        #assert self.nursery[0] == 15



More information about the Pypy-commit mailing list