Skip to content

Commit cdad272

Browse files
authored
bpo-40137: Add pycore_moduleobject.h internal header (pythonGH-25507)
Add pycore_moduleobject.h internal header file with static inline functions to access module members: * _PyModule_GetDict() * _PyModule_GetDef() * _PyModule_GetState() These functions don't check at runtime if their argument has a valid type and can be inlined even if Python is not built with LTO. _PyType_GetModuleByDef() uses _PyModule_GetDef(). Replace PyModule_GetState() with _PyModule_GetState() in the extension modules, considered as performance sensitive: * _abc * _functools * _operator * _pickle * _queue * _random * _sre * _struct * _thread * _winapi * array * posix The following extensions are now built with the Py_BUILD_CORE_MODULE macro defined, to be able to use the internal pycore_moduleobject.h header: _abc, array, _operator, _queue, _sre, _struct.
1 parent a32f8fe commit cdad272

21 files changed

+97
-47
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef Py_INTERNAL_MODULEOBJECT_H
2+
#define Py_INTERNAL_MODULEOBJECT_H
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#ifndef Py_BUILD_CORE
8+
# error "this header requires Py_BUILD_CORE define"
9+
#endif
10+
11+
typedef struct {
12+
PyObject_HEAD
13+
PyObject *md_dict;
14+
struct PyModuleDef *md_def;
15+
void *md_state;
16+
PyObject *md_weaklist;
17+
// for logging purposes after md_dict is cleared
18+
PyObject *md_name;
19+
} PyModuleObject;
20+
21+
static inline PyModuleDef* _PyModule_GetDef(PyObject *mod) {
22+
assert(PyModule_Check(mod));
23+
return ((PyModuleObject *)mod)->md_def;
24+
}
25+
26+
static inline void* _PyModule_GetState(PyObject* mod) {
27+
assert(PyModule_Check(mod));
28+
return ((PyModuleObject *)mod)->md_state;
29+
}
30+
31+
static inline PyObject* _PyModule_GetDict(PyObject *mod) {
32+
assert(PyModule_Check(mod));
33+
PyObject *dict = ((PyModuleObject *)mod) -> md_dict;
34+
// _PyModule_GetDict(mod) must not be used after calling module_clear(mod)
35+
assert(dict != NULL);
36+
return dict;
37+
}
38+
39+
#ifdef __cplusplus
40+
}
41+
#endif
42+
#endif /* !Py_INTERNAL_MODULEOBJECT_H */

Makefile.pre.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,7 @@ PYTHON_HEADERS= \
11611161
$(srcdir)/Include/internal/pycore_interp.h \
11621162
$(srcdir)/Include/internal/pycore_list.h \
11631163
$(srcdir)/Include/internal/pycore_long.h \
1164+
$(srcdir)/Include/internal/pycore_moduleobject.h \
11641165
$(srcdir)/Include/internal/pycore_object.h \
11651166
$(srcdir)/Include/internal/pycore_pathconfig.h \
11661167
$(srcdir)/Include/internal/pycore_pyarena.h \

Modules/Setup

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ posix -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal posixmodule.c # posix
105105
errno errnomodule.c # posix (UNIX) errno values
106106
pwd pwdmodule.c # this is needed to find out the user's home dir
107107
# if $HOME is not set
108-
_sre _sre.c # Fredrik Lundh's new regular expressions
108+
_sre -DPy_BUILD_CORE_BUILTIN _sre.c # Fredrik Lundh's new regular expressions
109109
_codecs _codecsmodule.c # access to the builtin codecs and codec registry
110110
_weakref _weakref.c # weak references
111111
_functools -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _functoolsmodule.c # Tools for working with functions and callable objects
112-
_operator _operator.c # operator.add() and similar goodies
112+
_operator -DPy_BUILD_CORE_BUILTIN _operator.c # operator.add() and similar goodies
113113
_collections _collectionsmodule.c # Container types
114-
_abc _abc.c # Abstract base classes
114+
_abc -DPy_BUILD_CORE_BUILTIN _abc.c # Abstract base classes
115115
itertools itertoolsmodule.c # Functions creating iterators for efficient looping
116116
atexit atexitmodule.c # Register functions to be run at interpreter-shutdown
117117
_signal -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal signalmodule.c
@@ -166,17 +166,17 @@ _symtable symtablemodule.c
166166

167167
# Modules that should always be present (non UNIX dependent):
168168

169-
#array arraymodule.c # array objects
169+
#array -DPy_BUILD_CORE_MODULE arraymodule.c # array objects
170170
#cmath cmathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # complex math library functions
171171
#math mathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # math library functions, e.g. sin()
172172
#_contextvars _contextvarsmodule.c # Context Variables
173-
#_struct _struct.c # binary structure packing/unpacking
173+
#_struct -DPy_BUILD_CORE_MODULE _struct.c # binary structure packing/unpacking
174174
#_weakref _weakref.c # basic weak reference support
175175
#_testcapi _testcapimodule.c # Python C API test module
176176
#_testinternalcapi _testinternalcapi.c -I$(srcdir)/Include/internal -DPy_BUILD_CORE_MODULE # Python internal C API test module
177177
#_random _randommodule.c -DPy_BUILD_CORE_MODULE # Random number generator
178178
#_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator
179-
#_pickle _pickle.c # pickle accelerator
179+
#_pickle -DPy_BUILD_CORE_MODULE _pickle.c # pickle accelerator
180180
#_datetime _datetimemodule.c # datetime accelerator
181181
#_zoneinfo _zoneinfo.c -DPy_BUILD_CORE_MODULE # zoneinfo accelerator
182182
#_bisect _bisectmodule.c # Bisection algorithms

Modules/_abc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* ABCMeta implementation */
22

33
#include "Python.h"
4+
#include "pycore_moduleobject.h" // _PyModule_GetState()
45
#include "clinic/_abc.c.h"
56

67
/*[clinic input]
@@ -27,7 +28,7 @@ typedef struct {
2728
static inline _abcmodule_state*
2829
get_abc_state(PyObject *module)
2930
{
30-
void *state = PyModule_GetState(module);
31+
void *state = _PyModule_GetState(module);
3132
assert(state != NULL);
3233
return (_abcmodule_state *)state;
3334
}

Modules/_functoolsmodule.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Python.h"
22
#include "pycore_long.h" // _PyLong_GetZero()
3+
#include "pycore_moduleobject.h" // _PyModule_GetState()
34
#include "pycore_object.h" // _PyObject_GC_TRACK
45
#include "pycore_pystate.h" // _PyThreadState_GET()
56
#include "pycore_tuple.h" // _PyTuple_ITEMS()
@@ -23,7 +24,7 @@ typedef struct _functools_state {
2324
static inline _functools_state *
2425
get_functools_state(PyObject *module)
2526
{
26-
void *state = PyModule_GetState(module);
27+
void *state = _PyModule_GetState(module);
2728
assert(state != NULL);
2829
return (_functools_state *)state;
2930
}
@@ -53,8 +54,7 @@ get_functools_state_by_type(PyTypeObject *type)
5354
if (module == NULL) {
5455
return NULL;
5556
}
56-
_functools_state *state = get_functools_state(module);
57-
return state;
57+
return get_functools_state(module);
5858
}
5959

6060
static PyObject *

Modules/_operator.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
21
#include "Python.h"
3-
2+
#include "pycore_moduleobject.h" // _PyModule_GetState()
43
#include "clinic/_operator.c.h"
54

65
typedef struct {
@@ -12,7 +11,7 @@ typedef struct {
1211
static inline _operator_state*
1312
get_operator_state(PyObject *module)
1413
{
15-
void *state = PyModule_GetState(module);
14+
void *state = _PyModule_GetState(module);
1615
assert(state != NULL);
1716
return (_operator_state *)state;
1817
}

Modules/_pickle.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#endif
1010

1111
#include "Python.h"
12+
#include "pycore_moduleobject.h" // _PyModule_GetState()
1213
#include "structmember.h" // PyMemberDef
1314

1415
PyDoc_STRVAR(pickle_module_doc,
@@ -182,7 +183,7 @@ static struct PyModuleDef _picklemodule;
182183
static PickleState *
183184
_Pickle_GetState(PyObject *module)
184185
{
185-
return (PickleState *)PyModule_GetState(module);
186+
return (PickleState *)_PyModule_GetState(module);
186187
}
187188

188189
/* Find the module instance imported in the currently running sub-interpreter

Modules/_queuemodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "Python.h"
2+
#include "pycore_moduleobject.h" // _PyModule_GetState()
23
#include "structmember.h" // PyMemberDef
34
#include <stddef.h> // offsetof()
45

@@ -10,7 +11,7 @@ typedef struct {
1011
static simplequeue_state *
1112
simplequeue_get_state(PyObject *module)
1213
{
13-
simplequeue_state *state = PyModule_GetState(module);
14+
simplequeue_state *state = _PyModule_GetState(module);
1415
assert(state);
1516
return state;
1617
}

Modules/_randommodule.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
/* ---------------------------------------------------------------*/
6868

6969
#include "Python.h"
70+
#include "pycore_moduleobject.h" // _PyModule_GetState()
7071
#ifdef HAVE_PROCESS_H
7172
# include <process.h> // getpid()
7273
#endif
@@ -86,7 +87,7 @@ typedef struct {
8687
static inline _randomstate*
8788
get_random_state(PyObject *module)
8889
{
89-
void *state = PyModule_GetState(module);
90+
void *state = _PyModule_GetState(module);
9091
assert(state != NULL);
9192
return (_randomstate *)state;
9293
}
@@ -538,7 +539,7 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
538539

539540
if (PyTuple_GET_SIZE(args) == 1)
540541
arg = PyTuple_GET_ITEM(args, 0);
541-
542+
542543
tmp = random_seed(self, arg);
543544
if (tmp == NULL) {
544545
Py_DECREF(self);

Modules/_sre.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static const char copyright[] =
4242

4343
#include "Python.h"
4444
#include "pycore_long.h" // _PyLong_GetZero()
45+
#include "pycore_moduleobject.h" // _PyModule_GetState()
4546
#include "structmember.h" // PyMemberDef
4647

4748
#include "sre.h"
@@ -258,7 +259,7 @@ typedef struct {
258259
static _sremodulestate *
259260
get_sre_module_state(PyObject *m)
260261
{
261-
_sremodulestate *state = (_sremodulestate *)PyModule_GetState(m);
262+
_sremodulestate *state = (_sremodulestate *)_PyModule_GetState(m);
262263
assert(state);
263264
return state;
264265
}

0 commit comments

Comments
 (0)