Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 41 additions & 17 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -896,24 +896,20 @@ free_values(PyDictValues *values, bool use_qsbr)
PyMem_Free(values);
}

/* Consumes a reference to the keys object */
static PyObject *
new_dict(PyDictKeysObject *keys, PyDictValues *values,
Py_ssize_t used, int free_values_on_failure)
static inline PyObject *
new_dict_impl(PyDictObject *mp, PyDictKeysObject *keys,
PyDictValues *values, Py_ssize_t used,
int free_values_on_failure)
{
assert(keys != NULL);
PyDictObject *mp = _Py_FREELIST_POP(PyDictObject, dicts);
if (mp == NULL) {
mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
if (mp == NULL) {
dictkeys_decref(keys, false);
if (free_values_on_failure) {
free_values(values, false);
}
return NULL;
dictkeys_decref(keys, false);
if (free_values_on_failure) {
free_values(values, false);
}
return NULL;
}
assert(Py_IS_TYPE(mp, &PyDict_Type));

mp->ma_keys = keys;
mp->ma_values = values;
mp->ma_used = used;
Expand All @@ -923,6 +919,29 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values,
return (PyObject *)mp;
}

/* Consumes a reference to the keys object */
static PyObject *
new_dict(PyDictKeysObject *keys, PyDictValues *values,
Py_ssize_t used, int free_values_on_failure)
{
PyDictObject *mp = _Py_FREELIST_POP(PyDictObject, dicts);
if (mp == NULL) {
mp = PyObject_GC_New(PyDictObject, &PyDict_Type);
}
assert(mp == NULL || Py_IS_TYPE(mp, &PyDict_Type));

return new_dict_impl(mp, keys, values, used, free_values_on_failure);
}

/* Consumes a reference to the keys object */
static PyObject *
new_frozendict(PyDictKeysObject *keys, PyDictValues *values,
Py_ssize_t used, int free_values_on_failure)
{
PyDictObject *mp = PyObject_GC_New(PyDictObject, &PyFrozenDict_Type);
return new_dict_impl(mp, keys, values, used, free_values_on_failure);
}

static PyObject *
new_dict_with_shared_keys(PyDictKeysObject *keys)
{
Expand Down Expand Up @@ -4313,8 +4332,7 @@ copy_lock_held(PyObject *o, int as_frozendict)

if (Py_TYPE(mp)->tp_iter == dict_iter &&
mp->ma_values == NULL &&
(mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3) &&
!as_frozendict)
(mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3))
{
/* Use fast-copy if:

Expand All @@ -4334,9 +4352,15 @@ copy_lock_held(PyObject *o, int as_frozendict)
if (keys == NULL) {
return NULL;
}
PyDictObject *new = (PyDictObject *)new_dict(keys, NULL, 0, 0);
PyDictObject *new;
if (as_frozendict) {
new = (PyDictObject *)new_frozendict(keys, NULL, 0, 0);
}
else {
new = (PyDictObject *)new_dict(keys, NULL, 0, 0);
}
if (new == NULL) {
/* In case of an error, `new_dict()` takes care of
/* In case of an error, new_dict()/new_frozendict() takes care of
cleaning up `keys`. */
return NULL;
}
Expand Down
Loading