GH-96075: move interned dict under runtime state (GH-96077)

This commit is contained in:
Kumar Aditya 2022-08-23 00:35:21 +05:30 committed by GitHub
parent 079baee196
commit 129998bd7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 14 deletions

View file

@ -45,6 +45,8 @@ struct _Py_global_objects {
_PyGC_Head_UNUSED _tuple_empty_gc_not_used; _PyGC_Head_UNUSED _tuple_empty_gc_not_used;
PyTupleObject tuple_empty; PyTupleObject tuple_empty;
} singletons; } singletons;
PyObject *interned;
}; };

View file

@ -191,16 +191,6 @@ extern "C" {
# define OVERALLOCATE_FACTOR 4 # define OVERALLOCATE_FACTOR 4
#endif #endif
/* This dictionary holds all interned unicode strings. Note that references
to strings in this dictionary are *not* counted in the string's ob_refcnt.
When the interned string reaches a refcnt of 0 the string deallocation
function will delete the reference from this dictionary.
Another way to look at this is that to say that the actual reference
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
*/
static PyObject *interned = NULL;
/* Forward declaration */ /* Forward declaration */
static inline int static inline int
_PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch); _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch);
@ -235,6 +225,23 @@ static inline PyObject* unicode_new_empty(void)
return empty; return empty;
} }
/* This dictionary holds all interned unicode strings. Note that references
to strings in this dictionary are *not* counted in the string's ob_refcnt.
When the interned string reaches a refcnt of 0 the string deallocation
function will delete the reference from this dictionary.
Another way to look at this is that to say that the actual reference
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
*/
static inline PyObject *get_interned_dict(void)
{
return _PyRuntime.global_objects.interned;
}
static inline void set_interned_dict(PyObject *dict)
{
_PyRuntime.global_objects.interned = dict;
}
#define _Py_RETURN_UNICODE_EMPTY() \ #define _Py_RETURN_UNICODE_EMPTY() \
do { \ do { \
return unicode_new_empty(); \ return unicode_new_empty(); \
@ -1523,7 +1530,7 @@ unicode_dealloc(PyObject *unicode)
_Py_FatalRefcountError("deallocating an Unicode singleton"); _Py_FatalRefcountError("deallocating an Unicode singleton");
} }
#endif #endif
PyObject *interned = get_interned_dict();
if (PyUnicode_CHECK_INTERNED(unicode)) { if (PyUnicode_CHECK_INTERNED(unicode)) {
/* Revive the dead object temporarily. PyDict_DelItem() removes two /* Revive the dead object temporarily. PyDict_DelItem() removes two
references (key and value) which were ignored by references (key and value) which were ignored by
@ -14657,12 +14664,14 @@ PyUnicode_InternInPlace(PyObject **p)
return; return;
} }
PyObject *interned = get_interned_dict();
if (interned == NULL) { if (interned == NULL) {
interned = PyDict_New(); interned = PyDict_New();
if (interned == NULL) { if (interned == NULL) {
PyErr_Clear(); /* Don't leave an exception */ PyErr_Clear(); /* Don't leave an exception */
return; return;
} }
set_interned_dict(interned);
} }
PyObject *t = PyDict_SetDefault(interned, s, s); PyObject *t = PyDict_SetDefault(interned, s, s);
@ -14713,6 +14722,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
return; return;
} }
PyObject *interned = get_interned_dict();
if (interned == NULL) { if (interned == NULL) {
return; return;
} }
@ -14748,7 +14758,8 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
#endif #endif
PyDict_Clear(interned); PyDict_Clear(interned);
Py_CLEAR(interned); Py_DECREF(interned);
set_interned_dict(NULL);
} }
@ -15155,7 +15166,7 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void)
static inline int static inline int
unicode_is_finalizing(void) unicode_is_finalizing(void)
{ {
return (interned == NULL); return (get_interned_dict() == NULL);
} }
#endif #endif
@ -15197,7 +15208,7 @@ _PyUnicode_Fini(PyInterpreterState *interp)
if (_Py_IsMainInterpreter(interp)) { if (_Py_IsMainInterpreter(interp)) {
// _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini()
assert(interned == NULL); assert(get_interned_dict() == NULL);
// bpo-47182: force a unicodedata CAPI capsule re-import on // bpo-47182: force a unicodedata CAPI capsule re-import on
// subsequent initialization of main interpreter. // subsequent initialization of main interpreter.
ucnhash_capi = NULL; ucnhash_capi = NULL;