Skip to content

Commit 129998b

Browse files
GH-96075: move interned dict under runtime state (GH-96077)
1 parent 079baee commit 129998b

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

Include/internal/pycore_global_objects.h

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ struct _Py_global_objects {
4545
_PyGC_Head_UNUSED _tuple_empty_gc_not_used;
4646
PyTupleObject tuple_empty;
4747
} singletons;
48+
49+
PyObject *interned;
4850
};
4951

5052

Objects/unicodeobject.c

+25-14
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,6 @@ extern "C" {
191191
# define OVERALLOCATE_FACTOR 4
192192
#endif
193193

194-
/* This dictionary holds all interned unicode strings. Note that references
195-
to strings in this dictionary are *not* counted in the string's ob_refcnt.
196-
When the interned string reaches a refcnt of 0 the string deallocation
197-
function will delete the reference from this dictionary.
198-
199-
Another way to look at this is that to say that the actual reference
200-
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
201-
*/
202-
static PyObject *interned = NULL;
203-
204194
/* Forward declaration */
205195
static inline int
206196
_PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch);
@@ -235,6 +225,23 @@ static inline PyObject* unicode_new_empty(void)
235225
return empty;
236226
}
237227

228+
/* This dictionary holds all interned unicode strings. Note that references
229+
to strings in this dictionary are *not* counted in the string's ob_refcnt.
230+
When the interned string reaches a refcnt of 0 the string deallocation
231+
function will delete the reference from this dictionary.
232+
Another way to look at this is that to say that the actual reference
233+
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
234+
*/
235+
static inline PyObject *get_interned_dict(void)
236+
{
237+
return _PyRuntime.global_objects.interned;
238+
}
239+
240+
static inline void set_interned_dict(PyObject *dict)
241+
{
242+
_PyRuntime.global_objects.interned = dict;
243+
}
244+
238245
#define _Py_RETURN_UNICODE_EMPTY() \
239246
do { \
240247
return unicode_new_empty(); \
@@ -1523,7 +1530,7 @@ unicode_dealloc(PyObject *unicode)
15231530
_Py_FatalRefcountError("deallocating an Unicode singleton");
15241531
}
15251532
#endif
1526-
1533+
PyObject *interned = get_interned_dict();
15271534
if (PyUnicode_CHECK_INTERNED(unicode)) {
15281535
/* Revive the dead object temporarily. PyDict_DelItem() removes two
15291536
references (key and value) which were ignored by
@@ -14657,12 +14664,14 @@ PyUnicode_InternInPlace(PyObject **p)
1465714664
return;
1465814665
}
1465914666

14667+
PyObject *interned = get_interned_dict();
1466014668
if (interned == NULL) {
1466114669
interned = PyDict_New();
1466214670
if (interned == NULL) {
1466314671
PyErr_Clear(); /* Don't leave an exception */
1466414672
return;
1466514673
}
14674+
set_interned_dict(interned);
1466614675
}
1466714676

1466814677
PyObject *t = PyDict_SetDefault(interned, s, s);
@@ -14713,6 +14722,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
1471314722
return;
1471414723
}
1471514724

14725+
PyObject *interned = get_interned_dict();
1471614726
if (interned == NULL) {
1471714727
return;
1471814728
}
@@ -14748,7 +14758,8 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
1474814758
#endif
1474914759

1475014760
PyDict_Clear(interned);
14751-
Py_CLEAR(interned);
14761+
Py_DECREF(interned);
14762+
set_interned_dict(NULL);
1475214763
}
1475314764

1475414765

@@ -15155,7 +15166,7 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void)
1515515166
static inline int
1515615167
unicode_is_finalizing(void)
1515715168
{
15158-
return (interned == NULL);
15169+
return (get_interned_dict() == NULL);
1515915170
}
1516015171
#endif
1516115172

@@ -15197,7 +15208,7 @@ _PyUnicode_Fini(PyInterpreterState *interp)
1519715208

1519815209
if (_Py_IsMainInterpreter(interp)) {
1519915210
// _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini()
15200-
assert(interned == NULL);
15211+
assert(get_interned_dict() == NULL);
1520115212
// bpo-47182: force a unicodedata CAPI capsule re-import on
1520215213
// subsequent initialization of main interpreter.
1520315214
ucnhash_capi = NULL;

0 commit comments

Comments
 (0)