Browse Source
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.
pull/18356/head
Victor Stinner
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with
54 additions and
55 deletions
Include/internal/pycore_pymem.h
Include/object.h
Include/pymem.h
Modules/_tracemalloc.c
Objects/object.c
@ -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
@ -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 )
@ -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
@ -1,4 +1,5 @@
# include "Python.h"
# include "pycore_pymem.h"
# include "pycore_traceback.h"
# include "hashtable.h"
# include "frameobject.h"
@ -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 )