Skip to content

Commit be86955

Browse files
Include immortal interned strings
1 parent 25fd52a commit be86955

File tree

2 files changed

+4
-74
lines changed

2 files changed

+4
-74
lines changed

Objects/unicodeobject.c

+3-73
Original file line numberDiff line numberDiff line change
@@ -1941,26 +1941,6 @@ unicode_dealloc(PyObject *unicode)
19411941
case SSTATE_NOT_INTERNED:
19421942
break;
19431943

1944-
case SSTATE_INTERNED_MORTAL:
1945-
{
1946-
#ifdef INTERNED_STRINGS
1947-
/* Revive the dead object temporarily. PyDict_DelItem() removes two
1948-
references (key and value) which were ignored by
1949-
PyUnicode_InternInPlace(). Use refcnt=3 rather than refcnt=2
1950-
to prevent calling unicode_dealloc() again. Adjust refcnt after
1951-
PyDict_DelItem(). */
1952-
assert(Py_REFCNT(unicode) == 0);
1953-
Py_SET_REFCNT(unicode, 3);
1954-
if (PyDict_DelItem(interned, unicode) != 0) {
1955-
_PyErr_WriteUnraisableMsg("deletion of interned string failed",
1956-
NULL);
1957-
}
1958-
assert(Py_REFCNT(unicode) == 1);
1959-
Py_SET_REFCNT(unicode, 0);
1960-
#endif
1961-
break;
1962-
}
1963-
19641944
case SSTATE_INTERNED_IMMORTAL:
19651945
_PyObject_ASSERT_FAILED_MSG(unicode, "Immortal interned string died");
19661946
break;
@@ -15608,16 +15588,12 @@ PyUnicode_InternInPlace(PyObject **p)
1560815588
}
1560915589

1561015590
if (t != s) {
15611-
Py_INCREF(t);
1561215591
Py_SETREF(*p, t);
1561315592
return;
1561415593
}
1561515594

15616-
/* The two references in interned dict (key and value) are not counted by
15617-
refcnt. unicode_dealloc() and _PyUnicode_ClearInterned() take care of
15618-
this. */
15619-
Py_SET_REFCNT(s, Py_REFCNT(s) - 2);
15620-
_PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL;
15595+
_Py_SetImmortal(s);
15596+
_PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL;
1562115597
#else
1562215598
// PyDict expects that interned strings have their hash
1562315599
// (PyASCIIObject.hash) already computed.
@@ -15638,10 +15614,6 @@ PyUnicode_InternImmortal(PyObject **p)
1563815614
}
1563915615

1564015616
PyUnicode_InternInPlace(p);
15641-
if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) {
15642-
_PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL;
15643-
Py_INCREF(*p);
15644-
}
1564515617
}
1564615618

1564715619
PyObject *
@@ -15668,49 +15640,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
1566815640
}
1566915641
assert(PyDict_CheckExact(interned));
1567015642

15671-
/* Interned unicode strings are not forcibly deallocated; rather, we give
15672-
them their stolen references back, and then clear and DECREF the
15673-
interned dict. */
15674-
15675-
#ifdef INTERNED_STATS
15676-
fprintf(stderr, "releasing %zd interned strings\n",
15677-
PyDict_GET_SIZE(interned));
15678-
15679-
Py_ssize_t immortal_size = 0, mortal_size = 0;
15680-
#endif
15681-
Py_ssize_t pos = 0;
15682-
PyObject *s, *ignored_value;
15683-
while (PyDict_Next(interned, &pos, &s, &ignored_value)) {
15684-
assert(PyUnicode_IS_READY(s));
15685-
15686-
switch (PyUnicode_CHECK_INTERNED(s)) {
15687-
case SSTATE_INTERNED_IMMORTAL:
15688-
Py_SET_REFCNT(s, Py_REFCNT(s) + 1);
15689-
#ifdef INTERNED_STATS
15690-
immortal_size += PyUnicode_GET_LENGTH(s);
15691-
#endif
15692-
break;
15693-
case SSTATE_INTERNED_MORTAL:
15694-
// Restore the two references (key and value) ignored
15695-
// by PyUnicode_InternInPlace().
15696-
Py_SET_REFCNT(s, Py_REFCNT(s) + 2);
15697-
#ifdef INTERNED_STATS
15698-
mortal_size += PyUnicode_GET_LENGTH(s);
15699-
#endif
15700-
break;
15701-
case SSTATE_NOT_INTERNED:
15702-
/* fall through */
15703-
default:
15704-
Py_UNREACHABLE();
15705-
}
15706-
_PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED;
15707-
}
15708-
#ifdef INTERNED_STATS
15709-
fprintf(stderr,
15710-
"total size of all interned strings: %zd/%zd mortal/immortal\n",
15711-
mortal_size, immortal_size);
15712-
#endif
15713-
15643+
/* Interned unicode strings are not forcibly deallocated */
1571415644
PyDict_Clear(interned);
1571515645
Py_CLEAR(interned);
1571615646
}

Programs/_testembed.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1829,7 +1829,7 @@ static int test_unicode_id_init(void)
18291829

18301830
str1 = _PyUnicode_FromId(&PyId_test_unicode_id_init);
18311831
assert(str1 != NULL);
1832-
assert(Py_REFCNT(str1) == 1);
1832+
assert(_Py_IsImmortal(str1));
18331833

18341834
str2 = PyUnicode_FromString("test_unicode_id_init");
18351835
assert(str2 != NULL);

0 commit comments

Comments
 (0)