mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Rearranged and added comments to object.h, to clarify many things
that have taken me "too long" to reverse-engineer over the years. Vastly reduced the nesting level and redundancy of #ifdef-ery. Took a light stab at repairing comments that are no longer true. sys_gettotalrefcount(): Changed to enable under Py_REF_DEBUG. It was enabled under Py_TRACE_REFS, which was much heavier than necessary. sys.gettotalrefcount() is now available in a Py_REF_DEBUG-only build.
This commit is contained in:
		
							parent
							
								
									144dea3e05
								
							
						
					
					
						commit
						4be93d0e84
					
				
					 3 changed files with 133 additions and 90 deletions
				
			
		
							
								
								
									
										200
									
								
								Include/object.h
									
										
									
									
									
								
							
							
						
						
									
										200
									
								
								Include/object.h
									
										
									
									
									
								
							| 
						 | 
					@ -13,7 +13,8 @@ the use of objects to ensure they are properly garbage-collected.
 | 
				
			||||||
Objects are never allocated statically or on the stack; they must be
 | 
					Objects are never allocated statically or on the stack; they must be
 | 
				
			||||||
accessed through special macros and functions only.  (Type objects are
 | 
					accessed through special macros and functions only.  (Type objects are
 | 
				
			||||||
exceptions to the first rule; the standard types are represented by
 | 
					exceptions to the first rule; the standard types are represented by
 | 
				
			||||||
statically initialized type objects.)
 | 
					statically initialized type objects, although work on type/class unification
 | 
				
			||||||
 | 
					for Python 2.2 made it possible to have heap-allocated type objects too).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
An object has a 'reference count' that is increased or decreased when a
 | 
					An object has a 'reference count' that is increased or decreased when a
 | 
				
			||||||
pointer to the object is copied or deleted; when the reference count
 | 
					pointer to the object is copied or deleted; when the reference count
 | 
				
			||||||
| 
						 | 
					@ -51,32 +52,76 @@ whose size is determined when the object is allocated.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef Py_DEBUG
 | 
					#ifdef Py_DEBUG
 | 
				
			||||||
 | 
					/* Turn on aggregate reference counting.  This arranges that extern
 | 
				
			||||||
/* Turn on heavy reference debugging */
 | 
					 * _Py_RefTotal hold a count of all references, the sum of ob_refcnt
 | 
				
			||||||
#define Py_TRACE_REFS
 | 
					 * across all objects.  The value can be gotten programatically via
 | 
				
			||||||
 | 
					 * sys.gettotalrefcount() (which exists only if Py_REF_DEBUG is enabled).
 | 
				
			||||||
/* Turn on reference counting */
 | 
					 * In a debug-mode build, this is where the "8288" comes from in
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  >>> 23
 | 
				
			||||||
 | 
					 *  23
 | 
				
			||||||
 | 
					 *  [8288 refs]
 | 
				
			||||||
 | 
					 *  >>>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note that if this count increases when you're not storing away new objects,
 | 
				
			||||||
 | 
					 * there's probably a leak.  Remember, though, that in interactive mode the
 | 
				
			||||||
 | 
					 * special name "_" holds a reference to the last result displayed!
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
#define Py_REF_DEBUG
 | 
					#define Py_REF_DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Turn on heavy reference debugging.  This is major surgery.  Every PyObject
 | 
				
			||||||
 | 
					 * grows two more pointers, to maintain a doubly-linked list of all live
 | 
				
			||||||
 | 
					 * heap-allocated objects (note that, e.g., most builtin type objects are
 | 
				
			||||||
 | 
					 * not in this list, as they're statically allocated).  This list can be
 | 
				
			||||||
 | 
					 * materialized into a Python list via sys.getobjects() (which exists only
 | 
				
			||||||
 | 
					 * if Py_TRACE_REFS is enabled).  Py_TRACE_REFS implies Py_REF_DEBUG.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define Py_TRACE_REFS
 | 
				
			||||||
#endif /* Py_DEBUG */
 | 
					#endif /* Py_DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef Py_TRACE_REFS
 | 
					/* Py_TRACE_REFS implies Py_REF_DEBUG. */
 | 
				
			||||||
#define PyObject_HEAD \
 | 
					#if defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG)
 | 
				
			||||||
	struct _object *_ob_next, *_ob_prev; \
 | 
					#define Py_REF_DEBUG
 | 
				
			||||||
	int ob_refcnt; \
 | 
					#endif
 | 
				
			||||||
	struct _typeobject *ob_type;
 | 
					 | 
				
			||||||
#define PyObject_HEAD_INIT(type) 0, 0, 1, type,
 | 
					 | 
				
			||||||
#else /* !Py_TRACE_REFS */
 | 
					 | 
				
			||||||
#define PyObject_HEAD \
 | 
					 | 
				
			||||||
	int ob_refcnt; \
 | 
					 | 
				
			||||||
	struct _typeobject *ob_type;
 | 
					 | 
				
			||||||
#define PyObject_HEAD_INIT(type) 1, type,
 | 
					 | 
				
			||||||
#endif /* !Py_TRACE_REFS */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef Py_TRACE_REFS
 | 
				
			||||||
 | 
					/* Define pointers to support a doubly-linked list of all live heap objects. */
 | 
				
			||||||
 | 
					#define _PyObject_HEAD_EXTRA		\
 | 
				
			||||||
 | 
						struct _object *_ob_next;	\
 | 
				
			||||||
 | 
						struct _object *_ob_prev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _PyObject_EXTRA_INIT 0, 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define _PyObject_HEAD_EXTRA
 | 
				
			||||||
 | 
					#define _PyObject_EXTRA_INIT
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* PyObject_HEAD defines the initial segment of every PyObject. */
 | 
				
			||||||
 | 
					#define PyObject_HEAD			\
 | 
				
			||||||
 | 
						_PyObject_HEAD_EXTRA		\
 | 
				
			||||||
 | 
						int ob_refcnt;			\
 | 
				
			||||||
 | 
						struct _typeobject *ob_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PyObject_HEAD_INIT(type)	\
 | 
				
			||||||
 | 
						_PyObject_EXTRA_INIT		\
 | 
				
			||||||
 | 
						1, type,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* PyObject_VAR_HEAD defines the initial segment of all variable-size
 | 
				
			||||||
 | 
					 * container objects.  These end with a declaration of an array with 1
 | 
				
			||||||
 | 
					 * element, but enough space is malloc'ed so that the array actually
 | 
				
			||||||
 | 
					 * has room for ob_size elements.  Note that ob_size is an element count,
 | 
				
			||||||
 | 
					 * not necessarily a byte count.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
#define PyObject_VAR_HEAD		\
 | 
					#define PyObject_VAR_HEAD		\
 | 
				
			||||||
	PyObject_HEAD			\
 | 
						PyObject_HEAD			\
 | 
				
			||||||
	int ob_size; /* Number of items in variable part */
 | 
						int ob_size; /* Number of items in variable part */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Nothing is actually declared to be a PyObject, but every pointer to
 | 
				
			||||||
 | 
					 * a Python object can be cast to a PyObject*.  This is inheritance built
 | 
				
			||||||
 | 
					 * by hand.  Similarly every pointer to a variable-size Python object can,
 | 
				
			||||||
 | 
					 * in addition, be cast to PyVarObject*.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
typedef struct _object {
 | 
					typedef struct _object {
 | 
				
			||||||
	PyObject_HEAD
 | 
						PyObject_HEAD
 | 
				
			||||||
} PyObject;
 | 
					} PyObject;
 | 
				
			||||||
| 
						 | 
					@ -88,13 +133,14 @@ typedef struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
Type objects contain a string containing the type name (to help somewhat
 | 
					Type objects contain a string containing the type name (to help somewhat
 | 
				
			||||||
in debugging), the allocation parameters (see newobj() and newvarobj()),
 | 
					in debugging), the allocation parameters (see PyObject_New() and
 | 
				
			||||||
 | 
					PyObject_NewVar()),
 | 
				
			||||||
and methods for accessing objects of the type.  Methods are optional, a
 | 
					and methods for accessing objects of the type.  Methods are optional, a
 | 
				
			||||||
nil pointer meaning that particular kind of access is not available for
 | 
					nil pointer meaning that particular kind of access is not available for
 | 
				
			||||||
this type.  The Py_DECREF() macro uses the tp_dealloc method without
 | 
					this type.  The Py_DECREF() macro uses the tp_dealloc method without
 | 
				
			||||||
checking for a nil pointer; it should always be implemented except if
 | 
					checking for a nil pointer; it should always be implemented except if
 | 
				
			||||||
the implementation can guarantee that the reference count will never
 | 
					the implementation can guarantee that the reference count will never
 | 
				
			||||||
reach zero (e.g., for type objects).
 | 
					reach zero (e.g., for statically allocated type objects).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NB: the methods for certain type groups are now contained in separate
 | 
					NB: the methods for certain type groups are now contained in separate
 | 
				
			||||||
method blocks.
 | 
					method blocks.
 | 
				
			||||||
| 
						 | 
					@ -121,7 +167,7 @@ typedef int (*traverseproc)(PyObject *, visitproc, void *);
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	/* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all
 | 
						/* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all
 | 
				
			||||||
	   arguments are guaranteed to be of the object's type (modulo
 | 
						   arguments are guaranteed to be of the object's type (modulo
 | 
				
			||||||
	   coercion hacks that is -- i.e. if the type's coercion function
 | 
						   coercion hacks -- i.e. if the type's coercion function
 | 
				
			||||||
	   returns other types, then these are allowed as well).  Numbers that
 | 
						   returns other types, then these are allowed as well).  Numbers that
 | 
				
			||||||
	   have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both*
 | 
						   have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both*
 | 
				
			||||||
	   arguments for proper type and implement the necessary conversions
 | 
						   arguments for proper type and implement the necessary conversions
 | 
				
			||||||
| 
						 | 
					@ -378,8 +424,7 @@ extern DL_IMPORT(long) _Py_HashPointer(void*);
 | 
				
			||||||
#define Py_PRINT_RAW	1	/* No string quotes etc. */
 | 
					#define Py_PRINT_RAW	1	/* No string quotes etc. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 | 
					`Type flags (tp_flags)
 | 
				
			||||||
Type flags (tp_flags)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
These flags are used to extend the type structure in a backwards-compatible
 | 
					These flags are used to extend the type structure in a backwards-compatible
 | 
				
			||||||
fashion. Extensions can use the flags to indicate (and test) when a given
 | 
					fashion. Extensions can use the flags to indicate (and test) when a given
 | 
				
			||||||
| 
						 | 
					@ -397,7 +442,6 @@ Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
 | 
					Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
 | 
				
			||||||
given type object has a specified feature.
 | 
					given type object has a specified feature.
 | 
				
			||||||
 | 
					 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* PyBufferProcs contains bf_getcharbuffer */
 | 
					/* PyBufferProcs contains bf_getcharbuffer */
 | 
				
			||||||
| 
						 | 
					@ -458,18 +502,25 @@ given type object has a specified feature.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement
 | 
					The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement
 | 
				
			||||||
reference counts.  Py_DECREF calls the object's deallocator function; for
 | 
					reference counts.  Py_DECREF calls the object's deallocator function when
 | 
				
			||||||
 | 
					the refcount falls to 0; for
 | 
				
			||||||
objects that don't contain references to other objects or heap memory
 | 
					objects that don't contain references to other objects or heap memory
 | 
				
			||||||
this can be the standard function free().  Both macros can be used
 | 
					this can be the standard function free().  Both macros can be used
 | 
				
			||||||
wherever a void expression is allowed.  The argument shouldn't be a
 | 
					wherever a void expression is allowed.  The argument must not be a
 | 
				
			||||||
NIL pointer.  The macro _Py_NewReference(op) is used only to initialize
 | 
					NIL pointer.  If it may be NIL, use Py_XINCREF/Py_XDECREF instead.
 | 
				
			||||||
reference counts to 1; it is defined here for convenience.
 | 
					The macro _Py_NewReference(op) initialize reference counts to 1, and
 | 
				
			||||||
 | 
					in special builds (Py_REF_DEBUG, Py_TRACE_REFS) performs additional
 | 
				
			||||||
 | 
					bookkeeping appropriate to the special build.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We assume that the reference count field can never overflow; this can
 | 
					We assume that the reference count field can never overflow; this can
 | 
				
			||||||
be proven when the size of the field is the same as the pointer size
 | 
					be proven when the size of the field is the same as the pointer size, so
 | 
				
			||||||
but even with a 16-bit reference count field it is pretty unlikely so
 | 
					we ignore the possibility.  Provided a C int is at least 32 bits (which
 | 
				
			||||||
we ignore the possibility.  (If you are paranoid, make it a long.)
 | 
					is implicitly assumed in many parts of this code), that's enough for
 | 
				
			||||||
 | 
					about 2**31 references to an object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					XXX The following became out of date in Python 2.2, but I'm not sure
 | 
				
			||||||
 | 
					XXX what the full truth is now.  Certainly, heap-allocated type objects
 | 
				
			||||||
 | 
					XXX can and should be deallocated.
 | 
				
			||||||
Type objects should never be deallocated; the type pointer in an object
 | 
					Type objects should never be deallocated; the type pointer in an object
 | 
				
			||||||
is not considered to be a reference to the type object, to save
 | 
					is not considered to be a reference to the type object, to save
 | 
				
			||||||
complications in the deallocation function.  (This is actually a
 | 
					complications in the deallocation function.  (This is actually a
 | 
				
			||||||
| 
						 | 
					@ -483,62 +534,60 @@ variable first, both of which are slower; and in a multi-threaded
 | 
				
			||||||
environment the global variable trick is not safe.)
 | 
					environment the global variable trick is not safe.)
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef Py_TRACE_REFS
 | 
					#ifdef Py_REF_DEBUG
 | 
				
			||||||
#ifndef Py_REF_DEBUG
 | 
					extern DL_IMPORT(long) _Py_RefTotal;
 | 
				
			||||||
#define Py_REF_DEBUG
 | 
					#define _PyMAYBE_BUMP_REFTOTAL	_Py_RefTotal++
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define _PyMAYBE_BUMP_REFTOTAL	(void)0
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef Py_TRACE_REFS
 | 
					 | 
				
			||||||
extern DL_IMPORT(void) _Py_Dealloc(PyObject *);
 | 
					 | 
				
			||||||
extern DL_IMPORT(void) _Py_NewReference(PyObject *);
 | 
					 | 
				
			||||||
extern DL_IMPORT(void) _Py_ForgetReference(PyObject *);
 | 
					 | 
				
			||||||
extern DL_IMPORT(void) _Py_PrintReferences(FILE *);
 | 
					 | 
				
			||||||
extern DL_IMPORT(void) _Py_ResetReferences(void);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef Py_TRACE_REFS
 | 
					 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					 | 
				
			||||||
#define _Py_Dealloc(op) ((op)->ob_type->tp_frees++, (*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
 | 
					 | 
				
			||||||
#define _Py_ForgetReference(op) ((op)->ob_type->tp_frees++)
 | 
					 | 
				
			||||||
#else /* !COUNT_ALLOCS */
 | 
					 | 
				
			||||||
#define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op))
 | 
					 | 
				
			||||||
#define _Py_ForgetReference(op) /*empty*/
 | 
					 | 
				
			||||||
#endif /* !COUNT_ALLOCS */
 | 
					 | 
				
			||||||
#endif /* !Py_TRACE_REFS */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					#ifdef COUNT_ALLOCS
 | 
				
			||||||
extern DL_IMPORT(void) inc_count(PyTypeObject *);
 | 
					extern DL_IMPORT(void) inc_count(PyTypeObject *);
 | 
				
			||||||
#endif
 | 
					#define _PyMAYBE_BUMP_COUNT(OP)		inc_count((OP)->ob_type)
 | 
				
			||||||
 | 
					#define _PyMAYBE_BUMP_FREECOUNT(OP)	(OP)->ob_type->tp_frees++
 | 
				
			||||||
#ifdef Py_REF_DEBUG
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern DL_IMPORT(long) _Py_RefTotal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef Py_TRACE_REFS
 | 
					 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					 | 
				
			||||||
#define _Py_NewReference(op) (inc_count((op)->ob_type), _Py_RefTotal++, (op)->ob_refcnt = 1)
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define _Py_NewReference(op) (_Py_RefTotal++, (op)->ob_refcnt = 1)
 | 
					#define _PyMAYBE_BUMP_COUNT(OP)		(void)0
 | 
				
			||||||
 | 
					#define _PyMAYBE_BUMP_FREECOUNT(OP)	(void)0
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef Py_TRACE_REFS
 | 
				
			||||||
 | 
					/* Py_TRACE_REFS is such major surgery that we call external routines. */
 | 
				
			||||||
 | 
					extern DL_IMPORT(void) _Py_NewReference(PyObject *);
 | 
				
			||||||
 | 
					extern DL_IMPORT(void) _Py_ForgetReference(PyObject *);
 | 
				
			||||||
 | 
					extern DL_IMPORT(void) _Py_Dealloc(PyObject *);
 | 
				
			||||||
 | 
					extern DL_IMPORT(void) _Py_PrintReferences(FILE *);
 | 
				
			||||||
 | 
					extern DL_IMPORT(void) _Py_ResetReferences(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					/* Without Py_TRACE_REFS, there's little enough to do that we expand code
 | 
				
			||||||
 | 
					 * inline.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define _Py_NewReference(op) (		\
 | 
				
			||||||
 | 
						_PyMAYBE_BUMP_COUNT(op),	\
 | 
				
			||||||
 | 
						_PyMAYBE_BUMP_REFTOTAL, 	\
 | 
				
			||||||
 | 
						(op)->ob_refcnt = 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _Py_ForgetReference(op) (_PyMAYBE_BUMP_FREECOUNT(op))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _Py_Dealloc(op) (		\
 | 
				
			||||||
 | 
						_Py_ForgetReference(op),	\
 | 
				
			||||||
 | 
						(*(op)->ob_type->tp_dealloc)((PyObject *)(op)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !Py_TRACE_REFS */
 | 
					#endif /* !Py_TRACE_REFS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define Py_INCREF(op) (_Py_RefTotal++, (op)->ob_refcnt++)
 | 
					#define Py_INCREF(op) (			\
 | 
				
			||||||
 | 
						_PyMAYBE_BUMP_REFTOTAL,		\
 | 
				
			||||||
 | 
						(op)->ob_refcnt++)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef Py_REF_DEBUG
 | 
				
			||||||
/* under Py_REF_DEBUG: also log negative ref counts after Py_DECREF() !! */
 | 
					/* under Py_REF_DEBUG: also log negative ref counts after Py_DECREF() !! */
 | 
				
			||||||
#define Py_DECREF(op)							\
 | 
					#define Py_DECREF(op)							\
 | 
				
			||||||
       if (--_Py_RefTotal, 0 < (--((op)->ob_refcnt))) ;			\
 | 
					       if (--_Py_RefTotal, 0 < (--((op)->ob_refcnt))) ;			\
 | 
				
			||||||
       else if (0 == (op)->ob_refcnt) _Py_Dealloc( (PyObject*)(op));	\
 | 
					       else if (0 == (op)->ob_refcnt) _Py_Dealloc( (PyObject*)(op));	\
 | 
				
			||||||
       else ((void)fprintf(stderr, "%s:%i negative ref count %i\n",	\
 | 
					       else ((void)fprintf(stderr, "%s:%i negative ref count %i\n",	\
 | 
				
			||||||
		           __FILE__, __LINE__, (op)->ob_refcnt), abort())
 | 
							           __FILE__, __LINE__, (op)->ob_refcnt), abort())
 | 
				
			||||||
#else /* !Py_REF_DEBUG */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
					 | 
				
			||||||
#define _Py_NewReference(op) (inc_count((op)->ob_type), (op)->ob_refcnt = 1)
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define _Py_NewReference(op) ((op)->ob_refcnt = 1)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define Py_INCREF(op) ((op)->ob_refcnt++)
 | 
					 | 
				
			||||||
#define Py_DECREF(op) \
 | 
					#define Py_DECREF(op) \
 | 
				
			||||||
	if (--(op)->ob_refcnt != 0) \
 | 
						if (--(op)->ob_refcnt != 0) \
 | 
				
			||||||
		; \
 | 
							; \
 | 
				
			||||||
| 
						 | 
					@ -547,7 +596,6 @@ extern DL_IMPORT(long) _Py_RefTotal;
 | 
				
			||||||
#endif /* !Py_REF_DEBUG */
 | 
					#endif /* !Py_REF_DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Macros to use in case the object pointer may be NULL: */
 | 
					/* Macros to use in case the object pointer may be NULL: */
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op)
 | 
					#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op)
 | 
				
			||||||
#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op)
 | 
					#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -557,18 +605,14 @@ where NULL (nil) is not suitable (since NULL often means 'error').
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Don't forget to apply Py_INCREF() when returning this value!!!
 | 
					Don't forget to apply Py_INCREF() when returning this value!!!
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					 | 
				
			||||||
extern DL_IMPORT(PyObject) _Py_NoneStruct; /* Don't use this directly */
 | 
					extern DL_IMPORT(PyObject) _Py_NoneStruct; /* Don't use this directly */
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define Py_None (&_Py_NoneStruct)
 | 
					#define Py_None (&_Py_NoneStruct)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
Py_NotImplemented is a singleton used to signal that an operation is
 | 
					Py_NotImplemented is a singleton used to signal that an operation is
 | 
				
			||||||
not implemented for a given type combination.
 | 
					not implemented for a given type combination.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					 | 
				
			||||||
extern DL_IMPORT(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
 | 
					extern DL_IMPORT(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define Py_NotImplemented (&_Py_NotImplementedStruct)
 | 
					#define Py_NotImplemented (&_Py_NotImplementedStruct)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Rich comparison opcodes */
 | 
					/* Rich comparison opcodes */
 | 
				
			||||||
| 
						 | 
					@ -624,7 +668,9 @@ is set (see errors.h), and the function result differs: functions that
 | 
				
			||||||
normally return a pointer return NULL for failure, functions returning
 | 
					normally return a pointer return NULL for failure, functions returning
 | 
				
			||||||
an integer return -1 (which could be a legal return value too!), and
 | 
					an integer return -1 (which could be a legal return value too!), and
 | 
				
			||||||
other functions return 0 for success and -1 for failure.
 | 
					other functions return 0 for success and -1 for failure.
 | 
				
			||||||
Callers should always check for errors before using the result.
 | 
					Callers should always check for errors before using the result.  If
 | 
				
			||||||
 | 
					an error was set, the caller must either explicitly clear it, or pass
 | 
				
			||||||
 | 
					the error on to its caller.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Reference Counts
 | 
					Reference Counts
 | 
				
			||||||
----------------
 | 
					----------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1858,9 +1858,7 @@ _Py_NewReference(PyObject *op)
 | 
				
			||||||
	op->_ob_prev = &refchain;
 | 
						op->_ob_prev = &refchain;
 | 
				
			||||||
	refchain._ob_next->_ob_prev = op;
 | 
						refchain._ob_next->_ob_prev = op;
 | 
				
			||||||
	refchain._ob_next = op;
 | 
						refchain._ob_next = op;
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
						_PyMAYBE_BUMP_COUNT(op);
 | 
				
			||||||
	inc_count(op->ob_type);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -1885,9 +1883,7 @@ _Py_ForgetReference(register PyObject *op)
 | 
				
			||||||
	op->_ob_next->_ob_prev = op->_ob_prev;
 | 
						op->_ob_next->_ob_prev = op->_ob_prev;
 | 
				
			||||||
	op->_ob_prev->_ob_next = op->_ob_next;
 | 
						op->_ob_prev->_ob_next = op->_ob_next;
 | 
				
			||||||
	op->_ob_next = op->_ob_prev = NULL;
 | 
						op->_ob_next = op->_ob_prev = NULL;
 | 
				
			||||||
#ifdef COUNT_ALLOCS
 | 
						_PyMAYBE_BUMP_FREECOUNT(op);
 | 
				
			||||||
	op->ob_type->tp_frees++;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -469,11 +469,10 @@ sys_getrefcount(PyObject *self, PyObject *arg)
 | 
				
			||||||
	return PyInt_FromLong(arg->ob_refcnt);
 | 
						return PyInt_FromLong(arg->ob_refcnt);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef Py_TRACE_REFS
 | 
					#ifdef Py_REF_DEBUG
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
sys_gettotalrefcount(PyObject *self)
 | 
					sys_gettotalrefcount(PyObject *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	extern long _Py_RefTotal;
 | 
					 | 
				
			||||||
	return PyInt_FromLong(_Py_RefTotal);
 | 
						return PyInt_FromLong(_Py_RefTotal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -564,6 +563,8 @@ static PyMethodDef sys_methods[] = {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef Py_TRACE_REFS
 | 
					#ifdef Py_TRACE_REFS
 | 
				
			||||||
	{"getobjects",	_Py_GetObjects, METH_VARARGS},
 | 
						{"getobjects",	_Py_GetObjects, METH_VARARGS},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef Py_REF_DEBUG
 | 
				
			||||||
	{"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS},
 | 
						{"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS},
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	{"getrefcount",	(PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
 | 
						{"getrefcount",	(PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue