[Python-checkins] python/dist/src/Objects classobject.c,2.159,2.160 object.c,2.185,2.186 stringobject.c,2.168,2.169 tupleobject.c,2.68,2.69 typeobject.c,2.157,2.158

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Wed, 10 Jul 2002 23:23:52 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv22768/python/Objects

Modified Files:
	classobject.c object.c stringobject.c tupleobject.c 
	typeobject.c 
Log Message:
object.h special-build macro minefield:  renamed all the new lexical
helper macros to something saner, and used them appropriately in other
files too, to reduce #ifdef blocks.

classobject.c, instance_dealloc():  One of my worst Python Memories is
trying to fix this routine a few years ago when COUNT_ALLOCS was defined
but Py_TRACE_REFS wasn't.  The special-build code here is way too
complicated.  Now it's much simpler.  Difference:  in a Py_TRACE_REFS
build, the instance is no longer in the doubly-linked list of live
objects while its __del__ method is executing, and that may be visible
via sys.getobjects() called from a __del__ method.  Tough -- the object
is presumed dead while its __del__ is executing anyway, and not calling
_Py_NewReference() at the start allows enormous code simplification.

typeobject.c, call_finalizer():  The special-build instance_dealloc()
pain apparently spread to here too via cut-'n-paste, and this is much
simpler now too.  In addition, I didn't understand why this routine
was calling _PyObject_GC_TRACK() after a resurrection, since there's no
plausible way _PyObject_GC_UNTRACK() could have been called on the
object by this point.  I suspect it was left over from pasting the
instance_delloc() code.  Instead asserted that the object is still
tracked.  Caution:  I suspect we don't have a test that actually
exercises the subtype_dealloc() __del__-resurrected-me code.


Index: classobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.159
retrieving revision 2.160
diff -C2 -d -r2.159 -r2.160
*** classobject.c	7 Jul 2002 03:59:34 -0000	2.159
--- classobject.c	11 Jul 2002 06:23:50 -0000	2.160
***************
*** 616,622 ****
  	PyObject *del;
  	static PyObject *delstr;
! #ifdef Py_REF_DEBUG
! 	extern long _Py_RefTotal;
! #endif
  	_PyObject_GC_UNTRACK(inst);
  	if (inst->in_weakreflist != NULL)
--- 616,620 ----
  	PyObject *del;
  	static PyObject *delstr;
! 
  	_PyObject_GC_UNTRACK(inst);
  	if (inst->in_weakreflist != NULL)
***************
*** 624,644 ****
  
  	/* Temporarily resurrect the object. */
! #ifdef Py_TRACE_REFS
! #ifndef Py_REF_DEBUG
! #   error "Py_TRACE_REFS defined but Py_REF_DEBUG not."
! #endif
! 	/* much too complicated if Py_TRACE_REFS defined */
! 	inst->ob_type = &PyInstance_Type;
! 	_Py_NewReference((PyObject *)inst);
! #ifdef COUNT_ALLOCS
! 	/* compensate for boost in _Py_NewReference; note that
! 	 * _Py_RefTotal was also boosted; we'll knock that down later.
! 	 */
! 	inst->ob_type->tp_allocs--;
! #endif
! #else /* !Py_TRACE_REFS */
! 	/* Py_INCREF boosts _Py_RefTotal if Py_REF_DEBUG is defined */
! 	Py_INCREF(inst);
! #endif /* !Py_TRACE_REFS */
  
  	/* Save the current exception, if any. */
--- 622,628 ----
  
  	/* Temporarily resurrect the object. */
! 	assert(inst->ob_type == &PyInstance_Type);
! 	assert(inst->ob_refcnt == 0);
! 	inst->ob_refcnt = 1;
  
  	/* Save the current exception, if any. */
***************
*** 657,686 ****
  	/* Restore the saved exception. */
  	PyErr_Restore(error_type, error_value, error_traceback);
  	/* Undo the temporary resurrection; can't use DECREF here, it would
  	 * cause a recursive call.
  	 */
! #ifdef Py_REF_DEBUG
! 	/* _Py_RefTotal was boosted either by _Py_NewReference or
! 	 * Py_INCREF above.
! 	 */
! 	_Py_RefTotal--;
! #endif
! 	if (--inst->ob_refcnt > 0) {
! #ifdef COUNT_ALLOCS
! 		inst->ob_type->tp_frees--;
! #endif
! 		_PyObject_GC_TRACK(inst);
! 		return; /* __del__ added a reference; don't delete now */
  	}
! #ifdef Py_TRACE_REFS
! 	_Py_ForgetReference((PyObject *)inst);
  #ifdef COUNT_ALLOCS
! 	/* compensate for increment in _Py_ForgetReference */
! 	inst->ob_type->tp_frees--;
! #endif
  #endif
! 	Py_DECREF(inst->in_class);
! 	Py_XDECREF(inst->in_dict);
! 	PyObject_GC_Del(inst);
  }
  
--- 641,675 ----
  	/* Restore the saved exception. */
  	PyErr_Restore(error_type, error_value, error_traceback);
+ 
  	/* Undo the temporary resurrection; can't use DECREF here, it would
  	 * cause a recursive call.
  	 */
! 	assert(inst->ob_refcnt > 0);
! 	if (--inst->ob_refcnt == 0) {
! 		Py_DECREF(inst->in_class);
! 		Py_XDECREF(inst->in_dict);
! 		PyObject_GC_Del(inst);
  	}
! 	else {
! 		int refcnt = inst->ob_refcnt;
! 		/* __del__ resurrected it!  Make it look like the original
! 		 * Py_DECREF never happened.
! 		 */
! 		_Py_NewReference((PyObject *)inst);
! 		inst->ob_refcnt = refcnt;
! 		_PyObject_GC_TRACK(inst);
! 		/* If Py_REF_DEBUG, the original decref dropped _Py_RefTotal,
! 		 * but _Py_NewReference bumped it again, so that's a wash.
! 		 * If Py_TRACE_REFS, _Py_NewReference re-added self to the
! 		 * object chain, so no more to do there either.
! 		 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
! 		 * _Py_NewReference bumped tp_allocs:  both of those need to
! 		 * be undone.
! 		 */
  #ifdef COUNT_ALLOCS
! 		--inst->ob_type->tp_frees;
! 		--inst->ob_type->tp_allocs;
  #endif
! 	}
  }
  
***************
*** 1098,1102 ****
  	if (!start)
  		return NULL;
! 	
  	end = PyInt_FromLong((long)j);
  	if (!end) {
--- 1087,1091 ----
  	if (!start)
  		return NULL;
! 
  	end = PyInt_FromLong((long)j);
  	if (!end) {
***************
*** 1132,1138 ****
  			return NULL;
  		arg = Py_BuildValue("(N)", sliceobj_from_intint(i, j));
! 	} else 
  		arg = Py_BuildValue("(ii)", i, j);
! 		
  	if (arg == NULL) {
  		Py_DECREF(func);
--- 1121,1127 ----
  			return NULL;
  		arg = Py_BuildValue("(N)", sliceobj_from_intint(i, j));
! 	} else
  		arg = Py_BuildValue("(ii)", i, j);
! 
  	if (arg == NULL) {
  		Py_DECREF(func);
***************
*** 1267,1271 ****
  		Py_DECREF(func);
  		Py_DECREF(arg);
! 		if(res == NULL) 
  			return -1;
  		ret = PyObject_IsTrue(res);
--- 1256,1260 ----
  		Py_DECREF(func);
  		Py_DECREF(arg);
! 		if(res == NULL)
  			return -1;
  		ret = PyObject_IsTrue(res);
***************
*** 1340,1344 ****
  /* Try one half of a binary operator involving a class instance. */
  static PyObject *
! half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc, 
  		int swapped)
  {
--- 1329,1333 ----
  /* Try one half of a binary operator involving a class instance. */
  static PyObject *
! half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc,
  		int swapped)
  {
***************
*** 1348,1352 ****
  	PyObject *v1;
  	PyObject *result;
! 	
  	if (!PyInstance_Check(v)) {
  		Py_INCREF(Py_NotImplemented);
--- 1337,1341 ----
  	PyObject *v1;
  	PyObject *result;
! 
  	if (!PyInstance_Check(v)) {
  		Py_INCREF(Py_NotImplemented);
***************
*** 1709,1713 ****
  static PyObject *
  instance_pow(PyObject *v, PyObject *w, PyObject *z)
! {	
  	if (z == Py_None) {
  		return do_binop(v, w, "__pow__", "__rpow__", bin_power);
--- 1698,1702 ----
  static PyObject *
  instance_pow(PyObject *v, PyObject *w, PyObject *z)
! {
  	if (z == Py_None) {
  		return do_binop(v, w, "__pow__", "__rpow__", bin_power);
***************
*** 1778,1782 ****
  static PyObject **name_op = NULL;
  
! static int 
  init_name_op(void)
  {
--- 1767,1771 ----
  static PyObject **name_op = NULL;
  
! static int
  init_name_op(void)
  {
***************
*** 1819,1823 ****
  	   exception on failure. */
  	if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) {
! 		method = instance_getattr2((PyInstanceObject *)v, 
  					   name_op[op]);
  		if (method == NULL) {
--- 1808,1812 ----
  	   exception on failure. */
  	if (((PyInstanceObject *)v)->in_class->cl_getattr == NULL) {
! 		method = instance_getattr2((PyInstanceObject *)v,
  					   name_op[op]);
  		if (method == NULL) {

Index: object.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v
retrieving revision 2.185
retrieving revision 2.186
diff -C2 -d -r2.185 -r2.186
*** object.c	9 Jul 2002 02:57:01 -0000	2.185
--- object.c	11 Jul 2002 06:23:50 -0000	2.186
***************
*** 8,12 ****
  #endif
  
! #if defined( Py_TRACE_REFS ) || defined( Py_REF_DEBUG )
  DL_IMPORT(long) _Py_RefTotal;
  #endif
--- 8,12 ----
  #endif
  
! #ifdef Py_REF_DEBUG
  DL_IMPORT(long) _Py_RefTotal;
  #endif
***************
*** 1877,1881 ****
  _Py_NewReference(PyObject *op)
  {
! 	_Py_RefTotal++;
  	op->ob_refcnt = 1;
  	op->_ob_next = refchain._ob_next;
--- 1877,1881 ----
  _Py_NewReference(PyObject *op)
  {
! 	_Py_INC_REFTOTAL;
  	op->ob_refcnt = 1;
  	op->_ob_next = refchain._ob_next;
***************
*** 1883,1887 ****
  	refchain._ob_next->_ob_prev = op;
  	refchain._ob_next = op;
! 	_PyMAYBE_BUMP_COUNT(op);
  }
  
--- 1883,1887 ----
  	refchain._ob_next->_ob_prev = op;
  	refchain._ob_next = op;
! 	_Py_INC_TPALLOCS(op);
  }
  
***************
*** 1908,1912 ****
  	op->_ob_prev->_ob_next = op->_ob_next;
  	op->_ob_next = op->_ob_prev = NULL;
! 	_PyMAYBE_BUMP_FREECOUNT(op);
  }
  
--- 1908,1912 ----
  	op->_ob_prev->_ob_next = op->_ob_next;
  	op->_ob_next = op->_ob_prev = NULL;
! 	_Py_INC_TPFREES(op);
  }
  

Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.168
retrieving revision 2.169
diff -C2 -d -r2.168 -r2.169
*** stringobject.c	14 Jun 2002 00:50:41 -0000	2.168
--- stringobject.c	11 Jul 2002 06:23:50 -0000	2.169
***************
*** 3061,3067 ****
  	}
  	/* XXX UNREF/NEWREF interface should be more symmetrical */
! #ifdef Py_REF_DEBUG
! 	--_Py_RefTotal;
! #endif
  	_Py_ForgetReference(v);
  	*pv = (PyObject *)
--- 3061,3065 ----
  	}
  	/* XXX UNREF/NEWREF interface should be more symmetrical */
! 	_Py_DEC_REFTOTAL;
  	_Py_ForgetReference(v);
  	*pv = (PyObject *)

Index: tupleobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v
retrieving revision 2.68
retrieving revision 2.69
diff -C2 -d -r2.68 -r2.69
*** tupleobject.c	20 Jun 2002 23:13:17 -0000	2.68
--- tupleobject.c	11 Jul 2002 06:23:50 -0000	2.69
***************
*** 678,684 ****
  
  	/* XXX UNREF/NEWREF interface should be more symmetrical */
! #ifdef Py_REF_DEBUG
! 	--_Py_RefTotal;
! #endif
  	_PyObject_GC_UNTRACK(v);
  	_Py_ForgetReference((PyObject *) v);
--- 678,682 ----
  
  	/* XXX UNREF/NEWREF interface should be more symmetrical */
! 	_Py_DEC_REFTOTAL;
  	_PyObject_GC_UNTRACK(v);
  	_Py_ForgetReference((PyObject *) v);

Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.157
retrieving revision 2.158
diff -C2 -d -r2.157 -r2.158
*** typeobject.c	24 Jun 2002 13:08:14 -0000	2.157
--- typeobject.c	11 Jul 2002 06:23:50 -0000	2.158
***************
*** 366,385 ****
  
  	/* Temporarily resurrect the object. */
! #ifdef Py_TRACE_REFS
! #ifndef Py_REF_DEBUG
! #   error "Py_TRACE_REFS defined but Py_REF_DEBUG not."
! #endif
! 	/* much too complicated if Py_TRACE_REFS defined */
! 	_Py_NewReference((PyObject *)self);
! #ifdef COUNT_ALLOCS
! 	/* compensate for boost in _Py_NewReference; note that
! 	 * _Py_RefTotal was also boosted; we'll knock that down later.
! 	 */
! 	self->ob_type->tp_allocs--;
! #endif
! #else /* !Py_TRACE_REFS */
! 	/* Py_INCREF boosts _Py_RefTotal if Py_REF_DEBUG is defined */
! 	Py_INCREF(self);
! #endif /* !Py_TRACE_REFS */
  
  	/* Save the current exception, if any. */
--- 366,371 ----
  
  	/* Temporarily resurrect the object. */
! 	assert(self->ob_refcnt == 0);
! 	self->ob_refcnt = 1;
  
  	/* Save the current exception, if any. */
***************
*** 403,428 ****
  	 * cause a recursive call.
  	 */
! #ifdef Py_REF_DEBUG
! 	/* _Py_RefTotal was boosted either by _Py_NewReference or
! 	 * Py_INCREF above.
  	 */
! 	_Py_RefTotal--;
! #endif
! 	if (--self->ob_refcnt > 0) {
! #ifdef COUNT_ALLOCS
! 		self->ob_type->tp_frees--;
! #endif
! 		_PyObject_GC_TRACK(self);
! 		return -1; /* __del__ added a reference; don't delete now */
  	}
! #ifdef Py_TRACE_REFS
! 	_Py_ForgetReference((PyObject *)self);
  #ifdef COUNT_ALLOCS
! 	/* compensate for increment in _Py_ForgetReference */
! 	self->ob_type->tp_frees--;
! #endif
  #endif
! 
! 	return 0;
  }
  
--- 389,418 ----
  	 * cause a recursive call.
  	 */
! 	assert(self->ob_refcnt > 0);
! 	if (--self->ob_refcnt == 0)
! 		return 0;	/* this is the normal path out */
! 
! 	/* __del__ resurrected it!  Make it look like the original Py_DECREF
! 	 * never happened.
  	 */
! 	{
! 		int refcnt = self->ob_refcnt;
! 		_Py_NewReference(self);
! 		self->ob_refcnt = refcnt;
  	}
! 	assert(_Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
! 	/* If Py_REF_DEBUG, the original decref dropped _Py_RefTotal, but
! 	 * _Py_NewReference bumped it again, so that's a wash.
! 	 * If Py_TRACE_REFS, _Py_NewReference re-added self to the object
! 	 * chain, so no more to do there either.
! 	 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
! 	 * _Py_NewReference bumped tp_allocs:  both of those need to be
! 	 * undone.
! 	 */
  #ifdef COUNT_ALLOCS
! 	--self->ob_type->tp_frees;
! 	--self->ob_type->tp_allocs;
  #endif
! 	return -1; /* __del__ added a reference; don't delete now */
  }
  
***************
*** 1388,1392 ****
  	/* No readable descriptor found yet */
  	meta_get = NULL;
! 		
  	/* Look for the attribute in the metatype */
  	meta_attribute = _PyType_Lookup(metatype, name);
--- 1378,1382 ----
  	/* No readable descriptor found yet */
  	meta_get = NULL;
! 
  	/* Look for the attribute in the metatype */
  	meta_attribute = _PyType_Lookup(metatype, name);
***************
*** 1394,1398 ****
  	if (meta_attribute != NULL) {
  		meta_get = meta_attribute->ob_type->tp_descr_get;
! 				
  		if (meta_get != NULL && PyDescr_IsData(meta_attribute)) {
  			/* Data descriptors implement tp_descr_set to intercept
--- 1384,1388 ----
  	if (meta_attribute != NULL) {
  		meta_get = meta_attribute->ob_type->tp_descr_get;
! 
  		if (meta_get != NULL && PyDescr_IsData(meta_attribute)) {
  			/* Data descriptors implement tp_descr_set to intercept
***************
*** 1417,1421 ****
  					 (PyObject *)type);
  		}
! 		
  		Py_INCREF(attribute);
  		return attribute;
--- 1407,1411 ----
  					 (PyObject *)type);
  		}
! 
  		Py_INCREF(attribute);
  		return attribute;