]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40137: Add pycore_moduleobject.h internal header (GH-25507)
authorVictor Stinner <vstinner@python.org>
Wed, 21 Apr 2021 22:52:52 +0000 (00:52 +0200)
committerGitHub <noreply@github.com>
Wed, 21 Apr 2021 22:52:52 +0000 (00:52 +0200)
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.

21 files changed:
Include/internal/pycore_moduleobject.h [new file with mode: 0644]
Makefile.pre.in
Modules/Setup
Modules/_abc.c
Modules/_functoolsmodule.c
Modules/_operator.c
Modules/_pickle.c
Modules/_queuemodule.c
Modules/_randommodule.c
Modules/_sre.c
Modules/_struct.c
Modules/_threadmodule.c
Modules/_winapi.c
Modules/arraymodule.c
Modules/posixmodule.c
Objects/frameobject.c
Objects/moduleobject.c
Objects/typeobject.c
PCbuild/pythoncore.vcxproj
PCbuild/pythoncore.vcxproj.filters
setup.py

diff --git a/Include/internal/pycore_moduleobject.h b/Include/internal/pycore_moduleobject.h
new file mode 100644 (file)
index 0000000..e9978ab
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef Py_INTERNAL_MODULEOBJECT_H
+#define Py_INTERNAL_MODULEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *md_dict;
+    struct PyModuleDef *md_def;
+    void *md_state;
+    PyObject *md_weaklist;
+    // for logging purposes after md_dict is cleared
+    PyObject *md_name;
+} PyModuleObject;
+
+static inline PyModuleDef* _PyModule_GetDef(PyObject *mod) {
+    assert(PyModule_Check(mod));
+    return ((PyModuleObject *)mod)->md_def;
+}
+
+static inline void* _PyModule_GetState(PyObject* mod) {
+    assert(PyModule_Check(mod));
+    return ((PyModuleObject *)mod)->md_state;
+}
+
+static inline PyObject* _PyModule_GetDict(PyObject *mod) {
+    assert(PyModule_Check(mod));
+    PyObject *dict = ((PyModuleObject *)mod) -> md_dict;
+    // _PyModule_GetDict(mod) must not be used after calling module_clear(mod)
+    assert(dict != NULL);
+    return dict;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_MODULEOBJECT_H */
index eccc72697704b86d28c674027415362b88cde1fc..4d9b760863ad596cdeaefdf5be83e7d6eb6d6823 100644 (file)
@@ -1161,6 +1161,7 @@ PYTHON_HEADERS= \
                $(srcdir)/Include/internal/pycore_interp.h \
                $(srcdir)/Include/internal/pycore_list.h \
                $(srcdir)/Include/internal/pycore_long.h \
+               $(srcdir)/Include/internal/pycore_moduleobject.h \
                $(srcdir)/Include/internal/pycore_object.h \
                $(srcdir)/Include/internal/pycore_pathconfig.h \
                $(srcdir)/Include/internal/pycore_pyarena.h \
index cce78582a1e28abe2ba5a2009be4873e8b8aae03..87c6a152f86eac094d3a8ff64d389986cae16e66 100644 (file)
@@ -105,13 +105,13 @@ posix -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal posixmodule.c # posix
 errno errnomodule.c                    # posix (UNIX) errno values
 pwd pwdmodule.c                                # this is needed to find out the user's home dir
                                        # if $HOME is not set
-_sre _sre.c                            # Fredrik Lundh's new regular expressions
+_sre -DPy_BUILD_CORE_BUILTIN _sre.c    # Fredrik Lundh's new regular expressions
 _codecs _codecsmodule.c                        # access to the builtin codecs and codec registry
 _weakref _weakref.c                    # weak references
 _functools -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal _functoolsmodule.c   # Tools for working with functions and callable objects
-_operator _operator.c                  # operator.add() and similar goodies
+_operator -DPy_BUILD_CORE_BUILTIN _operator.c                  # operator.add() and similar goodies
 _collections _collectionsmodule.c      # Container types
-_abc _abc.c                            # Abstract base classes
+_abc -DPy_BUILD_CORE_BUILTIN _abc.c    # Abstract base classes
 itertools itertoolsmodule.c            # Functions creating iterators for efficient looping
 atexit atexitmodule.c                  # Register functions to be run at interpreter-shutdown
 _signal -DPy_BUILD_CORE_BUILTIN -I$(srcdir)/Include/internal signalmodule.c
@@ -166,17 +166,17 @@ _symtable symtablemodule.c
 
 # Modules that should always be present (non UNIX dependent):
 
-#array arraymodule.c   # array objects
+#array -DPy_BUILD_CORE_MODULE arraymodule.c    # array objects
 #cmath cmathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # complex math library functions
 #math mathmodule.c _math.c -DPy_BUILD_CORE_MODULE # -lm # math library functions, e.g. sin()
 #_contextvars _contextvarsmodule.c  # Context Variables
-#_struct _struct.c     # binary structure packing/unpacking
+#_struct -DPy_BUILD_CORE_MODULE _struct.c      # binary structure packing/unpacking
 #_weakref _weakref.c   # basic weak reference support
 #_testcapi _testcapimodule.c    # Python C API test module
 #_testinternalcapi _testinternalcapi.c -I$(srcdir)/Include/internal -DPy_BUILD_CORE_MODULE  # Python internal C API test module
 #_random _randommodule.c -DPy_BUILD_CORE_MODULE        # Random number generator
 #_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c        # elementtree accelerator
-#_pickle _pickle.c     # pickle accelerator
+#_pickle -DPy_BUILD_CORE_MODULE _pickle.c      # pickle accelerator
 #_datetime _datetimemodule.c   # datetime accelerator
 #_zoneinfo _zoneinfo.c -DPy_BUILD_CORE_MODULE  # zoneinfo accelerator
 #_bisect _bisectmodule.c       # Bisection algorithms
index 7afaa759b2bfec943679f6f5306fc6037360b9f3..0ddc2abeee1e0e778b4b6ad487bbeabc1571d88b 100644 (file)
@@ -1,6 +1,7 @@
 /* ABCMeta implementation */
 
 #include "Python.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "clinic/_abc.c.h"
 
 /*[clinic input]
@@ -27,7 +28,7 @@ typedef struct {
 static inline _abcmodule_state*
 get_abc_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (_abcmodule_state *)state;
 }
index f3ae3b62ae332c54a321afd633bd3b7c247d4768..eea542e18c92d222eb5d613460d27ffddfe4d847 100644 (file)
@@ -1,5 +1,6 @@
 #include "Python.h"
 #include "pycore_long.h"          // _PyLong_GetZero()
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "pycore_object.h"        // _PyObject_GC_TRACK
 #include "pycore_pystate.h"       // _PyThreadState_GET()
 #include "pycore_tuple.h"         // _PyTuple_ITEMS()
@@ -23,7 +24,7 @@ typedef struct _functools_state {
 static inline _functools_state *
 get_functools_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (_functools_state *)state;
 }
@@ -53,8 +54,7 @@ get_functools_state_by_type(PyTypeObject *type)
     if (module == NULL) {
         return NULL;
     }
-    _functools_state *state = get_functools_state(module);
-    return state;
+    return get_functools_state(module);
 }
 
 static PyObject *
index da1e43158ee0ac2e30ada9d03a9eea89ea6a075f..f55c2f1d1f415e552eca2c2c95a1ae53d164153d 100644 (file)
@@ -1,6 +1,5 @@
-
 #include "Python.h"
-
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "clinic/_operator.c.h"
 
 typedef struct {
@@ -12,7 +11,7 @@ typedef struct {
 static inline _operator_state*
 get_operator_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (_operator_state *)state;
 }
index 5a8aad9de7679d3b0848fa4afb7c05f0126e7b19..691d4a293e8498045bc512539f3b569a70e81c9b 100644 (file)
@@ -9,6 +9,7 @@
 #endif
 
 #include "Python.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "structmember.h"         // PyMemberDef
 
 PyDoc_STRVAR(pickle_module_doc,
@@ -182,7 +183,7 @@ static struct PyModuleDef _picklemodule;
 static PickleState *
 _Pickle_GetState(PyObject *module)
 {
-    return (PickleState *)PyModule_GetState(module);
+    return (PickleState *)_PyModule_GetState(module);
 }
 
 /* Find the module instance imported in the currently running sub-interpreter
index 7a52617ade5b09ec3a38d07dba91234bc536dc0d..c27fb1a001d21e8895e2c28261a18c9cabcd7c3c 100644 (file)
@@ -1,4 +1,5 @@
 #include "Python.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "structmember.h"         // PyMemberDef
 #include <stddef.h>               // offsetof()
 
@@ -10,7 +11,7 @@ typedef struct {
 static simplequeue_state *
 simplequeue_get_state(PyObject *module)
 {
-    simplequeue_state *state = PyModule_GetState(module);
+    simplequeue_state *state = _PyModule_GetState(module);
     assert(state);
     return state;
 }
index 99be69c06556e6cf926da1957cc15e045f706537..cae49a009cbcc8f374a3a71161875a4b46135505 100644 (file)
@@ -67,6 +67,7 @@
 /* ---------------------------------------------------------------*/
 
 #include "Python.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #ifdef HAVE_PROCESS_H
 #  include <process.h>            // getpid()
 #endif
@@ -86,7 +87,7 @@ typedef struct {
 static inline _randomstate*
 get_random_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (_randomstate *)state;
 }
@@ -538,7 +539,7 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
     if (PyTuple_GET_SIZE(args) == 1)
         arg = PyTuple_GET_ITEM(args, 0);
-    
+
     tmp = random_seed(self, arg);
     if (tmp == NULL) {
         Py_DECREF(self);
index 57faf7bdaae4e6c6363c8860c4b3d8ef4124bd6b..d4bfff6e849e375cce8a3a82ce9e9502164f3f92 100644 (file)
@@ -42,6 +42,7 @@ static const char copyright[] =
 
 #include "Python.h"
 #include "pycore_long.h"          // _PyLong_GetZero()
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "structmember.h"         // PyMemberDef
 
 #include "sre.h"
@@ -258,7 +259,7 @@ typedef struct {
 static _sremodulestate *
 get_sre_module_state(PyObject *m)
 {
-    _sremodulestate *state = (_sremodulestate *)PyModule_GetState(m);
+    _sremodulestate *state = (_sremodulestate *)_PyModule_GetState(m);
     assert(state);
     return state;
 }
index 1a5e0ae28e876b746aacc7bc0b42ff2009ef9d3c..30ad9f2b79d8f3fdc378ade6c8a66bb9c2bec882 100644 (file)
@@ -6,6 +6,7 @@
 #define PY_SSIZE_T_CLEAN
 
 #include "Python.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "structmember.h"         // PyMemberDef
 #include <ctype.h>
 
@@ -24,7 +25,7 @@ typedef struct {
 static inline _structmodulestate*
 get_struct_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (_structmodulestate *)state;
 }
index 0613dfd3070c5c3eb788fbbf06d336357c27f833..7feb0b8a1f1f4d4ee529e562521a1ad40f32390c 100644 (file)
@@ -3,8 +3,9 @@
 /* Interface to Sjoerd's portable C thread library */
 
 #include "Python.h"
-#include "pycore_pylifecycle.h"
 #include "pycore_interp.h"        // _PyInterpreterState.num_threads
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
+#include "pycore_pylifecycle.h"
 #include "pycore_pystate.h"       // _PyThreadState_Init()
 #include <stddef.h>               // offsetof()
 #include "structmember.h"         // PyMemberDef
@@ -35,7 +36,7 @@ typedef struct {
 static inline thread_module_state*
 get_thread_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (thread_module_state *)state;
 }
index 7ba14095c96e19453627c0f4a8ccf589a8d396e1..9d5a45adac59d04d8b30ea12b3a8b05c19e38fa5 100644 (file)
@@ -35,7 +35,7 @@
 /* See http://www.python.org/2.4/license for licensing details. */
 
 #include "Python.h"
-#include "moduleobject.h"         // PyModuleDef_Slot
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "structmember.h"         // PyMemberDef
 
 
@@ -87,7 +87,7 @@ typedef struct {
 static inline WinApiState*
 winapi_get_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (WinApiState *)state;
 }
index fb9ebbe9f4870f00afaaea4a1bf741f4df5b7c46..f5326789521d30233a3172e5f5a50194ed8df9a9 100644 (file)
@@ -5,6 +5,7 @@
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #include "structmember.h"         // PyMemberDef
 #include <stddef.h>               // offsetof()
 
@@ -63,7 +64,7 @@ typedef struct {
 static array_state *
 get_array_state(PyObject *module)
 {
-    return (array_state *)PyModule_GetState(module);
+    return (array_state *)_PyModule_GetState(module);
 }
 
 #define find_array_state_by_type(tp) \
index 65e8d5e7bd984db21698c358587f2164e0b9ba6a..8ce62c88216e3d384154b8686383db37fe7f201a 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "Python.h"
 #include "pycore_fileutils.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
 #ifdef MS_WINDOWS
    /* include <windows.h> early to avoid conflict with pycore_condvar.h:
 
@@ -994,7 +995,7 @@ typedef struct {
 static inline _posixstate*
 get_posix_state(PyObject *module)
 {
-    void *state = PyModule_GetState(module);
+    void *state = _PyModule_GetState(module);
     assert(state != NULL);
     return (_posixstate *)state;
 }
index 9687ba5c7a93f85981f89b29756fe3632090782f..b0487c2b68811bab8d3c503460bf47beafc45a9a 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "Python.h"
 #include "pycore_ceval.h"         // _PyEval_BuiltinsFromGlobals()
+#include "pycore_moduleobject.h"  // _PyModule_GetDict()
 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
 
 #include "frameobject.h"          // PyFrameObject
@@ -1176,7 +1177,7 @@ _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals)
     PyObject *builtins = _PyDict_GetItemIdWithError(globals, &PyId___builtins__);
     if (builtins) {
         if (PyModule_Check(builtins)) {
-            builtins = PyModule_GetDict(builtins);
+            builtins = _PyModule_GetDict(builtins);
             assert(builtins != NULL);
         }
         return builtins;
index e57ea86e7694ceabb49c3dd888d1226dbaa9955c..a6eb85bdc2a9626d1bd20266c4d8ae57818017cf 100644 (file)
@@ -4,6 +4,7 @@
 #include "Python.h"
 #include "pycore_interp.h"        // PyInterpreterState.importlib
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
+#include "pycore_moduleobject.h"  // _PyModule_GetDef()
 #include "structmember.h"         // PyMemberDef
 
 static Py_ssize_t max_module_number;
@@ -12,15 +13,6 @@ _Py_IDENTIFIER(__doc__);
 _Py_IDENTIFIER(__name__);
 _Py_IDENTIFIER(__spec__);
 
-typedef struct {
-    PyObject_HEAD
-    PyObject *md_dict;
-    struct PyModuleDef *md_def;
-    void *md_state;
-    PyObject *md_weaklist;
-    PyObject *md_name;  /* for logging purposes after md_dict is cleared */
-} PyModuleObject;
-
 static PyMemberDef module_members[] = {
     {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY},
     {0}
@@ -469,14 +461,11 @@ PyModule_SetDocString(PyObject *m, const char *doc)
 PyObject *
 PyModule_GetDict(PyObject *m)
 {
-    PyObject *d;
     if (!PyModule_Check(m)) {
         PyErr_BadInternalCall();
         return NULL;
     }
-    d = ((PyModuleObject *)m) -> md_dict;
-    assert(d != NULL);
-    return d;
+    return _PyModule_GetDict(m);
 }
 
 PyObject*
@@ -556,7 +545,7 @@ PyModule_GetDef(PyObject* m)
         PyErr_BadArgument();
         return NULL;
     }
-    return ((PyModuleObject *)m)->md_def;
+    return _PyModule_GetDef(m);
 }
 
 void*
@@ -566,7 +555,7 @@ PyModule_GetState(PyObject* m)
         PyErr_BadArgument();
         return NULL;
     }
-    return ((PyModuleObject *)m)->md_state;
+    return _PyModule_GetState(m);
 }
 
 void
index 03af2c5d75dd80714f07eb1e2e6fb874bf04f4d2..254d12cc9701481c143b119081942b6252764aab 100644 (file)
@@ -4,6 +4,7 @@
 #include "pycore_call.h"
 #include "pycore_compile.h"       // _Py_Mangle()
 #include "pycore_initconfig.h"
+#include "pycore_moduleobject.h"  // _PyModule_GetDef()
 #include "pycore_object.h"
 #include "pycore_pyerrors.h"
 #include "pycore_pystate.h"       // _PyThreadState_GET()
@@ -3582,7 +3583,7 @@ PyType_GetModuleState(PyTypeObject *type)
     if (m == NULL) {
         return NULL;
     }
-    return PyModule_GetState(m);
+    return _PyModule_GetState(m);
 }
 
 
@@ -3617,7 +3618,7 @@ _PyType_GetModuleByDef(PyTypeObject *type, struct PyModuleDef *def)
 
         PyHeapTypeObject *ht = (PyHeapTypeObject*)super;
         PyObject *module = ht->ht_module;
-        if (module && PyModule_GetDef(module) == def) {
+        if (module && _PyModule_GetDef(module) == def) {
             return module;
         }
         i++;
index 3c4785c077e6a1e58e8e1920572eb2cda08ee8ed..429d437c5ebc2073a55b5bec2d9e921d9ec8b763 100644 (file)
     <ClInclude Include="..\Include\internal\pycore_interp.h" />
     <ClInclude Include="..\Include\internal\pycore_list.h" />
     <ClInclude Include="..\Include\internal\pycore_long.h" />
+    <ClInclude Include="..\Include\internal\pycore_moduleobject.h" />
     <ClInclude Include="..\Include\internal\pycore_object.h" />
     <ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
     <ClInclude Include="..\Include\internal\pycore_pyarena.h" />
index 8c104bf7b3103451e3c80df5508bd05fdadf6104..55b57ef29dc0c97dc9c8e6b5a466ac193b606456 100644 (file)
     <ClInclude Include="..\Include\internal\pycore_long.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_moduleobject.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_object.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
index af384409553eb8f214b38955fc5214b816f34b76..df434d48768e989e82b11a7d6ba103f08d09c887 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -869,7 +869,8 @@ class PyBuildExt(build_ext):
         #
 
         # array objects
-        self.add(Extension('array', ['arraymodule.c']))
+        self.add(Extension('array', ['arraymodule.c'],
+                           extra_compile_args=['-DPy_BUILD_CORE_MODULE']))
 
         # Context Variables
         self.add(Extension('_contextvars', ['_contextvarsmodule.c']))
@@ -934,9 +935,11 @@ class PyBuildExt(build_ext):
         self.add(Extension("_asyncio", ["_asynciomodule.c"],
                            extra_compile_args=['-DPy_BUILD_CORE_MODULE']))
         # _abc speedups
-        self.add(Extension("_abc", ["_abc.c"]))
+        self.add(Extension("_abc", ["_abc.c"],
+                           extra_compile_args=['-DPy_BUILD_CORE_MODULE']))
         # _queue module
-        self.add(Extension("_queue", ["_queuemodule.c"]))
+        self.add(Extension("_queue", ["_queuemodule.c"],
+                           extra_compile_args=['-DPy_BUILD_CORE_MODULE']))
         # _statistics module
         self.add(Extension("_statistics", ["_statisticsmodule.c"]))
 
@@ -2696,7 +2699,8 @@ def main():
                       'install_lib': PyBuildInstallLib},
           # The struct module is defined here, because build_ext won't be
           # called unless there's at least one extension module defined.
-          ext_modules=[Extension('_struct', ['_struct.c'])],
+          ext_modules=[Extension('_struct', ['_struct.c'],
+                                 extra_compile_args=['-DPy_BUILD_CORE_MODULE'])],
 
           # If you change the scripts installed here, you also need to
           # check the PyBuildScripts command above, and change the links