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.
This commit is contained in:
Victor Stinner 2020-02-05 01:11:10 +01:00 committed by GitHub
parent 2545fa8762
commit 40e547dfbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 55 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -1,4 +1,5 @@
#include "Python.h"
#include "pycore_pymem.h"
#include "pycore_traceback.h"
#include "hashtable.h"
#include "frameobject.h"

View File

@ -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)