From 5818b9ff8dcc8a48bdbd07ba631b4e150f81831b Mon Sep 17 00:00:00 2001 From: Carl Friedrich Bolz-Tereick Date: Tue, 29 Dec 2020 21:22:24 +0100 Subject: store everything erased --- pypy/objspace/std/mapdict.py | 29 ++++++++------- pypy/objspace/std/test/test_mapdict.py | 66 +++++++++++++++++++++------------- rpython/rlib/rerased.py | 1 + 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py index da3b726784..c992b31878 100644 --- a/pypy/objspace/std/mapdict.py +++ b/pypy/objspace/std/mapdict.py @@ -621,14 +621,14 @@ class MapdictStorageMixin(object): def _mapdict_init_empty(self, map): from rpython.rlib.debug import make_sure_not_resized self.map = map - self.storage = make_sure_not_resized([None] * map.size_estimate()) + self.storage = make_sure_not_resized([erase_item(None)] * map.size_estimate()) def _mapdict_read_storage(self, storageindex): assert storageindex >= 0 - return self.storage[storageindex] + return unerase_item(self.storage[storageindex]) def _mapdict_write_storage(self, storageindex, value): - self.storage[storageindex] = value + self.storage[storageindex] = erase_item(value) def _mapdict_storage_length(self): """ return the size of the storage (which should be longer or equal in @@ -638,8 +638,8 @@ class MapdictStorageMixin(object): def _set_mapdict_increase_storage(self, map, w_value): """ increase storage size, adding w_value """ len_storage = len(self.storage) - new_storage = self.storage + [None] * (map.size_estimate() - len_storage) - new_storage[len_storage] = w_value + new_storage = self.storage + [erase_item(None)] * (map.size_estimate() - len_storage) + new_storage[len_storage] = erase_item(w_value) self.map = map self.storage = new_storage @@ -679,9 +679,8 @@ def _make_storage_mixin_size_n(n=SUBCLASSES_NUM_FIELDS): def _set_mapdict_map(self, map): self.map = map def _mapdict_init_empty(self, map): - for i in rangenmin1: - setattr(self, "_value%s" % i, None) - setattr(self, valnmin1, erase_item(None)) + for i in rangen: + setattr(self, "_value%s" % i, erase_item(None)) self.map = map def _has_storage_list(self): @@ -696,7 +695,7 @@ def _make_storage_mixin_size_n(n=SUBCLASSES_NUM_FIELDS): if storageindex < nmin1: for i in rangenmin1: if storageindex == i: - return getattr(self, "_value%s" % i) + return unerase_item(getattr(self, "_value%s" % i)) if self._has_storage_list(): return self._mapdict_get_storage_list()[storageindex - nmin1] erased = getattr(self, "_value%s" % nmin1) @@ -707,10 +706,10 @@ def _make_storage_mixin_size_n(n=SUBCLASSES_NUM_FIELDS): if storageindex < nmin1: for i in rangenmin1: if storageindex == i: - setattr(self, "_value%s" % i, value) + setattr(self, "_value%s" % i, erase_item(value)) return if self._has_storage_list(): - self._mapdict_get_storage_list()[storageindex - nmin1] = value + self._mapdict_get_storage_list()[storageindex - nmin1] = erase_item(value) return setattr(self, "_value%s" % nmin1, erase_item(value)) @@ -726,7 +725,7 @@ def _make_storage_mixin_size_n(n=SUBCLASSES_NUM_FIELDS): if i < len_storage: erased = storage[i] else: - erased = None + erased = erase_item(None) setattr(self, "_value%s" % i, erased) has_storage_list = self._has_storage_list() if len_storage < n: @@ -734,7 +733,7 @@ def _make_storage_mixin_size_n(n=SUBCLASSES_NUM_FIELDS): erased = erase_item(None) elif len_storage == n: assert not has_storage_list - erased = erase_item(storage[nmin1]) + erased = storage[nmin1] elif not has_storage_list: # storage is longer than self.map.storage_needed() only due to # overallocation @@ -755,9 +754,9 @@ def _make_storage_mixin_size_n(n=SUBCLASSES_NUM_FIELDS): return if len_storage == n: erased = getattr(self, "_value%s" % nmin1) - new_storage = [unerase_item(erased), w_value] + new_storage = [erased, w_value] else: - new_storage = [None] * (map.size_estimate() - self._mapdict_storage_length()) + new_storage = [erase_item(None)] * (map.size_estimate() - self._mapdict_storage_length()) new_storage = self._mapdict_get_storage_list() + new_storage new_storage[len_storage - nmin1] = w_value self.map = map diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py index c757a7cf1b..875fa88a46 100644 --- a/pypy/objspace/std/test/test_mapdict.py +++ b/pypy/objspace/std/test/test_mapdict.py @@ -32,10 +32,28 @@ class ObjectWithoutDict(ObjectWithoutDict): class typedef: hasdict = False + @property + def checkstorage(self): + return [unerase_item(x) for x in self.storage] + + @checkstorage.setter + def checkstorage(self, value): + self.storage = [erase_item(x) for x in value] + + class Object(Object): class typedef: hasdict = False + @property + def checkstorage(self): + return [unerase_item(x) for x in self.storage] + + @checkstorage.setter + def checkstorage(self, value): + self.storage = [erase_item(x) for x in value] + + def test_plain_attribute(): w_cls = "class" aa = PlainAttribute("b", DICT, @@ -46,18 +64,18 @@ def test_plain_attribute(): assert aa.get_terminator() is aa.terminator obj = Object() - obj.map, obj.storage = aa, [10, 20] + obj.map, obj.checkstorage = aa, [10, 20] assert obj.getdictvalue(space, "a") == 10 assert obj.getdictvalue(space, "b") == 20 assert obj.getdictvalue(space, "c") is None obj = Object() - obj.map, obj.storage = aa, [30, 40] + obj.map, obj.checkstorage = aa, [30, 40] obj.setdictvalue(space, "a", 50) - assert obj.storage == [50, 40] + assert obj.checkstorage == [50, 40] assert obj.getdictvalue(space, "a") == 50 obj.setdictvalue(space, "b", 60) - assert obj.storage == [50, 60] + assert obj.checkstorage == [50, 60] assert obj.getdictvalue(space, "b") == 60 assert aa.storage_needed() == 2 @@ -85,7 +103,7 @@ def test_add_attribute(): cls = Class() obj = cls.instantiate() obj.setdictvalue(space, "a", 10) - assert obj.storage == [10] + assert obj.checkstorage == [10] assert obj.getdictvalue(space, "a") == 10 assert obj.getdictvalue(space, "b") is None assert obj.getdictvalue(space, "c") is None @@ -95,7 +113,7 @@ def test_add_attribute(): assert obj.getdictvalue(space, "c") is None obj.setdictvalue(space, "b", 30) - assert obj.storage == [20, 30] + assert obj.checkstorage == [20, 30] assert obj.getdictvalue(space, "a") == 20 assert obj.getdictvalue(space, "b") == 30 assert obj.getdictvalue(space, "c") is None @@ -121,7 +139,7 @@ def test_add_attribute_limit(): for i in range(1000): obj.setdictvalue(space, str(i), i) # moved to dict (which is the remaining non-slot item) - assert len(obj.storage) == 1 + numslots + assert len(obj.checkstorage) == 1 + numslots for i in range(1000): assert obj.getdictvalue(space, str(i)) == i @@ -133,7 +151,7 @@ def test_add_attribute_limit(): obj = cls.instantiate() for i in range(1000): obj.setslotvalue(i, i) - assert len(obj.storage) == 1000 + assert len(obj.checkstorage) == 1000 for i in range(1000): assert obj.getslotvalue(i) == i @@ -291,7 +309,7 @@ def test_attr_immutability(monkeypatch): obj.setdictvalue(space, "a", 10) obj.setdictvalue(space, "b", 20) obj.setdictvalue(space, "b", 30) - assert obj.storage == [10, 30] + assert obj.checkstorage == [10, 30] assert obj.map.ever_mutated == True assert obj.map.back.ever_mutated == False @@ -339,12 +357,12 @@ def test_delete(): obj.setdictvalue(space, "a", 50) obj.setdictvalue(space, "b", 60) obj.setdictvalue(space, "c", 70) - assert obj.storage == [50, 60, 70] + assert obj.checkstorage == [50, 60, 70] res = obj.deldictvalue(space, dattr) assert res s = [50, 60, 70] del s[i] - assert obj.storage == s + assert obj.checkstorage == s obj = c.instantiate() obj.setdictvalue(space, "a", 50) @@ -367,7 +385,7 @@ def test_class(): c2 = Class() obj.setclass(space, c2) assert obj.getclass(space) is c2 - assert obj.storage == [50, 60, 70] + assert obj.checkstorage == [50, 60, 70] def test_special(): from pypy.module._weakref.interp__weakref import WeakrefLifeline @@ -383,7 +401,7 @@ def test_special(): assert obj.getdictvalue(space, "a") == 50 assert obj.getdictvalue(space, "b") == 60 assert obj.getdictvalue(space, "c") == 70 - assert obj.storage == [50, 60, 70, lifeline1] + assert obj.checkstorage == [50, 60, 70, lifeline1] assert obj.getweakref() is lifeline1 obj2 = c.instantiate() @@ -391,7 +409,7 @@ def test_special(): obj2.setdictvalue(space, "b", 160) obj2.setdictvalue(space, "c", 170) obj2.setweakref(space, lifeline2) - assert obj2.storage == [150, 160, 170, lifeline2] + assert obj2.checkstorage == [150, 160, 170, lifeline2] assert obj2.getweakref() is lifeline2 assert obj2.map is obj.map @@ -421,7 +439,7 @@ def test_slots(): assert obj.getslotvalue(a) == 50 assert obj.getslotvalue(b) == 60 assert obj.getslotvalue(c) == 70 - assert obj.storage == [50, 60, 70] + assert obj.checkstorage == [50, 60, 70] obj.setdictvalue(space, "a", 5) obj.setdictvalue(space, "b", 6) @@ -432,7 +450,7 @@ def test_slots(): assert obj.getslotvalue(a) == 50 assert obj.getslotvalue(b) == 60 assert obj.getslotvalue(c) == 70 - assert obj.storage == [50, 60, 70, 5, 6, 7] + assert obj.checkstorage == [50, 60, 70, 5, 6, 7] obj2 = cls.instantiate() obj2.setslotvalue(a, 501) @@ -441,13 +459,13 @@ def test_slots(): obj2.setdictvalue(space, "a", 51) obj2.setdictvalue(space, "b", 61) obj2.setdictvalue(space, "c", 71) - assert obj2.storage == [501, 601, 701, 51, 61, 71] + assert obj2.checkstorage == [501, 601, 701, 51, 61, 71] assert obj.map is obj2.map assert obj2.getslotvalue(b) == 601 assert obj2.delslotvalue(b) assert obj2.getslotvalue(b) is None - assert obj2.storage == [501, 701, 51, 61, 71] + assert obj2.checkstorage == [501, 701, 51, 61, 71] assert not obj2.delslotvalue(b) @@ -460,7 +478,7 @@ def test_slots_no_dict(): obj.setslotvalue(b, 60) assert obj.getslotvalue(a) == 50 assert obj.getslotvalue(b) == 60 - assert obj.storage == [50, 60] + assert obj.checkstorage == [50, 60] assert not obj.setdictvalue(space, "a", 70) assert obj.getdict(space) is None assert obj.getdictvalue(space, "a") is None @@ -488,7 +506,7 @@ def test_materialize_r_dict(): obj.setdictvalue(space, "a", 5) obj.setdictvalue(space, "b", 6) obj.setdictvalue(space, "c", 7) - assert obj.storage == [50, 60, 70, 5, 6, 7] + assert obj.checkstorage == [50, 60, 70, 5, 6, 7] class FakeDict(W_DictObject): def __init__(self, d): @@ -505,7 +523,7 @@ def test_materialize_r_dict(): assert flag materialize_r_dict(space, obj, d) assert d == {"a": 5, "b": 6, "c": 7} - assert obj.storage == [50, 60, 70, w_d] + assert obj.checkstorage == [50, 60, 70, w_d] def test_size_prediction(): @@ -643,12 +661,12 @@ def test_specialized_class(): obj = objectcls() obj.user_setup(space, cls) obj.setdictvalue(space, "a", w1) - assert obj._value0 is w1 + assert unerase_item(obj._value0) is w1 assert obj.getdictvalue(space, "a") is w1 assert obj.getdictvalue(space, "b") is None assert obj.getdictvalue(space, "c") is None obj.setdictvalue(space, "a", w2) - assert obj._value0 is w2 + assert unerase_item(obj._value0) is w2 assert obj.getdictvalue(space, "a") == w2 assert obj.getdictvalue(space, "b") is None assert obj.getdictvalue(space, "c") is None @@ -666,7 +684,7 @@ def test_specialized_class(): res = obj.deldictvalue(space, "a") assert res - assert obj._value0 is w4 + assert unerase_item(obj._value0) is w4 assert obj.getdictvalue(space, "a") is None assert obj.getdictvalue(space, "b") is w4 assert obj.getdictvalue(space, "c") is None diff --git a/rpython/rlib/rerased.py b/rpython/rlib/rerased.py index 66666505bd..b27dc3c8ff 100644 --- a/rpython/rlib/rerased.py +++ b/rpython/rlib/rerased.py @@ -81,6 +81,7 @@ def new_erasing_pair(name): identity = ErasingPairIdentity(name) def erase(x): + assert not isinstance(x, Erased) return Erased(x, identity) def unerase(y): -- cgit v1.2.3-65-gdbad