[pypy-commit] lang-smalltalk storage-allocRemoval: Added an allocation-removal optimization for W_SmallInteger objects.
anton_gulenko
noreply at buildbot.pypy.org
Wed Apr 2 09:44:37 CEST 2014
Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage-allocRemoval
Changeset: r738:1efa7a6e3ddc
Date: 2014-04-02 09:44 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/1efa7a6e3ddc/
Log: Added an allocation-removal optimization for W_SmallInteger objects.
If a small-int is stored into a slot already containing a small-int,
then the value will just be overwritten, without changing the
object-reference. This means W_SmallInteger objects are not
immutable. It also means the JIT can eliminate a lot of allocations.
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -200,7 +200,6 @@
# TODO can we tell pypy that its never larger then 31-bit?
_attrs_ = ['value']
__slots__ = ('value',) # the only allowed slot here
- _immutable_fields_ = ["value"]
repr_classname = "W_SmallInteger"
def __init__(self, value):
@@ -264,6 +263,18 @@
def clone(self, space):
return self
+
+ def store_into_list(w_int, list_of_w_obj, index):
+ """This implements an allocation-removal optimization for Small Integers.
+ If some slot already contains a SmallInt, we simply store the new value.
+ This way, the JIT can eliminate lots of allocations of W_SmallInteger objects.
+ This must be used when storing into regular objects and also the stack/temps of contexts."""
+ # This code is duplicated in ContextPartShadow.stack_put
+ w_old = list_of_w_obj[index]
+ if isinstance(w_old, W_SmallInteger):
+ w_old.value = w_int.value
+ else:
+ list_of_w_obj[index] = W_SmallInteger(w_int.value)
class W_AbstractObjectWithIdentityHash(W_Object):
"""Object with explicit hash (ie all except small
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -229,7 +229,11 @@
def fetch(self, n0):
return self.storage[n0]
def store(self, n0, w_value):
- self.storage[n0] = w_value
+ assert n0 >= 0
+ if isinstance(w_value, model.W_SmallInteger):
+ model.W_SmallInteger.store_into_list(w_value, self.storage, n0)
+ else:
+ self.storage[n0] = w_value
class WeakListStorageShadow(AbstractStorageShadow):
_attrs_ = ['storage']
@@ -835,8 +839,18 @@
def stack_get(self, index0):
return self._temps_and_stack[index0]
- def stack_put(self, index0, w_val):
- self._temps_and_stack[index0] = w_val
+ def stack_put(self, index0, w_value):
+ if isinstance(w_value, model.W_SmallInteger):
+ # This code is copied from W_SmallInteger.store_into_list
+ # Cannot use that method, because _temps_and_stack is virtualizable
+ # and is not allowed to be passed around.
+ w_old = self._temps_and_stack[index0]
+ if isinstance(w_old, model.W_SmallInteger):
+ w_old.value = w_value.value
+ else:
+ self._temps_and_stack[index0] = model.W_SmallInteger(w_value.value)
+ else:
+ self._temps_and_stack[index0] = w_value
def stack(self):
"""NOT_RPYTHON""" # purely for testing
diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py
--- a/spyvm/squeakimage.py
+++ b/spyvm/squeakimage.py
@@ -217,9 +217,6 @@
# dictionary mapping old address to chunk object
self.chunks = {}
self.chunklist = []
- # cache wrapper integers
- self.intcache = {}
-
self.lastWindowSize = 0
def initialize(self):
@@ -440,12 +437,7 @@
self.reader = reader
self.value = value
self.size = -1
- if value in reader.intcache:
- w_int = reader.intcache[value]
- else:
- w_int = self.space.wrap_int(value)
- reader.intcache[value] = w_int
- self.w_object = w_int
+ self.w_object = self.space.wrap_int(value)
self.filled_in = True
def initialize(self, chunk, reader):
More information about the pypy-commit
mailing list