[pypy-commit] pypy default: Obviously, adding ll_prepare_dict_update() exposed a latent bug
arigo
noreply at buildbot.pypy.org
Sun Dec 14 17:23:09 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r74912:ef301ae5ae96
Date: 2014-12-14 17:23 +0100
http://bitbucket.org/pypy/pypy/changeset/ef301ae5ae96/
Log: Obviously, adding ll_prepare_dict_update() exposed a latent bug
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -600,10 +600,12 @@
else:
newitems = d.entries
#
- ENTRY = lltype.typeOf(d).TO.entries.TO.OF
+ ENTRIES = lltype.typeOf(d).TO.entries.TO
+ ENTRY = ENTRIES.OF
isrc = 0
idst = 0
- while isrc < len(d.entries):
+ isrclimit = d.num_used_items
+ while isrc < isrclimit:
if d.entries.valid(isrc):
src = d.entries[isrc]
dst = newitems[idst]
@@ -616,9 +618,21 @@
dst.f_valid = True
idst += 1
isrc += 1
- d.entries = newitems
assert d.num_items == idst
d.num_used_items = idst
+ if ((ENTRIES.must_clear_key or ENTRIES.must_clear_value) and
+ d.entries == newitems):
+ # must clear the extra entries: they may contain valid pointers
+ # which would create a temporary memory leak
+ while idst < isrclimit:
+ entry = newitems[idst]
+ if ENTRIES.must_clear_key:
+ entry.key = lltype.nullptr(ENTRY.key.TO)
+ if ENTRIES.must_clear_value:
+ entry.value = lltype.nullptr(ENTRY.value.TO)
+ idst += 1
+ else:
+ d.entries = newitems
ll_dict_reindex(d, _ll_len_of_d_indexes(d))
diff --git a/rpython/rtyper/test/test_rordereddict.py b/rpython/rtyper/test/test_rordereddict.py
--- a/rpython/rtyper/test/test_rordereddict.py
+++ b/rpython/rtyper/test/test_rordereddict.py
@@ -251,6 +251,16 @@
assert rordereddict.ll_dict_pop_default(ll_d, llstr("k"), 40) == 40
assert rordereddict.ll_dict_pop_default(ll_d, llstr("j"), 39) == 39
+ def test_bug_remove_deleted_items(self):
+ DICT = self._get_str_dict()
+ ll_d = rordereddict.ll_newdict(DICT)
+ for i in range(15):
+ rordereddict.ll_dict_setitem(ll_d, llstr(chr(i)), 5)
+ for i in range(15):
+ rordereddict.ll_dict_delitem(ll_d, llstr(chr(i)))
+ rordereddict.ll_prepare_dict_update(ll_d, 7)
+ # used to get UninitializedMemoryAccess
+
class TestRDictDirectDummyKey(TestRDictDirect):
class dummykeyobj:
ll_dummy_value = llstr("dupa")
More information about the pypy-commit
mailing list