[pypy-svn] r73634 - in pypy/trunk/pypy: rpython/memory/gctransform translator/c

benjamin at codespeak.net benjamin at codespeak.net
Sun Apr 11 01:57:57 CEST 2010


Author: benjamin
Date: Sun Apr 11 01:57:55 2010
New Revision: 73634

Modified:
   pypy/trunk/pypy/rpython/memory/gctransform/framework.py
   pypy/trunk/pypy/translator/c/gc.py
   pypy/trunk/pypy/translator/c/node.py
Log:
make the gc header inlined by the C compiler

This makes us follow strict aliasing correctly as well as simplifying genc a
bit.


Modified: pypy/trunk/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/trunk/pypy/rpython/memory/gctransform/framework.py	Sun Apr 11 01:57:55 2010
@@ -445,11 +445,7 @@
         self.c_const_gc = rmodel.inputconst(r_gc, self.gcdata.gc)
         self.malloc_zero_filled = GCClass.malloc_zero_filled
 
-        HDR = self._gc_HDR = self.gcdata.gc.gcheaderbuilder.HDR
-        self._gc_fields = fields = []
-        for fldname in HDR._names:
-            FLDTYPE = getattr(HDR, fldname)
-            fields.append(('_' + fldname, FLDTYPE))
+        HDR = self.HDR = self.gcdata.gc.gcheaderbuilder.HDR
 
         size_gc_header = self.gcdata.gc.gcheaderbuilder.size_gc_header
         vtableinfo = (HDR, size_gc_header, self.gcdata.gc.typeid_is_in_field)
@@ -472,17 +468,13 @@
     def finalizer_funcptr_for_type(self, TYPE):
         return self.layoutbuilder.finalizer_funcptr_for_type(TYPE)
 
-    def gc_fields(self):
-        return self._gc_fields
-
-    def gc_field_values_for(self, obj, needs_hash=False):
+    def gc_header_for(self, obj, needs_hash=False):
         hdr = self.gcdata.gc.gcheaderbuilder.header_of_object(obj)
-        HDR = self._gc_HDR
+        HDR = self.HDR
         withhash, flag = self.gcdata.gc.withhash_flag_is_in_field
-        result = []
         for fldname in HDR._names:
-            x = getattr(hdr, fldname)
             if fldname == withhash:
+                x = getattr(hdr, fldname)
                 TYPE = lltype.typeOf(x)
                 x = lltype.cast_primitive(lltype.Signed, x)
                 if needs_hash:
@@ -490,8 +482,8 @@
                 else:
                     x &= ~flag      # clear the flag in the header
                 x = lltype.cast_primitive(TYPE, x)
-            result.append(x)
-        return result
+                setattr(hdr, fldname, x)
+        return hdr
 
     def get_hash_offset(self, T):
         type_id = self.get_type_id(T)

Modified: pypy/trunk/pypy/translator/c/gc.py
==============================================================================
--- pypy/trunk/pypy/translator/c/gc.py	(original)
+++ pypy/trunk/pypy/translator/c/gc.py	Sun Apr 11 01:57:55 2010
@@ -20,16 +20,13 @@
 
     def common_gcheader_definition(self, defnode):
         if defnode.db.gctransformer is not None:
-            HDR = defnode.db.gctransformer.HDR
-            return [(name, HDR._flds[name]) for name in HDR._names]
-        else:
-            return []
+            return defnode.db.gctransformer.HDR
+        return None
 
     def common_gcheader_initdata(self, defnode):
         if defnode.db.gctransformer is not None:
             raise NotImplementedError
-        else:
-            return []
+        return None
 
     def struct_gcheader_definition(self, defnode):
         return self.common_gcheader_definition(defnode)
@@ -113,11 +110,9 @@
     def common_gcheader_initdata(self, defnode):
         if defnode.db.gctransformer is not None:
             gct = defnode.db.gctransformer
-            hdr = gct.gcheaderbuilder.header_of_object(top_container(defnode.obj))
-            HDR = gct.HDR
-            return [getattr(hdr, fldname) for fldname in HDR._names]
-        else:
-            return []
+            top = top_container(defnode.obj)
+            return gct.gcheaderbuilder.header_of_object(top)._obj
+        return None
 
     # for structs
 
@@ -196,9 +191,10 @@
 
     def common_gcheader_initdata(self, defnode):
         if defnode.db.gctransformer is not None:
-            return [lltype.identityhash_nocache(defnode.obj._as_ptr())]
-        else:
-            return []
+            hdr = lltype.malloc(defnode.db.gctransformer.HDR, immortal=True)
+            hdr.hash = lltype.identityhash_nocache(defnode.obj._as_ptr())
+            return hdr._obj
+        return None
 
     def array_setup(self, arraydefnode):
         pass
@@ -333,13 +329,11 @@
             args = [funcgen.expr(v) for v in op.args]
             return '%s = %s; /* for moving GCs */' % (args[1], args[0])
 
-    def common_gcheader_definition(self, defnode):
-        return defnode.db.gctransformer.gc_fields()
-
     def common_gcheader_initdata(self, defnode):
         o = top_container(defnode.obj)
         needs_hash = self.get_prebuilt_hash(o) is not None
-        return defnode.db.gctransformer.gc_field_values_for(o, needs_hash)
+        hdr = defnode.db.gctransformer.gc_header_for(o, needs_hash)
+        return hdr._obj
 
     def get_prebuilt_hash(self, obj):
         # for prebuilt objects that need to have their hash stored and
@@ -362,9 +356,14 @@
         # all implemented by a single call to a C macro.
         [v_obj, c_grpptr, c_skipoffset, c_vtableinfo] = op.args
         typename = funcgen.db.gettype(op.result.concretetype)
-        fieldname = c_vtableinfo.value[2]
+        tid_field = c_vtableinfo.value[2]
+        # Fish out the C name of the tid field.
+        HDR = self.db.gctransformer.HDR
+        hdr_node = self.db.gettypedefnode(HDR)
+        fieldname = hdr_node.c_struct_field_name(tid_field)
         return (
-        '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (pypy_halfword_t)%s->_%s, %s);'
+        '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (pypy_halfword_t)%s->'
+            '_gcheader.%s, %s);'
             % (funcgen.expr(op.result),
                cdecl(typename, ''),
                funcgen.expr(c_grpptr),

Modified: pypy/trunk/pypy/translator/c/node.py
==============================================================================
--- pypy/trunk/pypy/translator/c/node.py	(original)
+++ pypy/trunk/pypy/translator/c/node.py	Sun Apr 11 01:57:55 2010
@@ -88,8 +88,10 @@
         if self.varlength != 1:
             self.normalizedtypename = db.gettype(STRUCT, who_asks=self)
         if needs_gcheader(self.STRUCT):
-            for fname, T in db.gcpolicy.struct_gcheader_definition(self):
-                self.fields.append((fname, db.gettype(T, who_asks=self)))
+            HDR = db.gcpolicy.struct_gcheader_definition(self)
+            if HDR is not None:
+                gc_field = ("_gcheader", db.gettype(HDR, who_asks=self))
+                self.fields.append(gc_field)
         for name in self.fieldnames:
             T = self.c_struct_field_type(name)
             if name == STRUCT._arrayfld:
@@ -218,8 +220,10 @@
         if self.varlength != 1:
             self.normalizedtypename = db.gettype(ARRAY, who_asks=self)
         if needs_gcheader(ARRAY):
-            for fname, T in db.gcpolicy.array_gcheader_definition(self):
-                self.gcfields.append((fname, db.gettype(T, who_asks=self)))
+            HDR = db.gcpolicy.array_gcheader_definition(self)
+            if HDR is not None:
+                gc_field = ("_gcheader", db.gettype(HDR, who_asks=self))
+                self.gcfields.append(gc_field)
         self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
 
     def computegcinfo(self):
@@ -558,12 +562,12 @@
         data = []
 
         if needs_gcheader(self.T):
-            for i, thing in enumerate(self.db.gcpolicy.struct_gcheader_initdata(self)):
-                data.append(('gcheader%d'%i, thing))
-        
+            gc_init = self.db.gcpolicy.struct_gcheader_initdata(self)
+            data.append(('gcheader', gc_init))
+
         for name in defnode.fieldnames:
             data.append((name, getattr(self.obj, name)))
-        
+
         # Reasonably, you should only initialise one of the fields of a union
         # in C.  This is possible with the syntax '.fieldname value' or
         # '.fieldname = value'.  But here we don't know which of the
@@ -665,12 +669,11 @@
         defnode = self.db.gettypedefnode(self.T)
         yield '{'
         if needs_gcheader(self.T):
-            for i, thing in enumerate(self.db.gcpolicy.array_gcheader_initdata(self)):
-                lines = generic_initializationexpr(self.db, thing,
-                                                   'gcheader%d'%i,
-                                                   '%sgcheader%d' % (decoration, i))
-                for line in lines:
-                    yield line
+            gc_init = self.db.gcpolicy.array_gcheader_initdata(self)
+            lines = generic_initializationexpr(self.db, gc_init, 'gcheader',
+                                               '%sgcheader' % (decoration,))
+            for line in lines:
+                yield line
         if self.T._hints.get('nolength', False):
             length = ''
         else:



More information about the Pypy-commit mailing list