[Python-checkins] bpo-39542: Make _Py_NewReference() opaque in C API (GH-18346)

Victor Stinner webhook-mailer at python.org
Tue Feb 4 19:11:14 EST 2020


https://github.com/python/cpython/commit/40e547dfbb9052ca0c667b242f6825ed1c23c195
commit: 40e547dfbb9052ca0c667b242f6825ed1c23c195
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-02-05T01:11:10+01:00
summary:

bpo-39542: Make _Py_NewReference() opaque in C API (GH-18346)

_Py_NewReference() becomes a regular opaque function, rather than a
static inline function in the C API (object.h), to better hide
implementation details.

Move _Py_tracemalloc_config from public pymem.h to internal
pycore_pymem.h header.

Make _Py_AddToAllObjects() private.

files:
M Include/internal/pycore_pymem.h
M Include/object.h
M Include/pymem.h
M Modules/_tracemalloc.c
M Objects/object.c

diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index 06d0d06c75c36..db153e0bd2d71 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -169,6 +169,40 @@ PyAPI_FUNC(int) _PyMem_GetAllocatorName(
    PYMEM_ALLOCATOR_NOT_SET does nothing. */
 PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator);
 
+/* bpo-35053: Expose _Py_tracemalloc_config for _Py_NewReference()
+   which access directly _Py_tracemalloc_config.tracing for best
+   performances. */
+struct _PyTraceMalloc_Config {
+    /* Module initialized?
+       Variable protected by the GIL */
+    enum {
+        TRACEMALLOC_NOT_INITIALIZED,
+        TRACEMALLOC_INITIALIZED,
+        TRACEMALLOC_FINALIZED
+    } initialized;
+
+    /* Is tracemalloc tracing memory allocations?
+       Variable protected by the GIL */
+    int tracing;
+
+    /* limit of the number of frames in a traceback, 1 by default.
+       Variable protected by the GIL. */
+    int max_nframe;
+
+    /* use domain in trace key?
+       Variable protected by the GIL. */
+    int use_domain;
+};
+
+#define _PyTraceMalloc_Config_INIT \
+    {.initialized = TRACEMALLOC_NOT_INITIALIZED, \
+     .tracing = 0, \
+     .max_nframe = 1, \
+     .use_domain = 0}
+
+PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config;
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Include/object.h b/Include/object.h
index 175a208f0d2d7..8dccbf16971a7 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -1,8 +1,6 @@
 #ifndef Py_OBJECT_H
 #define Py_OBJECT_H
 
-#include "pymem.h"   /* _Py_tracemalloc_config */
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -390,28 +388,13 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
    when a memory block is reused from a free list. */
 PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op);
 
+PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
+
 #ifdef Py_TRACE_REFS
 /* Py_TRACE_REFS is such major surgery that we call external routines. */
 PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
-PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
 #endif
 
-
-static inline void _Py_NewReference(PyObject *op)
-{
-    if (_Py_tracemalloc_config.tracing) {
-        _PyTraceMalloc_NewReference(op);
-    }
-#ifdef Py_REF_DEBUG
-    _Py_RefTotal++;
-#endif
-    Py_REFCNT(op) = 1;
-#ifdef Py_TRACE_REFS
-    _Py_AddToAllObjects(op, 1);
-#endif
-}
-
-
 PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
 
 static inline void _Py_INCREF(PyObject *op)
diff --git a/Include/pymem.h b/Include/pymem.h
index 07b380aa6e7fa..607feb9484f24 100644
--- a/Include/pymem.h
+++ b/Include/pymem.h
@@ -101,41 +101,6 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr);
 #define PyMem_Del               PyMem_Free
 #define PyMem_DEL               PyMem_FREE
 
-/* bpo-35053: expose _Py_tracemalloc_config for performance:
-   _Py_NewReference() needs an efficient check to test if tracemalloc is
-   tracing.
-
-   It has to be defined in pymem.h, before object.h is included. */
-struct _PyTraceMalloc_Config {
-    /* Module initialized?
-       Variable protected by the GIL */
-    enum {
-        TRACEMALLOC_NOT_INITIALIZED,
-        TRACEMALLOC_INITIALIZED,
-        TRACEMALLOC_FINALIZED
-    } initialized;
-
-    /* Is tracemalloc tracing memory allocations?
-       Variable protected by the GIL */
-    int tracing;
-
-    /* limit of the number of frames in a traceback, 1 by default.
-       Variable protected by the GIL. */
-    int max_nframe;
-
-    /* use domain in trace key?
-       Variable protected by the GIL. */
-    int use_domain;
-};
-
-PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config;
-
-#define _PyTraceMalloc_Config_INIT \
-    {.initialized = TRACEMALLOC_NOT_INITIALIZED, \
-     .tracing = 0, \
-     .max_nframe = 1, \
-     .use_domain = 0}
-
 
 #ifndef Py_LIMITED_API
 #  define Py_CPYTHON_PYMEM_H
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
index 70219721b51cd..ddf6ef4e11dd4 100644
--- a/Modules/_tracemalloc.c
+++ b/Modules/_tracemalloc.c
@@ -1,4 +1,5 @@
 #include "Python.h"
+#include "pycore_pymem.h"
 #include "pycore_traceback.h"
 #include "hashtable.h"
 #include "frameobject.h"
diff --git a/Objects/object.c b/Objects/object.c
index 085605ae36714..e6bfad4e7295e 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -93,7 +93,7 @@ static PyObject refchain = {&refchain, &refchain};
  * way, though; exceptions include statically allocated type objects, and
  * statically allocated singletons (like Py_True and Py_None).
  */
-void
+static void
 _Py_AddToAllObjects(PyObject *op, int force)
 {
 #ifdef  Py_DEBUG
@@ -1805,6 +1805,22 @@ _PyTypes_Init(void)
 }
 
 
+void
+_Py_NewReference(PyObject *op)
+{
+    if (_Py_tracemalloc_config.tracing) {
+        _PyTraceMalloc_NewReference(op);
+    }
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal++;
+#endif
+    Py_REFCNT(op) = 1;
+#ifdef Py_TRACE_REFS
+    _Py_AddToAllObjects(op, 1);
+#endif
+}
+
+
 #ifdef Py_TRACE_REFS
 void
 _Py_ForgetReference(PyObject *op)



More information about the Python-checkins mailing list