diff options
Diffstat (limited to 'Objects/dictobject.c')
-rw-r--r-- | Objects/dictobject.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 4fdfd63cd4f..6b7b150f0e2 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -547,13 +547,13 @@ static inline uint8_t calculate_log2_keysize(Py_ssize_t minsize) { #if SIZEOF_LONG == SIZEOF_SIZE_T - minsize = (minsize | PyDict_MINSIZE) - 1; - return _Py_bit_length(minsize | (PyDict_MINSIZE-1)); + minsize = Py_MAX(minsize, PyDict_MINSIZE); + return _Py_bit_length(minsize - 1); #elif defined(_MSC_VER) - // On 64bit Windows, sizeof(long) == 4. - minsize = (minsize | PyDict_MINSIZE) - 1; + // On 64bit Windows, sizeof(long) == 4. We cannot use _Py_bit_length. + minsize = Py_MAX(minsize, PyDict_MINSIZE); unsigned long msb; - _BitScanReverse64(&msb, (uint64_t)minsize); + _BitScanReverse64(&msb, (uint64_t)minsize - 1); return (uint8_t)(msb + 1); #else uint8_t log2_size; @@ -813,7 +813,7 @@ free_keys_object(PyDictKeysObject *keys, bool use_qsbr) { #ifdef Py_GIL_DISABLED if (use_qsbr) { - _PyMem_FreeDelayed(keys); + _PyMem_FreeDelayed(keys, _PyDict_KeysSize(keys)); return; } #endif @@ -858,7 +858,7 @@ free_values(PyDictValues *values, bool use_qsbr) assert(values->embedded == 0); #ifdef Py_GIL_DISABLED if (use_qsbr) { - _PyMem_FreeDelayed(values); + _PyMem_FreeDelayed(values, values_size_from_count(values->capacity)); return; } #endif @@ -2916,6 +2916,11 @@ clear_lock_held(PyObject *op) } void +_PyDict_Clear_LockHeld(PyObject *op) { + clear_lock_held(op); +} + +void PyDict_Clear(PyObject *op) { Py_BEGIN_CRITICAL_SECTION(op); @@ -3178,9 +3183,10 @@ dict_set_fromkeys(PyInterpreterState *interp, PyDictObject *mp, Py_ssize_t pos = 0; PyObject *key; Py_hash_t hash; - - if (dictresize(interp, mp, - estimate_log2_keysize(PySet_GET_SIZE(iterable)), 0)) { + uint8_t new_size = Py_MAX( + estimate_log2_keysize(PySet_GET_SIZE(iterable)), + DK_LOG_SIZE(mp->ma_keys)); + if (dictresize(interp, mp, new_size, 0)) { Py_DECREF(mp); return NULL; } @@ -3285,7 +3291,6 @@ dict_dealloc(PyObject *self) /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(mp); - Py_TRASHCAN_BEGIN(mp, dict_dealloc) if (values != NULL) { if (values->embedded == 0) { for (i = 0, n = values->capacity; i < n; i++) { @@ -3305,7 +3310,6 @@ dict_dealloc(PyObject *self) else { Py_TYPE(mp)->tp_free((PyObject *)mp); } - Py_TRASHCAN_END } @@ -3730,13 +3734,14 @@ merge_from_seq2_lock_held(PyObject *d, PyObject *seq2, int override) } /* Convert item to sequence, and verify length 2. */ - fast = PySequence_Fast(item, ""); + fast = PySequence_Fast(item, "object is not iterable"); if (fast == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - PyErr_Format(PyExc_TypeError, - "cannot convert dictionary update " + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + _PyErr_FormatNote( + "Cannot convert dictionary update " "sequence element #%zd to a sequence", i); + } goto Fail; } n = PySequence_Fast_GET_SIZE(fast); @@ -3853,7 +3858,7 @@ dict_dict_merge(PyInterpreterState *interp, PyDictObject *mp, PyDictObject *othe } } - Py_ssize_t orig_size = other->ma_keys->dk_nentries; + Py_ssize_t orig_size = other->ma_used; Py_ssize_t pos = 0; Py_hash_t hash; PyObject *key, *value; @@ -3887,7 +3892,7 @@ dict_dict_merge(PyInterpreterState *interp, PyDictObject *mp, PyDictObject *othe if (err != 0) return -1; - if (orig_size != other->ma_keys->dk_nentries) { + if (orig_size != other->ma_used) { PyErr_SetString(PyExc_RuntimeError, "dict mutated during update"); return -1; @@ -4852,7 +4857,8 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) d->ma_used = 0; d->_ma_watcher_tag = 0; - dictkeys_incref(Py_EMPTY_KEYS); + // We don't inc ref empty keys because they're immortal + assert((Py_EMPTY_KEYS)->dk_refcnt == _Py_DICT_IMMORTAL_INITIAL_REFCNT); d->ma_keys = Py_EMPTY_KEYS; d->ma_values = NULL; ASSERT_CONSISTENT(d); |