mirror of https://github.com/python/cpython
gh-81057: Move tracemalloc Globals to _PyRuntimeState (gh-100151)
https://github.com/python/cpython/issues/81057
This commit is contained in:
parent
1583c6e326
commit
8790d4d31f
|
@ -90,28 +90,6 @@ PyAPI_FUNC(int) _PyMem_GetAllocatorName(
|
|||
PYMEM_ALLOCATOR_NOT_SET does nothing. */
|
||||
PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator);
|
||||
|
||||
struct _PyTraceMalloc_Config {
|
||||
/* Module initialized?
|
||||
Variable protected by the GIL */
|
||||
enum {
|
||||
TRACEMALLOC_NOT_INITIALIZED,
|
||||
TRACEMALLOC_INITIALIZED,
|
||||
TRACEMALLOC_FINALIZED
|
||||
} initialized;
|
||||
|
||||
/* Is tracemalloc tracing memory allocations?
|
||||
Variable protected by the GIL */
|
||||
int tracing;
|
||||
|
||||
/* limit of the number of frames in a traceback, 1 by default.
|
||||
Variable protected by the GIL. */
|
||||
int max_nframe;
|
||||
};
|
||||
|
||||
#define _PyTraceMalloc_Config_INIT \
|
||||
{.initialized = TRACEMALLOC_NOT_INITIALIZED, \
|
||||
.tracing = 0, \
|
||||
.max_nframe = 1}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#include "pycore_pythread.h" // struct _pythread_runtime_state
|
||||
#include "pycore_obmalloc.h" // struct obmalloc_state
|
||||
#include "pycore_time.h" // struct _time_runtime_state
|
||||
#include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state
|
||||
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids
|
||||
|
||||
struct _getargs_runtime_state {
|
||||
|
@ -137,11 +138,9 @@ typedef struct pyruntimestate {
|
|||
struct _ceval_runtime_state ceval;
|
||||
struct _gilstate_runtime_state gilstate;
|
||||
struct _getargs_runtime_state getargs;
|
||||
struct {
|
||||
struct _PyTraceMalloc_Config config;
|
||||
} tracemalloc;
|
||||
struct _dtoa_runtime_state dtoa;
|
||||
struct _fileutils_state fileutils;
|
||||
struct _tracemalloc_runtime_state tracemalloc;
|
||||
|
||||
PyPreConfig preconfig;
|
||||
|
||||
|
|
|
@ -50,13 +50,11 @@ extern "C" {
|
|||
in accordance with the specification. */ \
|
||||
.autoTSSkey = Py_tss_NEEDS_INIT, \
|
||||
}, \
|
||||
.tracemalloc = { \
|
||||
.config = _PyTraceMalloc_Config_INIT, \
|
||||
}, \
|
||||
.dtoa = _dtoa_runtime_state_INIT(runtime), \
|
||||
.fileutils = { \
|
||||
.force_ascii = -1, \
|
||||
}, \
|
||||
.tracemalloc = _tracemalloc_runtime_state_INIT, \
|
||||
.float_state = { \
|
||||
.float_format = _py_float_format_unknown, \
|
||||
.double_format = _py_float_format_unknown, \
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
#ifndef Py_INTERNAL_TRACEMALLOC_H
|
||||
#define Py_INTERNAL_TRACEMALLOC_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
#include "pycore_hashtable.h" // _Py_hashtable_t
|
||||
|
||||
|
||||
/* Trace memory blocks allocated by PyMem_RawMalloc() */
|
||||
#define TRACE_RAW_MALLOC
|
||||
|
||||
|
||||
struct _PyTraceMalloc_Config {
|
||||
/* Module initialized?
|
||||
Variable protected by the GIL */
|
||||
enum {
|
||||
TRACEMALLOC_NOT_INITIALIZED,
|
||||
TRACEMALLOC_INITIALIZED,
|
||||
TRACEMALLOC_FINALIZED
|
||||
} initialized;
|
||||
|
||||
/* Is tracemalloc tracing memory allocations?
|
||||
Variable protected by the GIL */
|
||||
int tracing;
|
||||
|
||||
/* limit of the number of frames in a traceback, 1 by default.
|
||||
Variable protected by the GIL. */
|
||||
int max_nframe;
|
||||
};
|
||||
|
||||
|
||||
/* Pack the frame_t structure to reduce the memory footprint on 64-bit
|
||||
architectures: 12 bytes instead of 16. */
|
||||
struct
|
||||
#ifdef __GNUC__
|
||||
__attribute__((packed))
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma pack(push, 4)
|
||||
#endif
|
||||
tracemalloc_frame {
|
||||
/* filename cannot be NULL: "<unknown>" is used if the Python frame
|
||||
filename is NULL */
|
||||
PyObject *filename;
|
||||
unsigned int lineno;
|
||||
};
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
struct tracemalloc_traceback {
|
||||
Py_uhash_t hash;
|
||||
/* Number of frames stored */
|
||||
uint16_t nframe;
|
||||
/* Total number of frames the traceback had */
|
||||
uint16_t total_nframe;
|
||||
struct tracemalloc_frame frames[1];
|
||||
};
|
||||
|
||||
|
||||
struct _tracemalloc_runtime_state {
|
||||
struct _PyTraceMalloc_Config config;
|
||||
|
||||
/* Protected by the GIL */
|
||||
struct {
|
||||
PyMemAllocatorEx mem;
|
||||
PyMemAllocatorEx raw;
|
||||
PyMemAllocatorEx obj;
|
||||
} allocators;
|
||||
|
||||
#if defined(TRACE_RAW_MALLOC)
|
||||
PyThread_type_lock tables_lock;
|
||||
#endif
|
||||
/* Size in bytes of currently traced memory.
|
||||
Protected by TABLES_LOCK(). */
|
||||
size_t traced_memory;
|
||||
/* Peak size in bytes of traced memory.
|
||||
Protected by TABLES_LOCK(). */
|
||||
size_t peak_traced_memory;
|
||||
/* Hash table used as a set to intern filenames:
|
||||
PyObject* => PyObject*.
|
||||
Protected by the GIL */
|
||||
_Py_hashtable_t *filenames;
|
||||
/* Buffer to store a new traceback in traceback_new().
|
||||
Protected by the GIL. */
|
||||
struct tracemalloc_traceback *traceback;
|
||||
/* Hash table used as a set to intern tracebacks:
|
||||
traceback_t* => traceback_t*
|
||||
Protected by the GIL */
|
||||
_Py_hashtable_t *tracebacks;
|
||||
/* pointer (void*) => trace (trace_t*).
|
||||
Protected by TABLES_LOCK(). */
|
||||
_Py_hashtable_t *traces;
|
||||
/* domain (unsigned int) => traces (_Py_hashtable_t).
|
||||
Protected by TABLES_LOCK(). */
|
||||
_Py_hashtable_t *domains;
|
||||
|
||||
struct tracemalloc_traceback empty_traceback;
|
||||
|
||||
Py_tss_t reentrant_key;
|
||||
};
|
||||
|
||||
#define _tracemalloc_runtime_state_INIT \
|
||||
{ \
|
||||
.config = { \
|
||||
.initialized = TRACEMALLOC_NOT_INITIALIZED, \
|
||||
.tracing = 0, \
|
||||
.max_nframe = 1, \
|
||||
}, \
|
||||
.reentrant_key = Py_tss_NEEDS_INIT, \
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // !Py_INTERNAL_TRACEMALLOC_H
|
|
@ -1678,6 +1678,7 @@ PYTHON_HEADERS= \
|
|||
$(srcdir)/Include/internal/pycore_time.h \
|
||||
$(srcdir)/Include/internal/pycore_token.h \
|
||||
$(srcdir)/Include/internal/pycore_traceback.h \
|
||||
$(srcdir)/Include/internal/pycore_tracemalloc.h \
|
||||
$(srcdir)/Include/internal/pycore_tuple.h \
|
||||
$(srcdir)/Include/internal/pycore_typeobject.h \
|
||||
$(srcdir)/Include/internal/pycore_ucnhash.h \
|
||||
|
|
|
@ -20,9 +20,6 @@ module _tracemalloc
|
|||
|
||||
_Py_DECLARE_STR(anon_unknown, "<unknown>");
|
||||
|
||||
/* Trace memory blocks allocated by PyMem_RawMalloc() */
|
||||
#define TRACE_RAW_MALLOC
|
||||
|
||||
/* Forward declaration */
|
||||
static void tracemalloc_stop(void);
|
||||
static void* raw_malloc(size_t size);
|
||||
|
@ -35,19 +32,14 @@ static void raw_free(void *ptr);
|
|||
#define TO_PTR(key) ((const void *)(uintptr_t)(key))
|
||||
#define FROM_PTR(key) ((uintptr_t)(key))
|
||||
|
||||
/* Protected by the GIL */
|
||||
static struct {
|
||||
PyMemAllocatorEx mem;
|
||||
PyMemAllocatorEx raw;
|
||||
PyMemAllocatorEx obj;
|
||||
} allocators;
|
||||
#define allocators _PyRuntime.tracemalloc.allocators
|
||||
|
||||
|
||||
#if defined(TRACE_RAW_MALLOC)
|
||||
/* This lock is needed because tracemalloc_free() is called without
|
||||
the GIL held from PyMem_RawFree(). It cannot acquire the lock because it
|
||||
would introduce a deadlock in _PyThreadState_DeleteCurrent(). */
|
||||
static PyThread_type_lock tables_lock;
|
||||
# define tables_lock _PyRuntime.tracemalloc.tables_lock
|
||||
# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1)
|
||||
# define TABLES_UNLOCK() PyThread_release_lock(tables_lock)
|
||||
#else
|
||||
|
@ -59,33 +51,8 @@ static PyThread_type_lock tables_lock;
|
|||
|
||||
#define DEFAULT_DOMAIN 0
|
||||
|
||||
/* Pack the frame_t structure to reduce the memory footprint on 64-bit
|
||||
architectures: 12 bytes instead of 16. */
|
||||
typedef struct
|
||||
#ifdef __GNUC__
|
||||
__attribute__((packed))
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma pack(push, 4)
|
||||
#endif
|
||||
{
|
||||
/* filename cannot be NULL: "<unknown>" is used if the Python frame
|
||||
filename is NULL */
|
||||
PyObject *filename;
|
||||
unsigned int lineno;
|
||||
} frame_t;
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
Py_uhash_t hash;
|
||||
/* Number of frames stored */
|
||||
uint16_t nframe;
|
||||
/* Total number of frames the traceback had */
|
||||
uint16_t total_nframe;
|
||||
frame_t frames[1];
|
||||
} traceback_t;
|
||||
typedef struct tracemalloc_frame frame_t;
|
||||
typedef struct tracemalloc_traceback traceback_t;
|
||||
|
||||
#define TRACEBACK_SIZE(NFRAME) \
|
||||
(sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1))
|
||||
|
@ -96,7 +63,8 @@ typedef struct {
|
|||
static const unsigned long MAX_NFRAME = Py_MIN(UINT16_MAX, ((SIZE_MAX - sizeof(traceback_t)) / sizeof(frame_t) + 1));
|
||||
|
||||
|
||||
static traceback_t tracemalloc_empty_traceback;
|
||||
#define tracemalloc_empty_traceback _PyRuntime.tracemalloc.empty_traceback
|
||||
|
||||
|
||||
/* Trace of a memory block */
|
||||
typedef struct {
|
||||
|
@ -108,35 +76,13 @@ typedef struct {
|
|||
} trace_t;
|
||||
|
||||
|
||||
/* Size in bytes of currently traced memory.
|
||||
Protected by TABLES_LOCK(). */
|
||||
static size_t tracemalloc_traced_memory = 0;
|
||||
|
||||
/* Peak size in bytes of traced memory.
|
||||
Protected by TABLES_LOCK(). */
|
||||
static size_t tracemalloc_peak_traced_memory = 0;
|
||||
|
||||
/* Hash table used as a set to intern filenames:
|
||||
PyObject* => PyObject*.
|
||||
Protected by the GIL */
|
||||
static _Py_hashtable_t *tracemalloc_filenames = NULL;
|
||||
|
||||
/* Buffer to store a new traceback in traceback_new().
|
||||
Protected by the GIL. */
|
||||
static traceback_t *tracemalloc_traceback = NULL;
|
||||
|
||||
/* Hash table used as a set to intern tracebacks:
|
||||
traceback_t* => traceback_t*
|
||||
Protected by the GIL */
|
||||
static _Py_hashtable_t *tracemalloc_tracebacks = NULL;
|
||||
|
||||
/* pointer (void*) => trace (trace_t*).
|
||||
Protected by TABLES_LOCK(). */
|
||||
static _Py_hashtable_t *tracemalloc_traces = NULL;
|
||||
|
||||
/* domain (unsigned int) => traces (_Py_hashtable_t).
|
||||
Protected by TABLES_LOCK(). */
|
||||
static _Py_hashtable_t *tracemalloc_domains = NULL;
|
||||
#define tracemalloc_traced_memory _PyRuntime.tracemalloc.traced_memory
|
||||
#define tracemalloc_peak_traced_memory _PyRuntime.tracemalloc.peak_traced_memory
|
||||
#define tracemalloc_filenames _PyRuntime.tracemalloc.filenames
|
||||
#define tracemalloc_traceback _PyRuntime.tracemalloc.traceback
|
||||
#define tracemalloc_tracebacks _PyRuntime.tracemalloc.tracebacks
|
||||
#define tracemalloc_traces _PyRuntime.tracemalloc.traces
|
||||
#define tracemalloc_domains _PyRuntime.tracemalloc.domains
|
||||
|
||||
|
||||
#ifdef TRACE_DEBUG
|
||||
|
@ -157,7 +103,7 @@ tracemalloc_error(const char *format, ...)
|
|||
#if defined(TRACE_RAW_MALLOC)
|
||||
#define REENTRANT_THREADLOCAL
|
||||
|
||||
static Py_tss_t tracemalloc_reentrant_key = Py_tss_NEEDS_INIT;
|
||||
#define tracemalloc_reentrant_key _PyRuntime.tracemalloc.reentrant_key
|
||||
|
||||
/* Any non-NULL pointer can be used */
|
||||
#define REENTRANT Py_True
|
||||
|
|
|
@ -259,6 +259,7 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_time.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_token.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_traceback.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_tracemalloc.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_tuple.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_typeobject.h" />
|
||||
<ClInclude Include="..\Include\internal\pycore_ucnhash.h" />
|
||||
|
|
|
@ -678,6 +678,9 @@
|
|||
<ClInclude Include="..\Include\internal\pycore_traceback.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_tracemalloc.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\internal\pycore_tuple.h">
|
||||
<Filter>Include\internal</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -377,17 +377,6 @@ Modules/faulthandler.c - old_stack -
|
|||
##-----------------------
|
||||
## state
|
||||
|
||||
Modules/_tracemalloc.c - allocators -
|
||||
Modules/_tracemalloc.c - tables_lock -
|
||||
Modules/_tracemalloc.c - tracemalloc_empty_traceback -
|
||||
Modules/_tracemalloc.c - tracemalloc_traced_memory -
|
||||
Modules/_tracemalloc.c - tracemalloc_peak_traced_memory -
|
||||
Modules/_tracemalloc.c - tracemalloc_filenames -
|
||||
Modules/_tracemalloc.c - tracemalloc_traceback -
|
||||
Modules/_tracemalloc.c - tracemalloc_tracebacks -
|
||||
Modules/_tracemalloc.c - tracemalloc_traces -
|
||||
Modules/_tracemalloc.c - tracemalloc_domains -
|
||||
Modules/_tracemalloc.c - tracemalloc_reentrant_key -
|
||||
Modules/faulthandler.c faulthandler_dump_traceback reentrant -
|
||||
Modules/signalmodule.c - is_tripped -
|
||||
Modules/signalmodule.c - signal_global_state -
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
Loading…
Reference in New Issue