]> granicus.if.org Git - python/commitdiff
Issue #26588:
authorVictor Stinner <victor.stinner@gmail.com>
Wed, 23 Mar 2016 08:38:54 +0000 (09:38 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Wed, 23 Mar 2016 08:38:54 +0000 (09:38 +0100)
* 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

Include/pymem.h
Modules/_tracemalloc.c
Modules/hashtable.h

index 941e00f6c2c57227cb96c4b9cd0ee5139fcf522c..431e5b6d0f41381be7d55852ef74057518d06370 100644 (file)
@@ -34,7 +34,7 @@ typedef unsigned int _PyTraceMalloc_domain_t;
 
    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,
index 0bab540ee1a6a4296970254277a7f06c769b6c0a..e6465a3b749fc0411a40a72baf337cc949a47008 100644 (file)
@@ -552,33 +552,49 @@ static int
 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);
index 9c3fbdd6712b91784f0822dfdef69aa11709a334..e3e8148fcc4e36e154da72ea89663dd001771670 100644 (file)
@@ -74,6 +74,9 @@ typedef struct {
                (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 */