gh-81057: Move More Globals to _PyRuntimeState (gh-100092)

https://github.com/python/cpython/issues/81057
This commit is contained in:
Eric Snow 2022-12-07 15:56:31 -07:00 committed by GitHub
parent d47ffeb9e3
commit 91a8e002c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 66 additions and 56 deletions

View File

@ -25,7 +25,7 @@ Bigint {
#ifdef Py_USING_MEMORY_DEBUGGER #ifdef Py_USING_MEMORY_DEBUGGER
struct _dtoa_runtime_state { struct _dtoa_runtime_state {
int _not_used; int _not_used;
}; };
#define _dtoa_runtime_state_INIT {0} #define _dtoa_runtime_state_INIT {0}
@ -41,9 +41,12 @@ struct _dtoa_runtime_state {
((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
struct _dtoa_runtime_state { struct _dtoa_runtime_state {
struct Bigint *freelist[Bigint_Kmax+1]; /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
double preallocated[Bigint_PREALLOC_SIZE]; // XXX This should be freed during runtime fini.
double *preallocated_next; struct Bigint *p5s;
struct Bigint *freelist[Bigint_Kmax+1];
double preallocated[Bigint_PREALLOC_SIZE];
double *preallocated_next;
}; };
#define _dtoa_runtime_state_INIT(runtime) \ #define _dtoa_runtime_state_INIT(runtime) \
{ \ { \

View File

@ -658,6 +658,7 @@ struct _obmalloc_usage {
struct _obmalloc_state { struct _obmalloc_state {
int dump_debug_stats;
struct _obmalloc_pools pools; struct _obmalloc_pools pools;
struct _obmalloc_mgmt mgmt; struct _obmalloc_mgmt mgmt;
struct _obmalloc_usage usage; struct _obmalloc_usage usage;

View File

@ -56,6 +56,7 @@ extern "C" {
#define _obmalloc_state_INIT(obmalloc) \ #define _obmalloc_state_INIT(obmalloc) \
{ \ { \
.dump_debug_stats = -1, \
.pools = { \ .pools = { \
.used = _obmalloc_pools_INIT(obmalloc.pools), \ .used = _obmalloc_pools_INIT(obmalloc.pools), \
}, \ }, \

View File

@ -8,12 +8,31 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define" # error "this header requires Py_BUILD_CORE define"
#endif #endif
#include "pycore_pyarena.h" // PyArena
#ifdef Py_DEBUG
#define _PYPEGEN_NSTATISTICS 2000
#endif
struct _parser_runtime_state {
#ifdef Py_DEBUG
long memo_statistics[_PYPEGEN_NSTATISTICS];
#else
int _not_used;
#endif
};
extern struct _mod* _PyParser_ASTFromString( extern struct _mod* _PyParser_ASTFromString(
const char *str, const char *str,
PyObject* filename, PyObject* filename,
int mode, int mode,
PyCompilerFlags *flags, PyCompilerFlags *flags,
PyArena *arena); PyArena *arena);
extern struct _mod* _PyParser_ASTFromFile( extern struct _mod* _PyParser_ASTFromFile(
FILE *fp, FILE *fp,
PyObject *filename_ob, PyObject *filename_ob,
@ -25,6 +44,7 @@ extern struct _mod* _PyParser_ASTFromFile(
int *errcode, int *errcode,
PyArena *arena); PyArena *arena);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -17,6 +17,7 @@ extern "C" {
#include "pycore_global_objects.h" // struct _Py_global_objects #include "pycore_global_objects.h" // struct _Py_global_objects
#include "pycore_import.h" // struct _import_runtime_state #include "pycore_import.h" // struct _import_runtime_state
#include "pycore_interp.h" // PyInterpreterState #include "pycore_interp.h" // PyInterpreterState
#include "pycore_parser.h" // struct _parser_runtime_state
#include "pycore_pymem.h" // struct _pymem_allocators #include "pycore_pymem.h" // struct _pymem_allocators
#include "pycore_pyhash.h" // struct pyhash_runtime_state #include "pycore_pyhash.h" // struct pyhash_runtime_state
#include "pycore_obmalloc.h" // struct obmalloc_state #include "pycore_obmalloc.h" // struct obmalloc_state
@ -129,6 +130,10 @@ typedef struct pyruntimestate {
unsigned long main_thread; unsigned long main_thread;
PyWideStringList orig_argv;
struct _parser_runtime_state parser;
#define NEXITFUNCS 32 #define NEXITFUNCS 32
void (*exitfuncs[NEXITFUNCS])(void); void (*exitfuncs[NEXITFUNCS])(void);
int nexitfuncs; int nexitfuncs;

View File

@ -9,6 +9,7 @@ extern "C" {
#endif #endif
#include "pycore_fileutils.h" // _Py_error_handler #include "pycore_fileutils.h" // _Py_error_handler
#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI
void _PyUnicode_ExactDealloc(PyObject *op); void _PyUnicode_ExactDealloc(PyObject *op);
@ -52,6 +53,8 @@ struct _Py_unicode_ids {
struct _Py_unicode_state { struct _Py_unicode_state {
struct _Py_unicode_fs_codec fs_codec; struct _Py_unicode_fs_codec fs_codec;
_PyUnicode_Name_CAPI *ucnhash_capi;
// Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId() // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
struct _Py_unicode_ids ids; struct _Py_unicode_ids ids;
}; };

View File

@ -746,26 +746,26 @@ _buffered_init(buffered *self)
int int
_PyIO_trap_eintr(void) _PyIO_trap_eintr(void)
{ {
static PyObject *eintr_int = NULL;
PyObject *typ, *val, *tb; PyObject *typ, *val, *tb;
PyOSErrorObject *env_err; PyOSErrorObject *env_err;
if (eintr_int == NULL) {
eintr_int = PyLong_FromLong(EINTR);
assert(eintr_int != NULL);
}
if (!PyErr_ExceptionMatches(PyExc_OSError)) if (!PyErr_ExceptionMatches(PyExc_OSError))
return 0; return 0;
PyErr_Fetch(&typ, &val, &tb); PyErr_Fetch(&typ, &val, &tb);
PyErr_NormalizeException(&typ, &val, &tb); PyErr_NormalizeException(&typ, &val, &tb);
env_err = (PyOSErrorObject *) val; env_err = (PyOSErrorObject *) val;
assert(env_err != NULL); assert(env_err != NULL);
if (env_err->myerrno != NULL && if (env_err->myerrno != NULL) {
PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) { assert(EINTR > 0 && EINTR < INT_MAX);
Py_DECREF(typ); assert(PyLong_CheckExact(env_err->myerrno));
Py_DECREF(val); int overflow;
Py_XDECREF(tb); int myerrno = PyLong_AsLongAndOverflow(env_err->myerrno, &overflow);
return 1; PyErr_Clear();
if (myerrno == EINTR) {
Py_DECREF(typ);
Py_DECREF(val);
Py_XDECREF(tb);
return 1;
}
} }
/* This silences any error set by PyObject_RichCompareBool() */ /* This silences any error set by PyObject_RichCompareBool() */
PyErr_Restore(typ, val, tb); PyErr_Restore(typ, val, tb);

View File

@ -908,11 +908,12 @@ new_arena(void)
struct arena_object* arenaobj; struct arena_object* arenaobj;
uint excess; /* number of bytes above pool alignment */ uint excess; /* number of bytes above pool alignment */
void *address; void *address;
static int debug_stats = -1;
int debug_stats = _PyRuntime.obmalloc.dump_debug_stats;
if (debug_stats == -1) { if (debug_stats == -1) {
const char *opt = Py_GETENV("PYTHONMALLOCSTATS"); const char *opt = Py_GETENV("PYTHONMALLOCSTATS");
debug_stats = (opt != NULL && *opt != '\0'); debug_stats = (opt != NULL && *opt != '\0');
_PyRuntime.obmalloc.dump_debug_stats = debug_stats;
} }
if (debug_stats) { if (debug_stats) {
_PyObject_DebugMallocStats(stderr); _PyObject_DebugMallocStats(stderr);

View File

@ -5697,8 +5697,6 @@ PyUnicode_AsUTF16String(PyObject *unicode)
/* --- Unicode Escape Codec ----------------------------------------------- */ /* --- Unicode Escape Codec ----------------------------------------------- */
static _PyUnicode_Name_CAPI *ucnhash_capi = NULL;
PyObject * PyObject *
_PyUnicode_DecodeUnicodeEscapeInternal(const char *s, _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
Py_ssize_t size, Py_ssize_t size,
@ -5711,6 +5709,8 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
const char *end; const char *end;
PyObject *errorHandler = NULL; PyObject *errorHandler = NULL;
PyObject *exc = NULL; PyObject *exc = NULL;
_PyUnicode_Name_CAPI *ucnhash_capi;
PyInterpreterState *interp = _PyInterpreterState_Get();
// so we can remember if we've seen an invalid escape char or not // so we can remember if we've seen an invalid escape char or not
*first_invalid_escape = NULL; *first_invalid_escape = NULL;
@ -5858,6 +5858,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
/* \N{name} */ /* \N{name} */
case 'N': case 'N':
ucnhash_capi = interp->unicode.ucnhash_capi;
if (ucnhash_capi == NULL) { if (ucnhash_capi == NULL) {
/* load the unicode data module */ /* load the unicode data module */
ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
@ -5869,6 +5870,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
); );
goto onError; goto onError;
} }
interp->unicode.ucnhash_capi = ucnhash_capi;
} }
message = "malformed \\N character escape"; message = "malformed \\N character escape";
@ -15128,10 +15130,10 @@ _PyUnicode_Fini(PyInterpreterState *interp)
assert(get_interned_dict() == NULL); assert(get_interned_dict() == NULL);
// bpo-47182: force a unicodedata CAPI capsule re-import on // bpo-47182: force a unicodedata CAPI capsule re-import on
// subsequent initialization of main interpreter. // subsequent initialization of main interpreter.
ucnhash_capi = NULL;
} }
_PyUnicode_FiniEncodings(&state->fs_codec); _PyUnicode_FiniEncodings(&state->fs_codec);
interp->unicode.ucnhash_capi = NULL;
unicode_clear_identifiers(state); unicode_clear_identifiers(state);
} }

View File

@ -246,8 +246,8 @@ _PyPegen_fill_token(Parser *p)
// The array counts the number of tokens skipped by memoization, // The array counts the number of tokens skipped by memoization,
// indexed by type. // indexed by type.
#define NSTATISTICS 2000 #define NSTATISTICS _PYPEGEN_NSTATISTICS
static long memo_statistics[NSTATISTICS]; #define memo_statistics _PyRuntime.parser.memo_statistics
void void
_PyPegen_clear_memo_statistics() _PyPegen_clear_memo_statistics()

View File

@ -673,10 +673,6 @@ mult(Bigint *a, Bigint *b)
#ifndef Py_USING_MEMORY_DEBUGGER #ifndef Py_USING_MEMORY_DEBUGGER
/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
static Bigint *p5s;
/* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on /* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on
failure; if the returned pointer is distinct from b then the original failure; if the returned pointer is distinct from b then the original
Bigint b will have been Bfree'd. Ignores the sign of b. */ Bigint b will have been Bfree'd. Ignores the sign of b. */
@ -696,7 +692,7 @@ pow5mult(Bigint *b, int k)
if (!(k >>= 2)) if (!(k >>= 2))
return b; return b;
p5 = p5s; p5 = _PyRuntime.dtoa.p5s;
if (!p5) { if (!p5) {
/* first time */ /* first time */
p5 = i2b(625); p5 = i2b(625);
@ -704,7 +700,7 @@ pow5mult(Bigint *b, int k)
Bfree(b); Bfree(b);
return NULL; return NULL;
} }
p5s = p5; _PyRuntime.dtoa.p5s = p5;
p5->next = 0; p5->next = 0;
} }
for(;;) { for(;;) {

View File

@ -595,17 +595,13 @@ _Py_ClearStandardStreamEncoding(void)
/* --- Py_GetArgcArgv() ------------------------------------------- */ /* --- Py_GetArgcArgv() ------------------------------------------- */
/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */
static PyWideStringList orig_argv = {.length = 0, .items = NULL};
void void
_Py_ClearArgcArgv(void) _Py_ClearArgcArgv(void)
{ {
PyMemAllocatorEx old_alloc; PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
_PyWideStringList_Clear(&orig_argv); _PyWideStringList_Clear(&_PyRuntime.orig_argv);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
} }
@ -620,7 +616,9 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
PyMemAllocatorEx old_alloc; PyMemAllocatorEx old_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
res = _PyWideStringList_Copy(&orig_argv, &argv_list); // XXX _PyRuntime.orig_argv only gets cleared by Py_Main(),
// so it it currently leaks for embedders.
res = _PyWideStringList_Copy(&_PyRuntime.orig_argv, &argv_list);
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
return res; return res;
@ -631,8 +629,8 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
void void
Py_GetArgcArgv(int *argc, wchar_t ***argv) Py_GetArgcArgv(int *argc, wchar_t ***argv)
{ {
*argc = (int)orig_argv.length; *argc = (int)_PyRuntime.orig_argv.length;
*argv = orig_argv.items; *argv = _PyRuntime.orig_argv.items;
} }

View File

@ -305,20 +305,12 @@ Objects/sliceobject.c - _Py_EllipsisObject -
##----------------------- ##-----------------------
## effectively-const but initialized lazily ## effectively-const but initialized lazily
## idempotent
Python/dtoa.c - p5s -
Objects/obmalloc.c new_arena debug_stats -
## others ## others
Python/perf_trampoline.c - perf_map_file - Python/perf_trampoline.c - perf_map_file -
Objects/unicodeobject.c - ucnhash_capi -
##----------------------- ##-----------------------
## state ## state
## local buffer
Python/suggestions.c levenshtein_distance buffer -
## other ## other
Objects/object.c - _Py_RefTotal - Objects/object.c - _Py_RefTotal -
Python/perf_trampoline.c - perf_status - Python/perf_trampoline.c - perf_status -
@ -398,7 +390,6 @@ Modules/faulthandler.c - old_stack -
##----------------------- ##-----------------------
## initialized once ## initialized once
Modules/_io/bufferedio.c _PyIO_trap_eintr eintr_int -
Modules/posixmodule.c os_dup2_impl dup3_works - Modules/posixmodule.c os_dup2_impl dup3_works -
Modules/posixmodule.c - structseq_new - Modules/posixmodule.c - structseq_new -
Modules/posixmodule.c - ticks_per_second - Modules/posixmodule.c - ticks_per_second -

Can't render this file because it has a wrong number of fields in line 4.

View File

@ -87,8 +87,6 @@ Parser/myreadline.c - PyOS_ReadlineFunctionPointer -
Python/initconfig.c - _Py_StandardStreamEncoding - Python/initconfig.c - _Py_StandardStreamEncoding -
Python/initconfig.c - _Py_StandardStreamErrors - Python/initconfig.c - _Py_StandardStreamErrors -
# XXX This only gets cleared by Py_Main().
Python/initconfig.c - orig_argv -
##----------------------- ##-----------------------
## public C-API ## public C-API
@ -143,15 +141,6 @@ Python/pylifecycle.c - runtime_initialized -
Modules/syslogmodule.c - S_ident_o - Modules/syslogmodule.c - S_ident_o -
Modules/syslogmodule.c - S_log_open - Modules/syslogmodule.c - S_log_open -
##-----------------------
## *not* tied to init/fini cycle
# These do not ge reset with each init/fini cycle.
# XXX These should probably be tied to init/fini. Move to _PyRuntimeState?
# special-use diagnistic state
Parser/pegen.c - memo_statistics -
##----------------------- ##-----------------------
## one-off temporary state ## one-off temporary state

Can't render this file because it has a wrong number of fields in line 4.