summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2022-11-15 16:45:11 (GMT)
committerGitHub <noreply@github.com>2022-11-15 16:45:11 (GMT)
commit3c57971a2d3b6d2c6fd1f525ba2108fccb35add2 (patch)
tree697c28707c62e43c9a444af3069304b8fad2e54b
parent73943cbc4c5e97f71b76150c549d07e8ed00066b (diff)
downloadcpython-3c57971a2d3b6d2c6fd1f525ba2108fccb35add2.zip
cpython-3c57971a2d3b6d2c6fd1f525ba2108fccb35add2.tar.gz
cpython-3c57971a2d3b6d2c6fd1f525ba2108fccb35add2.tar.bz2
gh-81057: Move Globals in Core Code to _PyRuntimeState (gh-99496)
This is the first of several changes to consolidate non-object globals in core code. https://github.com/python/cpython/issues/81057
-rw-r--r--Include/internal/pycore_dtoa.h43
-rw-r--r--Include/internal/pycore_interp.h1
-rw-r--r--Include/internal/pycore_pylifecycle.h1
-rw-r--r--Include/internal/pycore_pymem.h2
-rw-r--r--Include/internal/pycore_runtime.h8
-rw-r--r--Include/internal/pycore_runtime_init.h4
-rw-r--r--Modules/_tracemalloc.c50
-rw-r--r--Modules/getbuildinfo.c12
-rw-r--r--Objects/object.c2
-rw-r--r--Objects/obmalloc.c6
-rw-r--r--Parser/action_helpers.c1
-rw-r--r--Python/dtoa.c35
-rw-r--r--Python/getargs.c11
-rw-r--r--Python/getversion.c17
-rw-r--r--Python/pylifecycle.c2
-rw-r--r--Tools/c-analyzer/cpython/globals-to-fix.tsv100
-rw-r--r--Tools/c-analyzer/cpython/ignored.tsv109
17 files changed, 236 insertions, 168 deletions
diff --git a/Include/internal/pycore_dtoa.h b/Include/internal/pycore_dtoa.h
index c77cf6e..fdc6e74 100644
--- a/Include/internal/pycore_dtoa.h
+++ b/Include/internal/pycore_dtoa.h
@@ -1,3 +1,5 @@
+#ifndef Py_INTERNAL_DTOA_H
+#define Py_INTERNAL_DTOA_H
#ifdef __cplusplus
extern "C" {
#endif
@@ -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. */
@@ -26,3 +68,4 @@ PyAPI_FUNC(double) _Py_dg_infinity(int sign);
#ifdef __cplusplus
}
#endif
+#endif /* !Py_INTERNAL_DTOA_H */
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 7c998ac..a13bc32 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -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. */
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 85bf166..359b809 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -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);
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index b042a4c..5749af7 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -113,8 +113,6 @@ struct _PyTraceMalloc_Config {
.tracing = 0, \
.max_nframe = 1}
-PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config;
-
#ifdef __cplusplus
}
#endif
diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h
index 6bcb35b..8b2b9d7 100644
--- a/Include/internal/pycore_runtime.h
+++ b/Include/internal/pycore_runtime.h
@@ -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
@@ -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 */
@@ -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;
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index 62d5063..6bdee36 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -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, \
}, \
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
index fe73d63..0d70f0c 100644
--- a/Modules/_tracemalloc.c
+++ b/Modules/_tracemalloc.c
@@ -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() */
@@ -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++;
@@ -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) {
@@ -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) {
@@ -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);
@@ -919,7 +921,7 @@ 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;
}
@@ -927,9 +929,9 @@ tracemalloc_init(void)
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();
@@ -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);
@@ -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;
}
@@ -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
@@ -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);
}
@@ -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);
@@ -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
@@ -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;
@@ -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;
@@ -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);
}
@@ -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();
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
diff --git a/Modules/getbuildinfo.c b/Modules/getbuildinfo.c
index 7cb7397..a24750b 100644
--- a/Modules/getbuildinfo.c
+++ b/Modules/getbuildinfo.c
@@ -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();
diff --git a/Objects/object.c b/Objects/object.c
index 01eede9..a499cb3 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 481cbde..4c08bc2 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -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)
diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c
index d1be679..27c0933 100644
--- a/Parser/action_helpers.c
+++ b/Parser/action_helpers.c
@@ -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) {
diff --git a/Python/dtoa.c b/Python/dtoa.c
index 733e70b..1b47d83 100644
--- a/Python/dtoa.c
+++ b/Python/dtoa.c
@@ -119,6 +119,7 @@
#include "Python.h"
#include "pycore_dtoa.h" // _PY_SHORT_FLOAT_REPR
+#include "pycore_runtime.h" // _PyRuntime
#include <stdlib.h> // exit()
/* if _PY_SHORT_FLOAT_REPR == 0, then don't even try to compile
@@ -156,7 +157,7 @@
#endif
-typedef uint32_t ULong;
+// ULong is defined in pycore_dtoa.h.
typedef int32_t Long;
typedef uint64_t ULLong;
@@ -171,12 +172,6 @@ typedef uint64_t ULLong;
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
#endif
-#ifndef PRIVATE_MEM
-#define PRIVATE_MEM 2304
-#endif
-#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
-static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -298,8 +293,6 @@ BCinfo {
#define FFFFFFFF 0xffffffffUL
-#define Kmax 7
-
/* struct Bigint is used to represent arbitrary-precision integers. These
integers are stored in sign-magnitude format, with the magnitude stored as
an array of base 2**32 digits. Bigints are always normalized: if x is a
@@ -322,13 +315,7 @@ BCinfo {
significant (x[0]) to most significant (x[wds-1]).
*/
-struct
-Bigint {
- struct Bigint *next;
- int k, maxwds, sign, wds;
- ULong x[1];
-};
-
+// struct Bigint is defined in pycore_dtoa.h.
typedef struct Bigint Bigint;
#ifndef Py_USING_MEMORY_DEBUGGER
@@ -352,7 +339,9 @@ typedef struct Bigint Bigint;
Bfree to PyMem_Free. Investigate whether this has any significant
performance on impact. */
-static Bigint *freelist[Kmax+1];
+#define freelist _PyRuntime.dtoa.freelist
+#define private_mem _PyRuntime.dtoa.preallocated
+#define pmem_next _PyRuntime.dtoa.preallocated_next
/* Allocate space for a Bigint with up to 1<<k digits */
@@ -363,13 +352,15 @@ Balloc(int k)
Bigint *rv;
unsigned int len;
- if (k <= Kmax && (rv = freelist[k]))
+ if (k <= Bigint_Kmax && (rv = freelist[k]))
freelist[k] = rv->next;
else {
x = 1 << k;
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
/sizeof(double);
- if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) {
+ if (k <= Bigint_Kmax &&
+ pmem_next - private_mem + len <= (Py_ssize_t)Bigint_PREALLOC_SIZE
+ ) {
rv = (Bigint*)pmem_next;
pmem_next += len;
}
@@ -391,7 +382,7 @@ static void
Bfree(Bigint *v)
{
if (v) {
- if (v->k > Kmax)
+ if (v->k > Bigint_Kmax)
FREE((void*)v);
else {
v->next = freelist[v->k];
@@ -400,6 +391,10 @@ Bfree(Bigint *v)
}
}
+#undef pmem_next
+#undef private_mem
+#undef freelist
+
#else
/* Alternative versions of Balloc and Bfree that use PyMem_Malloc and
diff --git a/Python/getargs.c b/Python/getargs.c
index 7034622..748209d 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -1846,9 +1846,6 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
}
-/* List of static parsers. */
-static struct _PyArg_Parser *static_arg_parsers = NULL;
-
static int
scan_keywords(const char * const *keywords, int *ptotal, int *pposonly)
{
@@ -2024,8 +2021,8 @@ _parser_init(struct _PyArg_Parser *parser)
parser->initialized = owned ? 1 : -1;
assert(parser->next == NULL);
- parser->next = static_arg_parsers;
- static_arg_parsers = parser;
+ parser->next = _PyRuntime.getargs.static_parsers;
+ _PyRuntime.getargs.static_parsers = parser;
return 1;
}
@@ -2930,14 +2927,14 @@ _PyArg_NoKwnames(const char *funcname, PyObject *kwnames)
void
_PyArg_Fini(void)
{
- struct _PyArg_Parser *tmp, *s = static_arg_parsers;
+ struct _PyArg_Parser *tmp, *s = _PyRuntime.getargs.static_parsers;
while (s) {
tmp = s->next;
s->next = NULL;
parser_clear(s);
s = tmp;
}
- static_arg_parsers = NULL;
+ _PyRuntime.getargs.static_parsers = NULL;
}
#ifdef __cplusplus
diff --git a/Python/getversion.c b/Python/getversion.c
index 4691045..5db836a 100644
--- a/Python/getversion.c
+++ b/Python/getversion.c
@@ -5,12 +5,23 @@
#include "patchlevel.h"
-const char *
-Py_GetVersion(void)
+static int initialized = 0;
+static char version[250];
+
+void _Py_InitVersion(void)
{
- static char version[250];
+ if (initialized) {
+ return;
+ }
+ initialized = 1;
PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s",
PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler());
+}
+
+const char *
+Py_GetVersion(void)
+{
+ _Py_InitVersion();
return version;
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 44f8442..7ca284e 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -600,6 +600,8 @@ pycore_init_runtime(_PyRuntimeState *runtime,
*/
_PyRuntimeState_SetFinalizing(runtime, NULL);
+ _Py_InitVersion();
+
status = _Py_HashRandomization_Init(config);
if (_PyStatus_EXCEPTION(status)) {
return status;
diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv
index b60f16d..b4ac912 100644
--- a/Tools/c-analyzer/cpython/globals-to-fix.tsv
+++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv
@@ -311,110 +311,22 @@ Python/hamt.c - _empty_hamt -
# global non-objects to fix in core code
#-----------------------
-# initialized/set once
+# effectively-const but initialized lazily
-# pre-allocated buffer
-Modules/getbuildinfo.c Py_GetBuildInfo buildinfo -
-
-# during init
-Objects/unicodeobject.c - bloom_linebreak -
-Python/bootstrap_hash.c - _Py_HashSecret_Initialized -
-Python/bootstrap_hash.c py_getrandom getrandom_works -
-Python/initconfig.c - _Py_global_config_int_max_str_digits -
-Python/initconfig.c - Py_DebugFlag -
-Python/initconfig.c - Py_UTF8Mode -
-Python/initconfig.c - Py_DebugFlag -
-Python/initconfig.c - Py_VerboseFlag -
-Python/initconfig.c - Py_QuietFlag -
-Python/initconfig.c - Py_InteractiveFlag -
-Python/initconfig.c - Py_InspectFlag -
-Python/initconfig.c - Py_OptimizeFlag -
-Python/initconfig.c - Py_NoSiteFlag -
-Python/initconfig.c - Py_BytesWarningFlag -
-Python/initconfig.c - Py_FrozenFlag -
-Python/initconfig.c - Py_IgnoreEnvironmentFlag -
-Python/initconfig.c - Py_DontWriteBytecodeFlag -
-Python/initconfig.c - Py_NoUserSiteDirectory -
-Python/initconfig.c - Py_UnbufferedStdioFlag -
-Python/initconfig.c - Py_HashRandomizationFlag -
-Python/initconfig.c - Py_IsolatedFlag -
-Python/initconfig.c - Py_LegacyWindowsFSEncodingFlag -
-Python/initconfig.c - Py_LegacyWindowsStdioFlag -
-Python/initconfig.c - orig_argv -
-Python/pyhash.c - _Py_HashSecret -
-Python/pylifecycle.c - runtime_initialized -
-Python/sysmodule.c - _PySys_ImplCacheTag -
-Python/sysmodule.c - _PySys_ImplName -
-Python/sysmodule.c - _preinit_warnoptions -
-Python/sysmodule.c - _preinit_xoptions -
-Python/thread.c - initialized -
-Python/thread_pthread.h - condattr_monotonic -
-Python/thread_pthread.h init_condattr ca -
-
-# set by embedders during init
-Python/initconfig.c - _Py_StandardStreamEncoding -
-Python/initconfig.c - _Py_StandardStreamErrors -
-
-# lazy
-Objects/floatobject.c - double_format -
-Objects/floatobject.c - float_format -
-Objects/longobject.c long_from_non_binary_base log_base_BASE -
-Objects/longobject.c long_from_non_binary_base convwidth_base -
-Objects/longobject.c long_from_non_binary_base convmultmax_base -
-Python/perf_trampoline.c - perf_map_file -
-Objects/unicodeobject.c - ucnhash_capi -
-Parser/action_helpers.c _PyPegen_dummy_name cache -
+# idempotent
Python/dtoa.c - p5s -
-Python/fileutils.c - _Py_open_cloexec_works -
-Python/fileutils.c - force_ascii -
-Python/fileutils.c set_inheritable ioctl_works -
+Objects/obmalloc.c new_arena debug_stats -
-#-----------------------
-# unlikely to change after init (or main thread)
-
-# through C-API
-Python/frozen.c - PyImport_FrozenModules -
-Python/frozen.c - _PyImport_FrozenAliases -
-Python/frozen.c - _PyImport_FrozenBootstrap -
-Python/frozen.c - _PyImport_FrozenStdlib -
-Python/frozen.c - _PyImport_FrozenTest -
-Python/preconfig.c - Py_FileSystemDefaultEncoding -
-Python/preconfig.c - Py_HasFileSystemDefaultEncoding -
-Python/preconfig.c - Py_FileSystemDefaultEncodeErrors -
-Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors -
-
-# REPL
-Parser/myreadline.c - _PyOS_ReadlineLock -
-Parser/myreadline.c - _PyOS_ReadlineTState -
-Parser/myreadline.c - PyOS_InputHook -
-Parser/myreadline.c - PyOS_ReadlineFunctionPointer -
-
-# handling C argv
-Python/getopt.c - _PyOS_optarg -
-Python/getopt.c - _PyOS_opterr -
-Python/getopt.c - _PyOS_optind -
-Python/getopt.c - opt_ptr -
-Python/pathconfig.c - _Py_path_config -
+# others
+Python/perf_trampoline.c - perf_map_file -
+Objects/unicodeobject.c - ucnhash_capi -
#-----------------------
# state
-# object allocator
-Objects/obmalloc.c - _Py_tracemalloc_config -
-Objects/obmalloc.c new_arena debug_stats -
-
-# pre-allocated memory
-Python/dtoa.c - freelist -
-Python/dtoa.c - private_mem -
-
# local buffer
-Python/getversion.c Py_GetVersion version -
Python/suggestions.c levenshtein_distance buffer -
-# linked list
-Python/dtoa.c - pmem_next -
-Python/getargs.c - static_arg_parsers -
-
# other
Objects/dictobject.c - _pydict_global_version -
Objects/dictobject.c - next_dict_keys_version -
diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv
index 414e68d..0a6f3ec 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -4,22 +4,111 @@ filename funcname name reason
##################################
# mutable but known to be safe
-Python/import.c - inittab_copy -
-Python/import.c - PyImport_Inittab -
Python/pylifecycle.c - _PyRuntime -
# All uses of _PyArg_Parser are handled in c-analyzr/cpython/_analyzer.py.
#-----------------------
-# others
+# legacy config flags
+
+Python/initconfig.c - Py_UTF8Mode -
+Python/initconfig.c - Py_DebugFlag -
+Python/initconfig.c - Py_VerboseFlag -
+Python/initconfig.c - Py_QuietFlag -
+Python/initconfig.c - Py_InteractiveFlag -
+Python/initconfig.c - Py_InspectFlag -
+Python/initconfig.c - Py_OptimizeFlag -
+Python/initconfig.c - Py_NoSiteFlag -
+Python/initconfig.c - Py_BytesWarningFlag -
+Python/initconfig.c - Py_FrozenFlag -
+Python/initconfig.c - Py_IgnoreEnvironmentFlag -
+Python/initconfig.c - Py_DontWriteBytecodeFlag -
+Python/initconfig.c - Py_NoUserSiteDirectory -
+Python/initconfig.c - Py_UnbufferedStdioFlag -
+Python/initconfig.c - Py_HashRandomizationFlag -
+Python/initconfig.c - Py_IsolatedFlag -
+Python/initconfig.c - Py_LegacyWindowsFSEncodingFlag -
+Python/initconfig.c - Py_LegacyWindowsStdioFlag -
+
+#-----------------------
+# effectively const, initialized before init
+
+Python/frozen.c - PyImport_FrozenModules -
+Python/import.c - inittab_copy -
+Python/import.c - PyImport_Inittab -
+
+#-----------------------
+# effectively const, initialized before/during init
+
+Modules/getbuildinfo.c - buildinfo -
+Modules/getbuildinfo.c - initialized -
+Python/getversion.c - initialized -
+Python/getversion.c - version -
+
+#-----------------------
+# effectively const, initialized during init
+
+Objects/floatobject.c - double_format -
+Objects/floatobject.c - float_format -
+Objects/unicodeobject.c - bloom_linebreak -
+Python/bootstrap_hash.c py_getrandom getrandom_works -
+Python/bootstrap_hash.c - _Py_HashSecret_Initialized -
+Python/fileutils.c - _Py_open_cloexec_works -
+Python/fileutils.c - force_ascii -
+Python/fileutils.c set_inheritable ioctl_works -
+Python/import.c import_find_and_load header -
+Python/initconfig.c - orig_argv -
+Python/preconfig.c - Py_FileSystemDefaultEncoding -
+Python/preconfig.c - Py_HasFileSystemDefaultEncoding -
+Python/preconfig.c - Py_FileSystemDefaultEncodeErrors -
+Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors -
+Python/pyhash.c - _Py_HashSecret -
+Python/pylifecycle.c - runtime_initialized -
+Python/sysmodule.c - _preinit_warnoptions -
+Python/sysmodule.c - _preinit_xoptions -
+Python/thread.c - initialized -
+Python/thread_pthread.h - condattr_monotonic -
+Python/thread_pthread.h init_condattr ca -
+
+# set by embedders during init
+Python/initconfig.c - _Py_StandardStreamEncoding -
+Python/initconfig.c - _Py_StandardStreamErrors -
+
+#-----------------------
+# effectively const but initialized lazily
+# XXX Move them to _PyRuntimeState?
+
+# idempotent
+Objects/longobject.c long_from_non_binary_base log_base_BASE -
+Objects/longobject.c long_from_non_binary_base convwidth_base -
+Objects/longobject.c long_from_non_binary_base convmultmax_base -
+Parser/action_helpers.c _PyPegen_dummy_name cache -
+
+#-----------------------
+# used only in the main thread
+
+# REPL
+Parser/myreadline.c - _PyOS_ReadlineLock -
+Parser/myreadline.c - _PyOS_ReadlineTState -
+Parser/myreadline.c - PyOS_InputHook -
+Parser/myreadline.c - PyOS_ReadlineFunctionPointer -
+
+# handling C argv
+Python/getopt.c - _PyOS_optarg -
+Python/getopt.c - _PyOS_opterr -
+Python/getopt.c - _PyOS_optind -
+Python/getopt.c - opt_ptr -
+Python/pathconfig.c - _Py_path_config -
+
+
+##################################
+# The analyzer should have ignored these.
+# XXX Fix the analyzer.
-# XXX The analyzer should have ignored these.
Modules/_io/_iomodule.c - _PyIO_Module -
Modules/_sqlite/module.c - _sqlite3module -
-##################################
# forward/extern references
-# XXX The analyzer should have ignored these.
Include/py_curses.h - PyCurses_API -
Include/pydecimal.h - _decimal_api -
@@ -474,7 +563,6 @@ Objects/obmalloc.c - _PyMem_Debug -
Objects/obmalloc.c - _PyMem_Raw -
Objects/obmalloc.c - _PyObject -
Objects/obmalloc.c - usedpools -
-Python/perf_trampoline.c - _Py_perfmap_callbacks -
Objects/typeobject.c - name_op -
Objects/typeobject.c - slotdefs -
Objects/unicodeobject.c - stripfuncnames -
@@ -499,10 +587,15 @@ Python/frozen.c - aliases -
Python/frozen.c - bootstrap_modules -
Python/frozen.c - stdlib_modules -
Python/frozen.c - test_modules -
+Python/frozen.c - _PyImport_FrozenAliases -
+Python/frozen.c - _PyImport_FrozenBootstrap -
+Python/frozen.c - _PyImport_FrozenStdlib -
+Python/frozen.c - _PyImport_FrozenTest -
Python/getopt.c - longopts -
Python/import.c - _PyImport_Inittab -
Python/import.c - _PySys_ImplCacheTag -
Python/opcode_targets.h - opcode_targets -
+Python/perf_trampoline.c - _Py_perfmap_callbacks -
Python/pyhash.c - PyHash_Func -
Python/pylifecycle.c - _C_LOCALE_WARNING -
Python/pylifecycle.c - _PyOS_mystrnicmp_hack -
@@ -512,4 +605,6 @@ Python/specialize.c - adaptive_opcodes -
Python/specialize.c - cache_requirements -
Python/specialize.c - compare_masks -
Python/stdlib_module_names.h - _Py_stdlib_module_names -
+Python/sysmodule.c - _PySys_ImplCacheTag -
+Python/sysmodule.c - _PySys_ImplName -
Python/sysmodule.c - whatstrings -