[pypy-svn] r65578 - in pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86: . test

arigo at codespeak.net arigo at codespeak.net
Thu Jun 4 16:45:42 CEST 2009


Author: arigo
Date: Thu Jun  4 16:45:40 2009
New Revision: 65578

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py
Log:
Array allocation (i.e. fixed-sized list) with the JIT+GC.


Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py	Thu Jun  4 16:45:40 2009
@@ -92,6 +92,7 @@
         self.verbose = False
         self.rtyper = cpu.rtyper
         self.malloc_func_addr = 0
+        self.malloc_array_func_addr = 0
         self.malloc_str_func_addr = 0
         self.malloc_unicode_func_addr = 0
         self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed))
@@ -130,6 +131,10 @@
             gc_ll_descr = self.cpu.gc_ll_descr
             ll_new = gc_ll_descr.get_funcptr_for_new()
             self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new)
+            if gc_ll_descr.get_funcptr_for_newarray is not None:
+                ll_new_array = gc_ll_descr.get_funcptr_for_newarray()
+                self.malloc_array_func_addr = rffi.cast(lltype.Signed,
+                                                        ll_new_array)
             if gc_ll_descr.get_funcptr_for_newstr is not None:
                 ll_new_str = gc_ll_descr.get_funcptr_for_newstr()
                 self.malloc_str_func_addr = rffi.cast(lltype.Signed,
@@ -472,11 +477,16 @@
         # xxx ignore NULL returns for now
         self.mc.MOV(mem(eax, self.cpu.vtable_offset), loc_vtable)
 
-    # same as malloc varsize after all
+    # XXX genop_new is abused for all varsized mallocs with Boehm, for now
+    # (instead of genop_new_array, genop_newstr, genop_newunicode)
     def genop_new(self, op, arglocs, result_loc):
         assert result_loc is eax
         self.call(self.malloc_func_addr, arglocs, eax)
 
+    def genop_new_array(self, op, arglocs, result_loc):
+        assert result_loc is eax
+        self.call(self.malloc_array_func_addr, arglocs, eax)
+
     def genop_newstr(self, op, arglocs, result_loc):
         assert result_loc is eax
         self.call(self.malloc_str_func_addr, arglocs, eax)

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/gc.py	Thu Jun  4 16:45:40 2009
@@ -42,6 +42,17 @@
         size = symbolic.get_size(S, translate_support_code)
         return ConstDescr3(size, 0, False)
 
+    def arraydescrof(self, A, translate_support_code):
+        basesize, itemsize, ofs_length = symbolic.get_array_token(A,
+                                                       translate_support_code)
+        assert rffi.sizeof(A.OF) in [1, 2, WORD]
+        assert ofs_length == 0
+        if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc':
+            ptr = True
+        else:
+            ptr = False
+        return ConstDescr3(basesize, itemsize, ptr)
+
     def gc_malloc(self, descrsize):
         assert isinstance(descrsize, ConstDescr3)
         size = descrsize.v0
@@ -81,6 +92,7 @@
     def get_funcptr_for_new(self):
         return self.funcptr_for_new
 
+    get_funcptr_for_newarray = None
     get_funcptr_for_newstr = None
     get_funcptr_for_newunicode = None
 
@@ -280,6 +292,7 @@
         self.moving_gc = self.GCClass.moving_gc
         self.HDRPTR = lltype.Ptr(self.GCClass.HDR)
         self.fielddescr_tid = cpu.fielddescrof(self.GCClass.HDR, 'tid')
+        self._array_length_ofs = None
 
         # make a malloc function, with three arguments
         def malloc_basic(size, type_id, has_finalizer):
@@ -295,6 +308,15 @@
         self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
             [llmemory.Address, llmemory.Address], lltype.Void))
         #
+        def malloc_array(basesize, itemsize, type_id, num_elem):
+            return llop.do_malloc_varsize_clear(
+                llmemory.GCREF,
+                type_id, num_elem, basesize, itemsize,
+                self._array_length_ofs, True, False)
+        self.malloc_array = malloc_array
+        self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType(
+            [lltype.Signed] * 4, llmemory.GCREF))
+        #
         (str_basesize, str_itemsize, str_ofs_length
          ) = symbolic.get_array_token(rstr.STR, True)
         (unicode_basesize, unicode_itemsize, unicode_ofs_length
@@ -324,18 +346,42 @@
         type_id = self.layoutbuilder.get_type_id(S)
         has_finalizer = bool(self.layoutbuilder.has_finalizer(S))
         assert weakpointer_offset(S) == -1     # XXX
-        return ConstDescr3(size, type_id, has_finalizer)
+        descr = ConstDescr3(size, 0, has_finalizer)
+        descr.type_id = type_id
+        return descr
+
+    def arraydescrof(self, A, translate_support_code):
+        assert translate_support_code, "required with the framework GC"
+        basesize, itemsize, ofs_length = symbolic.get_array_token(A, True)
+        assert rffi.sizeof(A.OF) in [1, 2, WORD]
+        if self._array_length_ofs is None:
+            self._array_length_ofs = ofs_length
+        else:
+            assert self._array_length_ofs == ofs_length    # all the same
+        if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc':
+            ptr = True
+        else:
+            ptr = False
+        type_id = self.layoutbuilder.get_type_id(A)
+        descr = ConstDescr3(basesize, itemsize, ptr)
+        descr.type_id = type_id
+        return descr
 
     def gc_malloc(self, descrsize):
         assert isinstance(descrsize, ConstDescr3)
         size = descrsize.v0
-        type_id = descrsize.v1
+        type_id = descrsize.type_id
         has_finalizer = descrsize.flag2
         assert type_id > 0
         return self.malloc_basic(size, type_id, has_finalizer)
 
     def gc_malloc_array(self, arraydescr, num_elem):
-        raise NotImplementedError
+        assert isinstance(arraydescr, ConstDescr3)
+        basesize = arraydescr.v0
+        itemsize = arraydescr.v1
+        type_id = arraydescr.type_id
+        assert type_id > 0
+        return self.malloc_array(basesize, itemsize, type_id, num_elem)
 
     def gc_malloc_str(self, num_elem, translate_support_code):
         assert translate_support_code, "required with the framework GC"
@@ -348,13 +394,23 @@
     def args_for_new(self, descrsize):
         assert isinstance(descrsize, ConstDescr3)
         size = descrsize.v0
-        type_id = descrsize.v1
+        type_id = descrsize.type_id
         has_finalizer = descrsize.flag2
         return [size, type_id, has_finalizer]
 
+    def args_for_new_array(self, arraydescr):
+        assert isinstance(arraydescr, ConstDescr3)
+        basesize = arraydescr.v0
+        itemsize = arraydescr.v1
+        type_id = arraydescr.type_id
+        return [basesize, itemsize, type_id]
+
     def get_funcptr_for_new(self):
         return llhelper(self.GC_MALLOC_BASIC, self.malloc_basic)
 
+    def get_funcptr_for_newarray(self):
+        return llhelper(self.GC_MALLOC_ARRAY, self.malloc_array)
+
     def get_funcptr_for_newstr(self):
         return llhelper(self.GC_MALLOC_STR_UNICODE, self.malloc_str)
 

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py	Thu Jun  4 16:45:40 2009
@@ -939,13 +939,11 @@
     consider_call_pure = consider_call
 
     def consider_new(self, op, ignored):
-        from pypy.jit.backend.x86.runner import ConstDescr3
         args = self.assembler.cpu.gc_ll_descr.args_for_new(op.descr)
         arglocs = [imm(x) for x in args]
         return self._call(op, arglocs)
 
     def consider_new_with_vtable(self, op, ignored):
-        from pypy.jit.backend.x86.runner import ConstDescr3
         args = self.assembler.cpu.gc_ll_descr.args_for_new(op.descr)
         arglocs = [imm(x) for x in args]
         arglocs.append(self.loc(op.args[0]))
@@ -981,6 +979,7 @@
             assert False, itemsize
 
     def _malloc_varsize(self, ofs_items, ofs_length, size, v, res_v):
+        # XXX kill this function at some point
         if isinstance(v, Box):
             loc = self.make_sure_var_in_reg(v, [v])
             self.sync_var(v)
@@ -1003,6 +1002,14 @@
                             [eax, imm(ofs_length), imm(WORD), loc])
 
     def consider_new_array(self, op, ignored):
+        gc_ll_descr = self.assembler.cpu.gc_ll_descr
+        if gc_ll_descr.get_funcptr_for_newarray is not None:
+            # framework GC
+            args = self.assembler.cpu.gc_ll_descr.args_for_new_array(op.descr)
+            arglocs = [imm(x) for x in args]
+            arglocs.append(self.loc(op.args[0]))
+            return self._call(op, arglocs)
+        # boehm GC (XXX kill the following code at some point)
         size_of_field, basesize, _ = self._unpack_arraydescr(op.descr)
         return self._malloc_varsize(basesize, 0, size_of_field, op.args[0],
                                     op.result)

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py	Thu Jun  4 16:45:40 2009
@@ -609,15 +609,7 @@
         except KeyError:
             pass
         assert isinstance(A, lltype.GcArray)
-        basesize, itemsize, ofs_length = symbolic.get_array_token(A,
-                                                  self.translate_support_code)
-        assert rffi.sizeof(A.OF) in [1, 2, WORD]
-        assert ofs_length == 0
-        if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc':
-            ptr = True
-        else:
-            ptr = False
-        descr = ConstDescr3(basesize, itemsize, ptr)
+        descr = self.gc_ll_descr.arraydescrof(A, self.translate_support_code)
         self._descr_caches['array', A] = descr
         return descr
 

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/test/test_zrpy_gc.py	Thu Jun  4 16:45:40 2009
@@ -222,3 +222,21 @@
     res = compile_and_run(get_test(main), "hybrid", gcrootfinder="asmgcc",
                           jit=True)
     assert int(res) == 20
+
+def test_compile_hybrid_6():
+    # Array manipulation (i.e. fixed-sized list).
+    myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 'l'])
+    def main(n, x):
+        l = []
+        while n > 0:
+            myjitdriver.can_enter_jit(n=n, x=x, l=l)
+            myjitdriver.jit_merge_point(n=n, x=x, l=l)
+            l = [n, n, n]
+            n -= x.foo
+        assert len(l) == 3
+        assert l[0] == 2
+        assert l[1] == 2
+        assert l[2] == 2
+    res = compile_and_run(get_test(main), "hybrid", gcrootfinder="asmgcc",
+                          jit=True)
+    assert int(res) == 20



More information about the Pypy-commit mailing list