Author: Anton Gulenko <[email protected]>
Branch: storage
Changeset: r725:4e34de85beee
Date: 2014-03-31 14:08 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/4e34de85beee/
Log: Made become() more consistent (implemented for more types). Removed
_immutable_fields from ByteObject and WordsObject (not immutable due
to become). Merged W_AbstractPointersObject and subclasses into a
single W_PointersObject. This allowed for become() with a weak and a
non-weak object.
diff --git a/spyvm/interpreter_proxy.py b/spyvm/interpreter_proxy.py
--- a/spyvm/interpreter_proxy.py
+++ b/spyvm/interpreter_proxy.py
@@ -365,7 +365,7 @@
@expose_on_virtual_machine_proxy([oop], bool)
def isWeak(w_object):
- return isinstance(w_object, model.W_WeakPointersObject)
+ return isinstance(w_object, model.W_PointersObject) and w_object.is_weak()
@expose_on_virtual_machine_proxy([oop], bool)
def isWords(w_object):
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -284,7 +284,21 @@
def invariant(self):
return isinstance(self.hash, int)
+ def become(self, w_other):
+ if not self.can_become(w_other):
+ return False
+ if self.is_same_object(w_other):
+ return False
+ self._become(w_other)
+ return True
+
+ def can_become(self, w_other):
+ # TODO -- what about become: with a Float and a CompiledMethod etc.?
+ # We might be in trouble regarding W_LargePositiveInteger1Word, too.
+ return self.__class__ is w_other.__class__
+
def _become(self, w_other):
+ assert isinstance(w_other, W_AbstractObjectWithIdentityHash)
self.hash, w_other.hash = w_other.hash, self.hash
class W_LargePositiveInteger1Word(W_AbstractObjectWithIdentityHash):
@@ -370,6 +384,12 @@
def is_array_object(self):
return True
+
+ def _become(self, w_other):
+ assert isinstance(w_other, W_LargePositiveInteger1Word)
+ self.value, w_other.value = w_other.value, self.value
+ self._exposed_size, w_other._exposed_size = w_other._exposed_size,
self._exposed_size
+ W_AbstractObjectWithIdentityHash._become(self, w_other)
class W_Float(W_AbstractObjectWithIdentityHash):
"""Boxed float value."""
@@ -409,7 +429,7 @@
return isinstance(self.value, float)
def _become(self, w_other):
- # TODO -- shouldn't this be named 'become'?
+ assert isinstance(w_other, W_Float)
self.value, w_other.value = w_other.value, self.value
W_AbstractObjectWithIdentityHash._become(self, w_other)
@@ -509,6 +529,7 @@
isinstance(self.w_class.shadow, shadow.ClassShadow))
def _become(self, w_other):
+ assert isinstance(w_other, W_AbstractObjectWithClassReference)
self.w_class, w_other.w_class = w_other.w_class, self.w_class
W_AbstractObjectWithIdentityHash._become(self, w_other)
@@ -523,37 +544,45 @@
assert w_class is not None
return w_class.as_class_get_shadow(space)
-class W_AbstractPointersObject(W_AbstractObjectWithClassReference):
+class W_PointersObject(W_AbstractObjectWithClassReference):
"""Common object."""
_attrs_ = ['shadow']
shadow = None
- repr_classname = "W_AbstractPointersObject"
+ repr_classname = "W_PointersObject"
log_storage = storage_statistics.log
@jit.unroll_safe
- def __init__(self, space, w_class, size):
+ def __init__(self, space, w_class, size, weak=False):
"""Create new object with size = fixed + variable size."""
W_AbstractObjectWithClassReference.__init__(self, space, w_class)
- self.initialize_storage(space, size)
-
- def initialize_storage(self, space, size):
- self.store_shadow(self.empty_storage(space, size))
+ self.initialize_storage(space, size, weak)
+
+ def initialize_storage(self, space, size, weak=False):
+ if weak:
+ from spyvm.shadow import WeakListStorageShadow
+ storage = WeakListStorageShadow(space, self, size)
+ else:
+ from spyvm.shadow import AllNilStorageShadow
+ storage = AllNilStorageShadow(space, self, size)
+ self.store_shadow(storage)
self.log_storage("Initialized")
-
+
def fillin(self, space, g_self):
W_AbstractObjectWithClassReference.fillin(self, space, g_self)
# Recursive fillin required to enable specialized storage strategies.
for g_obj in g_self.pointers:
g_obj.fillin(space)
pointers = g_self.get_pointers()
- self.store_shadow(self.storage_for_list(space, pointers))
+ # TODO -- Also handle weak objects loaded from images.
+ from spyvm.shadow import find_storage_for_objects
+ storage = find_storage_for_objects(space, pointers)(space, self,
len(pointers))
+ self.store_shadow(storage)
self.store_all(space, pointers)
self.log_storage("Filledin", log_classname=False)
-
- def empty_storage(self, space, size):
- raise NotImplementedError()
- def storage_for_list(self, space, vars):
- raise NotImplementedError()
+
+ def is_weak(self):
+ from shadow import WeakListStorageShadow
+ return isinstance(self.shadow, WeakListStorageShadow)
def assert_shadow(self):
# Failing the following assert most likely indicates a bug. The shadow
can only be absent during
@@ -591,9 +620,9 @@
if self.has_shadow():
shadow_info = self.shadow.__repr__()
if self.shadow.provides_getname:
- name = self._get_shadow().getname()
- return '(%s) len=%d [%s]' % (shadow_info, self.size(), name)
-
+ name = " [%s]" % self._get_shadow().getname()
+ return '(%s) len=%d%s' % (shadow_info, self.size(), name)
+
def fetch_all(self, space):
return [self.fetch(space, i) for i in range(self.size())]
@@ -689,15 +718,13 @@
def has_shadow(self):
return self._get_shadow() is not None
- def become(self, w_other):
- if not isinstance(w_other, W_AbstractPointersObject):
- return False
+ def _become(self, w_other):
+ assert isinstance(w_other, W_PointersObject)
self.shadow, w_other.shadow = w_other.shadow, self.shadow
# shadow links are in both directions -> also update shadows
if self.shadow is not None: self.shadow._w_self = self
if w_other.shadow is not None: w_other.shadow._w_self = w_other
W_AbstractObjectWithClassReference._become(self, w_other)
- return True
@jit.unroll_safe
def clone(self, space):
@@ -706,33 +733,8 @@
w_result.store_all(space, my_pointers)
return w_result
-class W_PointersObject(W_AbstractPointersObject):
- repr_classname = 'W_PointersObject'
-
- def empty_storage(self, space, size):
- # A newly allocated object contains only nils.
- from spyvm.shadow import AllNilStorageShadow
- return AllNilStorageShadow(space, self, size)
-
- def storage_for_list(self, space, vars):
- #if not self.class_shadow(space).isvariable():
- # return ListStorageShadow(space, self, len(vars))
- from spyvm.shadow import find_storage_for_objects
- return find_storage_for_objects(space, vars)(space, self, len(vars))
-
-class W_WeakPointersObject(W_AbstractPointersObject):
- repr_classname = 'W_WeakPointersObject'
-
- def empty_storage(self, space, size):
- from spyvm.shadow import WeakListStorageShadow
- return WeakListStorageShadow(space, self, size)
- def storage_for_list(self, space, vars):
- from spyvm.shadow import WeakListStorageShadow
- return WeakListStorageShadow(space, self, len(vars))
-
class W_BytesObject(W_AbstractObjectWithClassReference):
_attrs_ = ['bytes', 'c_bytes', '_size']
- _immutable_fields_ = ['_size', 'bytes[*]?']
repr_classname = 'W_BytesObject'
bytes_per_slot = 1
@@ -859,13 +861,19 @@
self.bytes = None
return c_bytes
+ def _become(self, w_other):
+ assert isinstance(w_other, W_BytesObject)
+ self.bytes, w_other.bytes = w_other.bytes, self.bytes
+ self.c_bytes, w_other.c_bytes = w_other.c_bytes, self.c_bytes
+ self._size, w_other._size = w_other._size, self._size
+ W_AbstractObjectWithClassReference._become(self, w_other)
+
def __del__(self):
if self.bytes is None:
rffi.free_charp(self.c_bytes)
class W_WordsObject(W_AbstractObjectWithClassReference):
_attrs_ = ['words', 'c_words', '_size']
- _immutable_fields_ = ['_size']
repr_classname = "W_WordsObject"
def __init__(self, space, w_class, size):
@@ -974,12 +982,18 @@
w_display_bitmap.setword(idx, self.getword(idx))
w_form.store(interp.space, 0, w_display_bitmap)
return w_display_bitmap
-
+
+ def _become(self, w_other):
+ assert isinstance(w_other, W_WordsObject)
+ self.words, w_other.words = w_other.words, self.words
+ self.c_words, w_other.c_words = w_other.c_words, self.c_words
+ self._size, w_other._size = w_other._size, self._size
+ W_AbstractObjectWithClassReference._become(self, w_other)
+
def __del__(self):
if self.words is None:
lltype.free(self.c_words, flavor='raw')
-
class W_DisplayBitmap(W_AbstractObjectWithClassReference):
_attrs_ = ['pixelbuffer', '_realsize', '_real_depth_buffer', 'display',
'_depth']
_immutable_fields_ = ['_realsize', 'display', '_depth']
@@ -1051,6 +1065,10 @@
def convert_to_c_layout(self):
return self._real_depth_buffer
+ def can_become(self, w_other):
+ # TODO - implement _become() for this class. Impossible due to
_immutable_fields_?
+ return False
+
def __del__(self):
lltype.free(self._real_depth_buffer, flavor='raw')
@@ -1133,7 +1151,7 @@
"bytes", "literals",
# Additional info about the method
"_likely_methodname", "w_compiledin" ]
-
+
### Extension from Squeak 3.9 doc, which we do not implement:
### trailer (variable)
### The trailer has two variant formats. In the first variant, the last
@@ -1297,12 +1315,11 @@
index0 = index0 - self.bytecodeoffset()
assert index0 < len(self.bytes)
self.setchar(index0, chr(space.unwrap_int(w_value)))
-
+
# === Misc ===
- def become(self, w_other):
- if not isinstance(w_other, W_CompiledMethod):
- return False
+ def _become(self, w_other):
+ assert isinstance(w_other, W_CompiledMethod)
self.argsize, w_other.argsize = w_other.argsize, self.argsize
self._primitive, w_other._primitive = w_other._primitive,
self._primitive
self.literals, w_other.literals = w_other.literals, self.literals
@@ -1311,10 +1328,11 @@
self.header, w_other.header = w_other.header, self.header
self.literalsize, w_other.literalsize = w_other.literalsize,
self.literalsize
self.islarge, w_other.islarge = w_other.islarge, self.islarge
+ self._likely_methodname, w_other._likely_methodname =
w_other._likely_methodname, self._likely_methodname
+ self.w_compiledin, w_other.w_compiledin = w_other.w_compiledin,
self.w_compiledin
W_AbstractObjectWithIdentityHash._become(self, w_other)
self.changed()
w_other.changed()
- return True
def clone(self, space):
copy = W_CompiledMethod(space, 0, self.getheader())
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -19,7 +19,7 @@
def __init__(self, space, w_self):
self.space = space
- assert w_self is None or isinstance(w_self,
model.W_AbstractPointersObject)
+ assert w_self is None or isinstance(w_self, model.W_PointersObject)
self._w_self = w_self
def w_self(self):
return self._w_self
@@ -401,7 +401,7 @@
w_new = model.W_BytesObject(self.space, w_cls, extrasize)
elif self.instance_kind == WEAK_POINTERS:
size = self.instsize() + extrasize
- w_new = model.W_WeakPointersObject(self.space, w_cls, size)
+ w_new = model.W_PointersObject(self.space, w_cls, size, weak=True)
else:
raise NotImplementedError(self.instance_kind)
return w_new
diff --git a/spyvm/test/jittest/test_strategies.py
b/spyvm/test/jittest/test_strategies.py
--- a/spyvm/test/jittest/test_strategies.py
+++ b/spyvm/test/jittest/test_strategies.py
@@ -34,9 +34,9 @@
setarrayitem_gc(p78, 1, p195, descr=<ArrayP 4>),
guard_class(p193, 18294904, descr=<Guard0x32f9d90>),
p196 = getfield_gc(p193, descr=<FieldP
spyvm.model.W_AbstractObjectWithClassReference.inst_w_class 12>),
- p197 = getfield_gc(p196, descr=<FieldP
spyvm.model.W_AbstractPointersObject.inst_shadow 16>),
+ p197 = getfield_gc(p196, descr=<FieldP
spyvm.model.W_PointersObject.inst_shadow 16>),
guard_value(p197, ConstPtr(ptr117), descr=<Guard0x32f9e10>),
- p198 = getfield_gc(p193, descr=<FieldP
spyvm.model.W_AbstractPointersObject.inst_shadow 16>),
+ p198 = getfield_gc(p193, descr=<FieldP
spyvm.model.W_PointersObject.inst_shadow 16>),
setarrayitem_gc(p78, 0, ConstPtr(null), descr=<ArrayP 4>),
setfield_gc(p66, 0, descr=<FieldU
spyvm.shadow.ContextPartShadow.inst__stack_ptr 32>),
setfield_gc(ConstPtr(ptr80), i131, descr=<FieldS
spyvm.interpreter.Interpreter.inst_remaining_stack_depth 40>),
@@ -47,9 +47,9 @@
p203 = getarrayitem_gc(p201, 0, descr=<ArrayP 4>),
guard_class(p203, 18294904, descr=<Guard0x3311750>),
p204 = getfield_gc(p203, descr=<FieldP
spyvm.model.W_AbstractObjectWithClassReference.inst_w_class 12>),
- p205 = getfield_gc(p204, descr=<FieldP
spyvm.model.W_AbstractPointersObject.inst_shadow 16>),
+ p205 = getfield_gc(p204, descr=<FieldP
spyvm.model.W_PointersObject.inst_shadow 16>),
guard_value(p205, ConstPtr(ptr149), descr=<Guard0x3311710>),
- p206 = getfield_gc(p203, descr=<FieldP
spyvm.model.W_AbstractPointersObject.inst_shadow 16>),
+ p206 = getfield_gc(p203, descr=<FieldP
spyvm.model.W_PointersObject.inst_shadow 16>),
guard_nonnull_class(p206, 18300088, descr=<Guard0x3311450>),
p207 = getfield_gc_pure(p206, descr=<FieldP
spyvm.shadow.SmallIntegerOrNilStorageShadow.inst_storage 16>),
i208 = arraylen_gc(p207, descr=<ArrayS 4>),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit