summaryrefslogtreecommitdiff
path: root/Include
diff options
context:
space:
mode:
Diffstat (limited to 'Include')
-rw-r--r--Include/internal/pycore_bytesobject.h30
-rw-r--r--Include/internal/pycore_context.h29
-rw-r--r--Include/internal/pycore_dict.h26
-rw-r--r--Include/internal/pycore_exceptions.h37
-rw-r--r--Include/internal/pycore_floatobject.h29
-rw-r--r--Include/internal/pycore_frame.h8
-rw-r--r--Include/internal/pycore_genobject.h46
-rw-r--r--Include/internal/pycore_hamt.h11
-rw-r--r--Include/internal/pycore_interp.h183
-rw-r--r--Include/internal/pycore_list.h24
-rw-r--r--Include/internal/pycore_long.h16
-rw-r--r--Include/internal/pycore_long_state.h33
-rw-r--r--Include/internal/pycore_pyerrors.h8
-rw-r--r--Include/internal/pycore_pylifecycle.h28
-rw-r--r--Include/internal/pycore_runtime.h24
-rw-r--r--Include/internal/pycore_sliceobject.h20
-rw-r--r--Include/internal/pycore_structseq.h7
-rw-r--r--Include/internal/pycore_tuple.h37
-rw-r--r--Include/internal/pycore_typeobject.h47
-rw-r--r--Include/internal/pycore_unicodeobject.h71
20 files changed, 483 insertions, 231 deletions
diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h
new file mode 100644
index 0000000000..b00ed9784e
--- /dev/null
+++ b/Include/internal/pycore_bytesobject.h
@@ -0,0 +1,30 @@
+#ifndef Py_INTERNAL_BYTESOBJECT_H
+#define Py_INTERNAL_BYTESOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern PyStatus _PyBytes_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyBytes_InitTypes(PyInterpreterState *);
+extern void _PyBytes_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+struct _Py_bytes_state {
+ PyObject *empty_string;
+ PyBytesObject *characters[256];
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_BYTESOBJECT_H */
diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h
index a482dd4212..31ca0a43fa 100644
--- a/Include/internal/pycore_context.h
+++ b/Include/internal/pycore_context.h
@@ -7,6 +7,32 @@
#include "pycore_hamt.h" /* PyHamtObject */
+
+/* runtime lifecycle */
+
+PyStatus _PyContext_InitTypes(PyInterpreterState *);
+void _PyContext_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+# define PyContext_MAXFREELIST 0
+#endif
+
+#ifndef PyContext_MAXFREELIST
+# define PyContext_MAXFREELIST 255
+#endif
+
+struct _Py_context_state {
+#if PyContext_MAXFREELIST > 0
+ // List of free PyContext objects
+ PyContext *freelist;
+ int numfree;
+#endif
+};
+
struct _pycontextobject {
PyObject_HEAD
PyContext *ctx_prev;
@@ -36,7 +62,4 @@ struct _pycontexttokenobject {
};
-int _PyContext_Init(void);
-void _PyContext_Fini(PyInterpreterState *interp);
-
#endif /* !Py_INTERNAL_CONTEXT_H */
diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h
index 2f0536801e..faa8bb49bb 100644
--- a/Include/internal/pycore_dict.h
+++ b/Include/internal/pycore_dict.h
@@ -10,6 +10,32 @@ extern "C" {
#endif
+/* runtime lifecycle */
+
+extern void _PyDict_Fini(PyInterpreterState *interp);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+# define PyDict_MAXFREELIST 0
+#endif
+
+#ifndef PyDict_MAXFREELIST
+# define PyDict_MAXFREELIST 80
+#endif
+
+struct _Py_dict_state {
+#if PyDict_MAXFREELIST > 0
+ /* Dictionary reuse scheme to save calls to malloc and free */
+ PyDictObject *free_list[PyDict_MAXFREELIST];
+ int numfree;
+ PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
+ int keys_numfree;
+#endif
+};
+
typedef struct {
/* Cached hash code of me_key. */
Py_hash_t me_hash;
diff --git a/Include/internal/pycore_exceptions.h b/Include/internal/pycore_exceptions.h
new file mode 100644
index 0000000000..1651966dad
--- /dev/null
+++ b/Include/internal/pycore_exceptions.h
@@ -0,0 +1,37 @@
+#ifndef Py_INTERNAL_EXCEPTIONS_H
+#define Py_INTERNAL_EXCEPTIONS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern PyStatus _PyExc_InitState(PyInterpreterState *);
+extern PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyExc_InitTypes(PyInterpreterState *);
+extern void _PyExc_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+struct _Py_exc_state {
+ // The dict mapping from errno codes to OSError subclasses
+ PyObject *errnomap;
+ PyBaseExceptionObject *memerrors_freelist;
+ int memerrors_numfree;
+ // The ExceptionGroup type
+ PyObject *PyExc_ExceptionGroup;
+};
+
+extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_EXCEPTIONS_H */
diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h
index 18227c9e36..be6045587d 100644
--- a/Include/internal/pycore_floatobject.h
+++ b/Include/internal/pycore_floatobject.h
@@ -8,6 +8,35 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+
+/* runtime lifecycle */
+
+extern void _PyFloat_InitState(PyInterpreterState *);
+extern PyStatus _PyFloat_InitTypes(PyInterpreterState *);
+extern void _PyFloat_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+# define PyFloat_MAXFREELIST 0
+#endif
+
+#ifndef PyFloat_MAXFREELIST
+# define PyFloat_MAXFREELIST 100
+#endif
+
+struct _Py_float_state {
+#if PyFloat_MAXFREELIST > 0
+ /* Special free list
+ free_list is a singly-linked list of available PyFloatObjects,
+ linked via abuse of their ob_type members. */
+ int numfree;
+ PyFloatObject *free_list;
+#endif
+};
+
/* _PyFloat_{Pack,Unpack}{4,8}
*
* The struct and pickle (at least) modules need an efficient platform-
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index f4f7ab942c..a55877b55f 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -4,6 +4,14 @@
extern "C" {
#endif
+
+/* runtime lifecycle */
+
+extern void _PyFrame_Fini(PyInterpreterState *interp);
+
+
+/* other API */
+
/* These values are chosen so that the inline functions below all
* compare f_state to zero.
*/
diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h
new file mode 100644
index 0000000000..74a676df4a
--- /dev/null
+++ b/Include/internal/pycore_genobject.h
@@ -0,0 +1,46 @@
+#ifndef Py_INTERNAL_GENOBJECT_H
+#define Py_INTERNAL_GENOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern void _PyAsyncGen_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+# define _PyAsyncGen_MAXFREELIST 0
+#endif
+
+#ifndef _PyAsyncGen_MAXFREELIST
+# define _PyAsyncGen_MAXFREELIST 80
+#endif
+
+struct _Py_async_gen_state {
+#if _PyAsyncGen_MAXFREELIST > 0
+ /* Freelists boost performance 6-10%; they also reduce memory
+ fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
+ are short-living objects that are instantiated for every
+ __anext__() call. */
+ struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
+ int value_numfree;
+
+ struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
+ int asend_numfree;
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_GENOBJECT_H */
diff --git a/Include/internal/pycore_hamt.h b/Include/internal/pycore_hamt.h
index aaf6559095..cf9c19e022 100644
--- a/Include/internal/pycore_hamt.h
+++ b/Include/internal/pycore_hamt.h
@@ -8,6 +8,14 @@
#define _Py_HAMT_MAX_TREE_DEPTH 7
+/* runtime lifecycle */
+
+PyStatus _PyHamt_InitTypes(PyInterpreterState *);
+void _PyHamt_Fini(PyInterpreterState *);
+
+
+/* other API */
+
#define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type)
@@ -110,7 +118,4 @@ PyObject * _PyHamt_NewIterValues(PyHamtObject *o);
/* Return a Items iterator over "o". */
PyObject * _PyHamt_NewIterItems(PyHamtObject *o);
-int _PyHamt_Init(void);
-void _PyHamt_Fini(void);
-
#endif /* !Py_INTERNAL_HAMT_H */
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index e421aa4bc4..e4d7b1b875 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -10,8 +10,18 @@ extern "C" {
#include "pycore_atomic.h" // _Py_atomic_address
#include "pycore_ast_state.h" // struct ast_state
+#include "pycore_bytesobject.h" // struct _Py_bytes_state
+#include "pycore_context.h" // struct _Py_context_state
+#include "pycore_dict.h" // struct _Py_dict_state
+#include "pycore_exceptions.h" // struct _Py_exc_state
+#include "pycore_floatobject.h" // struct _Py_float_state
+#include "pycore_genobject.h" // struct _Py_async_gen_state
#include "pycore_gil.h" // struct _gil_runtime_state
#include "pycore_gc.h" // struct _gc_runtime_state
+#include "pycore_list.h" // struct _Py_list_state
+#include "pycore_tuple.h" // struct _Py_tuple_state
+#include "pycore_typeobject.h" // struct type_cache
+#include "pycore_unicodeobject.h" // struct _Py_unicode_state
#include "pycore_warnings.h" // struct _warnings_runtime_state
struct _pending_calls {
@@ -44,158 +54,6 @@ struct _ceval_state {
#endif
};
-/* fs_codec.encoding is initialized to NULL.
- Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
-struct _Py_unicode_fs_codec {
- char *encoding; // Filesystem encoding (encoded to UTF-8)
- int utf8; // encoding=="utf-8"?
- char *errors; // Filesystem errors (encoded to UTF-8)
- _Py_error_handler error_handler;
-};
-
-struct _Py_bytes_state {
- PyObject *empty_string;
- PyBytesObject *characters[256];
-};
-
-struct _Py_unicode_ids {
- Py_ssize_t size;
- PyObject **array;
-};
-
-struct _Py_unicode_state {
- // The empty Unicode object is a singleton to improve performance.
- PyObject *empty_string;
- /* Single character Unicode strings in the Latin-1 range are being
- shared as well. */
- PyObject *latin1[256];
- struct _Py_unicode_fs_codec fs_codec;
-
- /* This dictionary holds all interned unicode strings. Note that references
- to strings in this dictionary are *not* counted in the string's ob_refcnt.
- When the interned string reaches a refcnt of 0 the string deallocation
- function will delete the reference from this dictionary.
-
- Another way to look at this is that to say that the actual reference
- count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
- */
- PyObject *interned;
-
- // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
- struct _Py_unicode_ids ids;
-};
-
-#ifndef WITH_FREELISTS
-// without freelists
-# define PyFloat_MAXFREELIST 0
-// for tuples only store empty tuple singleton
-# define PyTuple_MAXSAVESIZE 1
-# define PyTuple_MAXFREELIST 1
-# define PyList_MAXFREELIST 0
-# define PyDict_MAXFREELIST 0
-# define _PyAsyncGen_MAXFREELIST 0
-# define PyContext_MAXFREELIST 0
-#endif
-
-#ifndef PyFloat_MAXFREELIST
-# define PyFloat_MAXFREELIST 100
-#endif
-
-struct _Py_float_state {
-#if PyFloat_MAXFREELIST > 0
- /* Special free list
- free_list is a singly-linked list of available PyFloatObjects,
- linked via abuse of their ob_type members. */
- int numfree;
- PyFloatObject *free_list;
-#endif
-};
-
-/* Speed optimization to avoid frequent malloc/free of small tuples */
-#ifndef PyTuple_MAXSAVESIZE
- // Largest tuple to save on free list
-# define PyTuple_MAXSAVESIZE 20
-#endif
-#ifndef PyTuple_MAXFREELIST
- // Maximum number of tuples of each size to save
-# define PyTuple_MAXFREELIST 2000
-#endif
-
-struct _Py_tuple_state {
-#if PyTuple_MAXSAVESIZE > 0
- /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists,
- entry 0 is the empty tuple () of which at most one instance
- will be allocated. */
- PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
- int numfree[PyTuple_MAXSAVESIZE];
-#endif
-};
-
-/* Empty list reuse scheme to save calls to malloc and free */
-#ifndef PyList_MAXFREELIST
-# define PyList_MAXFREELIST 80
-#endif
-
-struct _Py_list_state {
-#if PyList_MAXFREELIST > 0
- PyListObject *free_list[PyList_MAXFREELIST];
- int numfree;
-#endif
-};
-
-#ifndef PyDict_MAXFREELIST
-# define PyDict_MAXFREELIST 80
-#endif
-
-struct _Py_dict_state {
-#if PyDict_MAXFREELIST > 0
- /* Dictionary reuse scheme to save calls to malloc and free */
- PyDictObject *free_list[PyDict_MAXFREELIST];
- int numfree;
- PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
- int keys_numfree;
-#endif
-};
-
-#ifndef _PyAsyncGen_MAXFREELIST
-# define _PyAsyncGen_MAXFREELIST 80
-#endif
-
-struct _Py_async_gen_state {
-#if _PyAsyncGen_MAXFREELIST > 0
- /* Freelists boost performance 6-10%; they also reduce memory
- fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
- are short-living objects that are instantiated for every
- __anext__() call. */
- struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
- int value_numfree;
-
- struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
- int asend_numfree;
-#endif
-};
-
-#ifndef PyContext_MAXFREELIST
-# define PyContext_MAXFREELIST 255
-#endif
-
-struct _Py_context_state {
-#if PyContext_MAXFREELIST > 0
- // List of free PyContext objects
- PyContext *freelist;
- int numfree;
-#endif
-};
-
-struct _Py_exc_state {
- // The dict mapping from errno codes to OSError subclasses
- PyObject *errnomap;
- PyBaseExceptionObject *memerrors_freelist;
- int memerrors_numfree;
- // The ExceptionGroup type
- PyObject *PyExc_ExceptionGroup;
-};
-
// atexit state
typedef struct {
@@ -211,27 +69,6 @@ struct atexit_state {
};
-// Type attribute lookup cache: speed up attribute and method lookups,
-// see _PyType_Lookup().
-struct type_cache_entry {
- unsigned int version; // initialized from type->tp_version_tag
- PyObject *name; // reference to exactly a str or None
- PyObject *value; // borrowed reference or NULL
-};
-
-#define MCACHE_SIZE_EXP 12
-#define MCACHE_STATS 0
-
-struct type_cache {
- struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
-#if MCACHE_STATS
- size_t hits;
- size_t misses;
- size_t collisions;
-#endif
-};
-
-
/* interpreter state */
// The PyInterpreterState typedef is in Include/pystate.h.
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index f18fb052c4..0717a1f956 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -11,6 +11,30 @@ extern "C" {
#include "listobject.h" // _PyList_CAST()
+/* runtime lifecycle */
+
+extern void _PyList_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+# define PyList_MAXFREELIST 0
+#endif
+
+/* Empty list reuse scheme to save calls to malloc and free */
+#ifndef PyList_MAXFREELIST
+# define PyList_MAXFREELIST 80
+#endif
+
+struct _Py_list_state {
+#if PyList_MAXFREELIST > 0
+ PyListObject *free_list[PyList_MAXFREELIST];
+ int numfree;
+#endif
+};
+
#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item)
diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h
index b9f926996d..a5639ceb69 100644
--- a/Include/internal/pycore_long.h
+++ b/Include/internal/pycore_long.h
@@ -8,18 +8,28 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_interp.h" // PyInterpreterState.small_ints
+#include "pycore_long_state.h" // _PyLong_SMALL_INTS
#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_runtime.h" // _PyRuntime
+
+
+/* runtime lifecycle */
+
+extern void _PyLong_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyLong_InitTypes(PyInterpreterState *);
+
+
+/* other API */
// Return a borrowed reference to the zero singleton.
// The function cannot return NULL.
static inline PyObject* _PyLong_GetZero(void)
-{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS]; }
+{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; }
// Return a borrowed reference to the one singleton.
// The function cannot return NULL.
static inline PyObject* _PyLong_GetOne(void)
-{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS+1]; }
+{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
diff --git a/Include/internal/pycore_long_state.h b/Include/internal/pycore_long_state.h
new file mode 100644
index 0000000000..5fe8e623a9
--- /dev/null
+++ b/Include/internal/pycore_long_state.h
@@ -0,0 +1,33 @@
+#ifndef Py_INTERNAL_LONG_STATE_H
+#define Py_INTERNAL_LONG_STATE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#define _PY_NSMALLPOSINTS 257
+#define _PY_NSMALLNEGINTS 5
+
+// _PyLong_GetZero() and _PyLong_GetOne() must always be available
+#if _PY_NSMALLPOSINTS < 2
+# error "_PY_NSMALLPOSINTS must be greater than 1"
+#endif
+
+struct _Py_long_state {
+ /* Small integers are preallocated in this array so that they
+ * can be shared.
+ * The integers that are preallocated are those in the range
+ *-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
+ */
+ PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
+};
+
+#define _PyLong_SMALL_INTS _PyRuntime.int_state.small_ints
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_LONG_STATE_H */
diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h
index 14ea182f4f..3134afeb86 100644
--- a/Include/internal/pycore_pyerrors.h
+++ b/Include/internal/pycore_pyerrors.h
@@ -8,6 +8,14 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+
+/* runtime lifecycle */
+
+extern PyStatus _PyErr_InitTypes(PyInterpreterState *);
+
+
+/* other API */
+
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
{
assert(tstate != NULL);
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 5e0f36ab2a..766e889f23 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -49,13 +49,6 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
/* Various one-time initializers */
-extern PyStatus _PyUnicode_Init(PyInterpreterState *interp);
-extern PyStatus _PyUnicode_InitTypes(void);
-extern PyStatus _PyBytes_Init(PyInterpreterState *interp);
-extern int _PyStructSequence_Init(void);
-extern void _PyLong_Init(PyInterpreterState *interp);
-extern int _PyLong_InitTypes(void);
-extern PyStatus _PyTuple_Init(PyInterpreterState *interp);
extern PyStatus _PyFaulthandler_Init(int enable);
extern int _PyTraceMalloc_Init(int enable);
extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp);
@@ -65,15 +58,9 @@ extern PyStatus _PySys_Create(
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
extern int _PySys_UpdateConfig(PyThreadState *tstate);
-extern PyStatus _PyExc_Init(PyInterpreterState *interp);
-extern PyStatus _PyErr_InitTypes(void);
extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
-extern void _PyFloat_Init(void);
-extern int _PyFloat_InitTypes(void);
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
-extern PyStatus _PyTypes_Init(void);
-extern PyStatus _PyTypes_InitSlotDefs(void);
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
@@ -81,28 +68,13 @@ extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
/* Various internal finalizers */
-extern void _PyFrame_Fini(PyInterpreterState *interp);
-extern void _PyDict_Fini(PyInterpreterState *interp);
-extern void _PyTuple_Fini(PyInterpreterState *interp);
-extern void _PyList_Fini(PyInterpreterState *interp);
-extern void _PyBytes_Fini(PyInterpreterState *interp);
-extern void _PyFloat_Fini(PyInterpreterState *interp);
-extern void _PySlice_Fini(PyInterpreterState *interp);
-extern void _PyAsyncGen_Fini(PyInterpreterState *interp);
-
extern int _PySignal_Init(int install_signal_handlers);
extern void _PySignal_Fini(void);
-extern void _PyExc_ClearExceptionGroupType(PyInterpreterState *interp);
-extern void _PyExc_Fini(PyInterpreterState *interp);
extern void _PyImport_Fini(void);
extern void _PyImport_Fini2(void);
extern void _PyGC_Fini(PyInterpreterState *interp);
-extern void _PyType_Fini(PyInterpreterState *interp);
extern void _Py_HashRandomization_Fini(void);
-extern void _PyUnicode_Fini(PyInterpreterState *interp);
-extern void _PyUnicode_ClearInterned(PyInterpreterState *interp);
-extern void _PyLong_Fini(PyInterpreterState *interp);
extern void _PyFaulthandler_Fini(void);
extern void _PyHash_Fini(void);
extern void _PyTraceMalloc_Fini(void);
diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h
index 39e30b785a..bd88510d1f 100644
--- a/Include/internal/pycore_runtime.h
+++ b/Include/internal/pycore_runtime.h
@@ -10,14 +10,8 @@ extern "C" {
#include "pycore_atomic.h" /* _Py_atomic_address */
#include "pycore_gil.h" // struct _gil_runtime_state
-
-#define _PY_NSMALLPOSINTS 257
-#define _PY_NSMALLNEGINTS 5
-
-// _PyLong_GetZero() and _PyLong_GetOne() must always be available
-#if _PY_NSMALLPOSINTS < 2
-# error "_PY_NSMALLPOSINTS must be greater than 1"
-#endif
+#include "pycore_long_state.h" // struct _Py_long_state
+#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids
/* ceval state */
@@ -57,13 +51,6 @@ typedef struct _Py_AuditHookEntry {
void *userData;
} _Py_AuditHookEntry;
-struct _Py_unicode_runtime_ids {
- PyThread_type_lock lock;
- // next_index value must be preserved when Py_Initialize()/Py_Finalize()
- // is called multiple times: see _PyUnicode_FromId() implementation.
- Py_ssize_t next_index;
-};
-
/* Full Python runtime state */
typedef struct pyruntimestate {
@@ -114,12 +101,7 @@ typedef struct pyruntimestate {
unsigned long main_thread;
- /* Small integers are preallocated in this array so that they
- * can be shared.
- * The integers that are preallocated are those in the range
- *-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
- */
- PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
+ struct _Py_long_state int_state;
#define NEXITFUNCS 32
void (*exitfuncs[NEXITFUNCS])(void);
diff --git a/Include/internal/pycore_sliceobject.h b/Include/internal/pycore_sliceobject.h
new file mode 100644
index 0000000000..e81834c041
--- /dev/null
+++ b/Include/internal/pycore_sliceobject.h
@@ -0,0 +1,20 @@
+#ifndef Py_INTERNAL_SLICEOBJECT_H
+#define Py_INTERNAL_SLICEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern void _PySlice_Fini(PyInterpreterState *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_SLICEOBJECT_H */
diff --git a/Include/internal/pycore_structseq.h b/Include/internal/pycore_structseq.h
index 84c8d477e0..3a61cb9a12 100644
--- a/Include/internal/pycore_structseq.h
+++ b/Include/internal/pycore_structseq.h
@@ -9,6 +9,13 @@ extern "C" {
#endif
+/* runtime lifecycle */
+
+extern PyStatus _PyStructSequence_InitState(PyInterpreterState *);
+
+
+/* other API */
+
PyAPI_FUNC(int) _PyStructSequence_InitType(
PyTypeObject *type,
PyStructSequence_Desc *desc,
diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h
index 79c827fe88..624c21caec 100644
--- a/Include/internal/pycore_tuple.h
+++ b/Include/internal/pycore_tuple.h
@@ -10,6 +10,43 @@ extern "C" {
#include "tupleobject.h" /* _PyTuple_CAST() */
+
+/* runtime lifecycle */
+
+extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyTuple_InitTypes(PyInterpreterState *);
+extern void _PyTuple_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+#ifndef WITH_FREELISTS
+// without freelists
+// for tuples only store empty tuple singleton
+# define PyTuple_MAXSAVESIZE 1
+# define PyTuple_MAXFREELIST 1
+#endif
+
+/* Speed optimization to avoid frequent malloc/free of small tuples */
+#ifndef PyTuple_MAXSAVESIZE
+ // Largest tuple to save on free list
+# define PyTuple_MAXSAVESIZE 20
+#endif
+#ifndef PyTuple_MAXFREELIST
+ // Maximum number of tuples of each size to save
+# define PyTuple_MAXFREELIST 2000
+#endif
+
+struct _Py_tuple_state {
+#if PyTuple_MAXSAVESIZE > 0
+ /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists,
+ entry 0 is the empty tuple () of which at most one instance
+ will be allocated. */
+ PyTupleObject *free_list[PyTuple_MAXSAVESIZE];
+ int numfree[PyTuple_MAXSAVESIZE];
+#endif
+};
+
#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item)
extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t);
diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h
new file mode 100644
index 0000000000..7fd8a1f350
--- /dev/null
+++ b/Include/internal/pycore_typeobject.h
@@ -0,0 +1,47 @@
+#ifndef Py_INTERNAL_TYPEOBJECT_H
+#define Py_INTERNAL_TYPEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern PyStatus _PyTypes_InitState(PyInterpreterState *);
+extern PyStatus _PyTypes_InitTypes(PyInterpreterState *);
+extern void _PyTypes_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+// Type attribute lookup cache: speed up attribute and method lookups,
+// see _PyType_Lookup().
+struct type_cache_entry {
+ unsigned int version; // initialized from type->tp_version_tag
+ PyObject *name; // reference to exactly a str or None
+ PyObject *value; // borrowed reference or NULL
+};
+
+#define MCACHE_SIZE_EXP 12
+#define MCACHE_STATS 0
+
+struct type_cache {
+ struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
+#if MCACHE_STATS
+ size_t hits;
+ size_t misses;
+ size_t collisions;
+#endif
+};
+
+extern PyStatus _PyTypes_InitSlotDefs(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_TYPEOBJECT_H */
diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h
new file mode 100644
index 0000000000..c50c42011a
--- /dev/null
+++ b/Include/internal/pycore_unicodeobject.h
@@ -0,0 +1,71 @@
+#ifndef Py_INTERNAL_UNICODEOBJECT_H
+#define Py_INTERNAL_UNICODEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+/* runtime lifecycle */
+
+extern void _PyUnicode_InitState(PyInterpreterState *);
+extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *);
+extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *);
+extern void _PyUnicode_Fini(PyInterpreterState *);
+
+
+/* other API */
+
+struct _Py_unicode_runtime_ids {
+ PyThread_type_lock lock;
+ // next_index value must be preserved when Py_Initialize()/Py_Finalize()
+ // is called multiple times: see _PyUnicode_FromId() implementation.
+ Py_ssize_t next_index;
+};
+
+/* fs_codec.encoding is initialized to NULL.
+ Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */
+struct _Py_unicode_fs_codec {
+ char *encoding; // Filesystem encoding (encoded to UTF-8)
+ int utf8; // encoding=="utf-8"?
+ char *errors; // Filesystem errors (encoded to UTF-8)
+ _Py_error_handler error_handler;
+};
+
+struct _Py_unicode_ids {
+ Py_ssize_t size;
+ PyObject **array;
+};
+
+struct _Py_unicode_state {
+ // The empty Unicode object is a singleton to improve performance.
+ PyObject *empty_string;
+ /* Single character Unicode strings in the Latin-1 range are being
+ shared as well. */
+ PyObject *latin1[256];
+ struct _Py_unicode_fs_codec fs_codec;
+
+ /* This dictionary holds all interned unicode strings. Note that references
+ to strings in this dictionary are *not* counted in the string's ob_refcnt.
+ When the interned string reaches a refcnt of 0 the string deallocation
+ function will delete the reference from this dictionary.
+
+ Another way to look at this is that to say that the actual reference
+ count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
+ */
+ PyObject *interned;
+
+ // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId()
+ struct _Py_unicode_ids ids;
+};
+
+extern void _PyUnicode_ClearInterned(PyInterpreterState *);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_UNICODEOBJECT_H */