[pypy-commit] lang-smalltalk strategies3: Fixing things up
anton_gulenko
noreply at buildbot.pypy.org
Mon Jul 28 10:11:12 CEST 2014
Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: strategies3
Changeset: r988:a77d13fd8840
Date: 2014-03-19 12:42 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/a77d13fd8840/
Log: Fixing things up
diff --git a/spyvm/fieldtypes.py b/spyvm/fieldtypes.py
--- a/spyvm/fieldtypes.py
+++ b/spyvm/fieldtypes.py
@@ -9,20 +9,26 @@
_attrs_ = []
_settled_ = True
- def __init__(self):
- pass
- def fetch(self, w_obj, n0):
+ def fetch(self, space, w_obj, n0):
raise NotImplementedError("Abstract base class")
- def store(self, w_obj, n0, w_val):
+ 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")
- def initial_storage(self, size, default_element):
+
+ def initial_storage(self, space, size):
raise NotImplementedError("Abstract base class")
- def storage_for_list(self, collection):
+ def storage_for_list(self, space, collection):
raise NotImplementedError("Abstract base class")
- def all_vars(self, w_obj):
- return [self.fetch(w_obj, i) for i in range(0, self.size_of(w_obj))]
+ def copy_storage_from(self, space, w_obj, reuse_storage=False):
+ old_strategy = w_obj.strategy
+ if old_strategy == self and reuse_storage:
+ return w_obj.get_storage()
+ if isinstance(old_strategy, AllNilStorageStrategy):
+ return self.initial_storage(space, old_strategy.size_of(w_obj))
+ 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 SingletonMeta(type):
def __new__(cls, name, bases, dct):
@@ -43,14 +49,14 @@
erase, unerase = rerased.new_static_erasing_pair("list-storage-strategy")
import_from_mixin(BasicStorageStrategyMixin)
- def fetch(self, w_obj, n0):
+ def fetch(self, space, w_obj, n0):
return self.storage(w_obj)[n0]
- def store(self, w_obj, n0, w_val):
+ def store(self, space, w_obj, n0, w_val):
self.storage(w_obj)[n0] = w_val
def size_of(self, w_obj):
return len(self.storage(w_obj))
- def initial_storage(self, size, default_element):
- return self.erase([default_element] * size)
+ def initial_storage(self, space, size):
+ return self.erase([model.w_nil] * size)
def storage_for_list(self, space, collection):
return self.erase([x for x in collection])
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -507,12 +507,12 @@
def fetch(self, space, n0):
if self.has_shadow():
return self._shadow.fetch(n0)
- return self._fetch(n0)
+ return self._fetch(space, n0)
def store(self, space, n0, w_value):
if self.has_shadow():
return self._shadow.store(n0, w_value)
- return self._store(n0, w_value)
+ return self._store(space, n0, w_value)
def varsize(self, space):
return self.size() - self.instsize(space)
@@ -626,39 +626,36 @@
"""Create new object with size = fixed + variable size."""
W_AbstractPointersObject.__init__(self, space, w_class, size)
self.strategy = strategy_of_size(self.s_class, size)
- self.storage = self.strategy.initial_storage(size, w_nil)
+ self.storage = self.strategy.initial_storage(space, size)
def fillin(self, space, g_self):
W_AbstractPointersObject.fillin(self, space, g_self)
from spyvm.fieldtypes import strategy_for_list
pointers = g_self.get_pointers()
self.strategy = strategy_for_list(self.s_class, pointers)
- self.storage = self.strategy.storage_for_list(pointers)
+ self.storage = self.strategy.storage_for_list(space, pointers)
def get_strategy(self):
+ # return jit.promote(self.strategy)
return self.strategy
def get_storage(self):
return self.storage
- def all_vars(self):
- return self.strategy.all_vars(self)
+ def all_vars(self, space):
+ return [self.strategy.fetch(space, self, i) for i in range(self.basic_size())]
def set_all_vars(self, collection):
- # TODO reuse storage if possible
- self.storage = self.strategy.storage_for_list(collection)
+ self.storage = self.strategy.storage_for_list(space, collection)
- def _fetch(self, n0):
- strategy = jit.promote(self.strategy)
- return strategy.fetch(self, n0)
+ def _fetch(self, space, n0):
+ return self.get_strategy().fetch(space, self, n0)
- def _store(self, n0, w_value):
- strategy = jit.promote(self.strategy)
- return strategy.store(self, n0, w_value)
+ def _store(self, space, n0, w_value):
+ return self.get_strategy().store(space, self, n0, w_value)
def basic_size(self):
- strategy = jit.promote(self.strategy)
- return strategy.size_of(self)
+ return self.get_strategy().size_of(self)
def become(self, w_other):
if not isinstance(w_other, W_PointersObject):
@@ -672,7 +669,7 @@
length = self.strategy.size_of(self)
w_result = W_PointersObject(self.space, self.getclass(space), length)
cloned_vars = [self.fetch(space, i) for i in range(length)]
- w_result.storage = w_result.strategy.storage_for_list(cloned_vars)
+ w_result.storage = w_result.strategy.storage_for_list(space, cloned_vars)
return w_result
def fieldtype(self):
@@ -690,11 +687,11 @@
def fillin(self, space, g_self):
raise NotImplementedError("we don't expect weak objects in a fresh image")
- def _fetch(self, n0):
+ def _fetch(self, space, n0):
weakobj = self._weakvars[n0]
return weakobj() or w_nil
- def _store(self, n0, w_value):
+ def _store(self, space, n0, w_value):
assert w_value is not None
self._weakvars[n0] = weakref.ref(w_value)
@@ -1193,7 +1190,10 @@
if isinstance(w_candidate, W_PointersObject):
c_shadow = w_candidate._shadow
if c_shadow is None and w_candidate.size() >= 2:
- w_class = w_candidate._fetch(1)
+ space = None
+ if self._shadow:
+ space = self._shadow.space
+ w_class = w_candidate._fetch(space, 1)
if isinstance(w_class, W_PointersObject):
d_shadow = w_class._shadow
if isinstance(d_shadow, shadow.ClassShadow):
@@ -1260,7 +1260,7 @@
def as_compiledmethod_get_shadow(self, space=None):
from shadow import CompiledMethodShadow
if self._shadow is None:
- self._shadow = CompiledMethodShadow(self)
+ self._shadow = CompiledMethodShadow(space, self)
return self._shadow
def literalat0(self, space, index0):
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -165,7 +165,7 @@
from spyvm.fieldtypes import ListStorageStrategy
w_nil.space = self
w_nil.strategy = ListStorageStrategy.singleton
- w_nil.storage = w_nil.strategy.initial_storage(0, None)
+ w_nil.storage = w_nil.strategy.initial_storage(self, 0)
w_nil.s_class = self.classtable['w_UndefinedObject'].as_class_get_penumbra(self)
return w_nil
w_nil = self.w_nil = patch_nil(model.w_nil)
diff --git a/spyvm/plugins/bitblt.py b/spyvm/plugins/bitblt.py
--- a/spyvm/plugins/bitblt.py
+++ b/spyvm/plugins/bitblt.py
@@ -756,8 +756,8 @@
w_offset = self.fetch(4)
assert isinstance(w_offset, model.W_PointersObject)
if not w_offset is self.space.w_nil:
- self.offsetX = self.intOrIfNil(w_offset._fetch(0), 0)
- self.offsetY = self.intOrIfNil(w_offset._fetch(1), 0)
+ self.offsetX = self.intOrIfNil(w_offset._fetch(self.space, 0), 0)
+ self.offsetY = self.intOrIfNil(w_offset._fetch(self.space, 1), 0)
self.pixPerWord = 32 / self.depth
self.pitch = (self.width + (self.pixPerWord - 1)) / self.pixPerWord | 0
if self.w_bits.size() < (self.pitch * self.height):
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -374,7 +374,7 @@
print ("%s" % w_message).replace('\r', '\n')
print ("%s" % s_frame.peek(1)).replace('\r', '\n')
if isinstance(w_message, model.W_PointersObject):
- print ('%s' % w_message.all_vars()).replace('\r', '\n')
+ print ('%s' % w_message.all_vars(interp.space)).replace('\r', '\n')
# raise Exit('Probably Debugger called...')
raise PrimitiveFailedError()
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -23,9 +23,9 @@
self.space = space
self._w_self = w_self
def fetch(self, n0):
- return self.w_self()._fetch(n0)
+ return self.w_self()._fetch(self.space, n0)
def store(self, n0, w_value):
- return self.w_self()._store(n0, w_value)
+ return self.w_self()._store(self.space, n0, w_value)
def size(self):
return self.w_self().basic_size()
def w_self(self):
@@ -109,7 +109,7 @@
# read and painfully decode the format
try:
classformat = self.space.unwrap_int(
- w_self._fetch(constants.CLASS_FORMAT_INDEX))
+ w_self._fetch(self.space, constants.CLASS_FORMAT_INDEX))
# The classformat in Squeak, as an integer value, is:
# <2 bits=instSize//64><5 bits=cClass><4 bits=instSpec>
# <6 bits=instSize\\64><1 bit=0>
@@ -149,19 +149,19 @@
else:
raise ClassShadowError("unknown format %d" % (format,))
except UnwrappingError:
- assert w_self._fetch(constants.CLASS_FORMAT_INDEX) is self.space.w_nil
+ assert w_self._fetch(self.space, constants.CLASS_FORMAT_INDEX) is self.space.w_nil
pass # not enough information stored in w_self, yet
self.guess_class_name()
# read the methoddict
- w_methoddict = w_self._fetch(constants.CLASS_METHODDICT_INDEX)
+ w_methoddict = w_self._fetch(self.space, constants.CLASS_METHODDICT_INDEX)
assert isinstance(w_methoddict, model.W_PointersObject)
if not w_methoddict.is_same_object(self.space.w_nil):
self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space)
self._s_methoddict.s_class = self
- w_superclass = w_self._fetch(constants.CLASS_SUPERCLASS_INDEX)
+ w_superclass = w_self._fetch(self.space, constants.CLASS_SUPERCLASS_INDEX)
if w_superclass.is_same_object(self.space.w_nil):
self._s_superclass = None
else:
@@ -184,7 +184,7 @@
# read the name
if w_self.size() > constants.CLASS_NAME_INDEX:
- w_name = w_self._fetch(constants.CLASS_NAME_INDEX)
+ w_name = w_self._fetch(self.space, constants.CLASS_NAME_INDEX)
else:
# Some heuristic to find the classname
# Only used for debugging
@@ -193,11 +193,11 @@
# we are probably holding a metaclass instead of a class.
# metaclasses hold a pointer to the real class in the last
# slot. This is pos 6 in mini.image and higher in squeak3.9
- w_realclass = w_self._fetch(w_self.size() - 1)
+ w_realclass = w_self._fetch(self.space, w_self.size() - 1)
if (isinstance(w_realclass, model.W_PointersObject)
and w_realclass.size() > constants.CLASS_NAME_INDEX):
# TODO ADD TEST WHICH GOES OVER THIS PART
- w_name = w_realclass._fetch(constants.CLASS_NAME_INDEX)
+ w_name = w_realclass._fetch(self.space, constants.CLASS_NAME_INDEX)
else:
return
@@ -233,7 +233,7 @@
return w_new
def w_methoddict(self):
- return self.w_self()._fetch(constants.CLASS_METHODDICT_INDEX)
+ return self.w_self()._fetch(self.space, constants.CLASS_METHODDICT_INDEX)
def s_methoddict(self):
return self._s_methoddict
@@ -335,7 +335,7 @@
"NOT_RPYTHON" # this is only for testing.
if self._s_methoddict is None:
w_methoddict = model.W_PointersObject(self.space, None, 2)
- w_methoddict._store(1, model.W_PointersObject(self.space, None, 0))
+ w_methoddict._store(self.space, 1, model.W_PointersObject(self.space, None, 0))
self._s_methoddict = w_methoddict.as_methoddict_get_shadow(self.space)
self.s_methoddict().sync_cache()
self.s_methoddict().invalid = False
@@ -386,14 +386,14 @@
def sync_cache(self):
if self.w_self().size() == 0:
return
- w_values = self.w_self()._fetch(constants.METHODDICT_VALUES_INDEX)
+ w_values = self.w_self()._fetch(self.space, constants.METHODDICT_VALUES_INDEX)
assert isinstance(w_values, model.W_PointersObject)
s_values = w_values.as_observed_get_shadow(self.space)
s_values.notify(self)
size = self.w_self().size() - constants.METHODDICT_NAMES_INDEX
self.methoddict = {}
for i in range(size):
- w_selector = self.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i)
+ w_selector = self.w_self()._fetch(self.space, constants.METHODDICT_NAMES_INDEX+i)
if not w_selector.is_same_object(self.space.w_nil):
if not isinstance(w_selector, model.W_BytesObject):
pass
@@ -401,7 +401,7 @@
# Putting any key in the methodDict and running with
# perform is actually supported in Squeak
# raise ClassShadowError("bogus selector in method dict")
- w_compiledmethod = w_values._fetch(i)
+ w_compiledmethod = w_values._fetch(self.space, i)
if not isinstance(w_compiledmethod, model.W_CompiledMethod):
raise ClassShadowError("The methoddict must contain "
"CompiledMethods only, for now. "
@@ -441,7 +441,7 @@
self.copy_from_w_self(i)
except error.SenderChainManipulation, e:
assert e.s_context == self
- w_self.storage = w_self.strategy.initial_storage(0, None)
+ w_self.storage = w_self.strategy.initial_storage(self.space, 0)
# def detach_shadow(self):
# w_self = self.w_self()
@@ -451,9 +451,9 @@
# self.copy_to_w_self(i)
def copy_from_w_self(self, n0):
- self.store(n0, self.w_self()._fetch(n0))
+ self.store(n0, self.w_self()._fetch(self.space, n0))
def copy_to_w_self(self, n0):
- self.w_self()._store(n0, self.fetch(n0))
+ self.w_self()._store(self.space, n0, self.fetch(n0))
class ContextPartShadow(AbstractRedirectingShadow):
@@ -1031,11 +1031,12 @@
"literals", "bytecodeoffset",
"literalsize", "_tempsize", "_primitive",
"argsize", "islarge",
- "w_compiledin", "version"]
+ "w_compiledin", "version", "space"]
_immutable_fields_ = ["version?", "_w_self"]
- def __init__(self, w_compiledmethod):
+ def __init__(self, space, w_compiledmethod):
self._w_self = w_compiledmethod
+ self.space = space
self.update()
def w_self(self):
@@ -1110,11 +1111,11 @@
@jit.elidable
def safe_fetch(self, n0, version):
assert version is self.version
- return self._w_self._fetch(n0)
+ return self._w_self._fetch(self.space, n0)
def store(self, n0, w_value):
self.version = Version()
- return self._w_self._store(n0, w_value)
+ return self._w_self._store(self.space, n0, w_value)
def update(self): pass
diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py
--- a/spyvm/test/test_interpreter.py
+++ b/spyvm/test/test_interpreter.py
@@ -218,7 +218,7 @@
step_in_interp(s_frame)
assert s_frame.stack() == []
for test_index in range(8):
- print w_frame.all_vars()
+ print w_frame.all_vars(space)
if test_index == index:
assert s_frame.gettemp(test_index) == space.w_true
else:
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -14,7 +14,7 @@
class MockFrame(model.W_PointersObject):
def __init__(self, stack):
- self.set_all_vars([None] * 6 + stack + [space.w_nil] * 6)
+ self.set_all_vars(space, [None] * 6 + stack + [space.w_nil] * 6)
s_self = self.as_blockcontext_get_shadow()
s_self.init_stack_and_temps()
s_self.reset_stack()
diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py
--- a/spyvm/test/test_shadow.py
+++ b/spyvm/test/test_shadow.py
@@ -240,15 +240,15 @@
s_methoddict = s_class.s_methoddict()
s_methoddict.sync_cache()
i = 0
- key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i)
+ key = s_methoddict.w_self()._fetch(space, constants.METHODDICT_NAMES_INDEX+i)
while key is space.w_nil:
i = i + 1
- key = s_methoddict.w_self()._fetch(constants.METHODDICT_NAMES_INDEX+i)
+ key = s_methoddict.w_self()._fetch(space, constants.METHODDICT_NAMES_INDEX+i)
assert (s_class.lookup(key) is foo.as_compiledmethod_get_shadow(space)
or s_class.lookup(key) is bar.as_compiledmethod_get_shadow(space))
# change that entry
- w_array = s_class.w_methoddict()._fetch(constants.METHODDICT_VALUES_INDEX)
+ w_array = s_class.w_methoddict()._fetch(space, constants.METHODDICT_VALUES_INDEX)
version = s_class.version
w_array.atput0(space, i, baz)
@@ -268,7 +268,7 @@
s_md = w_parent.as_class_get_shadow(space).s_methoddict()
s_md.sync_cache()
- w_ary = s_md._w_self._fetch(constants.METHODDICT_VALUES_INDEX)
+ w_ary = s_md._w_self._fetch(space, constants.METHODDICT_VALUES_INDEX)
s_md._w_self.atput0(space, 0, key)
w_ary.atput0(space, 0, w_method)
More information about the pypy-commit
mailing list