changeset: 100676:14a552645c30 user: Victor Stinner date: Wed Mar 23 09:38:54 2016 +0100 files: Include/pymem.h Modules/_tracemalloc.c Modules/hashtable.h description: Issue #26588: * Optimize tracemalloc_add_trace(): modify hashtable entry data (trace) if the memory block is already tracked, rather than trying to remove the old trace and then add a new trace. * Add _Py_HASHTABLE_ENTRY_WRITE_DATA() macro diff -r 0e0a464faffb -r 14a552645c30 Include/pymem.h --- a/Include/pymem.h Wed Mar 23 09:25:01 2016 +0100 +++ b/Include/pymem.h Wed Mar 23 09:38:54 2016 +0100 @@ -34,7 +34,7 @@ Return -2 if tracemalloc is disabled. - If memory block was already tracked, begin by removing the old trace. */ + If memory block is already tracked, update the existing trace. */ PyAPI_FUNC(int) _PyTraceMalloc_Track( _PyTraceMalloc_domain_t domain, Py_uintptr_t ptr, diff -r 0e0a464faffb -r 14a552645c30 Modules/_tracemalloc.c --- a/Modules/_tracemalloc.c Wed Mar 23 09:25:01 2016 +0100 +++ b/Modules/_tracemalloc.c Wed Mar 23 09:38:54 2016 +0100 @@ -552,33 +552,49 @@ tracemalloc_add_trace(_PyTraceMalloc_domain_t domain, Py_uintptr_t ptr, size_t size) { + pointer_t key = {ptr, domain}; traceback_t *traceback; trace_t trace; + _Py_hashtable_entry_t* entry; int res; assert(tracemalloc_config.tracing); - /* first, remove the previous trace (if any) */ - tracemalloc_remove_trace(domain, ptr); - traceback = traceback_new(); if (traceback == NULL) { return -1; } - trace.size = size; - trace.traceback = traceback; - if (tracemalloc_config.use_domain) { - pointer_t key = {ptr, domain}; - res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace); + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, key); } else { - res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); + entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, ptr); } - if (res != 0) { - return res; + if (entry != NULL) { + /* the memory block is already tracked */ + _Py_HASHTABLE_ENTRY_READ_DATA(tracemalloc_traces, entry, trace); + assert(tracemalloc_traced_memory >= trace.size); + tracemalloc_traced_memory -= trace.size; + + trace.size = size; + trace.traceback = traceback; + _Py_HASHTABLE_ENTRY_WRITE_DATA(tracemalloc_traces, entry, trace); + } + else { + trace.size = size; + trace.traceback = traceback; + + if (tracemalloc_config.use_domain) { + res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace); + } + else { + res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); + } + if (res != 0) { + return res; + } } assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size); diff -r 0e0a464faffb -r 14a552645c30 Modules/hashtable.h --- a/Modules/hashtable.h Wed Mar 23 09:25:01 2016 +0100 +++ b/Modules/hashtable.h Wed Mar 23 09:38:54 2016 +0100 @@ -74,6 +74,9 @@ (PDATA), (DATA_SIZE)); \ } while (0) +#define _Py_HASHTABLE_ENTRY_WRITE_DATA(TABLE, ENTRY, DATA) \ + _Py_HASHTABLE_ENTRY_WRITE_PDATA(TABLE, ENTRY, sizeof(DATA), &(DATA)) + /* _Py_hashtable: prototypes */