Skip to content

Commit db85987

Browse files
this reuses SOME interned strings, but not utf-8 and friends
1 parent 5c942f1 commit db85987

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

Objects/codeobject.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ PyCode_ClearWatcher(int watcher_id)
113113

114114
#define _PyCodeObject_CAST(op) (assert(PyCode_Check(op)), (PyCodeObject *)(op))
115115

116-
static int
116+
static inline int
117117
should_intern_string(PyObject *o)
118118
{
119119
#ifdef Py_GIL_DISABLED
@@ -196,17 +196,45 @@ intern_strings(PyObject *tuple)
196196
return 0;
197197
}
198198

199+
static inline PyObject*
200+
get_interned_string(PyObject *interned_dict, PyObject *s) {
201+
if (!PyUnicode_CheckExact(s)) {
202+
return NULL;
203+
}
204+
205+
PyObject *existing = PyDict_GetItemWithError(interned_dict, s);
206+
if (existing == NULL) {
207+
if (PyErr_Occurred()) {
208+
return NULL;
209+
}
210+
return NULL;
211+
}
212+
return existing;
213+
}
214+
199215
/* Intern constants. In the default build, this interns selected string
200216
constants. In the free-threaded build, this also interns non-string
201217
constants. */
202218
static int
203219
intern_constants(PyObject *tuple, int *modified)
204220
{
205221
PyInterpreterState *interp = _PyInterpreterState_GET();
222+
PyObject *interned_dict = _Py_INTERP_CACHED_OBJECT(interp, interned_strings);
206223
for (Py_ssize_t i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
207224
PyObject *v = PyTuple_GET_ITEM(tuple, i);
208-
if (PyUnicode_CheckExact(v)) {
209-
if (should_intern_string(v)) {
225+
if (PyUnicode_CheckExact(v) && PyUnicode_GET_LENGTH(v) > 1) {
226+
if (PyUnicode_CHECK_INTERNED(v) != 0) {
227+
continue;
228+
}
229+
PyObject *interned = get_interned_string(interned_dict, v);
230+
if (interned != NULL && interned != v) {
231+
Py_INCREF(interned);
232+
PyTuple_SET_ITEM(tuple, i, interned);
233+
Py_DECREF(v);
234+
if (modified) {
235+
*modified = 1;
236+
}
237+
} else if (should_intern_string(v)) {
210238
PyObject *w = v;
211239
_PyUnicode_InternMortal(interp, &v);
212240
if (w != v) {

0 commit comments

Comments
 (0)