[pypy-commit] pypy op_malloc_gc: Progress.

arigo noreply at buildbot.pypy.org
Sun Dec 18 12:46:11 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: op_malloc_gc
Changeset: r50650:5267d7c61e57
Date: 2011-12-18 12:45 +0100
http://bitbucket.org/pypy/pypy/changeset/5267d7c61e57/

Log:	Progress.

diff --git a/pypy/jit/backend/llsupport/descr.py b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -23,7 +23,8 @@
         assert isinstance(STRUCT, lltype.GcStruct)
 
     def init_array_descr(self, ARRAY, arraydescr):
-        assert isinstance(ARRAY, lltype.GcArray)
+        assert (isinstance(ARRAY, lltype.GcArray) or
+                isinstance(ARRAY, lltype.GcStruct) and ARRAY._arrayfld)
 
 
 # ____________________________________________________________
@@ -73,6 +74,7 @@
 FLAG_UNSIGNED = 'U'
 FLAG_SIGNED   = 'S'
 FLAG_STRUCT   = 'X'
+FLAG_VOID     = 'V'
 
 class FieldDescr(AbstractDescr):
     name = ''
@@ -86,6 +88,9 @@
         self.field_size = field_size
         self.flag = flag
 
+    def is_field_signed(self):
+        return self.flag == FLAG_SIGNED
+
     def sort_key(self):
         return self.offset
 
@@ -156,23 +161,26 @@
         return '<Array%s %s>' % (self.flag, self.itemsize)
 
 
-def get_array_descr(gccache, ARRAY):
+def get_array_descr(gccache, ARRAY_OR_STRUCT):
     cache = gccache._cache_array
     try:
-        return cache[ARRAY]
+        return cache[ARRAY_OR_STRUCT]
     except KeyError:
-        assert isinstance(ARRAY, lltype.Array)
-        if ARRAY._hints.get('nolength', False):
+        tsc = gccache.translate_support_code
+        basesize, itemsize, _ = symbolic.get_array_token(ARRAY_OR_STRUCT, tsc)
+        if isinstance(ARRAY_OR_STRUCT, lltype.Array):
+            ARRAY_INSIDE = ARRAY_OR_STRUCT
+        else:
+            ARRAY_INSIDE = ARRAY_OR_STRUCT._flds[ARRAY_OR_STRUCT._arrayfld]
+        if ARRAY_INSIDE._hints.get('nolength', False):
             lendescr = None
         else:
-            lendescr = get_field_arraylen_descr(gccache, ARRAY)
-        tsc = gccache.translate_support_code
-        basesize, itemsize, _ = symbolic.get_array_token(ARRAY, tsc)
-        flag = get_type_flag(ARRAY.OF)
+            lendescr = get_field_arraylen_descr(gccache, ARRAY_OR_STRUCT)
+        flag = get_type_flag(ARRAY_INSIDE.OF)
         arraydescr = ArrayDescr(basesize, itemsize, lendescr, flag)
-        if isinstance(ARRAY, lltype.GcArray):
-            gccache.init_array_descr(ARRAY, arraydescr)
-        cache[ARRAY] = arraydescr
+        if ARRAY_OR_STRUCT._gckind == 'gc':
+            gccache.init_array_descr(ARRAY_OR_STRUCT, arraydescr)
+        cache[ARRAY_OR_STRUCT] = arraydescr
         return arraydescr
 
 
@@ -221,7 +229,7 @@
     call_stub_f = staticmethod(lambda func,args_i,args_r,args_f:
                                longlong.ZEROF)
 
-    def __init__(self, arg_classes, result_type, result_flag, result_size,
+    def __init__(self, arg_classes, result_type, result_signed, result_size,
                  extrainfo=None, ffi_flags=1):
         """
             'arg_classes' is a string of characters, one per argument:
@@ -229,11 +237,10 @@
 
             'result_type' is one character from the same list or 'v'
 
-            'result_flag' is a FLAG_xxx value about the result
+            'result_signed' is a boolean True/False
         """
         self.arg_classes = arg_classes
         self.result_type = result_type
-        self.result_flag = result_flag
         self.result_size = result_size
         self.extrainfo = extrainfo
         self.ffi_flags = ffi_flags
@@ -241,6 +248,22 @@
         # makes sense on Windows as it's the one for all the C functions
         # we are compiling together with the JIT.  On non-Windows platforms
         # it is just ignored anyway.
+        if result_type == 'v':
+            result_flag = FLAG_VOID
+        elif result_type == 'i':
+            if result_signed:
+                result_flag = FLAG_SIGNED
+            else:
+                result_flag = FLAG_UNSIGNED
+        elif result_type == history.REF:
+            result_flag = FLAG_POINTER
+        elif result_type == history.FLOAT or result_type == 'L':
+            result_flag = FLAG_FLOAT
+        elif result_type == 'S':
+            result_flag = FLAG_UNSIGNED
+        else:
+            raise NotImplementedError("result_type = %r" % (result_type,))
+        self.result_flag = result_flag
 
     def __repr__(self):
         res = 'CallDescr(%s)' % (self.arg_classes,)
@@ -382,20 +405,21 @@
     arg_classes = map(map_type_to_argclass, ARGS)
     arg_classes = ''.join(arg_classes)
     result_type = map_type_to_argclass(RESULT, accept_void=True)
-    result_flag = get_type_flag(RESULT)
     RESULT_ERASED = RESULT
     if RESULT is lltype.Void:
         result_size = 0
+        result_signed = False
     else:
         result_size = symbolic.get_size(RESULT, gccache.translate_support_code)
+        result_signed = get_type_flag(RESULT) == FLAG_SIGNED
         if isinstance(RESULT, lltype.Ptr):
             RESULT_ERASED = llmemory.Address  # avoid too many CallDescrs
-    key = (arg_classes, result_type, result_flag, RESULT_ERASED, extrainfo)
+    key = (arg_classes, result_type, result_signed, RESULT_ERASED, extrainfo)
     cache = gccache._cache_call
     try:
         calldescr = cache[key]
     except KeyError:
-        calldescr = CallDescr(arg_classes, result_type, result_flag,
+        calldescr = CallDescr(arg_classes, result_type, result_signed,
                               result_size, extrainfo)
         calldescr.create_call_stub(gccache.rtyper, RESULT_ERASED)
         cache[key] = calldescr
diff --git a/pypy/jit/backend/llsupport/ffisupport.py b/pypy/jit/backend/llsupport/ffisupport.py
--- a/pypy/jit/backend/llsupport/ffisupport.py
+++ b/pypy/jit/backend/llsupport/ffisupport.py
@@ -1,9 +1,7 @@
 from pypy.rlib.rarithmetic import intmask
 from pypy.jit.metainterp import history
 from pypy.rpython.lltypesystem import rffi
-from pypy.jit.backend.llsupport.descr import (
-    DynamicIntCallDescr, NonGcPtrCallDescr, FloatCallDescr, VoidCallDescr,
-    LongLongCallDescr, getCallDescrClass)
+from pypy.jit.backend.llsupport.descr import CallDescr
 
 class UnsupportedKind(Exception):
     pass
@@ -16,29 +14,13 @@
         argkinds = [get_ffi_type_kind(cpu, arg) for arg in ffi_args]
     except UnsupportedKind:
         return None
-    arg_classes = ''.join(argkinds)
-    if reskind == history.INT:
-        size = intmask(ffi_result.c_size)
-        signed = is_ffi_type_signed(ffi_result)
-        return DynamicIntCallDescr(arg_classes, size, signed, extrainfo,
-                                   ffi_flags=ffi_flags)
-    elif reskind == history.REF:
-        return  NonGcPtrCallDescr(arg_classes, extrainfo,
-                                  ffi_flags=ffi_flags)
-    elif reskind == history.FLOAT:
-        return FloatCallDescr(arg_classes, extrainfo,
-                              ffi_flags=ffi_flags)
-    elif reskind == history.VOID:
-        return VoidCallDescr(arg_classes, extrainfo,
-                             ffi_flags=ffi_flags)
-    elif reskind == 'L':
-        return LongLongCallDescr(arg_classes, extrainfo,
-                                 ffi_flags=ffi_flags)
-    elif reskind == 'S':
-        SingleFloatCallDescr = getCallDescrClass(rffi.FLOAT)
-        return SingleFloatCallDescr(arg_classes, extrainfo,
-                                    ffi_flags=ffi_flags)
-    assert False
+    if reskind == history.VOID:
+        result_size = 0
+    else:
+        result_size = intmask(ffi_result.c_size)
+    argkinds = ''.join(argkinds)
+    return CallDescr(argkinds, reskind, is_ffi_type_signed(ffi_result),
+                     result_size, extrainfo, ffi_flags=ffi_flags)
 
 def get_ffi_type_kind(cpu, ffi_type):
     from pypy.rlib.libffi import types
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -14,11 +14,11 @@
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.backend.llsupport.symbolic import WORD
-from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr
+##from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
 from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr
-from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr
-from pypy.jit.backend.llsupport.descr import get_call_descr
-from pypy.jit.backend.llsupport.descr import get_field_arraylen_descr
+from pypy.jit.backend.llsupport.descr import get_array_descr
+##from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr
+##from pypy.jit.backend.llsupport.descr import get_call_descr
 from pypy.jit.backend.llsupport.rewrite import GcRewriterAssembler
 from pypy.rpython.memory.gctransform import asmgcroot
 
@@ -34,15 +34,12 @@
         else:
             self.fielddescr_vtable = get_field_descr(self, rclass.OBJECT,
                                                      'typeptr')
-        (self.str_basesize, self.str_itemsize, self.str_ofs_length
-         ) = symbolic.get_array_token(rstr.STR, self.translate_support_code)
-        (self.unicode_basesize, self.unicode_itemsize, self.unicode_ofs_length
-         ) = symbolic.get_array_token(rstr.UNICODE,self.translate_support_code)
-        self.field_strlen_descr = get_field_arraylen_descr(self, rstr.STR)
-        self.field_unicodelen_descr = get_field_arraylen_descr(self,
-                                                               rstr.UNICODE)
         self._generated_functions = []
 
+    def _setup_str(self):
+        self.str_descr     = get_array_descr(self, rstr.STR)
+        self.unicode_descr = get_array_descr(self, rstr.UNICODE)
+
     def generate_function(self, funcname, func, ARGS, RESULT=llmemory.GCREF):
         """Generates a variant of malloc with the given name and the given
         arguments.  It should raise MemoryError and return NULL if out of
@@ -85,12 +82,14 @@
                                      arraydescr.tid)
 
     def gc_malloc_str(self, num_elem):
+        xxx
         return self._gc_malloc_array(self.str_basesize, num_elem,
                                      self.str_itemsize,
                                      self.str_ofs_length,
                                      self.str_type_id)
 
     def gc_malloc_unicode(self, num_elem):
+        xxx
         return self._gc_malloc_array(self.unicode_basesize, num_elem,
                                      self.unicode_itemsize,
                                      self.unicode_ofs_length,
@@ -116,11 +115,11 @@
 # ____________________________________________________________
 
 class GcLLDescr_boehm(GcLLDescription):
+    kind                  = 'boehm'
     moving_gc             = False
     gcrootmap             = None
     write_barrier_descr   = None
     fielddescr_tid        = None
-    has_tid               = False
     str_type_id           = 0
     unicode_type_id       = 0
 
@@ -168,6 +167,7 @@
         GcLLDescription.__init__(self, gcdescr, translator, rtyper)
         # grab a pointer to the Boehm 'malloc' function
         self.malloc_fn_ptr = self.configure_boehm_once()
+        self._setup_str()
         self._make_functions()
 
     def _make_functions(self):
@@ -181,7 +181,7 @@
         self.generate_function('malloc_fixedsize', malloc_fixedsize,
                                [lltype.Signed])
 
-        def malloc_array(basesize, itemsize, num_elem):
+        def malloc_array(basesize, num_elem, itemsize, ofs_length):
             xxx
             try:
                 totalsize = ovfcheck(basesize + ovfcheck(itemsize * num_elem))
@@ -194,23 +194,7 @@
             arrayptr[ofs_length/WORD] = num_elem
             return res
         self.generate_function('malloc_array', malloc_array,
-                               [lltype.Signed] * 3)
-
-        def malloc_str(length):
-            return llop1.do_malloc_varsize_clear(
-                llmemory.GCREF,
-                str_type_id, length, str_basesize, str_itemsize,
-                str_ofs_length)
-        self.generate_function('malloc_str', malloc_str,
-                               [lltype.Signed])
-
-        def malloc_unicode(length):
-            return llop1.do_malloc_varsize_clear(
-                llmemory.GCREF,
-                unicode_type_id, length, unicode_basesize, unicode_itemsize,
-                unicode_ofs_length)
-        self.generate_function('malloc_unicode', malloc_unicode,
-                               [lltype.Signed])
+                               [lltype.Signed] * 4)
 
     def _gc_malloc(self, size, tid):
         # Boehm: 'tid' is ignored
@@ -642,7 +626,7 @@
 
 class GcLLDescr_framework(GcLLDescription):
     DEBUG = False    # forced to True by x86/test/test_zrpy_gc.py
-    has_tid = True
+    kind = 'framework'
 
     def __init__(self, gcdescr, translator, rtyper, llop1=llop,
                  really_not_translated=False):
@@ -659,16 +643,21 @@
             self._make_gcrootmap()
             self._make_layoutbuilder()
             self._setup_gcclass()
+        self._setup_str()
+        self._setup_stuff(really_not_translated)
         self._make_functions()
 
     def _initialize_for_tests(self):
         self.layoutbuilder = None
-        self.str_type_id = 10083        # random, for tests only
-        self.unicode_type_id = 10085
         self.fielddescr_tid = AbstractDescr()
         self.max_size_of_young_obj = 1000
         self.write_barrier_descr = None
 
+    def _setup_stuff(self, really_not_translated):
+        (self.standard_array_basesize, _, self.standard_array_length_ofs) = \
+             symbolic.get_array_token(lltype.GcArray(lltype.Signed),
+                                      not really_not_translated)
+
     def _check_valid_gc(self):
         # we need the hybrid or minimark GC for rgc._make_sure_does_not_move()
         # to work
@@ -703,8 +692,6 @@
         self.moving_gc = self.GCClass.moving_gc
         self.HDRPTR = lltype.Ptr(self.GCClass.HDR)
         self.gcheaderbuilder = GCHeaderBuilder(self.HDRPTR.TO)
-        (self.array_basesize, _, self.array_length_ofs) = \
-             symbolic.get_array_token(lltype.GcArray(lltype.Signed), True)
         self.max_size_of_young_obj = self.GCClass.JIT_max_size_of_young_obj()
         self.minimal_size_in_nursery=self.GCClass.JIT_minimal_size_in_nursery()
 
@@ -718,6 +705,8 @@
         def malloc_nursery_slowpath(size):
             """Allocate 'size' null bytes out of the nursery.
             Note that the fast path is typically inlined by the backend."""
+            if self.DEBUG:
+                self._random_usage_of_xmm_registers()
             type_id = rffi.cast(llgroup.HALFWORD, 0)    # missing here
             return llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
                                                    type_id, size,
@@ -732,11 +721,25 @@
             check_typeid(type_id)
             return llop1.do_malloc_varsize_clear(
                 llmemory.GCREF,
-                type_id, num_elem, self.array_basesize, itemsize,
-                self.array_length_ofs)
+                type_id, num_elem, self.standard_array_basesize, itemsize,
+                self.standard_array_length_ofs)
         self.generate_function('malloc_array', malloc_array,
                                [lltype.Signed] * 3)
 
+        def malloc_array_nonstandard(arraydescr_gcref, num_elem):
+            """For the rare case of non-standard arrays, i.e. arrays where
+            self.standard_array_{basesize,length_ofs} is wrong.  It can
+            occur e.g. with arrays of floats on Win32."""
+            arraydescr = xxxxxxx
+            type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
+            check_typeid(type_id)
+            return llop1.do_malloc_varsize_clear(
+                llmemory.GCREF,
+                type_id, num_elem, xxx, itemsize, xxx)
+        self.generate_function('malloc_array_nonstandard',
+                               malloc_array_nonstandard,
+                               [llmemory.GCREF, lltype.Signed])
+
         def malloc_str(length):
             return llop1.do_malloc_varsize_clear(
                 llmemory.GCREF,
@@ -812,16 +815,6 @@
 ##        ###self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
 ##        ###    [lltype.Signed], llmemory.GCREF))
 ##        #
-##        class ForTestOnly:
-##            pass
-##        for_test_only = ForTestOnly()
-##        for_test_only.x = 1.23
-##        def random_usage_of_xmm_registers():
-##            x0 = for_test_only.x
-##            x1 = x0 * 0.1
-##            x2 = x0 * 0.2
-##            x3 = x0 * 0.3
-##            for_test_only.x = x0 + x1 + x2 + x3
 ##        #
 ##        def malloc_slowpath(size):
 ##            if self.DEBUG:
@@ -837,6 +830,18 @@
 ##        self.malloc_slowpath = malloc_slowpath
 ##        self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed], lltype.Signed)
 
+    class ForTestOnly:
+        pass
+    for_test_only = ForTestOnly()
+    for_test_only.x = 1.23
+
+    def _random_usage_of_xmm_registers(self):
+        x0 = self.for_test_only.x
+        x1 = x0 * 0.1
+        x2 = x0 * 0.2
+        x3 = x0 * 0.3
+        self.for_test_only.x = x0 + x1 + x2 + x3
+
     def get_funcptr_for_malloc_gc_fixed(self):
         """(size) -> GCREF"""
         return llhelper(self.MALLOC_GC_FIXED, self.malloc_gc_fixed)
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -9,10 +9,8 @@
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.backend.llsupport.symbolic import WORD, unroll_basic_sizes
 from pypy.jit.backend.llsupport.descr import (get_size_descr,
-     get_field_descr, BaseFieldDescr, DynamicFieldDescr, get_array_descr,
-     BaseArrayDescr, DynamicArrayNoLengthDescr, get_call_descr,
-     BaseIntCallDescr, GcPtrCallDescr, FloatCallDescr, VoidCallDescr,
-     InteriorFieldDescr, get_interiorfield_descr)
+     get_field_descr, FieldDescr, get_array_descr,
+     ArrayDescr, get_call_descr, get_interiorfield_descr)
 from pypy.jit.backend.llsupport.asmmemmgr import AsmMemoryManager
 
 
@@ -221,14 +219,14 @@
         return get_field_descr(self.gc_ll_descr, STRUCT, fieldname)
 
     def unpack_fielddescr(self, fielddescr):
-        assert isinstance(fielddescr, BaseFieldDescr)
+        assert isinstance(fielddescr, FieldDescr)
         return fielddescr.offset
     unpack_fielddescr._always_inline_ = True
 
     def unpack_fielddescr_size(self, fielddescr):
-        assert isinstance(fielddescr, BaseFieldDescr)
+        assert isinstance(fielddescr, FieldDescr)
         ofs = fielddescr.offset
-        size = fielddescr.get_field_size(self.translate_support_code)
+        size = fielddescr.field_size
         sign = fielddescr.is_field_signed()
         return ofs, size, sign
     unpack_fielddescr_size._always_inline_ = True
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -3,7 +3,7 @@
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.jit.codewriter import heaptracker
 from pypy.jit.backend.llsupport.symbolic import WORD
-from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr
+from pypy.jit.backend.llsupport.descr import SizeDescr, ArrayDescr
 
 
 class GcRewriterAssembler(object):
@@ -28,7 +28,6 @@
     def __init__(self, gc_ll_descr, cpu):
         self.gc_ll_descr = gc_ll_descr
         self.cpu = cpu
-        self.tsc = self.gc_ll_descr.translate_support_code
         self.newops = []
         self.known_lengths = {}
         self.recent_mallocs = {}     # set of variables
@@ -81,53 +80,43 @@
                 self.newops.append(op)
         elif opnum == rop.NEW_ARRAY:
             descr = op.getdescr()
-            assert isinstance(descr, BaseArrayDescr)
-            self.handle_new_array(descr.tid,
-                                  descr.get_base_size(self.tsc),
-                                  descr.get_item_size(self.tsc),
-                                  descr.get_field_arraylen_descr(),
-                                  op)
+            assert isinstance(descr, ArrayDescr)
+            self.handle_new_array(descr, op)
         elif opnum == rop.NEWSTR:
-            self.handle_new_array(self.gc_ll_descr.str_type_id,
-                                  self.gc_ll_descr.str_basesize,
-                                  self.gc_ll_descr.str_itemsize,
-                                  self.gc_ll_descr.field_strlen_descr,
-                                  op)
+            self.handle_new_array(self.gc_ll_descr.str_descr, op)
         elif opnum == rop.NEWUNICODE:
-            self.handle_new_array(self.gc_ll_descr.unicode_type_id,
-                                  self.gc_ll_descr.unicode_basesize,
-                                  self.gc_ll_descr.unicode_itemsize,
-                                  self.gc_ll_descr.field_unicodelen_descr,
-                                  op)
+            self.handle_new_array(self.gc_ll_descr.unicode_descr, op)
         else:
             raise NotImplementedError(op.getopname())
 
     def handle_new_fixedsize(self, descr, op):
-        assert isinstance(descr, BaseSizeDescr)
+        assert isinstance(descr, SizeDescr)
         size = descr.size
         self.gen_malloc_nursery(size, op.result)
         self.gen_initialize_tid(op.result, descr.tid)
 
-    def handle_new_array(self, tid, base_size, item_size, arraylen_descr, op):
+    def handle_new_array(self, arraydescr, op):
         v_length = op.getarg(0)
         total_size = -1
-        if item_size == 0:
-            total_size = base_size
+        if arraydescr.itemsize == 0:
+            total_size = arraydescr.basesize
         elif isinstance(v_length, ConstInt):
             num_elem = v_length.getint()
             try:
-                var_size = ovfcheck(item_size * num_elem)
-                total_size = ovfcheck(base_size + var_size)
+                var_size = ovfcheck(arraydescr.itemsize * num_elem)
+                total_size = ovfcheck(arraydescr.basesize + var_size)
             except OverflowError:
                 pass    # total_size is still -1
         if total_size >= 0:
             self.gen_malloc_nursery(total_size, op.result)
-            self.gen_initialize_tid(op.result, tid)
-            self.gen_initialize_len(op.result, v_length, arraylen_descr)
+            self.gen_initialize_tid(op.result, arraydescr.tid)
+            self.gen_initialize_len(op.result, v_length, arraydescr.lendescr)
+        elif self.gc_ll_descr.kind == 'boehm':
+            self.gen_boehm_malloc_array(arraydescr, v_length, op.result)
         else:
             opnum = op.getopnum()
             if opnum == rop.NEW_ARRAY:
-                self.gen_malloc_array(item_size, tid, v_length, op.result)
+                self.gen_malloc_array(arraydescr, v_length, op.result)
             elif opnum == rop.NEWSTR:
                 self.gen_malloc_str(v_length, op.result)
             elif opnum == rop.NEWUNICODE:
@@ -160,17 +149,31 @@
         self._gen_call_malloc_gc([self.gc_ll_descr.c_malloc_fixedsize_fn,
                                   ConstInt(size)], v_result)
 
-    def gen_malloc_array(self, itemsize, tid, v_num_elem, v_result):
-        """Generate a CALL_MALLOC_GC(malloc_array_fn, ...)."""
-        if self.gc_ll_descr.has_tid:
+    def gen_boehm_malloc_array(self, arraydescr, v_num_elem, v_result):
+        """Generate a CALL_MALLOC_GC(malloc_array_fn, ...) for Boehm."""
+        self._gen_call_malloc_gc([self.gc_ll_descr.c_malloc_array_fn,
+                                  ConstInt(arraydescr.basesize),
+                                  v_num_elem,
+                                  ConstInt(arraydescr.itemsize),
+                                  ConstInt(arraydescr.lendescr.offset)],
+                                 v_result)
+
+    def gen_malloc_array(self, arraydescr, v_num_elem, v_result):
+        """Generate a CALL_MALLOC_GC(malloc_array_fn, ...) going either
+        to the standard or the nonstandard version of the function."""
+        #
+        if (arraydescr.basesize == self.gc_ll_descr.standard_array_basesize
+            and arraydescr.lendescr.offset ==
+                self.gc_ll_descr.standard_array_length_ofs):
+            # this is a standard-looking array, common case
             args = [self.gc_ll_descr.c_malloc_array_fn,
-                    ConstInt(itemsize),
-                    ConstInt(tid),
+                    ConstInt(arraydescr.itemsize),
+                    ConstInt(arraydescr.tid),
                     v_num_elem]
         else:
-            args = [self.gc_ll_descr.c_malloc_array_fn,
-                    ConstInt(basesize),
-                    ConstInt(itemsize),
+            arraydescr_gcref = xxx
+            args = [self.gc_ll_descr.c_malloc_array_nonstandard_fn,
+                    ConstPtr(arraydescr_gcref),
                     v_num_elem]
         self._gen_call_malloc_gc(args, v_result)
 
@@ -296,7 +299,7 @@
         self.gen_write_barrier(v_base, v_value)
 
     def round_up_for_allocation(self, size):
-        if self.tsc:
+        if self.gc_ll_descr.translate_support_code:
             return llarena.round_up_for_allocation(
                 size, self.gc_ll_descr.minimal_size_in_nursery)
         else:
diff --git a/pypy/jit/backend/llsupport/test/test_descr.py b/pypy/jit/backend/llsupport/test/test_descr.py
--- a/pypy/jit/backend/llsupport/test/test_descr.py
+++ b/pypy/jit/backend/llsupport/test/test_descr.py
@@ -214,6 +214,13 @@
                                        True:  FLAG_SIGNED  }[signed]
 
 
+def test_get_array_descr_str():
+    c0 = GcCache(False)
+    descr1 = get_array_descr(c0, rstr.STR)
+    assert descr1.itemsize == rffi.sizeof(lltype.Char)
+    assert descr1.flag == FLAG_UNSIGNED
+
+
 def test_get_call_descr_not_translated():
     c0 = GcCache(False)
     descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char)
diff --git a/pypy/jit/backend/llsupport/test/test_ffisupport.py b/pypy/jit/backend/llsupport/test/test_ffisupport.py
--- a/pypy/jit/backend/llsupport/test/test_ffisupport.py
+++ b/pypy/jit/backend/llsupport/test/test_ffisupport.py
@@ -1,5 +1,6 @@
 from pypy.rlib.libffi import types
 from pypy.jit.codewriter.longlong import is_64_bit
+from pypy.jit.backend.llsupport.descr import *
 from pypy.jit.backend.llsupport.ffisupport import *
 
 
@@ -15,7 +16,9 @@
     args = [types.sint, types.pointer]
     descr = get_call_descr_dynamic(FakeCPU(), args, types.sint, None,
                                    ffi_flags=42)
-    assert isinstance(descr, DynamicIntCallDescr)
+    assert isinstance(descr, CallDescr)
+    assert descr.result_type == 'i'
+    assert descr.result_flag == FLAG_SIGNED
     assert descr.arg_classes == 'ii'
     assert descr.get_ffi_flags() == 42
 
@@ -24,18 +27,20 @@
     assert descr is None    # missing floats
     descr = get_call_descr_dynamic(FakeCPU(supports_floats=True),
                                    args, types.void, None, ffi_flags=43)
-    assert isinstance(descr, VoidCallDescr)
+    assert descr.result_type == 'v'
+    assert descr.result_flag == FLAG_VOID
     assert descr.arg_classes == 'ifi'
     assert descr.get_ffi_flags() == 43
 
     descr = get_call_descr_dynamic(FakeCPU(), [], types.sint8, None, 42)
-    assert isinstance(descr, DynamicIntCallDescr)
-    assert descr.get_result_size(False) == 1
+    assert descr.get_result_size() == 1
+    assert descr.result_flag == FLAG_SIGNED
     assert descr.is_result_signed() == True
 
     descr = get_call_descr_dynamic(FakeCPU(), [], types.uint8, None, 42)
-    assert isinstance(descr, DynamicIntCallDescr)
-    assert descr.get_result_size(False) == 1
+    assert isinstance(descr, CallDescr)
+    assert descr.get_result_size() == 1
+    assert descr.result_flag == FLAG_UNSIGNED
     assert descr.is_result_signed() == False
 
     if not is_64_bit:
@@ -44,7 +49,9 @@
         assert descr is None   # missing longlongs
         descr = get_call_descr_dynamic(FakeCPU(supports_longlong=True),
                                        [], types.slonglong, None, ffi_flags=43)
-        assert isinstance(descr, LongLongCallDescr)
+        assert isinstance(descr, CallDescr)
+        assert descr.result_flag == FLAG_FLOAT
+        assert descr.result_type == 'L'
         assert descr.get_ffi_flags() == 43
     else:
         assert types.slonglong is types.slong
@@ -53,6 +60,6 @@
     assert descr is None   # missing singlefloats
     descr = get_call_descr_dynamic(FakeCPU(supports_singlefloats=True),
                                    [], types.float, None, ffi_flags=44)
-    SingleFloatCallDescr = getCallDescrClass(rffi.FLOAT)
-    assert isinstance(descr, SingleFloatCallDescr)
+    assert descr.result_flag == FLAG_UNSIGNED
+    assert descr.result_type == 'S'
     assert descr.get_ffi_flags() == 44
diff --git a/pypy/jit/backend/llsupport/test/test_rewrite.py b/pypy/jit/backend/llsupport/test/test_rewrite.py
--- a/pypy/jit/backend/llsupport/test/test_rewrite.py
+++ b/pypy/jit/backend/llsupport/test/test_rewrite.py
@@ -49,16 +49,10 @@
         tiddescr = self.gc_ll_descr.fielddescr_tid
         WORD = globals()['WORD']
         #
-        str_type_id  = self.gc_ll_descr.str_type_id
-        str_basesize = self.gc_ll_descr.str_basesize
-        str_itemsize = self.gc_ll_descr.str_itemsize
-        strlendescr = get_field_arraylen_descr(self.gc_ll_descr, rstr.STR)
-        #
-        unicode_type_id  = self.gc_ll_descr.unicode_type_id
-        unicode_basesize = self.gc_ll_descr.unicode_basesize
-        unicode_itemsize = self.gc_ll_descr.unicode_itemsize
-        unicodelendescr = get_field_arraylen_descr(self.gc_ll_descr,
-                                                   rstr.UNICODE)
+        strdescr     = self.gc_ll_descr.str_descr
+        unicodedescr = self.gc_ll_descr.unicode_descr
+        strlendescr     = strdescr.lendescr
+        unicodelendescr = unicodedescr.lendescr
         #
         namespace = locals().copy()
         #
@@ -114,8 +108,7 @@
         """, """
             []
             p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
-                                %(adescr.get_base_size(False) + \
-                                10 * adescr.get_item_size(False))d)
+                                %(adescr.basesize + 10 * adescr.itemsize)d)
             setfield_gc(p0, 10, descr=alendescr)
             jump()
         """)
@@ -128,10 +121,10 @@
         """, """
             [i1]
             p0 = call_malloc_gc(ConstClass(malloc_array), \
-                                %(adescr.get_base_size(False))d, \
-                                i1, \
-                                %(adescr.get_item_size(False))d)
-            setfield_gc(p0, i1, descr=alendescr)
+                                %(adescr.basesize)d,      \
+                                i1,                       \
+                                %(adescr.itemsize)d,      \
+                                %(adescr.lendescr.offset)d)
             jump()
         """)
 
@@ -142,7 +135,7 @@
             jump()
         """, """
             [p1]
-            p0 = malloc_gc(102, 0, 0)
+            p0 = call_malloc_gc(ConstClass(malloc_fixedsize), 102)
             setfield_gc(p0, ConstClass(o_vtable), descr=vtable_descr)
             jump()
         """)
@@ -154,8 +147,11 @@
             jump()
         """, """
             [i1]
-            p0 = malloc_gc(%(str_basesize)d, i1, %(str_itemsize)d)
-            setfield_gc(p0, i1, descr=strlendescr)
+            p0 = call_malloc_gc(ConstClass(malloc_array), \
+                                %(strdescr.basesize)d,    \
+                                i1,                       \
+                                %(strdescr.itemsize)d,    \
+                                %(strlendescr.offset)d)
             jump()
         """)
 
@@ -166,7 +162,9 @@
             jump()
         """, """
             [i1]
-            p0 = malloc_gc(%(unicode_basesize + 10 * unicode_itemsize)d, 0, 0)
+            p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+                                %(unicodedescr.basesize +     \
+                                  10 * unicodedescr.itemsize)d)
             setfield_gc(p0, 10, descr=unicodelendescr)
             jump()
         """)
@@ -231,8 +229,7 @@
         """, """
             []
             p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
-                                %(adescr.get_base_size(False) +  \
-                                  10 * adescr.get_item_size(False))d)
+                                %(adescr.basesize + 10 * adescr.itemsize)d)
             setfield_gc(p0, 4321, descr=tiddescr)
             setfield_gc(p0, 10, descr=alendescr)
             jump()
@@ -248,8 +245,7 @@
             []
             p0 = call_malloc_nursery(ConstClass(malloc_nursery),       \
                                 %(sdescr.size +                        \
-                                  adescr.get_base_size(False) +        \
-                                  10 * adescr.get_item_size(False))d)
+                                  adescr.basesize + 10 * adescr.itemsize)d)
             setfield_gc(p0, 1234, descr=tiddescr)
             p1 = int_add(p0, %(sdescr.size)d)
             setfield_gc(p1, 4321, descr=tiddescr)
@@ -265,7 +261,7 @@
         """, """
             []
             p0 = call_malloc_nursery(ConstClass(malloc_nursery),   \
-                                     %(bdescr.get_base_size(False) + 8)d)
+                                     %(bdescr.basesize + 8)d)
             setfield_gc(p0, 8765, descr=tiddescr)
             setfield_gc(p0, 6, descr=blendescr)
             jump()
@@ -282,16 +278,16 @@
         """, """
             []
             p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
-                                     %(4 * (bdescr.get_base_size(False) + 8))d)
+                                     %(4 * (bdescr.basesize + 8))d)
             setfield_gc(p0, 8765, descr=tiddescr)
             setfield_gc(p0, 5, descr=blendescr)
-            p1 = int_add(p0, %(bdescr.get_base_size(False) + 8)d)
+            p1 = int_add(p0, %(bdescr.basesize + 8)d)
             setfield_gc(p1, 8765, descr=tiddescr)
             setfield_gc(p1, 5, descr=blendescr)
-            p2 = int_add(p1, %(bdescr.get_base_size(False) + 8)d)
+            p2 = int_add(p1, %(bdescr.basesize + 8)d)
             setfield_gc(p2, 8765, descr=tiddescr)
             setfield_gc(p2, 5, descr=blendescr)
-            p3 = int_add(p2, %(bdescr.get_base_size(False) + 8)d)
+            p3 = int_add(p2, %(bdescr.basesize + 8)d)
             setfield_gc(p3, 8765, descr=tiddescr)
             setfield_gc(p3, 5, descr=blendescr)
             jump()
@@ -333,7 +329,7 @@
         """, """
             []
             p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
-                                %(bdescr.get_base_size(False) + 100)d)
+                                %(bdescr.basesize + 100)d)
             setfield_gc(p0, 8765, descr=tiddescr)
             setfield_gc(p0, 100, descr=blendescr)
             jump()
@@ -350,14 +346,14 @@
         """, """
             []
             p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
-                              %(2 * (bdescr.get_base_size(False) + 104))d)
+                              %(2 * (bdescr.basesize + 104))d)
             setfield_gc(p0, 8765, descr=tiddescr)
             setfield_gc(p0, 101, descr=blendescr)
-            p1 = int_add(p0, %(bdescr.get_base_size(False) + 104)d)
+            p1 = int_add(p0, %(bdescr.basesize + 104)d)
             setfield_gc(p1, 8765, descr=tiddescr)
             setfield_gc(p1, 102, descr=blendescr)
             p2 = call_malloc_nursery(ConstClass(malloc_nursery), \
-                              %(bdescr.get_base_size(False) + 104)d)
+                              %(bdescr.basesize + 104)d)
             setfield_gc(p2, 8765, descr=tiddescr)
             setfield_gc(p2, 103, descr=blendescr)
             jump()
@@ -402,12 +398,12 @@
         """, """
             [i2]
             p0 = call_malloc_nursery(ConstClass(malloc_nursery),     \
-                                %(str_basesize + 16 * str_itemsize + \
-                                  unicode_basesize + 10 * unicode_itemsize)d)
-            setfield_gc(p0, %(str_type_id)d, descr=tiddescr)
+                      %(strdescr.basesize + 16 * strdescr.itemsize + \
+                        unicodedescr.basesize + 10 * unicodedescr.itemsize)d)
+            setfield_gc(p0, %(strdescr.tid)d, descr=tiddescr)
             setfield_gc(p0, 14, descr=strlendescr)
-            p1 = int_add(p0, %(str_basesize + 16 * str_itemsize)d)
-            setfield_gc(p1, %(unicode_type_id)d, descr=tiddescr)
+            p1 = int_add(p0, %(strdescr.basesize + 16 * strdescr.itemsize)d)
+            setfield_gc(p1, %(unicodedescr.tid)d, descr=tiddescr)
             setfield_gc(p1, 10, descr=unicodelendescr)
             p2 = call_malloc_gc(ConstClass(malloc_unicode), i2)
             p3 = call_malloc_gc(ConstClass(malloc_str), i2)


More information about the pypy-commit mailing list