diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-03-19 13:20:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-19 13:20:29 (GMT) |
commit | fecc4f2b474f16062514e95a67e66080fd626e14 (patch) | |
tree | 67c8c1859a3147cc190d3503fe1a730b6841e47f /Objects/unicodeobject.c | |
parent | a712679a2bffffefaacdc05f788d6ea50f72a561 (diff) | |
download | cpython-fecc4f2b474f16062514e95a67e66080fd626e14.zip cpython-fecc4f2b474f16062514e95a67e66080fd626e14.tar.gz cpython-fecc4f2b474f16062514e95a67e66080fd626e14.tar.bz2 |
bpo-36356: Release Unicode interned strings on Valgrind (#12431)
When Python is compiled with Valgrind support, release Unicode
interned strings at exit in _PyUnicode_Fini().
* Rename _Py_ReleaseInternedUnicodeStrings() to
unicode_release_interned() and make it private.
* unicode_release_interned() is now called from _PyUnicode_Fini():
it must be called with a running Python thread state for TRASHCAN,
it cannot be called from pymain_free().
* Don't display statistics on interned strings at exit anymore
Diffstat (limited to 'Objects/unicodeobject.c')
-rw-r--r-- | Objects/unicodeobject.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 9d3ed0d..6e83ed6 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -51,6 +51,11 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include <windows.h> #endif +/* Uncomment to display statistics on interned strings at exit when + using Valgrind or Insecure++. */ +/* #define INTERNED_STATS 1 */ + + /*[clinic input] class str "PyObject *" "&PyUnicode_Type" [clinic start generated code]*/ @@ -15157,18 +15162,6 @@ PyUnicode_ClearFreeList(void) return 0; } -void -_PyUnicode_Fini(void) -{ - int i; - - Py_CLEAR(unicode_empty); - - for (i = 0; i < 256; i++) - Py_CLEAR(unicode_latin1[i]); - _PyUnicode_ClearStaticStrings(); - (void)PyUnicode_ClearFreeList(); -} void PyUnicode_InternInPlace(PyObject **p) @@ -15233,8 +15226,10 @@ PyUnicode_InternFromString(const char *cp) return s; } -void -_Py_ReleaseInternedUnicodeStrings(void) + +#if defined(WITH_VALGRIND) || defined(__INSURE__) +static void +unicode_release_interned(void) { PyObject *keys; PyObject *s; @@ -15249,14 +15244,16 @@ _Py_ReleaseInternedUnicodeStrings(void) return; } - /* Since _Py_ReleaseInternedUnicodeStrings() is intended to help a leak + /* Since unicode_release_interned() is intended to help a leak detector, interned unicode strings are not forcibly deallocated; rather, we give them their stolen references back, and then clear and DECREF the interned dict. */ n = PyList_GET_SIZE(keys); +#ifdef INTERNED_STATS fprintf(stderr, "releasing %" PY_FORMAT_SIZE_T "d interned strings\n", n); +#endif for (i = 0; i < n; i++) { s = PyList_GET_ITEM(keys, i); if (PyUnicode_READY(s) == -1) { @@ -15279,13 +15276,16 @@ _Py_ReleaseInternedUnicodeStrings(void) } _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; } +#ifdef INTERNED_STATS fprintf(stderr, "total size of all interned strings: " "%" PY_FORMAT_SIZE_T "d/%" PY_FORMAT_SIZE_T "d " "mortal/immortal\n", mortal_size, immortal_size); +#endif Py_DECREF(keys); PyDict_Clear(interned); Py_CLEAR(interned); } +#endif /********************* Unicode Iterator **************************/ @@ -15564,6 +15564,33 @@ PyUnicode_AsUnicodeCopy(PyObject *unicode) return copy; } + +void +_PyUnicode_Fini(void) +{ +#if defined(WITH_VALGRIND) || defined(__INSURE__) + /* Insure++ is a memory analysis tool that aids in discovering + * memory leaks and other memory problems. On Python exit, the + * interned string dictionaries are flagged as being in use at exit + * (which it is). Under normal circumstances, this is fine because + * the memory will be automatically reclaimed by the system. Under + * memory debugging, it's a huge source of useless noise, so we + * trade off slower shutdown for less distraction in the memory + * reports. -baw + */ + unicode_release_interned(); +#endif /* __INSURE__ */ + + Py_CLEAR(unicode_empty); + + for (Py_ssize_t i = 0; i < 256; i++) { + Py_CLEAR(unicode_latin1[i]); + } + _PyUnicode_ClearStaticStrings(); + (void)PyUnicode_ClearFreeList(); +} + + /* A _string module, to export formatter_parser and formatter_field_name_split to the string.Formatter class implemented in Python. */ |