[pypy-svn] r68254 - in pypy/branch/gc-compress/pypy: rpython/lltypesystem rpython/memory rpython/memory/gc rpython/memory/gctransform rpython/memory/test translator/c/src

arigo at codespeak.net arigo at codespeak.net
Thu Oct 8 18:40:41 CEST 2009


Author: arigo
Date: Thu Oct  8 18:40:40 2009
New Revision: 68254

Modified:
   pypy/branch/gc-compress/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/gc-compress/pypy/rpython/lltypesystem/opimpl.py
   pypy/branch/gc-compress/pypy/rpython/memory/gc/semispace.py
   pypy/branch/gc-compress/pypy/rpython/memory/gctransform/framework.py
   pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py
   pypy/branch/gc-compress/pypy/rpython/memory/test/test_gctypelayout.py
   pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h
Log:
Progress: now semispace can again be translated.


Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/lloperation.py	Thu Oct  8 18:40:40 2009
@@ -412,6 +412,7 @@
     'cast_int_to_adr':      LLOp(canfold=True),   # not implemented in llinterp
     'get_group_member':     LLOp(canfold=True),
     'get_next_group_member':LLOp(canfold=True),
+    'is_group_member_zero': LLOp(canfold=True),
 
     # __________ used by the JIT ________
 

Modified: pypy/branch/gc-compress/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/branch/gc-compress/pypy/rpython/lltypesystem/opimpl.py	Thu Oct  8 18:40:40 2009
@@ -402,6 +402,14 @@
     return lltype.cast_pointer(TYPE, member)
 op_get_next_group_member.need_result_type = True
 
+def op_is_group_member_zero(memberoffset):
+    from pypy.rpython.lltypesystem import llgroup
+    if isinstance(memberoffset, llgroup.GroupMemberOffset):
+        return memberoffset.index == 0
+    else:
+        assert isinstance(memberoffset, int)
+        return memberoffset == 0
+
 # ____________________________________________________________
 
 def get_op_impl(opname):

Modified: pypy/branch/gc-compress/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/memory/gc/semispace.py	(original)
+++ pypy/branch/gc-compress/pypy/rpython/memory/gc/semispace.py	Thu Oct  8 18:40:40 2009
@@ -85,7 +85,7 @@
     # This class only defines the malloc_{fixed,var}size_clear() methods
     # because the spaces are filled with zeroes in advance.
 
-    def malloc_fixedsize_clear(self, typeid, size, can_collect,
+    def malloc_fixedsize_clear(self, typeid16, size, can_collect,
                                has_finalizer=False, contains_weakptr=False):
         size_gc_header = self.gcheaderbuilder.size_gc_header
         totalsize = size_gc_header + size
@@ -95,7 +95,7 @@
                 raise memoryError
             result = self.obtain_free_space(totalsize)
         llarena.arena_reserve(result, totalsize)
-        self.init_gc_object(result, typeid)
+        self.init_gc_object(result, typeid16)
         self.free = result + totalsize
         if has_finalizer:
             self.objects_with_finalizers.append(result + size_gc_header)
@@ -103,7 +103,7 @@
             self.objects_with_weakrefs.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
 
-    def malloc_varsize_clear(self, typeid, length, size, itemsize,
+    def malloc_varsize_clear(self, typeid16, length, size, itemsize,
                              offset_to_length, can_collect):
         size_gc_header = self.gcheaderbuilder.size_gc_header
         nonvarsize = size_gc_header + size
@@ -118,7 +118,7 @@
                 raise memoryError
             result = self.obtain_free_space(totalsize)
         llarena.arena_reserve(result, totalsize)
-        self.init_gc_object(result, typeid)
+        self.init_gc_object(result, typeid16)
         (result + size_gc_header + offset_to_length).signed[0] = length
         self.free = result + llarena.round_up_for_allocation(totalsize)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
@@ -417,14 +417,14 @@
         # done with the typeid is bogus.
         return hdr.typeid16
 
-    def init_gc_object(self, addr, typeid, flags=0):
+    def init_gc_object(self, addr, typeid16, flags=0):
         hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
-        hdr.typeid16 = typeid
+        hdr.typeid16 = typeid16
         hdr.setflags(flags)
 
-    def init_gc_object_immortal(self, addr, typeid, flags=0):
+    def init_gc_object_immortal(self, addr, typeid16, flags=0):
         hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR))
-        hdr.typeid16 = typeid
+        hdr.typeid16 = typeid16
         hdr.setflags(flags | GCFLAG_EXTERNAL | GCFLAG_FORWARDED)
         # immortal objects always have GCFLAG_FORWARDED set;
         # see get_forwarding_address().

Modified: pypy/branch/gc-compress/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/branch/gc-compress/pypy/rpython/memory/gctransform/framework.py	Thu Oct  8 18:40:40 2009
@@ -1,7 +1,7 @@
 from pypy.rpython.memory.gctransform.transform import GCTransformer
 from pypy.rpython.memory.gctransform.support import find_gc_ptrs_in_type, \
      get_rtti, ll_call_destructor, type_contains_pyobjs, var_ispyobj
-from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython import rmodel
 from pypy.rpython.memory import gctypelayout
 from pypy.rpython.memory.gc import marksweep
@@ -22,6 +22,9 @@
 import sys, types
 
 
+TYPE_ID = rffi.USHORT
+
+
 class CollectAnalyzer(graphanalyze.BoolGraphAnalyzer):
 
     def analyze_direct_call(self, graph, seen=None):
@@ -131,11 +134,9 @@
         self.layoutbuilder.transformer = self
         self.get_type_id = self.layoutbuilder.get_type_id
 
-        # set up dummy a table, to be overwritten with the real one in finish()
-        type_info_table = lltype._ptr(
-            lltype.Ptr(gctypelayout.GCData.TYPE_INFO_TABLE),
-            "delayed!type_info_table", solid=True)
-        gcdata = gctypelayout.GCData(type_info_table)
+        # set up GCData with the llgroup from the layoutbuilder, which
+        # will grow as more TYPE_INFO members are added to it
+        gcdata = gctypelayout.GCData(self.layoutbuilder.type_info_group)
 
         # initialize the following two fields with a random non-NULL address,
         # to make the annotator happy.  The fields are patched in finish()
@@ -163,6 +164,8 @@
             gcdata.gc.setup()
 
         bk = self.translator.annotator.bookkeeper
+        r_typeid16 = rffi.platform.numbertype_to_rclass[TYPE_ID]
+        s_typeid16 = annmodel.SomeInteger(knowntype=r_typeid16)
 
         # the point of this little dance is to not annotate
         # self.gcdata.static_root_xyz as constants. XXX is it still needed??
@@ -212,7 +215,7 @@
         malloc_fixedsize_clear_meth = GCClass.malloc_fixedsize_clear.im_func
         self.malloc_fixedsize_clear_ptr = getfn(
             malloc_fixedsize_clear_meth,
-            [s_gc, annmodel.SomeInteger(nonneg=True),
+            [s_gc, s_typeid16,
              annmodel.SomeInteger(nonneg=True),
              annmodel.SomeBool(), annmodel.SomeBool(),
              annmodel.SomeBool()], s_gcref,
@@ -221,7 +224,7 @@
             malloc_fixedsize_meth = GCClass.malloc_fixedsize.im_func
             self.malloc_fixedsize_ptr = getfn(
                 malloc_fixedsize_meth,
-                [s_gc, annmodel.SomeInteger(nonneg=True),
+                [s_gc, s_typeid16,
                  annmodel.SomeInteger(nonneg=True),
                  annmodel.SomeBool(), annmodel.SomeBool(),
                  annmodel.SomeBool()], s_gcref,
@@ -235,7 +238,8 @@
 ##             + [annmodel.SomeBool(), annmodel.SomeBool()], s_gcref)
         self.malloc_varsize_clear_ptr = getfn(
             GCClass.malloc_varsize_clear.im_func,
-            [s_gc] + [annmodel.SomeInteger(nonneg=True) for i in range(5)]
+            [s_gc, s_typeid16]
+            + [annmodel.SomeInteger(nonneg=True) for i in range(4)]
             + [annmodel.SomeBool()], s_gcref)
         self.collect_ptr = getfn(GCClass.collect.im_func,
             [s_gc, annmodel.SomeInteger()], annmodel.s_None)
@@ -268,7 +272,7 @@
             s_True  = annmodel.SomeBool(); s_True .const = True
             self.malloc_fast_ptr = getfn(
                 malloc_fast,
-                [s_gc, annmodel.SomeInteger(nonneg=True),
+                [s_gc, s_typeid16,
                  annmodel.SomeInteger(nonneg=True),
                  s_True, s_False,
                  s_False], s_gcref,
@@ -288,7 +292,7 @@
             s_True  = annmodel.SomeBool(); s_True .const = True
             self.malloc_varsize_clear_fast_ptr = getfn(
                 malloc_varsize_clear_fast,
-                [s_gc, annmodel.SomeInteger(nonneg=True),
+                [s_gc, s_typeid16,
                  annmodel.SomeInteger(nonneg=True),
                  annmodel.SomeInteger(nonneg=True),
                  annmodel.SomeInteger(nonneg=True),
@@ -304,7 +308,7 @@
                 "malloc_varsize_nonmovable")
             self.malloc_varsize_nonmovable_ptr = getfn(
                 malloc_nonmovable,
-                [s_gc, annmodel.SomeInteger(nonneg=True),
+                [s_gc, s_typeid16,
                  annmodel.SomeInteger(nonneg=True)], s_gcref)
         else:
             self.malloc_varsize_nonmovable_ptr = None
@@ -315,7 +319,7 @@
                 "malloc_varsize_resizable")
             self.malloc_varsize_resizable_ptr = getfn(
                 malloc_resizable,
-                [s_gc, annmodel.SomeInteger(nonneg=True),
+                [s_gc, s_typeid16,
                  annmodel.SomeInteger(nonneg=True)], s_gcref)
         else:
             self.malloc_varsize_resizable_ptr = None
@@ -421,21 +425,14 @@
         return [getattr(hdr, fldname) for fldname in HDR._names]
 
     def finish_tables(self):
-        table = self.layoutbuilder.flatten_table()
-        log.info("assigned %s typeids" % (len(table), ))
+        group = self.layoutbuilder.close_table()
+        log.info("assigned %s typeids" % (len(group.members), ))
         log.info("added %s push/pop stack root instructions" % (
                      self.num_pushs, ))
         if self.write_barrier_ptr:
             log.info("inserted %s write barrier calls" % (
                          self.write_barrier_calls, ))
 
-        # replace the type_info_table pointer in gcdata -- at this point,
-        # the database is in principle complete, so it has already seen
-        # the delayed pointer.  We need to force it to consider the new
-        # array now.
-
-        self.gcdata.type_info_table._become(table)
-
         # XXX because we call inputconst already in replace_malloc, we can't
         # modify the instance, we have to modify the 'rtyped instance'
         # instead.  horrors.  is there a better way?
@@ -467,12 +464,14 @@
         """write out the list of type ids together with some info"""
         from pypy.tool.udir import udir
         # XXX not ideal since it is not per compilation, but per run
+        # XXX argh argh, this only gives the member index but not the
+        #     real typeid, which is a complete mess to obtain now...
+        all_ids = self.layoutbuilder.id_of_type.items()
+        all_ids = [(typeinfo.index, TYPE) for (TYPE, typeinfo) in all_ids]
+        all_ids = dict(all_ids)
         f = udir.join("typeids.txt").open("w")
-        all = [(typeid, TYPE)
-               for TYPE, typeid in self.layoutbuilder.id_of_type.iteritems()]
-        all.sort()
-        for typeid, TYPE in all:
-            f.write("%s %s\n" % (typeid, TYPE))
+        for index in range(len(self.layoutbuilder.type_info_group.members)):
+            f.write("member%-4d %s\n" % (index, all_ids.get(index, '?')))
         f.close()
 
     def transform_graph(self, graph):
@@ -502,8 +501,8 @@
         assert PTRTYPE.TO == TYPE
         type_id = self.get_type_id(TYPE)
 
-        c_type_id = rmodel.inputconst(lltype.Signed, type_id)
-        info = self.layoutbuilder.type_info_list[type_id]
+        c_type_id = rmodel.inputconst(TYPE_ID, type_id)
+        info = self.layoutbuilder.get_info(type_id)
         c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
         has_finalizer = bool(self.finalizer_funcptr_for_type(TYPE))
         c_has_finalizer = rmodel.inputconst(lltype.Bool, has_finalizer)
@@ -523,9 +522,12 @@
                     c_has_finalizer, rmodel.inputconst(lltype.Bool, False)]
         else:
             assert not c_has_finalizer.value
+            info_varsize = self.layoutbuilder.get_info_varsize(type_id)
             v_length = op.args[-1]
-            c_ofstolength = rmodel.inputconst(lltype.Signed, info.ofstolength)
-            c_varitemsize = rmodel.inputconst(lltype.Signed, info.varitemsize)
+            c_ofstolength = rmodel.inputconst(lltype.Signed,
+                                              info_varsize.ofstolength)
+            c_varitemsize = rmodel.inputconst(lltype.Signed,
+                                              info_varsize.varitemsize)
             if flags.get('resizable') and self.malloc_varsize_resizable_ptr:
                 assert c_can_collect.value
                 malloc_ptr = self.malloc_varsize_resizable_ptr
@@ -656,8 +658,8 @@
 
         type_id = self.get_type_id(WEAKREF)
 
-        c_type_id = rmodel.inputconst(lltype.Signed, type_id)
-        info = self.layoutbuilder.type_info_list[type_id]
+        c_type_id = rmodel.inputconst(TYPE_ID, type_id)
+        info = self.layoutbuilder.get_info(type_id)
         c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
         malloc_ptr = self.malloc_fixedsize_ptr
         c_has_finalizer = rmodel.inputconst(lltype.Bool, False)

Modified: pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py	(original)
+++ pypy/branch/gc-compress/pypy/rpython/memory/gctypelayout.py	Thu Oct  8 18:40:40 2009
@@ -40,15 +40,15 @@
         self.type_info_group_ptr = type_info_group._as_ptr()
 
     def get(self, typeid):
-        if we_are_translated():
-            ll_assert(typeid, "invalid type_id")
+        ll_assert(not llop.is_group_member_zero(lltype.Bool, typeid),
+                  "invalid type_id")
         return llop.get_group_member(GCData.TYPE_INFO_PTR,
                                      self.type_info_group_ptr,
                                      typeid)
 
     def get_varsize(self, typeid):
-        if we_are_translated():
-            ll_assert(typeid, "invalid type_id")
+        ll_assert(not llop.is_group_member_zero(lltype.Bool, typeid),
+                  "invalid type_id")
         return llop.get_group_member(GCData.VARSIZE_TYPE_INFO_PTR,
                                      self.type_info_group_ptr,
                                      typeid)
@@ -194,9 +194,6 @@
             assert self.can_add_new_types
             assert isinstance(TYPE, (lltype.GcStruct, lltype.GcArray))
             # Record the new type_id description as a TYPE_INFO structure.
-            # It goes into a list for now, which will be turned into a
-            # TYPE_INFO_TABLE in flatten_table() by the gc transformer.
-
             # build the TYPE_INFO structure
             if not TYPE._is_varsize():
                 fullinfo = lltype.malloc(GCData.TYPE_INFO,
@@ -215,6 +212,16 @@
             self.id_of_type[TYPE] = type_id
             return type_id
 
+    def get_info(self, type_id):
+        return llop.get_group_member(GCData.TYPE_INFO_PTR,
+                                     self.type_info_group._as_ptr(),
+                                     type_id)
+
+    def get_info_varsize(self, type_id):
+        return llop.get_group_member(GCData.VARSIZE_TYPE_INFO_PTR,
+                                     self.type_info_group._as_ptr(),
+                                     type_id)
+
     def encode_type_shapes_now(self):
         if not self.can_encode_type_shape:
             self.can_encode_type_shape = True
@@ -240,20 +247,11 @@
             self.offsettable_cache[TYPE] = cachedarray
             return cachedarray
 
-    def flatten_table(self):
+    def close_table(self):
+        # make sure we no longer add members to the type_info_group.
         self.can_add_new_types = False
         self.offsettable_cache = None
-        table = lltype.malloc(GCData.TYPE_INFO_TABLE, len(self.type_info_list),
-                              immortal=True)
-        fieldnames = GCData.TYPE_INFO._names
-        for tableentry, newcontent in zip(table, self.type_info_list):
-            if newcontent is None:    # empty entry
-                tableentry.infobits = 0
-                tableentry.ofstolength = -1
-            else:
-                for name in fieldnames:
-                    setattr(tableentry, name, getattr(newcontent, name))
-        return table
+        return self.type_info_group
 
     def finalizer_funcptr_for_type(self, TYPE):
         if TYPE in self.finalizer_funcptrs:

Modified: pypy/branch/gc-compress/pypy/rpython/memory/test/test_gctypelayout.py
==============================================================================
--- pypy/branch/gc-compress/pypy/rpython/memory/test/test_gctypelayout.py	(original)
+++ pypy/branch/gc-compress/pypy/rpython/memory/test/test_gctypelayout.py	Thu Oct  8 18:40:40 2009
@@ -38,7 +38,7 @@
     for T1, T2 in [(GC_A, GC_S), (GC_A2, GC_S2), (GC_S3, GC_S2)]:
         tid1 = layoutbuilder.get_type_id(T1)
         tid2 = layoutbuilder.get_type_id(T2)
-        gcdata = GCData(layoutbuilder.type_info_list)
+        gcdata = GCData(layoutbuilder.type_info_group)
         lst1 = gcdata.q_varsize_offsets_to_gcpointers_in_var_part(tid1)
         lst2 = gcdata.q_offsets_to_gc_pointers(tid2)
         assert len(lst1) == len(lst2)

Modified: pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h
==============================================================================
--- pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h	(original)
+++ pypy/branch/gc-compress/pypy/translator/c/src/llgroup.h	Thu Oct  8 18:40:40 2009
@@ -11,6 +11,9 @@
 #define OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset, r)  \
   r = ((char*)groupptr) + ((long)compactoffset)*sizeof(long) + skipoffset
 
+#define OP_IS_GROUP_MEMBER_ZERO(compactoffset, r) \
+  r = (compactoffset == 0)
+
 /* A macro to crash at compile-time if sizeof(group) is too large.
    Uses a hack that I've found on some random forum.  Haaaaaaaaaackish. */
 #define PYPY_GROUP_CHECK_SIZE(groupname)                              \



More information about the Pypy-commit mailing list