Skip to content

bpo-46008: Make runtime-global object/type lifecycle functions and state consistent. #29998

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
db48819
pycore_init_singletons() -> pycore_init_global_objects().
ericsnowcurrently Dec 8, 2021
32cc38c
Clean up runtime lifecycle for types in general.
ericsnowcurrently Dec 8, 2021
b62c472
Clean up runtime lifecycle for PyLongObject.
ericsnowcurrently Dec 8, 2021
fec45a2
Clean up runtime lifecycle for PyStructSequence.
ericsnowcurrently Dec 8, 2021
69aab8c
Clean up runtime lifecycle for PyUnicodeObject.
ericsnowcurrently Dec 8, 2021
817cd04
Clean up runtime lifecycle for PyFloatObject.
ericsnowcurrently Dec 8, 2021
7565f16
Clean up runtime lifecycle for PyBytesObject.
ericsnowcurrently Dec 8, 2021
d4e3046
Clean up runtime lifecycle for PyTupleObject.
ericsnowcurrently Dec 8, 2021
0ee2251
Clean up runtime lifecycle for context/hamt types.
ericsnowcurrently Dec 8, 2021
04fc6f6
Clean up runtime lifecycle for exception types.
ericsnowcurrently Dec 9, 2021
bdf548b
Clean up runtime lifecycle for error handling types.
ericsnowcurrently Dec 9, 2021
b7ca4bb
Clean up runtime lifecycle for PyFrameObject.
ericsnowcurrently Dec 9, 2021
fcd7753
Clean up runtime lifecycle for PyDictObject.
ericsnowcurrently Dec 9, 2021
d1b1718
Clean up runtime lifecycle for PyListObject.
ericsnowcurrently Dec 9, 2021
bab319a
Clean up runtime lifecycle for PySliceObject.
ericsnowcurrently Dec 9, 2021
c50952b
Clean up runtime lifecycle for PyAsyncGenObject.
ericsnowcurrently Dec 9, 2021
cd3c419
Move unicode-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
828f6e4
Move float-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
0120a4e
Move tuple-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
11cf9a7
Move list-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
cbde112
Move dict-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
387c9fa
Move generator-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
860917b
Move context-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
0285089
Move bytes-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
88a2262
Move exceptions-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
946086d
Move type-related API to the correct header file.
ericsnowcurrently Dec 9, 2021
af61971
Move the small ints into struct _Py_long_state.
ericsnowcurrently Dec 9, 2021
02c86cc
Fix a typo.
ericsnowcurrently Dec 9, 2021
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
30 changes: 30 additions & 0 deletions Include/internal/pycore_bytesobject.h
Original file line number Diff line number Diff line change
@@ -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 */
29 changes: 26 additions & 3 deletions Include/internal/pycore_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -36,7 +62,4 @@ struct _pycontexttokenobject {
};


int _PyContext_Init(void);
void _PyContext_Fini(PyInterpreterState *interp);

#endif /* !Py_INTERNAL_CONTEXT_H */
26 changes: 26 additions & 0 deletions Include/internal/pycore_dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
37 changes: 37 additions & 0 deletions Include/internal/pycore_exceptions.h
Original file line number Diff line number Diff line change
@@ -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 */
29 changes: 29 additions & 0 deletions Include/internal/pycore_floatobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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-
Expand Down
8 changes: 8 additions & 0 deletions Include/internal/pycore_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
46 changes: 46 additions & 0 deletions Include/internal/pycore_genobject.h
Original file line number Diff line number Diff line change
@@ -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 */
11 changes: 8 additions & 3 deletions Include/internal/pycore_hamt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down Expand Up @@ -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 */
Loading