@@ -55,8 +55,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55
55
#include <windows.h>
56
56
#endif
57
57
58
- /* Uncomment to display statistics on interned strings at exit when
59
- using Valgrind or Insecure++ . */
58
+ /* Uncomment to display statistics on interned strings at exit
59
+ in _PyUnicode_ClearInterned() . */
60
60
/* #define INTERNED_STATS 1 */
61
61
62
62
@@ -15681,6 +15681,11 @@ PyUnicode_InternInPlace(PyObject **p)
15681
15681
}
15682
15682
15683
15683
#ifdef INTERNED_STRINGS
15684
+ if (PyUnicode_READY (s ) == -1 ) {
15685
+ PyErr_Clear ();
15686
+ return ;
15687
+ }
15688
+
15684
15689
if (interned == NULL ) {
15685
15690
interned = PyDict_New ();
15686
15691
if (interned == NULL ) {
@@ -15733,23 +15738,29 @@ PyUnicode_InternFromString(const char *cp)
15733
15738
}
15734
15739
15735
15740
15736
- #if defined(WITH_VALGRIND ) || defined(__INSURE__ )
15737
- static void
15738
- unicode_release_interned (void )
15741
+ void
15742
+ _PyUnicode_ClearInterned (PyThreadState * tstate )
15739
15743
{
15740
- if (interned == NULL || !PyDict_Check (interned )) {
15744
+ if (!_Py_IsMainInterpreter (tstate )) {
15745
+ // interned dict is shared by all interpreters
15746
+ return ;
15747
+ }
15748
+
15749
+ if (interned == NULL ) {
15741
15750
return ;
15742
15751
}
15752
+ assert (PyDict_CheckExact (interned ));
15753
+
15743
15754
PyObject * keys = PyDict_Keys (interned );
15744
- if (keys == NULL || ! PyList_Check ( keys ) ) {
15755
+ if (keys == NULL ) {
15745
15756
PyErr_Clear ();
15746
15757
return ;
15747
15758
}
15759
+ assert (PyList_CheckExact (keys ));
15748
15760
15749
- /* Since unicode_release_interned() is intended to help a leak
15750
- detector, interned unicode strings are not forcibly deallocated;
15751
- rather, we give them their stolen references back, and then clear
15752
- and DECREF the interned dict. */
15761
+ /* Interned unicode strings are not forcibly deallocated; rather, we give
15762
+ them their stolen references back, and then clear and DECREF the
15763
+ interned dict. */
15753
15764
15754
15765
Py_ssize_t n = PyList_GET_SIZE (keys );
15755
15766
#ifdef INTERNED_STATS
@@ -15759,9 +15770,8 @@ unicode_release_interned(void)
15759
15770
#endif
15760
15771
for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
15761
15772
PyObject * s = PyList_GET_ITEM (keys , i );
15762
- if (PyUnicode_READY (s ) == -1 ) {
15763
- Py_UNREACHABLE ();
15764
- }
15773
+ assert (PyUnicode_IS_READY (s ));
15774
+
15765
15775
switch (PyUnicode_CHECK_INTERNED (s )) {
15766
15776
case SSTATE_INTERNED_IMMORTAL :
15767
15777
Py_SET_REFCNT (s , Py_REFCNT (s ) + 1 );
@@ -15788,10 +15798,10 @@ unicode_release_interned(void)
15788
15798
mortal_size , immortal_size );
15789
15799
#endif
15790
15800
Py_DECREF (keys );
15801
+
15791
15802
PyDict_Clear (interned );
15792
15803
Py_CLEAR (interned );
15793
15804
}
15794
- #endif
15795
15805
15796
15806
15797
15807
/********************* Unicode Iterator **************************/
@@ -16160,31 +16170,17 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void)
16160
16170
void
16161
16171
_PyUnicode_Fini (PyThreadState * tstate )
16162
16172
{
16163
- struct _Py_unicode_state * state = & tstate -> interp -> unicode ;
16173
+ // _PyUnicode_ClearInterned() must be called before
16164
16174
16165
- int is_main_interp = _Py_IsMainInterpreter (tstate );
16166
- if (is_main_interp ) {
16167
- #if defined(WITH_VALGRIND ) || defined(__INSURE__ )
16168
- /* Insure++ is a memory analysis tool that aids in discovering
16169
- * memory leaks and other memory problems. On Python exit, the
16170
- * interned string dictionaries are flagged as being in use at exit
16171
- * (which it is). Under normal circumstances, this is fine because
16172
- * the memory will be automatically reclaimed by the system. Under
16173
- * memory debugging, it's a huge source of useless noise, so we
16174
- * trade off slower shutdown for less distraction in the memory
16175
- * reports. -baw
16176
- */
16177
- unicode_release_interned ();
16178
- #endif /* __INSURE__ */
16179
- }
16175
+ struct _Py_unicode_state * state = & tstate -> interp -> unicode ;
16180
16176
16181
16177
Py_CLEAR (state -> empty_string );
16182
16178
16183
16179
for (Py_ssize_t i = 0 ; i < 256 ; i ++ ) {
16184
16180
Py_CLEAR (state -> latin1 [i ]);
16185
16181
}
16186
16182
16187
- if (is_main_interp ) {
16183
+ if (_Py_IsMainInterpreter ( tstate ) ) {
16188
16184
unicode_clear_static_strings ();
16189
16185
}
16190
16186
0 commit comments