mirror of https://github.com/python/cpython
gh-81057: Move More Globals to _PyRuntimeState (gh-100092)
https://github.com/python/cpython/issues/81057
This commit is contained in:
parent
d47ffeb9e3
commit
91a8e002c2
|
@ -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) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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), \
|
||||||
}, \
|
}, \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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(;;) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
|
@ -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.
|
Loading…
Reference in New Issue