[pypy-svn] r76501 - pypy/trunk/pypy/translator/c

arigo at codespeak.net arigo at codespeak.net
Fri Aug 6 11:50:56 CEST 2010


Author: arigo
Date: Fri Aug  6 11:50:54 2010
New Revision: 76501

Modified:
   pypy/trunk/pypy/translator/c/genc.py
   pypy/trunk/pypy/translator/c/node.py
Log:
Remove two slots from ContainerNode, as an attempt to reduce memory usage
of a full translation.


Modified: pypy/trunk/pypy/translator/c/genc.py
==============================================================================
--- pypy/trunk/pypy/translator/c/genc.py	(original)
+++ pypy/trunk/pypy/translator/c/genc.py	Fri Aug  6 11:50:54 2010
@@ -1,7 +1,6 @@
 import autopath
 import py
 import sys, os
-from pypy.translator.c.node import PyObjectNode, FuncNode
 from pypy.translator.c.database import LowLevelDatabase
 from pypy.translator.c.extfunc import pre_include_code_lines
 from pypy.translator.llsupport.wrapper import new_wrapper
@@ -196,7 +195,7 @@
 
         all = []
         for node in self.db.globalcontainers():
-            eci = getattr(node, 'compilation_info', None)
+            eci = node.compilation_info()
             if eci:
                 all.append(eci)
         self.merge_eci(*all)
@@ -222,7 +221,7 @@
         graphs = db.all_graphs()
         db.gctransformer.prepare_inline_helpers(graphs)
         for node in db.containerlist:
-            if isinstance(node, FuncNode):
+            if hasattr(node, 'funcgens'):
                 for funcgen in node.funcgens:
                     funcgen.patch_graph(copy_graph=False)
         return db

Modified: pypy/trunk/pypy/translator/c/node.py
==============================================================================
--- pypy/trunk/pypy/translator/c/node.py	(original)
+++ pypy/trunk/pypy/translator/c/node.py	Fri Aug  6 11:50:54 2010
@@ -466,15 +466,15 @@
 
 
 class ContainerNode(object):
-    if USESLOTS:
-        __slots__ = """db T obj 
+    if USESLOTS:      # keep the number of slots down!
+        __slots__ = """db obj 
                        typename implementationtypename
-                        name ptrname compilation_info
+                        name ptrname
                         globalcontainer""".split()
+    eci_name = '_compilation_info'
 
     def __init__(self, db, T, obj):
         self.db = db
-        self.T = T
         self.obj = obj
         #self.dependencies = {}
         self.typename = db.gettype(T)  #, who_asks=self)
@@ -489,16 +489,22 @@
         else:
             self.globalcontainer = False
             parentnode = db.getcontainernode(parent)
-            defnode = db.gettypedefnode(parentnode.T)
+            defnode = db.gettypedefnode(parentnode.getTYPE())
             self.name = defnode.access_expr(parentnode.name, parentindex)
         if self.typename != self.implementationtypename:
             if db.gettypedefnode(T).extra_union_for_varlength:
                 self.name += '.b'
-        self.compilation_info = getattr(obj, '_compilation_info', None)
         self.ptrname = '(&%s)' % self.name
 
+    def getTYPE(self):
+        return typeOf(self.obj)
+
     def is_thread_local(self):
-        return hasattr(self.T, "_hints") and self.T._hints.get('thread_local')
+        T = self.getTYPE()
+        return hasattr(T, "_hints") and T._hints.get('thread_local')
+
+    def compilation_info(self):
+        return getattr(self.obj, self.eci_name, None)
 
     def get_declaration(self):
         if self.name[-2:] == '.b':
@@ -546,27 +552,31 @@
         __slots__ = ()
 
     def basename(self):
-        return self.T._name
+        T = self.getTYPE()
+        return T._name
 
     def enum_dependencies(self):
-        for name in self.T._names:
+        T = self.getTYPE()
+        for name in T._names:
             yield getattr(self.obj, name)
 
     def getlength(self):
-        if self.T._arrayfld is None:
+        T = self.getTYPE()
+        if T._arrayfld is None:
             return 1
         else:
-            array = getattr(self.obj, self.T._arrayfld)
+            array = getattr(self.obj, T._arrayfld)
             return len(array.items)
 
     def initializationexpr(self, decoration=''):
+        T = self.getTYPE()
         is_empty = True
         yield '{'
-        defnode = self.db.gettypedefnode(self.T)
+        defnode = self.db.gettypedefnode(T)
 
         data = []
 
-        if needs_gcheader(self.T):
+        if needs_gcheader(T):
             gc_init = self.db.gcpolicy.struct_gcheader_initdata(self)
             data.append(('gcheader', gc_init))
 
@@ -578,16 +588,16 @@
         # '.fieldname = value'.  But here we don't know which of the
         # fields need initialization, so XXX we pick the first one
         # arbitrarily.
-        if hasattr(self.T, "_hints") and self.T._hints.get('union'):
+        if hasattr(T, "_hints") and T._hints.get('union'):
             data = data[0:1]
 
-        if 'get_padding_drop' in self.T._hints:
+        if 'get_padding_drop' in T._hints:
             d = {}
             for name, _ in data:
-                T = defnode.c_struct_field_type(name)
-                typename = self.db.gettype(T)
+                T1 = defnode.c_struct_field_type(name)
+                typename = self.db.gettype(T1)
                 d[name] = cdecl(typename, '')
-            padding_drop = self.T._hints['get_padding_drop'](d)
+            padding_drop = T._hints['get_padding_drop'](d)
         else:
             padding_drop = []
 
@@ -617,9 +627,10 @@
         return 'struct _hashT_%s @' % self.name
 
     def forward_declaration(self):
+        T = self.getTYPE()
         assert self.typename == self.implementationtypename  # no array part
         hash_typename = self.get_hash_typename()
-        hash_offset = self.db.gctransformer.get_hash_offset(self.T)
+        hash_offset = self.db.gctransformer.get_hash_offset(T)
         yield '%s {' % cdecl(hash_typename, '')
         yield '\tunion {'
         yield '\t\t%s;' % cdecl(self.implementationtypename, 'head')
@@ -671,22 +682,23 @@
         return len(self.obj.items)
 
     def initializationexpr(self, decoration=''):
-        defnode = self.db.gettypedefnode(self.T)
+        T = self.getTYPE()
+        defnode = self.db.gettypedefnode(T)
         yield '{'
-        if needs_gcheader(self.T):
+        if needs_gcheader(T):
             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):
+        if T._hints.get('nolength', False):
             length = ''
         else:
             length = '%d, ' % len(self.obj.items)
-        if self.T.OF is Void or len(self.obj.items) == 0:
+        if T.OF is Void or len(self.obj.items) == 0:
             yield '\t%s' % length.rstrip(', ')
             yield '}'
-        elif self.T.OF == Char:
+        elif T.OF == Char:
             if len(self.obj.items) and self.obj.items[0] is None:
                 s = ''.join([self.obj.getitem(i) for i in range(len(self.obj.items))])
             else:
@@ -694,7 +706,7 @@
             yield '\t%s%s' % (length, c_char_array_constant(s))
             yield '}'
         else:
-            barebone = barebonearray(self.T)
+            barebone = barebonearray(T)
             if not barebone:
                 yield '\t%s{' % length
             for j in range(len(self.obj.items)):
@@ -722,7 +734,8 @@
             self.ptrname = self.name
 
     def basename(self):
-        return self.T._name
+        T = self.getTYPE()
+        return T._name
 
     def enum_dependencies(self):
         for i in range(self.obj.getlength()):
@@ -732,11 +745,12 @@
         return 1    # not variable-sized!
 
     def initializationexpr(self, decoration=''):
+        T = self.getTYPE()
         assert self.typename == self.implementationtypename  # not var-sized
         is_empty = True
         yield '{'
         # _names == ['item0', 'item1', ...]
-        for j, name in enumerate(self.T._names):
+        for j, name in enumerate(T._names):
             value = getattr(self.obj, name)
             lines = generic_initializationexpr(self.db, value,
                                                '%s[%d]' % (self.name, j),
@@ -777,6 +791,7 @@
 
 class FuncNode(ContainerNode):
     nodekind = 'func'
+    eci_name = 'compilation_info'
     # there not so many node of this kind, slots should not
     # be necessary
 
@@ -794,7 +809,6 @@
         else:
             self.name = (forcename or
                          db.namespace.uniquename('g_' + self.basename()))
-        self.compilation_info = getattr(obj, 'compilation_info', None)
         self.make_funcgens()
         #self.dependencies = {}
         self.typename = db.gettype(T)  #, who_asks=self)
@@ -939,18 +953,20 @@
         return []
 
     def initializationexpr(self, decoration=''):
-        yield 'RPyOpaque_INITEXPR_%s' % (self.T.tag,)
+        T = self.getTYPE()
+        yield 'RPyOpaque_INITEXPR_%s' % (T.tag,)
 
     def startupcode(self):
+        T = self.getTYPE()
         args = [self.ptrname]
         # XXX how to make this code more generic?
-        if self.T.tag == 'ThreadLock':
+        if T.tag == 'ThreadLock':
             lock = self.obj.externalobj
             if lock.locked():
                 args.append('1')
             else:
                 args.append('0')
-        yield 'RPyOpaque_SETUP_%s(%s);' % (self.T.tag, ', '.join(args))
+        yield 'RPyOpaque_SETUP_%s(%s);' % (T.tag, ', '.join(args))
 
 
 def opaquenode_factory(db, T, obj):



More information about the Pypy-commit mailing list