Skip to content

Commit 2372f96

Browse files
committed
Improve maybe_enable_deferred_ref_count() function.
Use it for LOAD_ATTR_MODULE in addition to LOAD_GLOBAL_MODULE. Don't enable deferred ref counts if the object is owned by the current thread. Specialized bytecode is per-thread so this works. Enable for frozensets, tuples and type objects.
1 parent 8fae6ec commit 2372f96

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

Python/specialize.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,28 @@ static int function_kind(PyCodeObject *code);
355355
static bool function_check_args(PyObject *o, int expected_argcount, int opcode);
356356
static uint32_t function_get_version(PyObject *o, int opcode);
357357

358+
#ifdef Py_GIL_DISABLED
359+
static void
360+
maybe_enable_deferred_ref_count(PyObject *dict, PyObject *name)
361+
{
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)) {
373+
PyUnstable_Object_EnableDeferredRefcount(op);
374+
}
375+
Py_DECREF(op);
376+
}
377+
#endif
378+
379+
358380
static int
359381
specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, PyObject *name)
360382
{
@@ -384,6 +406,9 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P
384406
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
385407
return -1;
386408
}
409+
#ifdef Py_GIL_DISABLED
410+
maybe_enable_deferred_ref_count((PyObject *)dict, name);
411+
#endif
387412
write_u32(cache->version, keys_version);
388413
cache->index = (uint16_t)index;
389414
specialize(instr, LOAD_ATTR_MODULE);
@@ -1264,25 +1289,6 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
12641289
return 1;
12651290
}
12661291

1267-
#ifdef Py_GIL_DISABLED
1268-
static void
1269-
maybe_enable_deferred_ref_count(PyObject *globals, PyObject *name)
1270-
{
1271-
PyObject *value;
1272-
if (PyDict_GetItemRef(globals, name, &value) != 1) {
1273-
return;
1274-
}
1275-
if (!PyType_IS_GC(Py_TYPE(value)) || _PyObject_HasDeferredRefcount(value)) {
1276-
Py_DECREF(value);
1277-
return;
1278-
}
1279-
if (PyFrozenSet_Check(value)) {
1280-
PyUnstable_Object_EnableDeferredRefcount(value);
1281-
}
1282-
Py_DECREF(value);
1283-
}
1284-
#endif
1285-
12861292
static void
12871293
specialize_load_global_lock_held(
12881294
PyObject *globals, PyObject *builtins,

0 commit comments

Comments
 (0)