[pypy-svn] r32841 - in pypy/dist/pypy/translator/cli: . src

antocuni at codespeak.net antocuni at codespeak.net
Tue Oct 3 14:47:05 CEST 2006


Author: antocuni
Date: Tue Oct  3 14:47:03 2006
New Revision: 32841

Modified:
   pypy/dist/pypy/translator/cli/constgenerator.py
   pypy/dist/pypy/translator/cli/database.py
   pypy/dist/pypy/translator/cli/ilgenerator.py
   pypy/dist/pypy/translator/cli/src/pypylib.cs
Log:
Added another way of rendering constants: instead of being stored as
static fields, they are stored as instance fields of a
Singleton. After the first run the singleton is serialized to
disk. Next runs will initialize contants by reading that file.



Modified: pypy/dist/pypy/translator/cli/constgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/constgenerator.py	(original)
+++ pypy/dist/pypy/translator/cli/constgenerator.py	Tue Oct  3 14:47:03 2006
@@ -1,17 +1,19 @@
 CONST_NAMESPACE = 'pypy.runtime'
-CONST_CLASS = 'Constants'
+CONST_CLASSNAME = 'Constants'
+CONST_CLASS = '%s.%s' % (CONST_NAMESPACE, CONST_CLASSNAME)
 
 DEBUG_CONST_INIT = False
 DEBUG_CONST_INIT_VERBOSE = False
 MAX_CONST_PER_STEP = 100
+SERIALIZE = False
 
-class StaticFieldConstGenerator:
+class BaseConstGenerator:
     def __init__(self, ilasm):
         self.ilasm = ilasm
     
     def begin_class(self):
         self.ilasm.begin_namespace(CONST_NAMESPACE)
-        self.ilasm.begin_class(CONST_CLASS, beforefieldinit=True)
+        self.ilasm.begin_class(CONST_CLASSNAME, beforefieldinit=True)
 
     def end_class(self):
         self.ilasm.end_class()
@@ -20,17 +22,32 @@
     def declare_const(self, const):
         self.ilasm.field(const.name, const.get_type(), static=True)
 
-    def __new_step(self):
+class FieldConstGenerator(BaseConstGenerator):
+    def _new_step(self):
         if self.step > 0:
-            self.__end_step() # close the previous step
-        # open the new step
-        self.ilasm.begin_function('step%d' % self.step, [], 'void', False, 'static')
+            self._end_step() # close the previous step
+        self._declare_step()  # open the next step
         self.step += 1
-
-    def __end_step(self):
+        
+    def _end_step(self):
         if self.step > 0:
-            self.ilasm.ret()
-            self.ilasm.end_function()
+            self._close_step()
+
+    def _declare_step(self):
+        raise NotImplementedError
+
+    def _close_step(self):
+        raise NotImplementedError
+
+
+class StaticFieldConstGenerator(FieldConstGenerator):
+
+    def _declare_step(self):
+        self.ilasm.begin_function('step%d' % self.step, [], 'void', False, 'static')
+
+    def _close_step(self):
+        self.ilasm.ret()
+        self.ilasm.end_function()
 
     def generate_consts(self, const_list):
         # this point we have collected all constant we
@@ -39,19 +56,19 @@
         ilasm = self.ilasm
         for i, const in enumerate(const_list):
             if i % MAX_CONST_PER_STEP == 0:
-                self.__new_step()
+                self._new_step()
             type_ = const.get_type()
             const.instantiate(ilasm)
-            ilasm.store_static_constant(type_, CONST_NAMESPACE, CONST_CLASS, const.name)
+            ilasm.store_static_constant(type_, CONST_NAMESPACE, CONST_CLASSNAME, const.name)
 
         for i, const in enumerate(const_list):
             if i % MAX_CONST_PER_STEP == 0:
-                self.__new_step()
+                self._new_step()
             ilasm.stderr('CONST: initializing #%d' % i, DEBUG_CONST_INIT_VERBOSE)
             type_ = const.get_type()
-            ilasm.load_static_constant(type_, CONST_NAMESPACE, CONST_CLASS, const.name)
+            ilasm.load_static_constant(type_, CONST_NAMESPACE, CONST_CLASSNAME, const.name)
             const.init(ilasm)
-        self.__end_step() # close the pending step
+        self._end_step() # close the pending step
 
         ilasm.begin_function('.cctor', [], 'void', False, 'static',
             'specialname', 'rtspecialname', 'default')
@@ -59,17 +76,100 @@
         for i in range(self.step):
             ilasm.stderr('CONST: step %d of %d' % (i, self.step), DEBUG_CONST_INIT)
             step_name = 'step%d' % i
-            ilasm.call('void %s.%s::%s()' % (CONST_NAMESPACE, CONST_CLASS, step_name))
+            ilasm.call('void %s::%s()' % (CONST_CLASS, step_name))
         ilasm.stderr('CONST: initialization completed', DEBUG_CONST_INIT)
         ilasm.ret()
         ilasm.end_function()
 
     def load_const(cls, ilasm, const):
-        full_name = '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, const.name)
+        full_name = '%s::%s' % (CONST_CLASS, const.name)
         ilasm.opcode('ldsfld %s %s' % (const.get_type(), full_name))
     load_const = classmethod(load_const)
 
 
+class InstanceFieldConstGenerator(FieldConstGenerator):
+    
+    def declare_const(self, const):
+        self.ilasm.field(const.name, const.get_type(), static=False)
+    
+    def _declare_step(self):
+        self.ilasm.begin_function('step%d' % self.step, [], 'void', False)
+
+    def _close_step(self):
+        self.ilasm.ret()
+        self.ilasm.end_function()
+
+    def generate_consts(self, const_list):
+        # this point we have collected all constant we
+        # need. Instantiate&initialize them.
+        self.step = 0
+        ilasm = self.ilasm
+        for i, const in enumerate(const_list):
+            if i % MAX_CONST_PER_STEP == 0:
+                self._new_step()
+            ilasm.opcode('ldarg.0')
+            const.instantiate(ilasm)
+            ilasm.set_field((const.get_type(), CONST_CLASS, const.name))
+
+        for i, const in enumerate(const_list):
+            if i % MAX_CONST_PER_STEP == 0:
+                self._new_step()
+            ilasm.stderr('CONST: initializing #%d' % i, DEBUG_CONST_INIT_VERBOSE)
+            ilasm.opcode('ldarg.0')
+            ilasm.get_field((const.get_type(), CONST_CLASS, const.name))
+            const.init(ilasm)
+        self._end_step() # close the pending step
+
+        ilasm.begin_function('.ctor', [], 'void', False, 'specialname', 'rtspecialname', 'instance')
+        ilasm.opcode('ldarg.0')
+        ilasm.call('instance void object::.ctor()')
+
+        ilasm.opcode('ldarg.0')
+        ilasm.opcode('stsfld class %s %s::Singleton' % (CONST_CLASS, CONST_CLASS))
+        
+        for i in range(self.step):
+            step_name = 'step%d' % i
+            ilasm.opcode('ldarg.0')
+            ilasm.call('instance void %s::%s()' % (CONST_CLASS, step_name))
+        ilasm.ret()
+        ilasm.end_function()
+
+        # declare&init the Singleton containing the constants
+        self.ilasm.field('Singleton', 'class %s' % CONST_CLASS, static=True)
+        self.ilasm.begin_function('.cctor', [], 'void', False, 'static', 'specialname', 'rtspecialname', 'default')
+        if SERIALIZE:
+            self._serialize_ctor()
+        else:
+            self._plain_ctor()
+        self.ilasm.end_function()
+
+    def _plain_ctor(self):
+        self.ilasm.new('instance void class %s::.ctor()' % CONST_CLASS)
+        self.ilasm.pop()
+        self.ilasm.ret()
+
+    def _serialize_ctor(self):
+        self.ilasm.opcode('ldstr "constants.dat"')
+        self.ilasm.call('object [pypylib]pypy.runtime.Utils::Deserialize(string)')
+        self.ilasm.opcode('dup')
+        self.ilasm.opcode('brfalse initialize')
+        self.ilasm.stderr('Constants deserialized successfully')        
+        self.ilasm.opcode('stsfld class %s %s::Singleton' % (CONST_CLASS, CONST_CLASS))
+        self.ilasm.ret()
+        self.ilasm.label('initialize')
+        self.ilasm.pop()
+        self.ilasm.stderr('Cannot deserialize constants... initialize them!')
+        self.ilasm.new('instance void class %s::.ctor()' % CONST_CLASS)
+        self.ilasm.opcode('ldstr "constants.dat"')
+        self.ilasm.call('void [pypylib]pypy.runtime.Utils::Serialize(object, string)')
+        self.ilasm.ret()
+
+    def load_const(cls, ilasm, const):
+        ilasm.opcode('ldsfld class %s %s::Singleton' % (CONST_CLASS, CONST_CLASS))
+        ilasm.opcode('ldfld %s %s::%s' % (const.get_type(), CONST_CLASS, const.name))
+    load_const = classmethod(load_const)
+
+
 class LazyConstGenerator(StaticFieldConstGenerator):
     def generate_consts(self, const_list):
         ilasm = self.ilasm
@@ -94,6 +194,6 @@
             ilasm.end_function()
 
     def load_const(cls, ilasm, const):
-        getter_name = '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, 'get_%s' % const.name)
+        getter_name = '%s::%s' % (CONST_CLASS, 'get_%s' % const.name)
         ilasm.call('%s %s()' % (const.get_type(), getter_name))
     load_const = classmethod(load_const)

Modified: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- pypy/dist/pypy/translator/cli/database.py	(original)
+++ pypy/dist/pypy/translator/cli/database.py	Tue Oct  3 14:47:03 2006
@@ -8,7 +8,7 @@
 from pypy.translator.cli.comparer import EqualityComparer
 from pypy.translator.cli.node import Node
 from pypy.translator.cli.support import string_literal, Counter
-from pypy.translator.cli.constgenerator import StaticFieldConstGenerator, LazyConstGenerator
+from pypy.translator.cli.constgenerator import StaticFieldConstGenerator, InstanceFieldConstGenerator, LazyConstGenerator
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.ootypesystem.module import ll_os
 from pypy.rpython.lltypesystem import lltype
@@ -21,6 +21,7 @@
 except NameError:
     from sets import Set as set
 
+#CONST_GENERATOR = InstanceFieldConstGenerator
 CONST_GENERATOR = StaticFieldConstGenerator
 #CONST_GENERATOR = LazyConstGenerator
 

Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py	(original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py	Tue Oct  3 14:47:03 2006
@@ -56,7 +56,7 @@
         self.code.closeblock()
 
     def begin_class(self, name, base=None, sealed=False, interfaces=(), abstract=False,
-                    beforefieldinit=False):
+                    beforefieldinit=False, serializable=True):
         if base is None:
             base = '[mscorlib]System.Object'
         s = ''
@@ -66,6 +66,8 @@
             s += 'sealed '
         if beforefieldinit:
             s += 'beforefieldinit '
+        if serializable:
+            s += 'serializable '
 
         self.code.writeline('.class public %s %s extends %s' % (s, name, base))
         if interfaces:

Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/dist/pypy/translator/cli/src/pypylib.cs	(original)
+++ pypy/dist/pypy/translator/cli/src/pypylib.cs	Tue Oct  3 14:47:03 2006
@@ -1,6 +1,9 @@
 using System;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Runtime.Serialization;
+using System.IO;
 using pypy.runtime;
 
 namespace pypy.test
@@ -115,8 +118,46 @@
         {
             return obj.GetHashCode();
         }
+
+        public static void Serialize(object obj, string filename)
+        {
+            FileStream fs = new FileStream(filename, FileMode.Create);
+            BinaryFormatter formatter = new BinaryFormatter();
+            try {
+                formatter.Serialize(fs, obj);
+            }
+            catch (SerializationException e) {
+                Console.Error.WriteLine("Failed to serialize. Reason: " + e.Message);
+                throw;
+            }
+            finally {
+                fs.Close();
+            }
+        }
+
+        public static object Deserialize(string filename)
+        {
+            FileStream fs = null;
+            try {
+                fs = new FileStream(filename, FileMode.Open);
+                BinaryFormatter formatter = new BinaryFormatter();
+                return formatter.Deserialize(fs);
+            }
+            catch (FileNotFoundException e) {
+                return null;
+            }
+            catch (SerializationException e) {
+                Console.Error.WriteLine("Failed to deserialize. Reason: " + e.Message);
+                return null;
+            }
+            finally {
+                if (fs != null)
+                    fs.Close();
+            }
+        }
     }
 
+    [Serializable()]
     public class StringBuilder
     {
         System.Text.StringBuilder builder = new System.Text.StringBuilder();
@@ -250,6 +291,7 @@
 
     //The public interface List must implement is defined in
     // rpython.ootypesystem.ootype.List.GENERIC_METHODS
+    [Serializable()]
     public class List<T>: System.Collections.Generic.List<T>
     {
         public List(): base()
@@ -319,6 +361,7 @@
         }
     }
 
+    [Serializable()]
     public class ListOfVoid
     {
         int Count = 0;
@@ -344,6 +387,7 @@
         public void _ll_resize_le(int length) { this.Count = length; }
     }
 
+    [Serializable()]
     public class Dict<TKey, TValue>: System.Collections.Generic.Dictionary<TKey, TValue>
     {
         IEqualityComparer<TKey> comparer = null;
@@ -376,6 +420,7 @@
     }
 
     // it assumes TValue is a placeholder, it's not really used
+    [Serializable()]
     public class DictOfVoid<TKey, TValue>: System.Collections.Generic.Dictionary<TKey, TValue>
     {
         public int ll_length() { return this.Count; }
@@ -391,6 +436,7 @@
         }
     }
 
+    [Serializable()]
     public class DictVoidVoid
     {
         public int ll_length() { return 0; }
@@ -409,6 +455,7 @@
         */
     }
 
+    [Serializable()]
     public class DictItemsIterator<TKey, TValue>
     {
         IEnumerator<KeyValuePair<TKey, TValue>> it;
@@ -423,6 +470,7 @@
         public TValue ll_current_value() { return it.Current.Value; }
     }
 
+    [Serializable()]
     public class Record_Float_Signed {
         public double item0;
         public int item1;
@@ -435,6 +483,7 @@
         public override int GetHashCode() { return item0.GetHashCode(); }
     }
 
+    [Serializable()]
     public class Record_Float_Float {
         public double item0;
         public double item1;
@@ -447,6 +496,7 @@
         public override int GetHashCode() { return item0.GetHashCode(); }
     }
 
+    [Serializable()]
     public class Record_Stat_Result {
         public int item0, item1, item2, item3, item4, item5, item6, item7, item8, item9;
         public override string ToString() 



More information about the Pypy-commit mailing list