[pypy-commit] lang-smalltalk storage: Optimizing storage strategies.

anton_gulenko noreply at buildbot.pypy.org
Fri Jul 18 14:08:24 CEST 2014


Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage
Changeset: r899:2c3b6f965b1a
Date: 2014-07-10 21:29 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/2c3b6f965b1a/

Log:	Optimizing storage strategies.

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -614,7 +614,7 @@
     
     def switch_shadow(self, new_shadow, w_element=None):
         old_shadow = self.assert_shadow()
-        new_shadow.copy_from(old_shadow)
+        old_shadow.copy_into(new_shadow)
         self.store_shadow(new_shadow)
         new_shadow.attach_shadow()
         self.log_storage("Switched", old_shadow, w_element=w_element)
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -38,16 +38,27 @@
     def size(self):
         raise NotImplementedError("Abstract class")
 
+    # This will invoke an appropriate copy_from_* method.
+    # Overwriting this allows optimized transitions between certain storage types.
+    def copy_into(self, other_shadow):
+        other_shadow.copy_from(self)
+    
     def attach_shadow(self): pass
 
     def copy_field_from(self, n0, other_shadow):
         self.store(n0, other_shadow.fetch(n0))
 
-    # This can be overwritten to change the order of initialization.
     def copy_from(self, other_shadow):
         assert self.size() == other_shadow.size()
         for i in range(self.size()):
             self.copy_field_from(i, other_shadow)
+    
+    def copy_from_AllNil(self, all_nil_storage):
+        self.copy_from(all_nil_storage)
+    def copy_from_SmallIntegerOrNil(self, small_int_storage):
+        self.copy_from(small_int_storage)
+    def copy_from_FloatOrNil(self, float_storage):
+        self.copy_from(float_storage)
 
 class AbstractStorageShadow(AbstractShadow):
     _attrs_ = []
@@ -80,6 +91,8 @@
         if n0 >= self._size:
             raise IndexError
         return self.space.w_nil
+    def copy_into(self, other_shadow):
+        other_shadow.copy_from_AllNil(self)
     def do_store(self, n0, w_value):
         pass
     def size(self):
@@ -117,6 +130,9 @@
             self.storage[n0] = self.nil_value
         else:
             self.storage[n0] = self.unwrap(self.space, w_val)
+            
+    def copy_from_AllNil(self, all_nil_storage):
+        pass # Already initialized
 
 # This is to avoid code duplication
 @objectmodel.specialize.arg(0)
@@ -143,6 +159,8 @@
     @staticmethod
     def unwrap(space, w_val):
         return space.unwrap_int(w_val)
+    def copy_into(self, other_shadow):
+        other_shadow.copy_from_SmallIntegerOrNil(self)
 
 class FloatOrNilStorageShadow(AbstractStorageShadow):
     repr_classname = "FloatOrNilStorageShadow"
@@ -162,6 +180,8 @@
     @staticmethod
     def unwrap(space, w_val):
         return space.unwrap_float(w_val)
+    def copy_into(self, other_shadow):
+        other_shadow.copy_from_FloatOrNil(self)
 
 def empty_storage(space, w_self, size, weak=False):
     if weak:
@@ -170,6 +190,7 @@
         return ListStorageShadow(space, w_self, size)
     return AllNilStorageShadow(space, w_self, size)
 
+ at jit.unroll_safe
 def find_storage_for_objects(space, vars, weak=False):
     if weak:
         return WeakListStorageShadow
@@ -212,7 +233,10 @@
     def copy_from(self, other_shadow):
         if self.size() != other_shadow.size():
             self.initialize_storage(other_shadow.size())
-        AbstractShadow.copy_from(self, other_shadow)
+        for i in range(self.size()):
+            w_val = other_shadow.fetch(i)
+            if not w_val.is_nil(self.space):
+                self.store(i, w_val)
 
 class ListStorageShadow(AbstractStorageShadow):
     _attrs_ = ['storage']


More information about the pypy-commit mailing list