Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ca79ccd

Browse files
committed
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
1 parent e8c6b2f commit ca79ccd

3 files changed

Lines changed: 31 additions & 12 deletions

File tree

Include/pymem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ typedef unsigned int _PyTraceMalloc_domain_t;
3434
3535
Return -2 if tracemalloc is disabled.
3636
37-
If memory block was already tracked, begin by removing the old trace. */
37+
If memory block is already tracked, update the existing trace. */
3838
PyAPI_FUNC(int) _PyTraceMalloc_Track(
3939
_PyTraceMalloc_domain_t domain,
4040
Py_uintptr_t ptr,

Modules/_tracemalloc.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -552,33 +552,49 @@ static int
552552
tracemalloc_add_trace(_PyTraceMalloc_domain_t domain, Py_uintptr_t ptr,
553553
size_t size)
554554
{
555+
pointer_t key = {ptr, domain};
555556
traceback_t *traceback;
556557
trace_t trace;
558+
_Py_hashtable_entry_t* entry;
557559
int res;
558560

559561
assert(tracemalloc_config.tracing);
560562

561-
/* first, remove the previous trace (if any) */
562-
tracemalloc_remove_trace(domain, ptr);
563-
564563
traceback = traceback_new();
565564
if (traceback == NULL) {
566565
return -1;
567566
}
568567

569-
trace.size = size;
570-
trace.traceback = traceback;
571-
572568
if (tracemalloc_config.use_domain) {
573-
pointer_t key = {ptr, domain};
574-
res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace);
569+
entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, key);
575570
}
576571
else {
577-
res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace);
572+
entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_traces, ptr);
578573
}
579574

580-
if (res != 0) {
581-
return res;
575+
if (entry != NULL) {
576+
/* the memory block is already tracked */
577+
_Py_HASHTABLE_ENTRY_READ_DATA(tracemalloc_traces, entry, trace);
578+
assert(tracemalloc_traced_memory >= trace.size);
579+
tracemalloc_traced_memory -= trace.size;
580+
581+
trace.size = size;
582+
trace.traceback = traceback;
583+
_Py_HASHTABLE_ENTRY_WRITE_DATA(tracemalloc_traces, entry, trace);
584+
}
585+
else {
586+
trace.size = size;
587+
trace.traceback = traceback;
588+
589+
if (tracemalloc_config.use_domain) {
590+
res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace);
591+
}
592+
else {
593+
res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace);
594+
}
595+
if (res != 0) {
596+
return res;
597+
}
582598
}
583599

584600
assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size);

Modules/hashtable.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ typedef struct {
7474
(PDATA), (DATA_SIZE)); \
7575
} while (0)
7676

77+
#define _Py_HASHTABLE_ENTRY_WRITE_DATA(TABLE, ENTRY, DATA) \
78+
_Py_HASHTABLE_ENTRY_WRITE_PDATA(TABLE, ENTRY, sizeof(DATA), &(DATA))
79+
7780

7881
/* _Py_hashtable: prototypes */
7982

0 commit comments

Comments
 (0)