diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2016-03-21 13:36:39 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2016-03-21 13:36:39 (GMT) |
commit | 322bc12c3142e7816dd34c6c3085929ab29d3ed8 (patch) | |
tree | 6198f0a586970bd578569611eaefb6a059338916 /Modules/_tracemalloc.c | |
parent | fac395681fb758401d17974f258b17d285336c57 (diff) | |
download | cpython-322bc12c3142e7816dd34c6c3085929ab29d3ed8.zip cpython-322bc12c3142e7816dd34c6c3085929ab29d3ed8.tar.gz cpython-322bc12c3142e7816dd34c6c3085929ab29d3ed8.tar.bz2 |
Ooops, revert changeset ea9efa06c137
Change pushed by mistake, the patch is still under review :-/
"""
_tracemalloc: add domain to trace keys
* hashtable.h: key has now a variable size
* _tracemalloc uses (pointer: void*, domain: unsigned int) as key for traces
"""
Diffstat (limited to 'Modules/_tracemalloc.c')
-rw-r--r-- | Modules/_tracemalloc.c | 186 |
1 files changed, 48 insertions, 138 deletions
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 73aa53b..5752904 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -3,7 +3,6 @@ #include "frameobject.h" #include "pythread.h" #include "osdefs.h" -#include <stddef.h> /* For offsetof */ /* Trace memory blocks allocated by PyMem_RawMalloc() */ #define TRACE_RAW_MALLOC @@ -55,26 +54,6 @@ static PyThread_type_lock tables_lock; # define TABLES_UNLOCK() #endif -typedef unsigned int domain_t; - -/* FIXME: pack also? */ -typedef struct { - void *ptr; - domain_t domain; -} pointer_t; - -/* Size of pointer_t content, it can be smaller than sizeof(pointer_t) */ -#define POINTER_T_SIZE \ - (offsetof(pointer_t, domain) + sizeof(domain_t)) - -#define POINTER_T_FILL_PADDING(key) \ - do { \ - if (POINTER_T_SIZE != sizeof(pointer_t)) { \ - memset((char *)&(key) + POINTER_T_SIZE, 0, \ - sizeof(pointer_t) - POINTER_T_SIZE); \ - } \ - } while (0) - /* Pack the frame_t structure to reduce the memory footprint on 64-bit architectures: 12 bytes instead of 16. This optimization might produce SIGBUS on architectures not supporting unaligned memory accesses (64-bit @@ -217,56 +196,23 @@ set_reentrant(int reentrant) } #endif -static Py_uhash_t -hashtable_hash_pointer(size_t key_size, const void *pkey) -{ - pointer_t ptr; - Py_uhash_t hash; - - assert(sizeof(ptr) == key_size); - ptr = *(pointer_t *)pkey; - - hash = (Py_uhash_t)_Py_HashPointer(ptr.ptr); - hash ^= ptr.domain; - return hash; -} - -static Py_uhash_t -hashtable_hash_pyobject(size_t key_size, const void *pkey) -{ - PyObject *obj; - - assert(key_size == sizeof(PyObject *)); - obj = *(PyObject **)pkey; - - return PyObject_Hash(obj); -} - static int -hashtable_compare_unicode(size_t key_size, const void *pkey, - const _Py_hashtable_entry_t *entry) +hashtable_compare_unicode(const void *key, const _Py_hashtable_entry_t *entry) { - PyObject *key, *entry_key; - - assert(sizeof(key) == key_size); - key = *(PyObject **)pkey; - assert(sizeof(entry_key) == key_size); - entry_key = *(PyObject **)_Py_HASHTABLE_ENTRY_KEY(entry); - - if (key != NULL && entry_key != NULL) - return (PyUnicode_Compare(key, entry_key) == 0); + if (key != NULL && entry->key != NULL) + return (PyUnicode_Compare((PyObject *)key, (PyObject *)entry->key) == 0); else - return key == entry_key; + return key == entry->key; } static _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; static _Py_hashtable_t * -hashtable_new(size_t key_size, size_t data_size, +hashtable_new(size_t data_size, _Py_hashtable_hash_func hash_func, _Py_hashtable_compare_func compare_func) { - return _Py_hashtable_new_full(key_size, data_size, 0, + return _Py_hashtable_new_full(data_size, 0, hash_func, compare_func, NULL, NULL, NULL, &hashtable_alloc); } @@ -284,26 +230,20 @@ raw_free(void *ptr) } static Py_uhash_t -hashtable_hash_traceback(size_t key_size, const void *pkey) +hashtable_hash_traceback(const void *key) { - const traceback_t *traceback = *(const traceback_t **)pkey; - assert(key_size == sizeof(const traceback_t *)); + const traceback_t *traceback = key; return traceback->hash; } static int -hashtable_compare_traceback(size_t key_size, const void *pkey, +hashtable_compare_traceback(const traceback_t *traceback1, const _Py_hashtable_entry_t *he) { - traceback_t *traceback1, *traceback2; + const traceback_t *traceback2 = he->key; const frame_t *frame1, *frame2; int i; - assert(sizeof(traceback1) == key_size); - assert(sizeof(traceback2) == key_size); - traceback1 = *(traceback_t **)pkey; - traceback2 = *(traceback_t **)_Py_HASHTABLE_ENTRY_KEY(he); - if (traceback1->nframe != traceback2->nframe) return 0; @@ -372,16 +312,15 @@ tracemalloc_get_frame(PyFrameObject *pyframe, frame_t *frame) } /* intern the filename */ - entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_filenames, filename); + entry = _Py_hashtable_get_entry(tracemalloc_filenames, filename); if (entry != NULL) { - assert(sizeof(filename) == tracemalloc_filenames->key_size); - filename = *(PyObject **)_Py_HASHTABLE_ENTRY_KEY(entry); + filename = (PyObject *)entry->key; } else { /* tracemalloc_filenames is responsible to keep a reference to the filename */ Py_INCREF(filename); - if (_Py_HASHTABLE_SET_NODATA(tracemalloc_filenames, filename) < 0) { + if (_Py_hashtable_set(tracemalloc_filenames, filename, NULL, 0) < 0) { Py_DECREF(filename); #ifdef TRACE_DEBUG tracemalloc_error("failed to intern the filename"); @@ -464,10 +403,9 @@ traceback_new(void) traceback->hash = traceback_hash(traceback); /* intern the traceback */ - entry = _Py_HASHTABLE_GET_ENTRY(tracemalloc_tracebacks, traceback); + entry = _Py_hashtable_get_entry(tracemalloc_tracebacks, traceback); if (entry != NULL) { - assert(sizeof(traceback) == tracemalloc_tracebacks->key_size); - traceback = *(traceback_t **)_Py_HASHTABLE_ENTRY_KEY(entry); + traceback = (traceback_t *)entry->key; } else { traceback_t *copy; @@ -484,7 +422,7 @@ traceback_new(void) } memcpy(copy, traceback, traceback_size); - if (_Py_HASHTABLE_SET_NODATA(tracemalloc_tracebacks, copy) < 0) { + if (_Py_hashtable_set(tracemalloc_tracebacks, copy, NULL, 0) < 0) { raw_free(copy); #ifdef TRACE_DEBUG tracemalloc_error("failed to intern the traceback: putdata failed"); @@ -497,9 +435,8 @@ traceback_new(void) } static int -tracemalloc_add_trace(void *ptr, domain_t domain, size_t size) +tracemalloc_add_trace(void *ptr, size_t size) { - pointer_t key; traceback_t *traceback; trace_t trace; int res; @@ -508,14 +445,10 @@ tracemalloc_add_trace(void *ptr, domain_t domain, size_t size) if (traceback == NULL) return -1; - key.ptr = ptr; - key.domain = 0; - POINTER_T_FILL_PADDING(key); - trace.size = size; trace.traceback = traceback; - res = _Py_HASHTABLE_SET(tracemalloc_traces, key, trace); + res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); if (res == 0) { assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size); tracemalloc_traced_memory += size; @@ -527,16 +460,11 @@ tracemalloc_add_trace(void *ptr, domain_t domain, size_t size) } static void -tracemalloc_remove_trace(void *ptr, domain_t domain) +tracemalloc_remove_trace(void *ptr) { - pointer_t key; trace_t trace; - key.ptr = ptr; - key.domain = domain; - POINTER_T_FILL_PADDING(key); - - if (_Py_HASHTABLE_POP(tracemalloc_traces, key, trace)) { + if (_Py_hashtable_pop(tracemalloc_traces, ptr, &trace, sizeof(trace))) { assert(tracemalloc_traced_memory >= trace.size); tracemalloc_traced_memory -= trace.size; } @@ -558,7 +486,7 @@ tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) return NULL; TABLES_LOCK(); - if (tracemalloc_add_trace(ptr, 0, nelem * elsize) < 0) { + if (tracemalloc_add_trace(ptr, nelem * elsize) < 0) { /* Failed to allocate a trace for the new memory block */ TABLES_UNLOCK(); alloc->free(alloc->ctx, ptr); @@ -582,9 +510,9 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) /* an existing memory block has been resized */ TABLES_LOCK(); - tracemalloc_remove_trace(ptr, 0); + tracemalloc_remove_trace(ptr); - if (tracemalloc_add_trace(ptr2, 0, new_size) < 0) { + if (tracemalloc_add_trace(ptr2, new_size) < 0) { /* Memory allocation failed. The error cannot be reported to the caller, because realloc() may already have shrinked the memory block and so removed bytes. @@ -602,7 +530,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) /* new allocation */ TABLES_LOCK(); - if (tracemalloc_add_trace(ptr2, 0, new_size) < 0) { + if (tracemalloc_add_trace(ptr2, new_size) < 0) { /* Failed to allocate a trace for the new memory block */ TABLES_UNLOCK(); alloc->free(alloc->ctx, ptr2); @@ -627,7 +555,7 @@ tracemalloc_free(void *ctx, void *ptr) alloc->free(alloc->ctx, ptr); TABLES_LOCK(); - tracemalloc_remove_trace(ptr, 0); + tracemalloc_remove_trace(ptr); TABLES_UNLOCK(); } @@ -682,7 +610,7 @@ tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); if (ptr2 != NULL && ptr != NULL) { TABLES_LOCK(); - tracemalloc_remove_trace(ptr, 0); + tracemalloc_remove_trace(ptr); TABLES_UNLOCK(); } return ptr2; @@ -761,7 +689,7 @@ tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) if (ptr2 != NULL && ptr != NULL) { TABLES_LOCK(); - tracemalloc_remove_trace(ptr, 0); + tracemalloc_remove_trace(ptr); TABLES_UNLOCK(); } return ptr2; @@ -786,27 +714,17 @@ tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) #endif /* TRACE_RAW_MALLOC */ static int -tracemalloc_clear_filename(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, - void *user_data) +tracemalloc_clear_filename(_Py_hashtable_entry_t *entry, void *user_data) { - PyObject *filename; - - assert(sizeof(filename) == ht->key_size); - filename = *(PyObject **)_Py_HASHTABLE_ENTRY_KEY(entry); - + PyObject *filename = (PyObject *)entry->key; Py_DECREF(filename); return 0; } static int -traceback_free_traceback(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry, - void *user_data) +traceback_free_traceback(_Py_hashtable_entry_t *entry, void *user_data) { - traceback_t *traceback; - - assert(sizeof(traceback) == ht->key_size); - traceback = *(traceback_t **)_Py_HASHTABLE_ENTRY_KEY(entry); - + traceback_t *traceback = (traceback_t *)entry->key; raw_free(traceback); return 0; } @@ -873,16 +791,16 @@ tracemalloc_init(void) } #endif - tracemalloc_filenames = hashtable_new(sizeof(PyObject *), 0, - hashtable_hash_pyobject, + tracemalloc_filenames = hashtable_new(0, + (_Py_hashtable_hash_func)PyObject_Hash, hashtable_compare_unicode); - tracemalloc_tracebacks = hashtable_new(sizeof(traceback_t *), 0, - hashtable_hash_traceback, - hashtable_compare_traceback); + tracemalloc_tracebacks = hashtable_new(0, + (_Py_hashtable_hash_func)hashtable_hash_traceback, + (_Py_hashtable_compare_func)hashtable_compare_traceback); - tracemalloc_traces = hashtable_new(sizeof(pointer_t), sizeof(trace_t), - hashtable_hash_pointer, + tracemalloc_traces = hashtable_new(sizeof(trace_t), + _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct); if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL @@ -1147,15 +1065,14 @@ typedef struct { } get_traces_t; static int -tracemalloc_get_traces_fill(_Py_hashtable_t *traces, _Py_hashtable_entry_t *entry, - void *user_data) +tracemalloc_get_traces_fill(_Py_hashtable_entry_t *entry, void *user_data) { get_traces_t *get_traces = user_data; trace_t *trace; PyObject *tracemalloc_obj; int res; - trace = (trace_t *)_Py_HASHTABLE_ENTRY_DATA(traces, entry); + trace = (trace_t *)_Py_HASHTABLE_ENTRY_DATA(entry); tracemalloc_obj = trace_to_pyobject(trace, get_traces->tracebacks); if (tracemalloc_obj == NULL) @@ -1170,11 +1087,9 @@ tracemalloc_get_traces_fill(_Py_hashtable_t *traces, _Py_hashtable_entry_t *entr } static int -tracemalloc_pyobject_decref_cb(_Py_hashtable_t *tracebacks, - _Py_hashtable_entry_t *entry, - void *user_data) +tracemalloc_pyobject_decref_cb(_Py_hashtable_entry_t *entry, void *user_data) { - PyObject *obj = (PyObject *)_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(tracebacks, entry); + PyObject *obj = (PyObject *)_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry); Py_DECREF(obj); return 0; } @@ -1205,7 +1120,7 @@ py_tracemalloc_get_traces(PyObject *self, PyObject *obj) /* the traceback hash table is used temporarily to intern traceback tuple of (filename, lineno) tuples */ - get_traces.tracebacks = hashtable_new(sizeof(traceback_t *), sizeof(PyObject *), + get_traces.tracebacks = hashtable_new(sizeof(PyObject *), _Py_hashtable_hash_ptr, _Py_hashtable_compare_direct); if (get_traces.tracebacks == NULL) { @@ -1237,7 +1152,7 @@ error: finally: if (get_traces.tracebacks != NULL) { _Py_hashtable_foreach(get_traces.tracebacks, - tracemalloc_pyobject_decref_cb, NULL); + tracemalloc_pyobject_decref_cb, NULL); _Py_hashtable_destroy(get_traces.tracebacks); } if (get_traces.traces != NULL) @@ -1247,21 +1162,16 @@ finally: } static traceback_t* -tracemalloc_get_traceback(const void *ptr, domain_t domain) +tracemalloc_get_traceback(const void *ptr) { - pointer_t key; trace_t trace; int found; if (!tracemalloc_config.tracing) return NULL; - key.ptr = (void *)ptr; - key.domain = domain; - POINTER_T_FILL_PADDING(key); - TABLES_LOCK(); - found = _Py_HASHTABLE_GET(tracemalloc_traces, key, trace); + found = _Py_HASHTABLE_GET(tracemalloc_traces, ptr, trace); TABLES_UNLOCK(); if (!found) @@ -1292,7 +1202,7 @@ py_tracemalloc_get_object_traceback(PyObject *self, PyObject *obj) else ptr = (void *)obj; - traceback = tracemalloc_get_traceback(ptr, 0); + traceback = tracemalloc_get_traceback(ptr); if (traceback == NULL) Py_RETURN_NONE; @@ -1319,7 +1229,7 @@ _PyMem_DumpTraceback(int fd, const void *ptr) traceback_t *traceback; int i; - traceback = tracemalloc_get_traceback(ptr, 0); + traceback = tracemalloc_get_traceback(ptr); if (traceback == NULL) return; |