Author: Anton Gulenko <[email protected]>
Branch: strategies-tagging
Changeset: r672:fd9669dc8f6d
Date: 2014-03-20 12:17 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/fd9669dc8f6d/
Log: Replaced uses_int_storage special casing in favor of subclassing.
Removed size_of from the strategy interface. Removed
make_sure_not_resized. Turned needs_objspace into an attribute.
Removed unused imports.
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -1268,7 +1268,7 @@
if isinstance(w_candidate, W_PointersObject):
c_shadow = w_candidate._get_shadow()
if c_shadow is None and w_candidate.size() >= 2:
- if not w_candidate.strategy.needs_objspace():
+ if not w_candidate.strategy.needs_objspace:
# We can fetch without having an object space at hand.
# XXX How to get an object space from a
CompiledMethodShadow, anyways?
w_class = w_candidate._fetch(None, 1)
diff --git a/spyvm/strategies.py b/spyvm/strategies.py
--- a/spyvm/strategies.py
+++ b/spyvm/strategies.py
@@ -1,8 +1,7 @@
from spyvm import model, shadow
-from rpython.rlib import rerased, objectmodel, jit, signature
+from rpython.rlib import rerased
from rpython.rlib.objectmodel import import_from_mixin
-from rpython.rlib.debug import make_sure_not_resized
# Disables all optimized strategies, for debugging.
only_list_storage = False
@@ -12,55 +11,36 @@
_attrs_ = []
_settled_ = True
strategy_tag = 'abstract'
- uses_int_storage = False
-
- def __init__(self):
- pass
- def needs_objspace(self):
- # Return True, if fetch/store operations use the space parameter.
- # If not, the space-parameter can be passed in as None (probably).
- return False
+ needs_objspace = False
def set_initial_storage(self, space, w_obj, size):
- if self.uses_int_storage:
- w_obj.int_storage = self.initial_int_storage(space, size)
- else:
- w_obj.list_storage = self.initial_storage(space, size)
-
+ raise NotImplementedError("Abstract base class")
def set_storage_for_list(self, space, w_obj, collection):
- if self.uses_int_storage:
- w_obj.int_storage = self.int_storage_for_list(space, collection)
- else:
- w_obj.list_storage = self.storage_for_list(space, collection)
-
+ raise NotImplementedError("Abstract base class")
def set_storage_copied_from(self, space, w_obj, w_source_obj,
reuse_storage=False):
- if self.uses_int_storage:
- w_obj.int_storage = self.copy_int_storage_from(space,
w_source_obj, reuse_storage)
- else:
- w_obj.list_storage = self.copy_storage_from(space, w_source_obj,
reuse_storage)
+ raise NotImplementedError("Abstract base class")
def fetch(self, space, w_obj, n0):
raise NotImplementedError("Abstract base class")
def store(self, space, w_obj, n0, w_val):
raise NotImplementedError("Abstract base class")
- def size_of(self, w_obj):
- raise NotImplementedError("Abstract base class")
+
+class AbstractListStorageStrategy(AbstractStorageStrategy):
+ strategy_tag = 'abstract-list'
+
+ def storage(self, w_obj):
+ return w_obj.list_storage
+ def set_initial_storage(self, space, w_obj, size):
+ w_obj.list_storage = self.initial_storage(space, size)
+ def set_storage_for_list(self, space, w_obj, collection):
+ w_obj.list_storage = self.storage_for_list(space, collection)
+ def set_storage_copied_from(self, space, w_obj, w_source_obj,
reuse_storage=False):
+ w_obj.list_storage = self.copy_storage_from(space, w_source_obj,
reuse_storage)
def initial_storage(self, space, size):
raise NotImplementedError("Abstract base class")
- def initial_int_storage(self, space, size):
- raise NotImplementedError("Abstract base class")
def storage_for_list(self, space, collection):
raise NotImplementedError("Abstract base class")
- def int_storage_for_list(self, space, collection):
- raise NotImplementedError("Abstract base class")
- def copy_int_storage_from(self, space, w_obj, reuse_storage):
- old_strategy = w_obj.strategy
- if old_strategy == self and reuse_storage:
- return w_obj.int_storage
- else:
- # This can be overridden and optimized (reuse_storage flag, less
temporary storage)
- return self.int_storage_for_list(space, w_obj.fetch_all(space))
def copy_storage_from(self, space, w_obj, reuse_storage):
old_strategy = w_obj.strategy
if old_strategy == self and reuse_storage:
@@ -68,6 +48,30 @@
else:
# This can be overridden and optimized (reuse_storage flag, less
temporary storage)
return self.storage_for_list(space, w_obj.fetch_all(space))
+
+class AbstractIntStorageStrategy(AbstractStorageStrategy):
+ strategy_tag = 'abstract-int'
+
+ def storage(self, w_obj):
+ return w_obj.int_storage
+ def set_initial_storage(self, space, w_obj, size):
+ w_obj.int_storage = self.initial_storage(space, size)
+ def set_storage_for_list(self, space, w_obj, collection):
+ w_obj.int_storage = self.storage_for_list(space, collection)
+ def set_storage_copied_from(self, space, w_obj, w_source_obj,
reuse_storage=False):
+ w_obj.int_storage = self.copy_storage_from(space, w_source_obj,
reuse_storage)
+
+ def initial_storage(self, space, size):
+ raise NotImplementedError("Abstract base class")
+ def storage_for_list(self, space, collection):
+ raise NotImplementedError("Abstract base class")
+ def copy_storage_from(self, space, w_obj, reuse_storage):
+ old_strategy = w_obj.strategy
+ if old_strategy == self and reuse_storage:
+ return w_obj.int_storage
+ else:
+ # This can be overridden and optimized (reuse_storage flag, less
temporary storage)
+ return self.int_storage_for_list(space, w_obj.fetch_all(space))
class SingletonMeta(type):
def __new__(cls, name, bases, dct):
@@ -76,25 +80,15 @@
return result
class BasicStorageStrategyMixin(object):
- # Concrete class must implement: unerase
- def size_of(self, w_obj):
- if self.uses_int_storage:
- return len(self.int_storage(w_obj))
- else:
- return len(self.storage(w_obj))
- def int_storage(self, w_obj):
- return w_obj.int_storage
- def storage(self, w_obj):
- return w_obj.list_storage
def erase(self, a): return a
def unerase(self, a): return a
+ # erase, unerase = rerased.new_static_erasing_pair(self.strategy_tag)
# this is the typical "initial" storage strategy, for when every slot
-# in a var-sized object is still nil. No storage is allocated except for
-# holding the size of the object.
+# in an object is still nil. No storage is allocated.
class AllNilStorageStrategy(AbstractStorageStrategy):
__metaclass__ = SingletonMeta
- # erase, unerase = rerased.new_static_erasing_pair("all-nil-strategy")
+ # erase, unerase = rerased.new_static_erasing_pair("allnil-strategy")
import_from_mixin(BasicStorageStrategyMixin)
strategy_tag = 'allnil'
@@ -110,19 +104,19 @@
return w_obj.store_with_new_strategy(space,
TaggingSmallIntegerStorageStrategy.singleton, n0, w_val)
return w_obj.store_with_new_strategy(space,
ListStorageStrategy.singleton, n0, w_val)
- def initial_storage(self, space, size):
- return []
- def storage_for_list(self, space, collection):
- return []
- def copy_storage_from(self, space, w_obj, reuse_storage=False):
- return []
+ def set_initial_storage(self, space, w_obj, size):
+ pass
+ def set_storage_for_list(self, space, w_obj, collection):
+ pass
+ def set_storage_copied_from(self, space, w_obj, w_source_obj,
reuse_storage=False):
+ pass
# This is the regular storage strategy that does not result in any
# optimizations but can handle every case. Applicable for both
# fixed-sized and var-sized objects.
-class ListStorageStrategy(AbstractStorageStrategy):
+class ListStorageStrategy(AbstractListStorageStrategy):
__metaclass__ = SingletonMeta
- # erase, unerase = rerased.new_static_erasing_pair("list-storage-strategy")
+ # erase, unerase = rerased.new_static_erasing_pair("list-strategy")
import_from_mixin(BasicStorageStrategyMixin)
strategy_tag = 'list'
@@ -131,23 +125,20 @@
def store(self, space, w_obj, n0, w_val):
# TODO enable generalization by maintaining a counter of elements that
are nil.
self.storage(w_obj)[n0] = w_val
- def erased_list(self, list):
- make_sure_not_resized(list)
- return self.erase(list)
def initial_storage(self, space, size):
- return self.erased_list([model.w_nil] * size)
+ return [model.w_nil] * size
def storage_for_list(self, space, collection):
- return self.erased_list([x for x in collection])
+ return [x for x in collection]
def copy_storage_from(self, space, w_obj, reuse_storage=False):
length = w_obj.basic_size()
- return self.erased_list([w_obj.strategy.fetch(space, w_obj, i) for i
in range(length)])
+ return [w_obj.strategy.fetch(space, w_obj, i) for i in range(length)]
-class TaggingSmallIntegerStorageStrategy(AbstractStorageStrategy):
+class TaggingSmallIntegerStorageStrategy(AbstractIntStorageStrategy):
__metaclass__ = SingletonMeta
- strategy_tag = 'tagging'
- # erase, unerase =
rerased.new_static_erasing_pair("tagging-small-integer-strategry")
+ # erase, unerase =
rerased.new_static_erasing_pair("tagging-smallint-strategry")
import_from_mixin(BasicStorageStrategyMixin)
- uses_int_storage = True
+ strategy_tag = 'tagging-smallint'
+ needs_objspace = True
@staticmethod
def wrap(val):
@@ -163,18 +154,15 @@
# also store W_LargePositiveInteger1Word?
nil_value = 1
- def needs_objspace(self):
- return True
-
def fetch(self, space, w_obj, n0):
- val = self.int_storage(w_obj)[n0]
+ val = self.storage(w_obj)[n0]
if val == self.nil_value:
return space.w_nil
else:
return space.wrap_int(self.unwrap(val))
def store(self, space, w_obj, n0, w_val):
- store = self.int_storage(w_obj)
+ store = self.storage(w_obj)
if self.can_contain(w_val):
store[n0] = self.wrap(space.unwrap_int(w_val))
else:
@@ -186,7 +174,7 @@
return w_obj.store_with_new_strategy(space,
ListStorageStrategy.singleton, n0, w_val)
def initial_int_storage(self, space, size):
- return self.erase([self.nil_value] * size)
+ return [self.nil_value] * size
def int_storage_for_list(self, space, collection):
length = len(collection)
@@ -194,7 +182,7 @@
for i in range(length):
if collection[i] != space.w_nil:
store[i] = self.wrap(space.unwrap_int(collection[i]))
- return self.erase(store)
+ return store
def strategy_of_size(s_containing_class, size):
if s_containing_class is None:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit