@@ -206,22 +206,6 @@ extern "C" {
206
206
# define OVERALLOCATE_FACTOR 4
207
207
#endif
208
208
209
- /* bpo-40521: Interned strings are shared by all interpreters. */
210
- #ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
211
- # define INTERNED_STRINGS
212
- #endif
213
-
214
- /* This dictionary holds all interned unicode strings. Note that references
215
- to strings in this dictionary are *not* counted in the string's ob_refcnt.
216
- When the interned string reaches a refcnt of 0 the string deallocation
217
- function will delete the reference from this dictionary.
218
-
219
- Another way to look at this is that to say that the actual reference
220
- count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
221
- */
222
- #ifdef INTERNED_STRINGS
223
- static PyObject * interned = NULL ;
224
- #endif
225
209
226
210
static struct _Py_unicode_state *
227
211
get_unicode_state (void )
@@ -1946,22 +1930,23 @@ unicode_dealloc(PyObject *unicode)
1946
1930
break ;
1947
1931
1948
1932
case SSTATE_INTERNED_MORTAL :
1949
- #ifdef INTERNED_STRINGS
1933
+ {
1934
+ struct _Py_unicode_state * state = get_unicode_state ();
1950
1935
/* Revive the dead object temporarily. PyDict_DelItem() removes two
1951
1936
references (key and value) which were ignored by
1952
1937
PyUnicode_InternInPlace(). Use refcnt=3 rather than refcnt=2
1953
1938
to prevent calling unicode_dealloc() again. Adjust refcnt after
1954
1939
PyDict_DelItem(). */
1955
1940
assert (Py_REFCNT (unicode ) == 0 );
1956
1941
Py_SET_REFCNT (unicode , 3 );
1957
- if (PyDict_DelItem (interned , unicode ) != 0 ) {
1942
+ if (PyDict_DelItem (state -> interned , unicode ) != 0 ) {
1958
1943
_PyErr_WriteUnraisableMsg ("deletion of interned string failed" ,
1959
1944
NULL );
1960
1945
}
1961
1946
assert (Py_REFCNT (unicode ) == 1 );
1962
1947
Py_SET_REFCNT (unicode , 0 );
1963
- #endif
1964
1948
break ;
1949
+ }
1965
1950
1966
1951
case SSTATE_INTERNED_IMMORTAL :
1967
1952
_PyObject_ASSERT_FAILED_MSG (unicode , "Immortal interned string died" );
@@ -11536,12 +11521,11 @@ _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right)
11536
11521
if (PyUnicode_CHECK_INTERNED (left ))
11537
11522
return 0 ;
11538
11523
11539
- #ifdef INTERNED_STRINGS
11540
11524
assert (_PyUnicode_HASH (right_uni ) != -1 );
11541
11525
Py_hash_t hash = _PyUnicode_HASH (left );
11542
- if (hash != -1 && hash != _PyUnicode_HASH (right_uni ))
11526
+ if (hash != -1 && hash != _PyUnicode_HASH (right_uni )) {
11543
11527
return 0 ;
11544
- #endif
11528
+ }
11545
11529
11546
11530
return unicode_compare_eq (left , right_uni );
11547
11531
}
@@ -15765,23 +15749,21 @@ PyUnicode_InternInPlace(PyObject **p)
15765
15749
return ;
15766
15750
}
15767
15751
15768
- #ifdef INTERNED_STRINGS
15769
15752
if (PyUnicode_READY (s ) == -1 ) {
15770
15753
PyErr_Clear ();
15771
15754
return ;
15772
15755
}
15773
15756
15774
- if (interned == NULL ) {
15775
- interned = PyDict_New ();
15776
- if (interned == NULL ) {
15757
+ struct _Py_unicode_state * state = get_unicode_state ();
15758
+ if (state -> interned == NULL ) {
15759
+ state -> interned = PyDict_New ();
15760
+ if (state -> interned == NULL ) {
15777
15761
PyErr_Clear (); /* Don't leave an exception */
15778
15762
return ;
15779
15763
}
15780
15764
}
15781
15765
15782
- PyObject * t ;
15783
- t = PyDict_SetDefault (interned , s , s );
15784
-
15766
+ PyObject * t = PyDict_SetDefault (state -> interned , s , s );
15785
15767
if (t == NULL ) {
15786
15768
PyErr_Clear ();
15787
15769
return ;
@@ -15798,13 +15780,9 @@ PyUnicode_InternInPlace(PyObject **p)
15798
15780
this. */
15799
15781
Py_SET_REFCNT (s , Py_REFCNT (s ) - 2 );
15800
15782
_PyUnicode_STATE (s ).interned = SSTATE_INTERNED_MORTAL ;
15801
- #else
15802
- // PyDict expects that interned strings have their hash
15803
- // (PyASCIIObject.hash) already computed.
15804
- (void )unicode_hash (s );
15805
- #endif
15806
15783
}
15807
15784
15785
+
15808
15786
void
15809
15787
PyUnicode_InternImmortal (PyObject * * p )
15810
15788
{
@@ -15838,35 +15816,25 @@ PyUnicode_InternFromString(const char *cp)
15838
15816
void
15839
15817
_PyUnicode_ClearInterned (PyThreadState * tstate )
15840
15818
{
15841
- if (!_Py_IsMainInterpreter (tstate )) {
15842
- // interned dict is shared by all interpreters
15843
- return ;
15844
- }
15845
-
15846
- if (interned == NULL ) {
15847
- return ;
15848
- }
15849
- assert (PyDict_CheckExact (interned ));
15850
-
15851
- PyObject * keys = PyDict_Keys (interned );
15852
- if (keys == NULL ) {
15853
- PyErr_Clear ();
15819
+ struct _Py_unicode_state * state = & tstate -> interp -> unicode ;
15820
+ if (state -> interned == NULL ) {
15854
15821
return ;
15855
15822
}
15856
- assert (PyList_CheckExact ( keys ));
15823
+ assert (PyDict_CheckExact ( state -> interned ));
15857
15824
15858
15825
/* Interned unicode strings are not forcibly deallocated; rather, we give
15859
15826
them their stolen references back, and then clear and DECREF the
15860
15827
interned dict. */
15861
15828
15862
- Py_ssize_t n = PyList_GET_SIZE (keys );
15863
15829
#ifdef INTERNED_STATS
15864
- fprintf (stderr , "releasing %zd interned strings\n" , n );
15830
+ fprintf (stderr , "releasing %zd interned strings\n" ,
15831
+ PyDict_GET_SIZE (state -> interned ));
15865
15832
15866
15833
Py_ssize_t immortal_size = 0 , mortal_size = 0 ;
15867
15834
#endif
15868
- for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
15869
- PyObject * s = PyList_GET_ITEM (keys , i );
15835
+ Py_ssize_t pos = 0 ;
15836
+ PyObject * s , * ignored_value ;
15837
+ while (PyDict_Next (state -> interned , & pos , & s , & ignored_value )) {
15870
15838
assert (PyUnicode_IS_READY (s ));
15871
15839
15872
15840
switch (PyUnicode_CHECK_INTERNED (s )) {
@@ -15896,10 +15864,9 @@ _PyUnicode_ClearInterned(PyThreadState *tstate)
15896
15864
"total size of all interned strings: %zd/%zd mortal/immortal\n" ,
15897
15865
mortal_size , immortal_size );
15898
15866
#endif
15899
- Py_DECREF (keys );
15900
15867
15901
- PyDict_Clear (interned );
15902
- Py_CLEAR (interned );
15868
+ PyDict_Clear (state -> interned );
15869
+ Py_CLEAR (state -> interned );
15903
15870
}
15904
15871
15905
15872
@@ -16269,19 +16236,19 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void)
16269
16236
void
16270
16237
_PyUnicode_Fini (PyThreadState * tstate )
16271
16238
{
16239
+ struct _Py_unicode_state * state = & tstate -> interp -> unicode ;
16240
+
16272
16241
// _PyUnicode_ClearInterned() must be called before
16242
+ assert (state -> interned == NULL );
16273
16243
16274
- struct _Py_unicode_state * state = & tstate -> interp -> unicode ;
16244
+ _PyUnicode_FiniEncodings ( & state -> fs_codec ) ;
16275
16245
16276
- Py_CLEAR ( state -> empty_string );
16246
+ unicode_clear_identifiers ( tstate );
16277
16247
16278
16248
for (Py_ssize_t i = 0 ; i < 256 ; i ++ ) {
16279
16249
Py_CLEAR (state -> latin1 [i ]);
16280
16250
}
16281
-
16282
- unicode_clear_identifiers (tstate );
16283
-
16284
- _PyUnicode_FiniEncodings (& tstate -> interp -> unicode .fs_codec );
16251
+ Py_CLEAR (state -> empty_string );
16285
16252
}
16286
16253
16287
16254
0 commit comments