[pypy-svn] r68450 - pypy/branch/gc-hash/pypy/translator/c

arigo at codespeak.net arigo at codespeak.net
Wed Oct 14 17:04:16 CEST 2009


Author: arigo
Date: Wed Oct 14 17:04:16 2009
New Revision: 68450

Modified:
   pypy/branch/gc-hash/pypy/translator/c/gc.py
   pypy/branch/gc-hash/pypy/translator/c/node.py
Log:
Refactor my changes.  Revert details to make them look
exactly as they do on trunk again.


Modified: pypy/branch/gc-hash/pypy/translator/c/gc.py
==============================================================================
--- pypy/branch/gc-hash/pypy/translator/c/gc.py	(original)
+++ pypy/branch/gc-hash/pypy/translator/c/gc.py	Wed Oct 14 17:04:16 2009
@@ -34,8 +34,8 @@
     def struct_gcheader_definition(self, defnode):
         return self.common_gcheader_definition(defnode)
 
-    def struct_gcheader_initdata(self, defnode, needs_hash=False):
-        return self.common_gcheader_initdata(defnode, needs_hash)
+    def struct_gcheader_initdata(self, defnode):
+        return self.common_gcheader_initdata(defnode)
 
     def array_gcheader_definition(self, defnode):
         return self.common_gcheader_definition(defnode)
@@ -55,6 +55,9 @@
             post_include_bits=['typedef void *GC_hidden_pointer;']
             )
 
+    def get_prebuilt_hash(self, obj, outermostonly):
+        return None
+
     def need_no_typeptr(self):
         return False
 
@@ -333,10 +336,20 @@
     def common_gcheader_definition(self, defnode):
         return defnode.db.gctransformer.gc_fields()
 
-    def common_gcheader_initdata(self, defnode, needs_hash=False):
+    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)
 
+    def get_prebuilt_hash(self, obj):
+        # for prebuilt objects that need to have their hash stored and
+        # restored.  Note that only structures that are StructNodes all
+        # the way have their hash stored (and not e.g. structs with var-
+        # sized arrays at the end).  'obj' must be the top_container.
+        if not isinstance(typeOf(obj), lltype.GcStruct):
+            return None
+        return getattr(obj, '_hash_cache_', None)
+
     def need_no_typeptr(self):
         config = self.db.translator.config
         return config.translation.gcconfig.removetypeptr

Modified: pypy/branch/gc-hash/pypy/translator/c/node.py
==============================================================================
--- pypy/branch/gc-hash/pypy/translator/c/node.py	(original)
+++ pypy/branch/gc-hash/pypy/translator/c/node.py	Wed Oct 14 17:04:16 2009
@@ -3,7 +3,7 @@
      GcStruct, GcArray, RttiStruct, ContainerType, \
      parentlink, Ptr, PyObject, Void, OpaqueType, Float, \
      RuntimeTypeInfo, getRuntimeTypeInfo, Char, _subarray
-from pypy.rpython.lltypesystem import lltype, llmemory, llgroup
+from pypy.rpython.lltypesystem import llmemory, llgroup
 from pypy.translator.c.funcgen import FunctionCodeGenerator
 from pypy.translator.c.external import CExternalFunctionCodeGenerator
 from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
@@ -37,12 +37,11 @@
 
 class StructDefNode:
     typetag = 'struct'
-    def __init__(self, db, STRUCT, varlength=1, hash_at_end=False):
+    def __init__(self, db, STRUCT, varlength=1):
         self.db = db
         self.STRUCT = STRUCT
         self.LLTYPE = STRUCT
         self.varlength = varlength
-        self.hash_at_end = hash_at_end
         if varlength == 1:
             basename = STRUCT._name
             with_number = True
@@ -50,8 +49,6 @@
             basename = db.gettypedefnode(STRUCT).barename
             basename = '%s_len%d' % (basename, varlength)
             with_number = False
-        if hash_at_end:
-            basename += '_hash'
         if STRUCT._hints.get('union'):
             self.typetag = 'union'
             assert STRUCT._gckind == 'raw'   # not supported: "GcUnion"
@@ -97,8 +94,6 @@
             else:
                 typename = db.gettype(T, who_asks=self)
             self.fields.append((self.c_struct_field_name(name), typename))
-        if self.hash_at_end:
-            self.fields.append(('_hash', 'long @'))
         self.gcinfo  # force it to be computed
 
     def computegcinfo(self):
@@ -451,7 +446,7 @@
         self.obj = obj
         #self.dependencies = {}
         self.typename = db.gettype(T)  #, who_asks=self)
-        self.implementationtypename = self.getimpltypename()
+        self.implementationtypename = db.gettype(T, varlength=self.getlength())
         parent, parentindex = parentlink(obj)
         if parent is None:
             self.name = db.namespace.uniquename('g_' + self.basename())
@@ -467,9 +462,6 @@
             self.ptrname = '((%s)(void*)%s)' % (cdecl(ptrtypename, ''),
                                                 self.ptrname)
 
-    def getimpltypename(self):
-        return self.db.gettype(self.T, varlength=self.getlength())
-
     def is_thread_local(self):
         return hasattr(self.T, "_hints") and self.T._hints.get('thread_local')
 
@@ -484,16 +476,12 @@
         if llgroup.member_of_group(self.obj):
             return []
         lines = list(self.initializationexpr())
-        name = self.get_implementation_name()
         lines[0] = '%s = %s' % (
-            cdecl(self.implementationtypename, name, self.is_thread_local()),
+            cdecl(self.implementationtypename, self.name, self.is_thread_local()),
             lines[0])
         lines[-1] += ';'
         return lines
 
-    def get_implementation_name(self):
-        return self.name
-
     def startupcode(self):
         return []
 
@@ -521,62 +509,15 @@
             array = getattr(self.obj, self.T._arrayfld)
             return len(array.items)
 
-    def get_prebuilt_hash(self, outermostonly):
-        # for prebuilt objects that need to have their hash stored and
-        # restored.  Note that only structures that are StructNodes all
-        # the way have their hash stored (and not e.g. structs with var-
-        # sized arrays at the end).
-        if self.db.gcpolicy.stores_hash_at_the_end:
-            obj = lltype.top_container(self.obj)
-            if outermostonly:
-                if obj is not self.obj:
-                    return None
-            if ContainerNodeFactory[typeOf(obj).__class__] is StructNode:
-                return getattr(obj, '_hash_cache_', None)
-        return None
-
-    def getimpltypename(self):
-        basetypename = ContainerNode.getimpltypename(self)
-        if self.get_prebuilt_hash(True) is not None:
-            return 'struct %s @' % (
-                self.db.namespace.uniquename(self.basename() + '_hash'),)
-        return basetypename
-
-    def forward_declaration(self):
-        if self.get_prebuilt_hash(True) is not None:
-            basetypename = ContainerNode.getimpltypename(self)
-            hash_offset = self.db.gctransformer.get_hash_offset(self.T)
-            yield '%s {' % cdecl(self.implementationtypename, '')
-            yield '\tunion {'
-            yield '\t\t%s;' % cdecl(basetypename, 'head')
-            yield '\t\tchar pad[%s];' % name_signed(hash_offset, self.db)
-            yield '\t} u;'
-            yield '\tlong hash;'
-            yield '};'
-            yield '%s;' % (
-                forward_cdecl(self.implementationtypename,
-                              '_' + self.name, self.db.standalone,
-                              self.is_thread_local()),)
-            yield '#define %s _%s.u.head' % (self.name, self.name)
-        else:
-            for line in ContainerNode.forward_declaration(self):
-                yield line
-
-    def get_implementation_name(self):
-        if self.get_prebuilt_hash(True) is not None:
-            return '_' + self.name
-        return self.name
-
     def initializationexpr(self, decoration=''):
         is_empty = True
+        yield '{'
         defnode = self.db.gettypedefnode(self.T)
 
         data = []
 
         if needs_gcheader(self.T):
-            needs_hash = self.get_prebuilt_hash(False) is not None
-            hdr = self.db.gcpolicy.struct_gcheader_initdata(self, needs_hash)
-            for i, thing in enumerate(hdr):
+            for i, thing in enumerate(self.db.gcpolicy.struct_gcheader_initdata(self)):
                 data.append(('gcheader%d'%i, thing))
         
         for name in defnode.fieldnames:
@@ -590,11 +531,6 @@
         if hasattr(self.T, "_hints") and self.T._hints.get('union'):
             data = data[0:1]
 
-        hash = self.get_prebuilt_hash(True)
-        if hash is not None:
-            yield '{ {'
-
-        yield '{'
         for name, value in data:
             c_expr = defnode.access_expr(self.name, name)
             lines = generic_initializationexpr(self.db, value, c_expr,
@@ -604,14 +540,54 @@
             if not lines[0].startswith('/*'):
                 is_empty = False
         if is_empty:
-            yield '\t0'
+            yield '\t%s' % '0,'
         yield '}'
 
-        if hash is not None:
-            yield '}, %s /* hash */ }' % name_signed(hash, self.db)
-
 assert not USESLOTS or '__dict__' not in dir(StructNode)
 
+class GcStructNodeWithHash(StructNode):
+    # for the outermost level of nested structures, if it has a _hash_cache_.
+    nodekind = 'struct'
+    if USESLOTS:
+        __slots__ = ()
+
+    def get_hash_typename(self):
+        return 'struct _hashT_%s @' % self.name
+
+    def forward_declaration(self):
+        hash_typename = self.get_hash_typename()
+        hash_offset = self.db.gctransformer.get_hash_offset(self.T)
+        yield '%s {' % cdecl(hash_typename, '')
+        yield '\tunion {'
+        yield '\t\t%s;' % cdecl(self.implementationtypename, 'head')
+        yield '\t\tchar pad[%s];' % name_signed(hash_offset, self.db)
+        yield '\t} u;'
+        yield '\tlong hash;'
+        yield '};'
+        yield '%s;' % (
+            forward_cdecl(hash_typename, '_hash_' + self.name,
+                          self.db.standalone, self.is_thread_local()),)
+        yield '#define %s _hash_%s.u.head' % (self.name, self.name)
+
+    def implementation(self):
+        hash_typename = self.get_hash_typename()
+        hash = self.db.gcpolicy.get_prebuilt_hash(self.obj)
+        assert hash is not None
+        lines = list(self.initializationexpr())
+        lines.insert(0, '%s = { {' % (
+            cdecl(hash_typename, '_hash_' + self.name,
+                  self.is_thread_local()),))
+        lines.append('}, %s /* hash */ };' % name_signed(hash, self.db))
+        return lines
+
+def gcstructnode_factory(db, T, obj):
+    if db.gcpolicy.get_prebuilt_hash(obj) is not None:
+        cls = GcStructNodeWithHash
+    else:
+        cls = StructNode
+    return cls(db, T, obj)
+
+
 class ArrayNode(ContainerNode):
     nodekind = 'array'
     if USESLOTS:
@@ -1035,7 +1011,7 @@
 
 ContainerNodeFactory = {
     Struct:       StructNode,
-    GcStruct:     StructNode,
+    GcStruct:     gcstructnode_factory,
     Array:        ArrayNode,
     GcArray:      ArrayNode,
     FixedSizeArray: FixedSizeArrayNode,



More information about the Pypy-commit mailing list