Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-81057: Move Globals in Core Code to _PyRuntimeState #99496

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Include/internal/pycore_dtoa.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#ifndef Py_INTERNAL_DTOA_H
#define Py_INTERNAL_DTOA_H
#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -11,6 +13,46 @@ extern "C" {

#if _PY_SHORT_FLOAT_REPR == 1

typedef uint32_t ULong;

struct
Bigint {
struct Bigint *next;
int k, maxwds, sign, wds;
ULong x[1];
};

#ifdef Py_USING_MEMORY_DEBUGGER

struct _dtoa_runtime_state {
int _not_used;
};
#define _dtoa_runtime_state_INIT {0}

#else // !Py_USING_MEMORY_DEBUGGER

/* The size of the Bigint freelist */
#define Bigint_Kmax 7

#ifndef PRIVATE_MEM
#define PRIVATE_MEM 2304
#endif
#define Bigint_PREALLOC_SIZE \
((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))

struct _dtoa_runtime_state {
struct Bigint *freelist[Bigint_Kmax+1];
double preallocated[Bigint_PREALLOC_SIZE];
double *preallocated_next;
};
#define _dtoa_runtime_state_INIT(runtime) \
{ \
.preallocated_next = runtime.dtoa.preallocated, \
}

#endif // !Py_USING_MEMORY_DEBUGGER


/* These functions are used by modules compiled as C extension like math:
they must be exported. */

Expand All @@ -26,3 +68,4 @@ PyAPI_FUNC(double) _Py_dg_infinity(int sign);
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_DTOA_H */
1 change: 1 addition & 0 deletions Include/internal/pycore_interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ extern "C" {
#include "pycore_unicodeobject.h" // struct _Py_unicode_state
#include "pycore_warnings.h" // struct _warnings_runtime_state


struct _pending_calls {
PyThread_type_lock lock;
/* Request for running pending calls. */
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);

/* Various one-time initializers */

extern void _Py_InitVersion(void);
extern PyStatus _PyImport_Init(void);
extern PyStatus _PyFaulthandler_Init(int enable);
extern int _PyTraceMalloc_Init(int enable);
Expand Down
2 changes: 0 additions & 2 deletions Include/internal/pycore_pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ struct _PyTraceMalloc_Config {
.tracing = 0, \
.max_nframe = 1}

PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config;

#ifdef __cplusplus
}
#endif
Expand Down
8 changes: 7 additions & 1 deletion Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extern "C" {
#endif

#include "pycore_atomic.h" /* _Py_atomic_address */
#include "pycore_dtoa.h" // struct _dtoa_runtime_state
#include "pycore_gil.h" // struct _gil_runtime_state
#include "pycore_global_objects.h" // struct _Py_global_objects
#include "pycore_import.h" // struct _import_runtime_state
Expand All @@ -18,7 +19,8 @@ extern "C" {
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids

struct _getargs_runtime_state {
PyThread_type_lock mutex;
PyThread_type_lock mutex;
struct _PyArg_Parser *static_parsers;
};

/* ceval state */
Expand Down Expand Up @@ -125,6 +127,10 @@ 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;

PyPreConfig preconfig;

Expand Down
4 changes: 4 additions & 0 deletions Include/internal/pycore_runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ extern "C" {
until _PyInterpreterState_Enable() is called. */ \
.next_id = -1, \
}, \
.tracemalloc = { \
.config = _PyTraceMalloc_Config_INIT, \
}, \
.dtoa = _dtoa_runtime_state_INIT(runtime), \
.types = { \
.next_version_tag = 1, \
}, \
Expand Down
50 changes: 26 additions & 24 deletions Modules/_tracemalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ module _tracemalloc
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/

#define tracemalloc_config _PyRuntime.tracemalloc.config

_Py_DECLARE_STR(anon_unknown, "<unknown>");

/* Trace memory blocks allocated by PyMem_RawMalloc() */
Expand Down Expand Up @@ -407,7 +409,7 @@ traceback_get_frames(traceback_t *traceback)
if (pyframe == NULL) {
break;
}
if (traceback->nframe < _Py_tracemalloc_config.max_nframe) {
if (traceback->nframe < tracemalloc_config.max_nframe) {
tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]);
assert(traceback->frames[traceback->nframe].filename != NULL);
traceback->nframe++;
Expand Down Expand Up @@ -505,7 +507,7 @@ tracemalloc_get_traces_table(unsigned int domain)
static void
tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr)
{
assert(_Py_tracemalloc_config.tracing);
assert(tracemalloc_config.tracing);

_Py_hashtable_t *traces = tracemalloc_get_traces_table(domain);
if (!traces) {
Expand All @@ -529,7 +531,7 @@ static int
tracemalloc_add_trace(unsigned int domain, uintptr_t ptr,
size_t size)
{
assert(_Py_tracemalloc_config.tracing);
assert(tracemalloc_config.tracing);

traceback_t *traceback = traceback_new();
if (traceback == NULL) {
Expand Down Expand Up @@ -863,13 +865,13 @@ tracemalloc_clear_traces(void)
static int
tracemalloc_init(void)
{
if (_Py_tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) {
if (tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) {
PyErr_SetString(PyExc_RuntimeError,
"the tracemalloc module has been unloaded");
return -1;
}

if (_Py_tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED)
if (tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED)
return 0;

PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw);
Expand Down Expand Up @@ -919,17 +921,17 @@ tracemalloc_init(void)
tracemalloc_empty_traceback.frames[0].lineno = 0;
tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback);

_Py_tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED;
tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED;
return 0;
}


static void
tracemalloc_deinit(void)
{
if (_Py_tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED)
if (tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED)
return;
_Py_tracemalloc_config.initialized = TRACEMALLOC_FINALIZED;
tracemalloc_config.initialized = TRACEMALLOC_FINALIZED;

tracemalloc_stop();

Expand Down Expand Up @@ -969,12 +971,12 @@ tracemalloc_start(int max_nframe)
return -1;
}

if (_Py_tracemalloc_config.tracing) {
if (tracemalloc_config.tracing) {
/* hook already installed: do nothing */
return 0;
}

_Py_tracemalloc_config.max_nframe = max_nframe;
tracemalloc_config.max_nframe = max_nframe;

/* allocate a buffer to store a new traceback */
size = TRACEBACK_SIZE(max_nframe);
Expand Down Expand Up @@ -1010,7 +1012,7 @@ tracemalloc_start(int max_nframe)
PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc);

/* everything is ready: start tracing Python memory allocations */
_Py_tracemalloc_config.tracing = 1;
tracemalloc_config.tracing = 1;

return 0;
}
Expand All @@ -1019,11 +1021,11 @@ tracemalloc_start(int max_nframe)
static void
tracemalloc_stop(void)
{
if (!_Py_tracemalloc_config.tracing)
if (!tracemalloc_config.tracing)
return;

/* stop tracing Python memory allocations */
_Py_tracemalloc_config.tracing = 0;
tracemalloc_config.tracing = 0;

/* unregister the hook on memory allocators */
#ifdef TRACE_RAW_MALLOC
Expand Down Expand Up @@ -1051,7 +1053,7 @@ static PyObject *
_tracemalloc_is_tracing_impl(PyObject *module)
/*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/
{
return PyBool_FromLong(_Py_tracemalloc_config.tracing);
return PyBool_FromLong(tracemalloc_config.tracing);
}


Expand All @@ -1065,7 +1067,7 @@ static PyObject *
_tracemalloc_clear_traces_impl(PyObject *module)
/*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/
{
if (!_Py_tracemalloc_config.tracing)
if (!tracemalloc_config.tracing)
Py_RETURN_NONE;

set_reentrant(1);
Expand Down Expand Up @@ -1345,7 +1347,7 @@ _tracemalloc__get_traces_impl(PyObject *module)
if (get_traces.list == NULL)
goto error;

if (!_Py_tracemalloc_config.tracing)
if (!tracemalloc_config.tracing)
return get_traces.list;

/* the traceback hash table is used temporarily to intern traceback tuple
Expand Down Expand Up @@ -1418,7 +1420,7 @@ static traceback_t*
tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr)
{

if (!_Py_tracemalloc_config.tracing)
if (!tracemalloc_config.tracing)
return NULL;

trace_t *trace;
Expand Down Expand Up @@ -1498,7 +1500,7 @@ _PyMem_DumpTraceback(int fd, const void *ptr)
traceback_t *traceback;
int i;

if (!_Py_tracemalloc_config.tracing) {
if (!tracemalloc_config.tracing) {
PUTS(fd, "Enable tracemalloc to get the memory block "
"allocation traceback\n\n");
return;
Expand Down Expand Up @@ -1572,7 +1574,7 @@ static PyObject *
_tracemalloc_get_traceback_limit_impl(PyObject *module)
/*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/
{
return PyLong_FromLong(_Py_tracemalloc_config.max_nframe);
return PyLong_FromLong(tracemalloc_config.max_nframe);
}


Expand Down Expand Up @@ -1630,7 +1632,7 @@ _tracemalloc_get_traced_memory_impl(PyObject *module)
{
Py_ssize_t size, peak_size;

if (!_Py_tracemalloc_config.tracing)
if (!tracemalloc_config.tracing)
return Py_BuildValue("ii", 0, 0);

TABLES_LOCK();
Expand All @@ -1654,7 +1656,7 @@ static PyObject *
_tracemalloc_reset_peak_impl(PyObject *module)
/*[clinic end generated code: output=140c2870f691dbb2 input=18afd0635066e9ce]*/
{
if (!_Py_tracemalloc_config.tracing) {
if (!tracemalloc_config.tracing) {
Py_RETURN_NONE;
}

Expand Down Expand Up @@ -1735,7 +1737,7 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
int res;
PyGILState_STATE gil_state;

if (!_Py_tracemalloc_config.tracing) {
if (!tracemalloc_config.tracing) {
/* tracemalloc is not tracing: do nothing */
return -2;
}
Expand All @@ -1754,7 +1756,7 @@ PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr,
int
PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)
{
if (!_Py_tracemalloc_config.tracing) {
if (!tracemalloc_config.tracing) {
/* tracemalloc is not tracing: do nothing */
return -2;
}
Expand All @@ -1777,7 +1779,7 @@ _PyTraceMalloc_NewReference(PyObject *op)
{
assert(PyGILState_Check());

if (!_Py_tracemalloc_config.tracing) {
if (!tracemalloc_config.tracing) {
/* tracemalloc is not tracing: do nothing */
return -1;
}
Expand Down
12 changes: 9 additions & 3 deletions Modules/getbuildinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@
#define GITBRANCH ""
#endif

static int initialized = 0;
static char buildinfo[50 + sizeof(GITVERSION) +
((sizeof(GITTAG) > sizeof(GITBRANCH)) ?
sizeof(GITTAG) : sizeof(GITBRANCH))];

const char *
Py_GetBuildInfo(void)
{
static char buildinfo[50 + sizeof(GITVERSION) +
((sizeof(GITTAG) > sizeof(GITBRANCH)) ?
sizeof(GITTAG) : sizeof(GITBRANCH))];
if (initialized) {
return buildinfo;
}
initialized = 1;
const char *revision = _Py_gitversion();
const char *sep = *revision ? ":" : "";
const char *gitid = _Py_gitidentifier();
Expand Down
2 changes: 1 addition & 1 deletion Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -2001,7 +2001,7 @@ _PyTypes_FiniTypes(PyInterpreterState *interp)
void
_Py_NewReference(PyObject *op)
{
if (_Py_tracemalloc_config.tracing) {
if (_PyRuntime.tracemalloc.config.tracing) {
_PyTraceMalloc_NewReference(op);
}
#ifdef Py_REF_DEBUG
Expand Down
6 changes: 0 additions & 6 deletions Objects/obmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,6 @@ _PyMem_ArenaFree(void *Py_UNUSED(ctx), void *ptr,
#endif


/* bpo-35053: Declare tracemalloc configuration here rather than
Modules/_tracemalloc.c because _tracemalloc can be compiled as dynamic
library, whereas _Py_NewReference() requires it. */
struct _PyTraceMalloc_Config _Py_tracemalloc_config = _PyTraceMalloc_Config_INIT;


#define _PyMem_Raw (_PyRuntime.allocators.standard.raw)
#define _PyMem (_PyRuntime.allocators.standard.mem)
#define _PyObject (_PyRuntime.allocators.standard.obj)
Expand Down
1 change: 1 addition & 0 deletions Parser/action_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ _create_dummy_identifier(Parser *p)
void *
_PyPegen_dummy_name(Parser *p, ...)
{
// XXX This leaks memory from the initial arena.
static void *cache = NULL;

if (cache != NULL) {
Expand Down
Loading