bpo-36356: Release Unicode interned strings on Valgrind (#12431) · python/cpython@fecc4f2

@@ -51,6 +51,11 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

5151

#include <windows.h>

5252

#endif

535354+

/* Uncomment to display statistics on interned strings at exit when

55+

using Valgrind or Insecure++. */

56+

/* #define INTERNED_STATS 1 */

57+58+5459

/*[clinic input]

5560

class str "PyObject *" "&PyUnicode_Type"

5661

[clinic start generated code]*/

@@ -15157,18 +15162,6 @@ PyUnicode_ClearFreeList(void)

1515715162

return 0;

1515815163

}

151591516415160-

void

15161-

_PyUnicode_Fini(void)

15162-

{

15163-

int i;

15164-15165-

Py_CLEAR(unicode_empty);

15166-15167-

for (i = 0; i < 256; i++)

15168-

Py_CLEAR(unicode_latin1[i]);

15169-

_PyUnicode_ClearStaticStrings();

15170-

(void)PyUnicode_ClearFreeList();

15171-

}

15172151651517315166

void

1517415167

PyUnicode_InternInPlace(PyObject **p)

@@ -15233,8 +15226,10 @@ PyUnicode_InternFromString(const char *cp)

1523315226

return s;

1523415227

}

152351522815236-

void

15237-

_Py_ReleaseInternedUnicodeStrings(void)

15229+15230+

#if defined(WITH_VALGRIND) || defined(__INSURE__)

15231+

static void

15232+

unicode_release_interned(void)

1523815233

{

1523915234

PyObject *keys;

1524015235

PyObject *s;

@@ -15249,14 +15244,16 @@ _Py_ReleaseInternedUnicodeStrings(void)

1524915244

return;

1525015245

}

152511524615252-

/* Since _Py_ReleaseInternedUnicodeStrings() is intended to help a leak

15247+

/* Since unicode_release_interned() is intended to help a leak

1525315248

detector, interned unicode strings are not forcibly deallocated;

1525415249

rather, we give them their stolen references back, and then clear

1525515250

and DECREF the interned dict. */

15256152511525715252

n = PyList_GET_SIZE(keys);

15253+

#ifdef INTERNED_STATS

1525815254

fprintf(stderr, "releasing %" PY_FORMAT_SIZE_T "d interned strings\n",

1525915255

n);

15256+

#endif

1526015257

for (i = 0; i < n; i++) {

1526115258

s = PyList_GET_ITEM(keys, i);

1526215259

if (PyUnicode_READY(s) == -1) {

@@ -15279,13 +15276,16 @@ _Py_ReleaseInternedUnicodeStrings(void)

1527915276

}

1528015277

_PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED;

1528115278

}

15279+

#ifdef INTERNED_STATS

1528215280

fprintf(stderr, "total size of all interned strings: "

1528315281

"%" PY_FORMAT_SIZE_T "d/%" PY_FORMAT_SIZE_T "d "

1528415282

"mortal/immortal\n", mortal_size, immortal_size);

15283+

#endif

1528515284

Py_DECREF(keys);

1528615285

PyDict_Clear(interned);

1528715286

Py_CLEAR(interned);

1528815287

}

15288+

#endif

152891528915290152901529115291

/********************* Unicode Iterator **************************/

@@ -15564,6 +15564,33 @@ PyUnicode_AsUnicodeCopy(PyObject *unicode)

1556415564

return copy;

1556515565

}

155661556615567+15568+

void

15569+

_PyUnicode_Fini(void)

15570+

{

15571+

#if defined(WITH_VALGRIND) || defined(__INSURE__)

15572+

/* Insure++ is a memory analysis tool that aids in discovering

15573+

* memory leaks and other memory problems. On Python exit, the

15574+

* interned string dictionaries are flagged as being in use at exit

15575+

* (which it is). Under normal circumstances, this is fine because

15576+

* the memory will be automatically reclaimed by the system. Under

15577+

* memory debugging, it's a huge source of useless noise, so we

15578+

* trade off slower shutdown for less distraction in the memory

15579+

* reports. -baw

15580+

*/

15581+

unicode_release_interned();

15582+

#endif /* __INSURE__ */

15583+15584+

Py_CLEAR(unicode_empty);

15585+15586+

for (Py_ssize_t i = 0; i < 256; i++) {

15587+

Py_CLEAR(unicode_latin1[i]);

15588+

}

15589+

_PyUnicode_ClearStaticStrings();

15590+

(void)PyUnicode_ClearFreeList();

15591+

}

15592+15593+1556715594

/* A _string module, to export formatter_parser and formatter_field_name_split

1556815595

to the string.Formatter class implemented in Python. */

1556915596