[pypy-svn] r67331 - in pypy/branch/pyjitpl5-llmodel/pypy: jit/backend jit/backend/llsupport jit/backend/llsupport/test jit/backend/x86 jit/backend/x86/test jit/metainterp rpython/memory/gctransform

arigo at codespeak.net arigo at codespeak.net
Sat Aug 29 23:00:30 CEST 2009


Author: arigo
Date: Sat Aug 29 23:00:29 2009
New Revision: 67331

Added:
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py   (contents, props changed)
Modified:
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py
   pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py
   pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py
Log:
In-progress.  We can now at least test directly the code in gc.py.


Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/descr.py	Sat Aug 29 23:00:29 2009
@@ -1,4 +1,3 @@
-import weakref
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr
@@ -11,6 +10,21 @@
 # (in methods actually) using a few classes instead of just one.
 
 
+class GcCache(object):
+    def __init__(self, translate_support_code):
+        self.translate_support_code = translate_support_code
+        self._cache_size = {}
+        self._cache_field = {}
+        self._cache_array = {}
+        self._cache_call = {}
+
+    def init_size_descr(self, STRUCT, sizedescr):
+        pass
+
+    def init_array_descr(self, ARRAY, arraydescr):
+        pass
+
+
 # ____________________________________________________________
 # SizeDescrs
 
@@ -23,15 +37,15 @@
 
 BaseSizeDescr = SizeDescr
 
-def get_size_descr(STRUCT, translate_support_code,
-                   _cache=weakref.WeakKeyDictionary()):
+def get_size_descr(gccache, STRUCT):
+    cache = gccache._cache_size
     try:
-        return _cache[STRUCT][translate_support_code]
+        return cache[STRUCT]
     except KeyError:
-        size = symbolic.get_size(STRUCT, translate_support_code)
+        size = symbolic.get_size(STRUCT, gccache.translate_support_code)
         sizedescr = SizeDescr(size)
-        cachedict = _cache.setdefault(STRUCT, {})
-        cachedict[translate_support_code] = sizedescr
+        gccache.init_size_descr(STRUCT, sizedescr)
+        cache[STRUCT] = sizedescr
         return sizedescr
 
 
@@ -70,17 +84,17 @@
     return getDescrClass(TYPE, BaseFieldDescr, GcPtrFieldDescr,
                          NonGcPtrFieldDescr, 'Field')
 
-def get_field_descr(STRUCT, fieldname, translate_support_code,
-                    _cache=weakref.WeakKeyDictionary()):
+def get_field_descr(gccache, STRUCT, fieldname):
+    cache = gccache._cache_field
     try:
-        return _cache[STRUCT][fieldname, translate_support_code]
+        return cache[STRUCT][fieldname]
     except KeyError:
         offset, _ = symbolic.get_field_token(STRUCT, fieldname,
-                                             translate_support_code)
+                                             gccache.translate_support_code)
         FIELDTYPE = getattr(STRUCT, fieldname)
         fielddescr = getFieldDescrClass(FIELDTYPE)(offset)
-        cachedict = _cache.setdefault(STRUCT, {})
-        cachedict[fieldname, translate_support_code] = fielddescr
+        cachedict = cache.setdefault(STRUCT, {})
+        cachedict[fieldname] = fielddescr
         return fielddescr
 
 
@@ -91,6 +105,7 @@
 
 
 class BaseArrayDescr(AbstractDescr):
+    _clsname = ''
 
     def get_base_size(self, translate_support_code):
         basesize, _, _ = symbolic.get_array_token(_A, translate_support_code)
@@ -124,9 +139,10 @@
     return getDescrClass(ARRAY.OF, BaseArrayDescr, GcPtrArrayDescr,
                          NonGcPtrArrayDescr, 'Array')
 
-def get_array_descr(ARRAY, _cache=weakref.WeakKeyDictionary()):
+def get_array_descr(gccache, ARRAY):
+    cache = gccache._cache_array
     try:
-        return _cache[ARRAY]
+        return cache[ARRAY]
     except KeyError:
         arraydescr = getArrayDescrClass(ARRAY)()
         # verify basic assumption that all arrays' basesize and ofslength
@@ -135,7 +151,8 @@
         assert basesize == arraydescr.get_base_size(False)
         assert itemsize == arraydescr.get_item_size(False)
         assert ofslength == arraydescr.get_ofs_length(False)
-        _cache[ARRAY] = arraydescr
+        gccache.init_array_descr(ARRAY, arraydescr)
+        cache[ARRAY] = arraydescr
         return arraydescr
 
 
@@ -144,6 +161,7 @@
 
 class BaseCallDescr(AbstractDescr):
     call_loop = None
+    arg_classes = []     # <-- annotation hack
 
     def __init__(self, arg_classes):
         self.arg_classes = arg_classes    # list of BoxInt/BoxPtr classes
@@ -196,7 +214,7 @@
         return self.result_size
 
 
-def get_call_descr(ARGS, RESULT, translate_support_code, cache):
+def get_call_descr(gccache, ARGS, RESULT):
     arg_classes = []
     for ARG in ARGS:
         kind = getkind(ARG)
@@ -207,9 +225,10 @@
     if RESULT is lltype.Void:
         result_size = 0
     else:
-        result_size = symbolic.get_size(RESULT, translate_support_code)
+        result_size = symbolic.get_size(RESULT, gccache.translate_support_code)
     ptr = isinstance(RESULT, lltype.Ptr) and RESULT.TO._gckind == 'gc'
-    key = (translate_support_code, tuple(arg_classes), result_size, ptr)
+    key = (tuple(arg_classes), result_size, ptr)
+    cache = gccache._cache_call
     try:
         return cache[key]
     except KeyError:

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/gc.py	Sat Aug 29 23:00:29 2009
@@ -1,4 +1,5 @@
 from pypy.rlib import rgc
+from pypy.rlib.objectmodel import we_are_translated
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.annlowlevel import llhelper
@@ -6,11 +7,13 @@
 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 GcCache, get_field_descr
 
 # ____________________________________________________________
 
-class GcLLDescription:
-    def __init__(self, gcdescr, cpu):
+class GcLLDescription(GcCache):
+    def __init__(self, gcdescr, translator=None):
+        GcCache.__init__(self, translator is not None)
         self.gcdescr = gcdescr
     def _freeze_(self):
         return True
@@ -24,11 +27,10 @@
 class GcLLDescr_boehm(GcLLDescription):
     moving_gc = False
     gcrootmap = None
-    array_length_ofs = 0
 
-    def __init__(self, gcdescr, cpu):
+    def __init__(self, gcdescr, translator):
+        GcLLDescription.__init__(self, gcdescr, translator)
         # grab a pointer to the Boehm 'malloc' function
-        self.translate_support_code = cpu.translate_support_code
         compilation_info = ExternalCompilationInfo(libraries=['gc'])
         malloc_fn_ptr = rffi.llexternal("GC_local_malloc",
                                         [lltype.Signed], # size_t, but good enough
@@ -90,7 +92,10 @@
     get_funcptr_for_newstr = None
     get_funcptr_for_newunicode = None
 
+
 # ____________________________________________________________
+# All code below is for the hybrid GC
+
 
 class GcRefList:
     """Handles all references from the generated assembler to GC objects.
@@ -104,7 +109,9 @@
     HASHTABLE_SIZE = 1 << HASHTABLE_BITS
 
     def __init__(self):
-        self.list = self.alloc_gcref_list(2000)
+        if we_are_translated(): n = 2000
+        else:                   n = 10    # tests only
+        self.list = self.alloc_gcref_list(n)
         self.nextindex = 0
         self.oldlists = []
         # A pseudo dictionary: it is fixed size, and it may contain
@@ -122,8 +129,11 @@
     def alloc_gcref_list(self, n):
         # Important: the GRREF_LISTs allocated are *non-movable*.  This
         # requires support in the gc (only the hybrid GC supports it so far).
-        list = rgc.malloc_nonmovable(self.GCREF_LIST, n)
-        assert list, "malloc_nonmovable failed!"
+        if we_are_translated():
+            list = rgc.malloc_nonmovable(self.GCREF_LIST, n)
+            assert list, "malloc_nonmovable failed!"
+        else:
+            list = lltype.malloc(self.GCREF_LIST, n)     # for tests only
         return list
 
     def get_address_of_gcref(self, gcref):
@@ -136,7 +146,9 @@
         hash &= self.HASHTABLE_SIZE - 1
         addr_ref = self.hashtable[hash]
         # the following test is safe anyway, because the addresses found
-        # in the hashtable are always the addresses of nonmovable stuff:
+        # in the hashtable are always the addresses of nonmovable stuff
+        # ('addr_ref' is an address inside self.list, not directly the
+        # address of a real moving GC object -- that's 'addr_ref.address[0]'.)
         if addr_ref.address[0] == addr:
             return addr_ref
         # if it fails, add an entry to the list
@@ -198,7 +210,7 @@
         self._gcmap_curlength = index + 2
 
     def _enlarge_gcmap(self):
-        newlength = 128 + self._gcmap_maxlength * 5 // 4
+        newlength = 250 + self._gcmap_maxlength * 2
         newgcmap = lltype.malloc(self.GCMAP_ARRAY, newlength, flavor='raw')
         oldgcmap = self._gcmap
         for i in range(self._gcmap_curlength):
@@ -210,7 +222,7 @@
 
     def encode_callshape(self, gclocs):
         """Encode a callshape from the list of locations containing GC
-        pointers."""
+        pointers.  'gclocs' is a list of offsets relative to EBP."""
         shape = self._get_callshape(gclocs)
         return self._compress_callshape(shape)
 
@@ -222,9 +234,7 @@
                  self.LOC_EBP_BASED | 0,     # saved %ebp:  at    (%ebp)
                  0]
         for loc in gclocs:
-            assert isinstance(loc, MODRM)
-            assert loc.is_relative_to_ebp()
-            shape.append(self.LOC_EBP_BASED | (-4 * (4 + loc.position)))
+            shape.append(self.LOC_EBP_BASED | loc)
         return shape
 
     def _compress_callshape(self, shape):
@@ -254,11 +264,13 @@
 class GcLLDescr_framework(GcLLDescription):
     GcRefList = GcRefList
 
-    def __init__(self, gcdescr, cpu):
+    def __init__(self, gcdescr, translator, llop1=llop):
         from pypy.rpython.memory.gc.base import choose_gc_from_config
         from pypy.rpython.memory.gctransform import framework
-        self.cpu = cpu
-        self.translator = cpu.mixlevelann.rtyper.annotator.translator
+        GcLLDescription.__init__(self, gcdescr, translator)
+        assert self.translate_support_code, "required with the framework GC"
+        self.translator = translator
+        self.llop1 = llop1
 
         # we need the hybrid GC for GcRefList.alloc_gcref_list() to work
         if gcdescr.config.translation.gc != 'hybrid':
@@ -287,15 +299,15 @@
         self.GCClass, _ = choose_gc_from_config(gcdescr.config)
         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 = symbolic.get_array_token(
-            lltype.GcArray(lltype.Signed), True)
+        self.fielddescr_tid = get_field_descr(self, self.GCClass.HDR, 'tid')
+        (self.array_basesize, _, self.array_length_ofs) = \
+             symbolic.get_array_token(lltype.GcArray(lltype.Signed), True)
 
         # make a malloc function, with three arguments
         def malloc_basic(size, type_id, has_finalizer):
-            res = llop.do_malloc_fixedsize_clear(llmemory.GCREF,
-                                                 type_id, size, True,
-                                                 has_finalizer, False)
+            res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+                                                  type_id, size, True,
+                                                  has_finalizer, False)
             #llop.debug_print(lltype.Void, "\tmalloc_basic", size, type_id,
             #                 "-->", res)
             return res
@@ -305,10 +317,10 @@
         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(
+        def malloc_array(itemsize, type_id, num_elem):
+            return llop1.do_malloc_varsize_clear(
                 llmemory.GCREF,
-                type_id, num_elem, basesize, itemsize,
+                type_id, num_elem, self.array_basesize, itemsize,
                 self.array_length_ofs, True, False)
         self.malloc_array = malloc_array
         self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType(
@@ -322,12 +334,12 @@
         unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE)
         #
         def malloc_str(length):
-            return llop.do_malloc_varsize_clear(
+            return llop1.do_malloc_varsize_clear(
                 llmemory.GCREF,
                 str_type_id, length, str_basesize, str_itemsize,
                 str_ofs_length, True, False)
         def malloc_unicode(length):
-            return llop.do_malloc_varsize_clear(
+            return llop1.do_malloc_varsize_clear(
                 llmemory.GCREF,
                 unicode_type_id, length, unicode_basesize, unicode_itemsize,
                 unicode_ofs_length, True, False)
@@ -336,57 +348,41 @@
         self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType(
             [lltype.Signed], llmemory.GCREF))
 
-    def sizeof(self, S, translate_support_code):
+    def init_size_descr(self, S, descr):
         from pypy.rpython.memory.gctypelayout import weakpointer_offset
-        assert translate_support_code, "required with the framework GC"
-        size = symbolic.get_size(S, True)
         type_id = self.layoutbuilder.get_type_id(S)
         has_finalizer = bool(self.layoutbuilder.has_finalizer(S))
         assert weakpointer_offset(S) == -1     # XXX
-        descr = ConstDescr3(size, 0, has_finalizer)
         descr.type_id = type_id
-        return descr
+        descr.has_finalizer = has_finalizer
 
-    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]
-        # assert ofs_length == self.array_length_ofs --- but it's symbolics...
-        if isinstance(A.OF, lltype.Ptr) and A.OF.TO._gckind == 'gc':
-            ptr = True
-        else:
-            ptr = False
+    def init_array_descr(self, A, descr):
         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.type_id
-        has_finalizer = descrsize.flag2
+    def gc_malloc(self, sizedescr):
+        assert isinstance(sizedescr, BaseSizeDescr)
+        size = sizedescr.size
+        type_id = sizedescr.type_id
+        has_finalizer = sizedescr.has_finalizer
         assert type_id > 0
         return self.malloc_basic(size, type_id, has_finalizer)
 
     def gc_malloc_array(self, arraydescr, num_elem):
-        assert isinstance(arraydescr, ConstDescr3)
-        basesize = arraydescr.v0
-        itemsize = arraydescr.v1
+        assert isinstance(arraydescr, BaseArrayDescr)
+        itemsize = arraydescr.get_item_size(self.translate_support_code)
         type_id = arraydescr.type_id
         assert type_id > 0
-        return self.malloc_array(basesize, itemsize, type_id, num_elem)
+        return self.malloc_array(itemsize, type_id, num_elem)
 
-    def gc_malloc_str(self, num_elem, translate_support_code):
-        assert translate_support_code, "required with the framework GC"
+    def gc_malloc_str(self, num_elem):
         return self.malloc_str(num_elem)
 
-    def gc_malloc_unicode(self, num_elem, translate_support_code):
-        assert translate_support_code, "required with the framework GC"
+    def gc_malloc_unicode(self, num_elem):
         return self.malloc_unicode(num_elem)
 
-    def args_for_new(self, descrsize):
-        assert isinstance(descrsize, ConstDescr3)
+    def args_for_new(self, sizedescr):
+        assert isinstance(sizedescr, BaseSizeDescr)
         size = descrsize.v0
         type_id = descrsize.type_id
         has_finalizer = descrsize.flag2
@@ -417,7 +413,8 @@
         if hdr.tid & self.GCClass.JIT_WB_IF_FLAG:
             # get a pointer to the 'remember_young_pointer' function from
             # the GC, and call it immediately
-            funcptr = llop.get_write_barrier_failing_case(self.WB_FUNCPTR)
+            llop1 = self.llop1
+            funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
             funcptr(llmemory.cast_ptr_to_adr(gcref_struct),
                     llmemory.cast_ptr_to_adr(gcref_newptr))
 
@@ -449,7 +446,7 @@
         mc.PUSHA()                   # 1 byte
         mc.PUSH(value_reg)           # 1 or 5 bytes
         mc.PUSH(base_reg)            # 1 or 5 bytes
-        funcptr = llop.get_write_barrier_failing_case(self.WB_FUNCPTR)
+        funcptr = self.llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
         funcaddr = rffi.cast(lltype.Signed, funcptr)
         mc.CALL(rel32(funcaddr))     # 5 bytes
         mc.POP(eax)                  # 1 byte
@@ -460,7 +457,8 @@
 
 # ____________________________________________________________
 
-def get_ll_description(gcdescr, cpu):
+def get_ll_description(gcdescr, translator=None):
+    # translator is None if translate_support_code is False.
     if gcdescr is not None:
         name = gcdescr.config.translation.gctransformer
     else:
@@ -469,5 +467,5 @@
         cls = globals()['GcLLDescr_' + name]
     except KeyError:
         raise NotImplementedError("GC transformer %r not supported by "
-                                  "the x86 backend" % (name,))
-    return cls(gcdescr, cpu)
+                                  "the JIT backend" % (name,))
+    return cls(gcdescr, translator)

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/llmodel.py	Sat Aug 29 23:00:29 2009
@@ -28,8 +28,11 @@
         self.rtyper = rtyper
         self.stats = stats
         self.translate_support_code = translate_support_code
-        self._call_cache = {}
-        self.gc_ll_descr = get_ll_description(gcdescr, self)
+        if translate_support_code:
+            translator = rtyper.annotator.translator
+        else:
+            translator = None
+        self.gc_ll_descr = get_ll_description(gcdescr, translator)
         self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT,
                                                          'typeptr',
                                                         translate_support_code)
@@ -58,11 +61,6 @@
     # ------------------- helpers and descriptions --------------------
 
     @staticmethod
-    def cast_adr_to_int(x):
-        res = rffi.cast(lltype.Signed, x)
-        return res
-
-    @staticmethod
     def cast_int_to_gcref(x):
         if not we_are_translated():
             _check_addr_range(x)
@@ -78,11 +76,15 @@
             _check_addr_range(x)
         return rffi.cast(llmemory.Address, x)
 
+    @staticmethod
+    def cast_adr_to_int(x):
+        return rffi.cast(lltype.Signed, x)
+
     def sizeof(self, S):
-        return get_size_descr(S, self.translate_support_code)
+        return get_size_descr(self.gc_ll_descr, S)
 
     def fielddescrof(self, STRUCT, fieldname):
-        return get_field_descr(STRUCT, fieldname, self.translate_support_code)
+        return get_field_descr(self.gc_ll_descr, STRUCT, fieldname)
 
     def unpack_fielddescr(self, fielddescr):
         assert isinstance(fielddescr, BaseFieldDescr)
@@ -93,7 +95,7 @@
     unpack_fielddescr._always_inline_ = True
 
     def arraydescrof(self, A):
-        return get_array_descr(A)
+        return get_array_descr(self.gc_ll_descr, A)
 
     def unpack_arraydescr(self, arraydescr):
         assert isinstance(arraydescr, BaseArrayDescr)
@@ -104,8 +106,7 @@
     unpack_arraydescr._always_inline_ = True
 
     def calldescrof(self, FUNC, ARGS, RESULT):
-        return get_call_descr(ARGS, RESULT, self.translate_support_code,
-                              self._call_cache)
+        return get_call_descr(self.gc_ll_descr, ARGS, RESULT)
 
     def get_overflow_error(self):
         ovf_vtable = self.cast_adr_to_int(self._ovf_error_vtable)

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_descr.py	Sat Aug 29 23:00:29 2009
@@ -5,17 +5,19 @@
 
 
 def test_get_size_descr():
+    c0 = GcCache(False)
+    c1 = GcCache(True)
     T = lltype.GcStruct('T')
     S = lltype.GcStruct('S', ('x', lltype.Char),
                              ('y', lltype.Ptr(T)))
-    descr_s = get_size_descr(S, False)
-    descr_t = get_size_descr(T, False)
+    descr_s = get_size_descr(c0, S)
+    descr_t = get_size_descr(c0, T)
     assert descr_s.size == symbolic.get_size(S, False)
     assert descr_t.size == symbolic.get_size(T, False)
-    assert descr_s == get_size_descr(S, False)
-    assert descr_s != get_size_descr(S, True)
+    assert descr_s == get_size_descr(c0, S)
+    assert descr_s != get_size_descr(c1, S)
     #
-    descr_s = get_size_descr(S, True)
+    descr_s = get_size_descr(c1, S)
     assert isinstance(descr_s.size, Symbolic)
 
 
@@ -31,12 +33,15 @@
     assert cls != getFieldDescrClass(lltype.Signed)
     assert cls == getFieldDescrClass(lltype.Char)
     #
-    assert get_field_descr(S, 'y', False) == get_field_descr(S, 'y', False)
-    assert get_field_descr(S, 'y', False) != get_field_descr(S, 'y', True)
+    c0 = GcCache(False)
+    c1 = GcCache(True)
+    assert get_field_descr(c0, S, 'y') == get_field_descr(c0, S, 'y')
+    assert get_field_descr(c0, S, 'y') != get_field_descr(c1, S, 'y')
     for tsc in [False, True]:
-        descr_x = get_field_descr(S, 'x', tsc)
-        descr_y = get_field_descr(S, 'y', tsc)
-        descr_z = get_field_descr(S, 'z', tsc)
+        c2 = GcCache(tsc)
+        descr_x = get_field_descr(c2, S, 'x')
+        descr_y = get_field_descr(c2, S, 'y')
+        descr_z = get_field_descr(c2, S, 'z')
         assert descr_x.__class__ is cls
         assert descr_y.__class__ is GcPtrFieldDescr
         assert descr_z.__class__ is NonGcPtrFieldDescr
@@ -70,13 +75,14 @@
     assert cls != getArrayDescrClass(lltype.GcArray(lltype.Signed))
     assert cls == getArrayDescrClass(lltype.GcArray(lltype.Char))
     #
-    descr1 = get_array_descr(A1)
-    descr2 = get_array_descr(A2)
-    descr3 = get_array_descr(A3)
+    c0 = GcCache(False)
+    descr1 = get_array_descr(c0, A1)
+    descr2 = get_array_descr(c0, A2)
+    descr3 = get_array_descr(c0, A3)
     assert descr1.__class__ is cls
     assert descr2.__class__ is GcPtrArrayDescr
     assert descr3.__class__ is NonGcPtrArrayDescr
-    assert descr1 == get_array_descr(lltype.GcArray(lltype.Char))
+    assert descr1 == get_array_descr(c0, lltype.GcArray(lltype.Char))
     assert not descr1.is_array_of_pointers()
     assert     descr2.is_array_of_pointers()
     assert not descr3.is_array_of_pointers()
@@ -104,52 +110,49 @@
 
 
 def test_get_call_descr():
-    cache = {}
-    descr1 = get_call_descr([lltype.Char, lltype.Signed], lltype.Char, False,
-                            cache)
+    c0 = GcCache(False)
+    descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char)
     assert descr1.get_result_size(False) == rffi.sizeof(lltype.Char)
     assert not descr1.returns_a_pointer()
     assert descr1.arg_classes == [BoxInt, BoxInt]
     #
     T = lltype.GcStruct('T')
-    descr2 = get_call_descr([lltype.Ptr(T)], lltype.Ptr(T), False, cache)
+    descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T))
     assert descr2.get_result_size(False) == rffi.sizeof(lltype.Ptr(T))
     assert descr2.returns_a_pointer()
     assert descr2.arg_classes == [BoxPtr]
     #
     U = lltype.GcStruct('U', ('x', lltype.Signed))
-    assert descr2 == get_call_descr([lltype.Ptr(U)], lltype.Ptr(U), False,
-                                    cache)
+    assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U))
 
 
 def test_repr_of_descr():
+    c0 = GcCache(False)
     T = lltype.GcStruct('T')
     S = lltype.GcStruct('S', ('x', lltype.Char),
                              ('y', lltype.Ptr(T)),
                              ('z', lltype.Ptr(T)))
-    descr1 = get_size_descr(S, False)
+    descr1 = get_size_descr(c0, S)
     s = symbolic.get_size(S, False)
     assert descr1.repr_of_descr() == '<SizeDescr %d>' % s
     #
-    descr2 = get_field_descr(S, 'y', False)
+    descr2 = get_field_descr(c0, S, 'y')
     o, _ = symbolic.get_field_token(S, 'y', False)
     assert descr2.repr_of_descr() == '<GcPtrFieldDescr %d>' % o
     #
-    descr2i = get_field_descr(S, 'x', False)
+    descr2i = get_field_descr(c0, S, 'x')
     o, _ = symbolic.get_field_token(S, 'x', False)
     assert descr2i.repr_of_descr() == '<CharFieldDescr %d>' % o
     #
-    descr3 = get_array_descr(lltype.GcArray(lltype.Ptr(S)))
+    descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S)))
     assert descr3.repr_of_descr() == '<GcPtrArrayDescr>'
     #
-    descr3i = get_array_descr(lltype.GcArray(lltype.Char))
+    descr3i = get_array_descr(c0, lltype.GcArray(lltype.Char))
     assert descr3i.repr_of_descr() == '<CharArrayDescr>'
     #
     cache = {}
-    descr4 = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Ptr(S),
-                            False, cache)
+    descr4 = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Ptr(S))
     assert 'GcPtrCallDescr' in descr4.repr_of_descr()
     #
-    descr4i = get_call_descr([lltype.Char, lltype.Ptr(S)], lltype.Char,
-                             False, cache)
+    descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char)
     assert 'IntCallDescr' in descr4i.repr_of_descr()

Added: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/llsupport/test/test_gc.py	Sat Aug 29 23:00:29 2009
@@ -0,0 +1,170 @@
+import random
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr
+from pypy.jit.backend.llsupport.descr import *
+from pypy.jit.backend.llsupport.gc import *
+from pypy.jit.backend.llsupport import symbolic
+from pypy.jit.metainterp.gc import get_description
+
+
+def test_boehm():
+    gc_ll_descr = GcLLDescr_boehm(None, None)
+    #
+    record = []
+    prev_funcptr_for_new = gc_ll_descr.funcptr_for_new
+    def my_funcptr_for_new(size):
+        p = prev_funcptr_for_new(size)
+        record.append((size, p))
+        return p
+    gc_ll_descr.funcptr_for_new = my_funcptr_for_new
+    #
+    # ---------- gc_malloc ----------
+    S = lltype.GcStruct('S', ('x', lltype.Signed))
+    sizedescr = get_size_descr(gc_ll_descr, S)
+    p = gc_ll_descr.gc_malloc(sizedescr)
+    assert record == [(sizedescr.size, p)]
+    del record[:]
+    # ---------- gc_malloc_array ----------
+    A = lltype.GcArray(lltype.Signed)
+    arraydescr = get_array_descr(gc_ll_descr, A)
+    p = gc_ll_descr.gc_malloc_array(arraydescr, 10)
+    assert record == [(arraydescr.get_base_size(False) +
+                       10 * arraydescr.get_item_size(False), p)]
+    del record[:]
+    # ---------- gc_malloc_str ----------
+    p = gc_ll_descr.gc_malloc_str(10)
+    basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, False)
+    assert record == [(basesize + 10 * itemsize, p)]
+    del record[:]
+    # ---------- gc_malloc_unicode ----------
+    p = gc_ll_descr.gc_malloc_unicode(10)
+    basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
+                                                              False)
+    assert record == [(basesize + 10 * itemsize, p)]
+    del record[:]
+
+# ____________________________________________________________
+
+def test_GcRefList():
+    S = lltype.GcStruct('S')
+    order = range(50) * 4
+    random.shuffle(order)
+    allocs = [lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))
+              for i in range(50)]
+    allocs = [allocs[i] for i in order]
+    #
+    gcrefs = GcRefList()
+    addrs = [gcrefs.get_address_of_gcref(ptr) for ptr in allocs]
+    for i in range(len(allocs)):
+        assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i])
+
+def test_GcRootMap_asmgcc():
+    def stack_pos(n):
+        return -4*(4+n)
+    gcrootmap = GcRootMap_asmgcc()
+    num1 = stack_pos(1)
+    num2 = stack_pos(55)
+    shape = gcrootmap._get_callshape([num1, num2])
+    assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2]
+    #
+    shapeaddr = gcrootmap.encode_callshape([num1, num2])
+    PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY)
+    p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE)
+    num1a = -2*(num1|2)-1
+    num2a = ((-2*(num2|2)-1) >> 7) | 128
+    num2b = (-2*(num2|2)-1) & 127
+    for i, expected in enumerate([num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]):
+        assert p[i] == expected
+    #
+    retaddr = rffi.cast(llmemory.Address, 1234567890)
+    gcrootmap.put(retaddr, shapeaddr)
+    assert gcrootmap._gcmap[0] == retaddr
+    assert gcrootmap._gcmap[1] == shapeaddr
+    assert gcrootmap.gcmapstart().address[0] == retaddr
+    #
+    # the same as before, but enough times to trigger a few resizes
+    expected_shapeaddr = {}
+    for i in range(1, 600):
+        shapeaddr = gcrootmap.encode_callshape([stack_pos(i)])
+        expected_shapeaddr[i] = shapeaddr
+        retaddr = rffi.cast(llmemory.Address, 123456789 + i)
+        gcrootmap.put(retaddr, shapeaddr)
+    for i in range(1, 600):
+        expected_retaddr = rffi.cast(llmemory.Address, 123456789 + i)
+        assert gcrootmap._gcmap[i*2+0] == expected_retaddr
+        assert gcrootmap._gcmap[i*2+1] == expected_shapeaddr[i]
+
+
+class FakeLLOp:
+    def __init__(self):
+        self.record = []
+
+    def do_malloc_fixedsize_clear(self, RESTYPE, type_id, size, can_collect,
+                                  has_finalizer, contains_weakptr):
+        assert can_collect
+        assert not contains_weakptr
+        p = llmemory.raw_malloc(size)
+        p = llmemory.cast_adr_to_ptr(p, RESTYPE)
+        self.record.append(("fixedsize", type_id, repr(size),
+                            has_finalizer, p))
+        return p
+
+    def do_malloc_varsize_clear(self, RESTYPE, type_id, length, size,
+                                itemsize, offset_to_length, can_collect,
+                                has_finalizer):
+        assert can_collect
+        assert not has_finalizer
+        p = llmemory.raw_malloc(size + itemsize * length)
+        (p + offset_to_length).signed[0] = length
+        p = llmemory.cast_adr_to_ptr(p, RESTYPE)
+        self.record.append(("varsize", type_id, length,
+                            repr(size), repr(itemsize),
+                            repr(offset_to_length), p))
+        return p
+
+
+def test_framework_malloc():
+    class FakeTranslator:
+        pass
+    class config:
+        class translation:
+            gc = 'hybrid'
+            gcrootfinder = 'asmgcc'
+            gctransformer = 'framework'
+    gcdescr = get_description(config)
+    translator = FakeTranslator()
+    llop1 = FakeLLOp()
+    gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1)
+    #
+    # ---------- gc_malloc ----------
+    S = lltype.GcStruct('S', ('x', lltype.Signed))
+    sizedescr = get_size_descr(gc_ll_descr, S)
+    p = gc_ll_descr.gc_malloc(sizedescr)
+    assert llop1.record == [("fixedsize", sizedescr.type_id,
+                             repr(sizedescr.size), False, p)]
+    del llop1.record[:]
+    # ---------- gc_malloc_array ----------
+    A = lltype.GcArray(lltype.Signed)
+    arraydescr = get_array_descr(gc_ll_descr, A)
+    p = gc_ll_descr.gc_malloc_array(arraydescr, 10)
+    assert llop1.record == [("varsize", arraydescr.type_id, 10,
+                             repr(arraydescr.get_base_size(True)),
+                             repr(arraydescr.get_item_size(True)),
+                             repr(arraydescr.get_ofs_length(True)), p)]
+    del llop1.record[:]
+    # ---------- gc_malloc_str ----------
+    p = gc_ll_descr.gc_malloc_str(10)
+    type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.STR)
+    basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, True)
+    assert llop1.record == [("varsize", type_id, 10,
+                             repr(basesize), repr(itemsize), repr(ofs_length),
+                             p)]
+    del llop1.record[:]
+    # ---------- gc_malloc_unicode ----------
+    p = gc_ll_descr.gc_malloc_unicode(10)
+    type_id = gc_ll_descr.layoutbuilder.get_type_id(rstr.UNICODE)
+    basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
+                                                              True)
+    assert llop1.record == [("varsize", type_id, 10,
+                             repr(basesize), repr(itemsize), repr(ofs_length),
+                             p)]
+    del llop1.record[:]

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/model.py	Sat Aug 29 23:00:29 2009
@@ -92,11 +92,11 @@
     def typedescrof(TYPE):
         raise NotImplementedError
 
-    def cast_adr_to_int(self, adr):
-        raise NotImplementedError
+    #def cast_adr_to_int(self, adr):
+    #    raise NotImplementedError
 
-    def cast_int_to_adr(self, int):
-        raise NotImplementedError
+    #def cast_int_to_adr(self, int):
+    #    raise NotImplementedError
 
     # ---------- the backend-dependent operations ----------
 

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/runner.py	Sat Aug 29 23:00:29 2009
@@ -18,13 +18,10 @@
     BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
 
     def __init__(self, rtyper, stats, translate_support_code=False,
-                 mixlevelann=None, gcdescr=None):
+                 gcdescr=None):
         AbstractLLCPU.__init__(self, rtyper, stats, translate_support_code,
                                gcdescr)
-        if translate_support_code:
-            assert mixlevelann
-            self.mixlevelann = mixlevelann
-        else:
+        if not translate_support_code:
             self.current_interpreter = LLInterpreter(self.rtyper)
 
             def _store_exception(lle):

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/backend/x86/test/test_zrpy_gc.py	Sat Aug 29 23:00:29 2009
@@ -11,7 +11,7 @@
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rlib.jit import JitDriver
 from pypy.jit.backend.x86.runner import CPU386
-from pypy.jit.backend.x86.gc import GcRefList, GcRootMap_asmgcc
+from pypy.jit.backend.llsupport.gc import GcRefList, GcRootMap_asmgcc
 from pypy.jit.backend.x86.regalloc import stack_pos
 
 
@@ -82,22 +82,6 @@
     res = compile_and_run(get_test(main), "boehm", jit=True)
     assert int(res) >= 16
 
-def test_GcRefList():
-    S = lltype.GcStruct('S')
-    order = range(20000) * 4
-    random.shuffle(order)
-    def fn(args):
-        allocs = [lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S))
-                  for i in range(20000)]
-        allocs = [allocs[i] for i in order]
-        #
-        gcrefs = GcRefList()
-        addrs = [gcrefs.get_address_of_gcref(ptr) for ptr in allocs]
-        for i in range(len(allocs)):
-            assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i])
-        return 0
-    compile_and_run(fn, "hybrid", gcrootfinder="asmgcc", jit=False)
-
 def test_compile_hybrid_1():
     # a moving GC.  Supports malloc_varsize_nonmovable.  Simple test, works
     # without write_barriers and root stack enumeration.
@@ -113,39 +97,8 @@
                           jit=True)
     assert int(res) == 20
 
-def test_GcRootMap_asmgcc():
-    gcrootmap = GcRootMap_asmgcc()
-    shape = gcrootmap._get_callshape([stack_pos(1), stack_pos(55)])
-    num1 = stack_pos(1).ofs_relative_to_ebp()
-    num2 = stack_pos(55).ofs_relative_to_ebp()
-    assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2]
-    #
-    shapeaddr = gcrootmap.encode_callshape([stack_pos(1), stack_pos(55)])
-    PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY)
-    p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE)
-    num1a = -2*(num1|2)-1
-    num2a = ((-2*(num2|2)-1) >> 7) | 128
-    num2b = (-2*(num2|2)-1) & 127
-    for i, expected in enumerate([num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]):
-        assert p[i] == expected
-    #
-    retaddr = rffi.cast(llmemory.Address, 1234567890)
-    gcrootmap.put(retaddr, shapeaddr)
-    assert gcrootmap._gcmap[0] == retaddr
-    assert gcrootmap._gcmap[1] == shapeaddr
-    assert gcrootmap.gcmapstart().address[0] == retaddr
-    #
-    # the same as before, but enough times to trigger a few resizes
-    expected_shapeaddr = {}
-    for i in range(1, 600):
-        shapeaddr = gcrootmap.encode_callshape([stack_pos(i)])
-        expected_shapeaddr[i] = shapeaddr
-        retaddr = rffi.cast(llmemory.Address, 123456789 + i)
-        gcrootmap.put(retaddr, shapeaddr)
-    for i in range(1, 600):
-        expected_retaddr = rffi.cast(llmemory.Address, 123456789 + i)
-        assert gcrootmap._gcmap[i*2+0] == expected_retaddr
-        assert gcrootmap._gcmap[i*2+1] == expected_shapeaddr[i]
+def test_get_callshape():
+    xxx #test that _get_callshape() is called with the right arguments
 
 def test_compile_hybrid_2():
     # More complex test, requires root stack enumeration but

Modified: pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/jit/metainterp/warmspot.py	Sat Aug 29 23:00:29 2009
@@ -222,7 +222,7 @@
         else:
             annhelper = None
         cpu = CPUClass(self.translator.rtyper, self.stats,
-                       translate_support_code, annhelper, self.gcdescr)
+                       translate_support_code, gcdescr=self.gcdescr)
         self.cpu = cpu
         self.metainterp_sd = MetaInterpStaticData(self.portal_graph,
                                                   self.translator.graphs, cpu,

Modified: pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/pyjitpl5-llmodel/pypy/rpython/memory/gctransform/framework.py	Sat Aug 29 23:00:29 2009
@@ -607,7 +607,7 @@
                   resultvar=op.result)
 
     def gct_do_malloc_fixedsize_clear(self, hop):
-        # used by the JIT (see the x86 backend)
+        # used by the JIT (see pypy.jit.backend.llsupport.gc)
         op = hop.spaceop
         [v_typeid, v_size, v_can_collect,
          v_has_finalizer, v_contains_weakptr] = op.args
@@ -620,7 +620,7 @@
         self.pop_roots(hop, livevars)
 
     def gct_do_malloc_varsize_clear(self, hop):
-        # used by the JIT (see the x86 backend)
+        # used by the JIT (see pypy.jit.backend.llsupport.gc)
         op = hop.spaceop
         [v_typeid, v_length, v_size, v_itemsize,
          v_offset_to_length, v_can_collect, v_has_finalizer] = op.args



More information about the Pypy-commit mailing list