Skip to content

Commit fc173e3

Browse files
committed
unicode: always immortalize interned strings
1 parent 7b6b6f1 commit fc173e3

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

Objects/unicodeobject.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,7 @@ _PyUnicode_FromId(_Py_Identifier *id)
19241924
return obj;
19251925
}
19261926

1927-
static int
1927+
static void
19281928
_PyUnicode_Immortalize(PyObject *obj)
19291929
{
19301930
assert(!_PyObject_IS_IMMORTAL(obj));
@@ -1937,8 +1937,11 @@ _PyUnicode_Immortalize(PyObject *obj)
19371937
Py_ssize_t capacity = imm->capacity;
19381938
PyObject **new_array = resize_array(imm->array, &capacity);
19391939
if (new_array == NULL) {
1940+
PyErr_WriteUnraisable(NULL);
19401941
_PyMutex_unlock(&imm->mutex);
1941-
return -1;
1942+
// mark the object as immortal anyways
1943+
_PyObject_SetImmortal(obj);
1944+
return;
19421945
}
19431946

19441947
imm->array = new_array;
@@ -1949,7 +1952,6 @@ _PyUnicode_Immortalize(PyObject *obj)
19491952
imm->array[index] = obj;
19501953
imm->size++;
19511954
_PyMutex_unlock(&imm->mutex);
1952-
return 0;
19531955
}
19541956

19551957

@@ -14667,6 +14669,12 @@ PyUnicode_InternInPlace(PyObject **p)
1466714669
set_interned_dict(interned);
1466814670
}
1466914671

14672+
if (!_Py_ThreadLocal(s) && !_PyObject_IS_IMMORTAL(s)) {
14673+
/* Make a copy so that we can safely immortalize the string. */
14674+
s = _PyUnicode_Copy(s);
14675+
Py_SETREF(*p, s);
14676+
}
14677+
1467014678
PyObject *t = PyDict_SetDefault(interned, s, s);
1467114679
if (t == NULL) {
1467214680
PyErr_Clear();
@@ -14680,15 +14688,11 @@ PyUnicode_InternInPlace(PyObject **p)
1468014688

1468114689
_PyUnicode_STATE(s).interned = 1;
1468214690

14683-
if (_Py_ThreadLocal(t) && _PyUnicode_Immortalize(t) == 0) {
14684-
/* Nothing to do if we immortalize the string */
14685-
return;
14691+
if (_Py_ThreadLocal(t)) {
14692+
_PyUnicode_Immortalize(t);
1468614693
}
1468714694
else {
14688-
/* The two references in interned dict (key and value) are not counted by
14689-
refcnt. unicode_dealloc() and _PyUnicode_ClearInterned() take care of
14690-
this. */
14691-
Py_SET_REFCNT(s, Py_REFCNT(s) - 2);
14695+
assert(_PyObject_IS_IMMORTAL(t));
1469214696
}
1469314697
}
1469414698

0 commit comments

Comments
 (0)