mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
GH-96075: move interned dict under runtime state (GH-96077)
This commit is contained in:
parent
079baee196
commit
129998bd7b
2 changed files with 27 additions and 14 deletions
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue