From: Victor Stinner <victor.stinner@gmail.com> Date: Thu, 15 Dec 2016 16:23:24 +0000 (+0100) Subject: Merge 3.6 X-Git-Tag: v3.7.0a1~1744 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5cc70c9935ca07d4ac08cddaeee90a87ec1e5a4a;p=python Merge 3.6 --- 5cc70c9935ca07d4ac08cddaeee90a87ec1e5a4a diff --cc Objects/dictobject.c index e7c0db1882,5fff34b119..6a7e831944 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@@ -1214,12 -1245,12 +1214,12 @@@ After resizing a table is always combin but can be resplit by make_keys_shared(). */ static int - dictresize(PyDictObject *mp, Py_ssize_t minused) + dictresize(PyDictObject *mp, Py_ssize_t minsize) { - Py_ssize_t i, newsize; + Py_ssize_t newsize, numentries; PyDictKeysObject *oldkeys; PyObject **oldvalues; - PyDictKeyEntry *ep0; + PyDictKeyEntry *oldentries, *newentries; /* Find the smallest table size > minused. */ for (newsize = PyDict_MINSIZE; @@@ -1244,30 -1269,37 +1244,32 @@@ mp->ma_keys = oldkeys; return -1; } + // New table must be large enough. + assert(mp->ma_keys->dk_usable >= mp->ma_used); if (oldkeys->dk_lookup == lookdict) mp->ma_keys->dk_lookup = lookdict; - mp->ma_values = NULL; - ep0 = DK_ENTRIES(oldkeys); - /* Main loop below assumes we can transfer refcount to new keys - * and that value is stored in me_value. - * Increment ref-counts and copy values here to compensate - * This (resizing a split table) should be relatively rare */ + + numentries = mp->ma_used; + oldentries = DK_ENTRIES(oldkeys); + newentries = DK_ENTRIES(mp->ma_keys); + oldvalues = mp->ma_values; if (oldvalues != NULL) { - for (i = 0; i < oldkeys->dk_nentries; i++) { - if (oldvalues[i] != NULL) { - Py_INCREF(ep0[i].me_key); - ep0[i].me_value = oldvalues[i]; - } - } - } - /* Main loop */ - for (i = 0; i < oldkeys->dk_nentries; i++) { - PyDictKeyEntry *ep = &ep0[i]; - if (ep->me_value != NULL) { - insertdict_clean(mp, ep->me_key, ep->me_hash, ep->me_value); + /* Convert split table into new combined table. + * We must incref keys; we can transfer values. + * Note that values of split table is always dense. + */ + for (Py_ssize_t i = 0; i < numentries; i++) { + assert(oldvalues[i] != NULL); + PyDictKeyEntry *ep = &oldentries[i]; + PyObject *key = ep->me_key; + Py_INCREF(key); + newentries[i].me_key = key; + newentries[i].me_hash = ep->me_hash; + newentries[i].me_value = oldvalues[i]; } - } - mp->ma_keys->dk_usable -= mp->ma_used; - if (oldvalues != NULL) { - /* NULL out me_value slot in oldkeys, in case it was shared */ - for (i = 0; i < oldkeys->dk_nentries; i++) - ep0[i].me_value = NULL; + DK_DECREF(oldkeys); + mp->ma_values = NULL; if (oldvalues != empty_values) { free_values(oldvalues); }