Author: Carl Friedrich Bolz <[email protected]>
Branch: type-specialized-instances
Changeset: r60054:2007a3fae522
Date: 2013-01-14 18:26 +0100
http://bitbucket.org/pypy/pypy/changeset/2007a3fae522/
Log: type-specialize int attributes
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -7,6 +7,7 @@
from pypy.objspace.std.dictmultiobject import W_DictMultiObject, DictStrategy,
ObjectDictStrategy
from pypy.objspace.std.dictmultiobject import BaseKeyIterator,
BaseValueIterator, BaseItemIterator
from pypy.objspace.std.dictmultiobject import _never_equal_to_string
+from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.objectobject import W_ObjectObject
from pypy.objspace.std.typeobject import TypeCell
@@ -141,6 +142,8 @@
# XXX not so nice that the classes have to be listed
if attrclass_key == PlainAttribute.attrclass_key:
attr = PlainAttribute((name, index), self)
+ elif attrclass_key == StrAttribute.attrclass_key:
+ attr = StrAttribute((name, index), self)
else:
assert attrclass_key == IntAttribute.attrclass_key
attr = IntAttribute((name, index), self)
@@ -372,6 +375,26 @@
erased = self.erase_item(self.space.int_w(w_value))
obj._mapdict_write_storage(self.position, erased)
+class StrAttribute(AbstractStoredAttribute):
+ attrclass_key = 2
+
+ erase_item, unerase_item = rerased.new_erasing_pair("mapdict storage
string item")
+ erase_item = staticmethod(erase_item)
+ unerase_item = staticmethod(unerase_item)
+
+ def read_attr(self, obj):
+ erased = obj._mapdict_read_storage(self.position)
+ value = self.unerase_item(erased)
+ return self.space.wrap(value)
+
+ def write_attr(self, obj, w_value):
+ if type(w_value) is not W_StringObject:
+ self._replace(obj, self.selector, w_value)
+ return
+ erased = self.erase_item(self.space.str_w(w_value))
+ obj._mapdict_write_storage(self.position, erased)
+
+
def is_taggable_int(space, w_value):
from pypy.objspace.std.intobject import W_IntObject
if type(w_value) is W_IntObject:
@@ -386,7 +409,8 @@
attrclass = PlainAttribute
if is_taggable_int(space, w_value):
attrclass = IntAttribute
-
+ elif type(w_value) is W_StringObject:
+ attrclass = StrAttribute
return attrclass
def _become(w_obj, new_obj):
diff --git a/pypy/objspace/std/test/test_mapdict.py
b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -407,6 +407,66 @@
assert isinstance(obj1.map, PlainAttribute)
assert space.eq_w(obj1.getdictvalue(space, "x"),
space.wrap(sys.maxint))
+ def test_str_attributes(self):
+ space = self.space
+ cls = Class(sp=space)
+ obj1 = cls.instantiate()
+ obj1.setdictvalue(space, "x", space.wrap("a"))
+ assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap("a"))
+
+ obj2 = cls.instantiate()
+ w1 = W_Root()
+ obj2.setdictvalue(space, "x", w1)
+ assert obj2.getdictvalue(space, "x") is w1
+
+ assert obj1.map is not obj2.map
+ assert isinstance(obj1.map, StrAttribute)
+
+ obj3 = cls.instantiate()
+ obj3.setdictvalue(space, "x", space.wrap("a"))
+ assert space.eq_w(obj3.getdictvalue(space, "x"), space.wrap("a"))
+
+ assert obj1.map is obj3.map
+
+ assert StrAttribute.unerase_item(obj1.storage[0]) == "a"
+ assert PlainAttribute.unerase_item(obj2.storage[0]) == w1
+
+ def test_overwrite_str_attribute_with_another_type(self):
+ space = self.space
+ cls = Class(sp=space)
+ obj1 = cls.instantiate()
+
+ obj1.setdictvalue(space, "x", space.wrap("a"))
+ assert isinstance(obj1.map, StrAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap("a"))
+
+ w1 = W_Root()
+ obj1.setdictvalue(space, "x", w1)
+ assert isinstance(obj1.map, PlainAttribute)
+ assert obj1.getdictvalue(space, "x") is w1
+
+ def test_overwrite_str_attribute_with_another_type2(self):
+ space = self.space
+ cls = Class(sp=space)
+ obj1 = cls.instantiate()
+
+ obj1.setdictvalue(space, "x", space.wrap("a"))
+ assert isinstance(obj1.map, StrAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "x"), space.wrap("a"))
+
+ obj1.setdictvalue(space, "y", space.wrap("b"))
+ assert isinstance(obj1.map.back, StrAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap("b"))
+
+ # overwrite 'x' with new type
+ w1 = W_Root()
+ obj1.setdictvalue(space, "x", w1)
+ assert isinstance(obj1.map, PlainAttribute)
+ assert obj1.getdictvalue(space, "x") is w1
+
+ # check if 'y' is still reachable
+ assert isinstance(obj1.map.back, StrAttribute)
+ assert space.eq_w(obj1.getdictvalue(space, "y"), space.wrap("b"))
# ___________________________________________________________
# dict tests
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit