Skip to content

Commit 03977d9

Browse files
committed
Enable deferred counting for more types.
Also, avoid PyDict_GetItemRef() call by returning the value when the index is looked up (as previously discarded).
1 parent 2372f96 commit 03977d9

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

Include/internal/pycore_dict.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ extern Py_ssize_t _Py_dict_lookup_threadsafe_stackref(PyDictObject *mp, PyObject
114114

115115
extern int _PyDict_GetMethodStackRef(PyDictObject *dict, PyObject *name, _PyStackRef *method);
116116

117+
extern Py_ssize_t _PyDict_LookupIndexAndValue(PyDictObject *, PyObject *, PyObject **);
117118
extern Py_ssize_t _PyDict_LookupIndex(PyDictObject *, PyObject *);
118119
extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key);
119120

Objects/dictobject.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,10 +2346,9 @@ dict_unhashable_type(PyObject *key)
23462346
}
23472347

23482348
Py_ssize_t
2349-
_PyDict_LookupIndex(PyDictObject *mp, PyObject *key)
2349+
_PyDict_LookupIndexAndValue(PyDictObject *mp, PyObject *key, PyObject **value)
23502350
{
23512351
// TODO: Thread safety
2352-
PyObject *value;
23532352
assert(PyDict_CheckExact((PyObject*)mp));
23542353
assert(PyUnicode_CheckExact(key));
23552354

@@ -2359,7 +2358,14 @@ _PyDict_LookupIndex(PyDictObject *mp, PyObject *key)
23592358
return -1;
23602359
}
23612360

2362-
return _Py_dict_lookup(mp, key, hash, &value);
2361+
return _Py_dict_lookup(mp, key, hash, value);
2362+
}
2363+
2364+
Py_ssize_t
2365+
_PyDict_LookupIndex(PyDictObject *mp, PyObject *key)
2366+
{
2367+
PyObject *value; // discarded
2368+
return _PyDict_LookupIndexAndValue(mp, key, &value);
23632369
}
23642370

23652371
/* Same as PyDict_GetItemWithError() but with hash supplied by caller.

Python/specialize.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -357,22 +357,11 @@ static uint32_t function_get_version(PyObject *o, int opcode);
357357

358358
#ifdef Py_GIL_DISABLED
359359
static void
360-
maybe_enable_deferred_ref_count(PyObject *dict, PyObject *name)
360+
maybe_enable_deferred_ref_count(PyObject *op)
361361
{
362-
PyObject *op;
363-
if (PyDict_GetItemRef(dict, name, &op) != 1) {
364-
return;
365-
}
366-
if (_Py_IsOwnedByCurrentThread(op) ||
367-
!PyType_IS_GC(Py_TYPE(op)) ||
368-
_PyObject_HasDeferredRefcount(op)) {
369-
Py_DECREF(op);
370-
return;
371-
}
372-
if (PyFrozenSet_Check(op) || PyTuple_Check(op) || PyType_Check(op)) {
362+
if (!_Py_IsOwnedByCurrentThread(op)) {
373363
PyUnstable_Object_EnableDeferredRefcount(op);
374364
}
375-
Py_DECREF(op);
376365
}
377366
#endif
378367

@@ -391,7 +380,8 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P
391380
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND);
392381
return -1;
393382
}
394-
index = _PyDict_LookupIndex(dict, name);
383+
PyObject *value;
384+
index = _PyDict_LookupIndexAndValue(dict, name, &value);
395385
assert (index != DKIX_ERROR);
396386
if (index != (uint16_t)index) {
397387
SPECIALIZATION_FAIL(LOAD_ATTR,
@@ -407,7 +397,7 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P
407397
return -1;
408398
}
409399
#ifdef Py_GIL_DISABLED
410-
maybe_enable_deferred_ref_count((PyObject *)dict, name);
400+
maybe_enable_deferred_ref_count(value);
411401
#endif
412402
write_u32(cache->version, keys_version);
413403
cache->index = (uint16_t)index;
@@ -1308,7 +1298,12 @@ specialize_load_global_lock_held(
13081298
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT);
13091299
goto fail;
13101300
}
1301+
#ifdef Py_GIL_DISABLED
1302+
PyObject *value;
1303+
Py_ssize_t index = _PyDict_LookupIndexAndValue((PyDictObject *)globals, name, &value);
1304+
#else
13111305
Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name);
1306+
#endif
13121307
if (index == DKIX_ERROR) {
13131308
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
13141309
goto fail;
@@ -1330,7 +1325,7 @@ specialize_load_global_lock_held(
13301325
goto fail;
13311326
}
13321327
#ifdef Py_GIL_DISABLED
1333-
maybe_enable_deferred_ref_count(globals, name);
1328+
maybe_enable_deferred_ref_count(value);
13341329
#endif
13351330
cache->index = (uint16_t)index;
13361331
cache->module_keys_version = (uint16_t)keys_version;

0 commit comments

Comments
 (0)