[pypy-svn] r77904 - in pypy/branch/32ptr-on-64bit/pypy/objspace/std: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Oct 14 11:40:19 CEST 2010
Author: arigo
Date: Thu Oct 14 11:40:18 2010
New Revision: 77904
Modified:
pypy/branch/32ptr-on-64bit/pypy/objspace/std/mapdict.py
pypy/branch/32ptr-on-64bit/pypy/objspace/std/test/test_mapdict.py
Log:
Upgrade the previous hack by not using 'rerased' at all in the compressptr
case. Instead, point to a small W_Root subclass that itself contains the
pointer to the list.
Modified: pypy/branch/32ptr-on-64bit/pypy/objspace/std/mapdict.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/objspace/std/mapdict.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/objspace/std/mapdict.py Thu Oct 14 11:40:18 2010
@@ -359,8 +359,8 @@
assert isinstance(weakreflifeline, WeakrefLifeline)
self._get_mapdict_map().write(self, ("weakref", SPECIAL), weakreflifeline)
-class ObjectMixin(object):
- _mixin_ = True
+class Object(BaseMapdictObject, W_Root):
+ # mainly for tests
def _init_empty(self, map):
from pypy.rlib.debug import make_sure_not_resized
self.map = map
@@ -376,18 +376,13 @@
self.storage = storage
self.map = map
-class Object(ObjectMixin, BaseMapdictObject, W_Root):
- pass # mainly for tests
-
def get_subclass_of_correct_size(space, cls, w_type):
assert space.config.objspace.std.withmapdict
map = w_type.terminator
classes = memo_get_subclass_of_correct_size(space, cls)
size = map.size_estimate()
- if not size:
- size = 1
try:
- return classes[size - 1]
+ return classes[size]
except IndexError:
return classes[-1]
get_subclass_of_correct_size._annspecialcase_ = "specialize:arg(1)"
@@ -401,24 +396,48 @@
except KeyError:
assert not hasattr(supercls, "__del__")
result = []
- for i in range(1, NUM_SUBCLASSES+1):
- result.append(_make_subclass_size_n(supercls, i))
+ if space.config.translation.compressptr:
+ # with 'compressptr', there are two issues: first we only need
+ # half as many classes, because there is no point in having a
+ # class that contains an odd number of hiddengcrefs (there is
+ # one too for the map, so there is no point in having an even
+ # number of attributes); and we avoid using rlib.rerased because
+ # such an erased pointer cannot be compressed, as it might point
+ # to a list.
+ for i in range(0, NUM_SUBCLASSES // 2 + 1):
+ subcls = _make_subclass_size_n(supercls, i * 2 + 1,
+ use_erased=False)
+ result.append(subcls)
+ result.append(subcls)
+ else:
+ # common case
+ for i in range(1, NUM_SUBCLASSES+1):
+ result.append(_make_subclass_size_n(supercls, i,
+ use_erased=True))
+ result.insert(0, result[0])
_subclass_cache[key] = result
return result
memo_get_subclass_of_correct_size._annspecialcase_ = "specialize:memo"
_subclass_cache = {}
-def _make_subclass_size_n(supercls, n):
- from pypy.rlib import unroll, rerased
+def _make_subclass_size_n(supercls, n, use_erased):
+ from pypy.rlib import unroll
rangen = unroll.unrolling_iterable(range(n))
nmin1 = n - 1
rangenmin1 = unroll.unrolling_iterable(range(nmin1))
+ if use_erased:
+ from pypy.rlib import rerased
+ erase = rerased.erase
+ unerase = rerased.unerase
+ else:
+ erase = lambda x: x
+ unerase = lambda x, t: x
#
- class subcls(ObjectMixin, BaseMapdictObject, supercls):
+ class subcls(BaseMapdictObject, supercls):
_nmin1 = nmin1
for _i in rangenmin1:
locals()["_value%s" % _i] = None
- locals()["_value%s" % nmin1] = rerased.erase(None)
+ locals()["_value%s" % nmin1] = erase(None)
def _init_empty(self, map):
self.map = map
@@ -428,7 +447,11 @@
def _mapdict_get_storage_list(self):
erased = getattr(self, "_value%s" % nmin1)
- return rerased.unerase_fixedsizelist(erased, W_Root)
+ if use_erased:
+ return rerased.unerase_fixedsizelist(erased, W_Root)
+ else:
+ assert isinstance(erased, ExtraAttributes)
+ return erased.storage
def _mapdict_read_storage(self, index):
for i in rangenmin1:
@@ -437,7 +460,7 @@
if self._has_storage_list():
return self._mapdict_get_storage_list()[index - nmin1]
erased = getattr(self, "_value%s" % nmin1)
- return rerased.unerase(erased, W_Root)
+ return unerase(erased, W_Root)
def _mapdict_write_storage(self, index, value):
for i in rangenmin1:
@@ -447,7 +470,7 @@
if self._has_storage_list():
self._mapdict_get_storage_list()[index - nmin1] = value
return
- erased = rerased.erase(value)
+ erased = erase(value)
setattr(self, "_value%s" % nmin1, erased)
def _mapdict_storage_length(self):
@@ -467,25 +490,33 @@
has_storage_list = self._has_storage_list()
if len_storage < n:
assert not has_storage_list
- erased = rerased.erase(None)
+ erased = erase(None)
elif len_storage == n:
assert not has_storage_list
- erased = rerased.erase(storage[nmin1])
+ erased = erase(storage[nmin1])
elif not has_storage_list:
# storage is longer than self.map.length() only due to
# overallocation
- erased = rerased.erase(storage[nmin1])
+ erased = erase(storage[nmin1])
# in theory, we should be ultra-paranoid and check all entries,
# but checking just one should catch most problems anyway:
assert storage[n] is None
else:
storage_list = storage[nmin1:]
- erased = rerased.erase_fixedsizelist(storage_list, W_Root)
+ if use_erased:
+ erased = rerased.erase_fixedsizelist(storage_list, W_Root)
+ else:
+ erased = ExtraAttributes(storage_list)
setattr(self, "_value%s" % nmin1, erased)
subcls.__name__ = supercls.__name__ + "Size%s" % n
return subcls
+class ExtraAttributes(W_Root):
+ def __init__(self, storage):
+ from pypy.rlib.debug import make_sure_not_resized
+ self.storage = make_sure_not_resized(storage)
+
# ____________________________________________________________
# dict implementation
Modified: pypy/branch/32ptr-on-64bit/pypy/objspace/std/test/test_mapdict.py
==============================================================================
--- pypy/branch/32ptr-on-64bit/pypy/objspace/std/test/test_mapdict.py (original)
+++ pypy/branch/32ptr-on-64bit/pypy/objspace/std/test/test_mapdict.py Thu Oct 14 11:40:18 2010
@@ -1,6 +1,7 @@
from pypy.conftest import gettestobjspace, option
from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictMultiObject
from pypy.objspace.std.mapdict import *
+from pypy.objspace.std.mapdict import _subclass_cache
space = FakeSpace()
@@ -357,9 +358,15 @@
# check specialized classes
-def test_specialized_class():
+def test_specialized_class(compressptr=False):
from pypy.objspace.std.objectobject import W_ObjectObject
from pypy.rlib import rerased
+ space = FakeSpace()
+ class translation:
+ pass
+ translation.compressptr = compressptr
+ space.config.translation = translation
+ _subclass_cache.clear()
classes = memo_get_subclass_of_correct_size(space, W_ObjectObject)
w1 = W_Root()
w2 = W_Root()
@@ -372,7 +379,7 @@
obj = objectcls()
obj.user_setup(space, cls)
obj.setdictvalue(space, "a", w1)
- if objectcls._nmin1 == 0:
+ if objectcls._nmin1 == 0 and not compressptr:
assert rerased.unerase(obj._value0, W_Root) is w1
else:
assert obj._value0 is w1
@@ -380,7 +387,7 @@
assert obj.getdictvalue(space, "b") is None
assert obj.getdictvalue(space, "c") is None
obj.setdictvalue(space, "a", w2)
- if objectcls._nmin1 == 0:
+ if objectcls._nmin1 == 0 and not compressptr:
assert rerased.unerase(obj._value0, W_Root) is w2
else:
assert obj._value0 is w2
@@ -401,7 +408,7 @@
res = obj.deldictvalue(space, "a")
assert res
- if objectcls._nmin1 == 0:
+ if objectcls._nmin1 == 0 and not compressptr:
assert rerased.unerase(obj._value0, W_Root) is w4
else:
assert obj._value0 is w4
@@ -417,6 +424,9 @@
assert obj2.getdictvalue(space, "b") is w6
assert obj2.map is abmap
+def test_specialized_class_compressptr():
+ test_specialized_class(compressptr=True)
+
# ___________________________________________________________
# integration tests
More information about the Pypy-commit
mailing list