[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.16.8.65,2.16.8.66

Guido van Rossum gvanrossum@users.sourceforge.net
Tue, 10 Jul 2001 17:57:11 -0700


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

Modified Files:
      Tag: descr-branch
	typeobject.c 
Log Message:
subtype_dealloc():
    - add some comments and an assert;
    - finalize GC if needed.

type_new():
    - always override the tp_alloc and tp_free slots;
    - install subtype_dealloc as the tp_dealloc slot.

Alas, the last bullet stabilizes the reference count of heap types
(previously, for each instance a reference was added but never
removed), but doesn't make them go away when the last reference goes.
Heap types have (at least) two references to themselves: one in tp_mro
and (at least) one added by add_members(), in the descriptor for
__dict__.  I suppose this means we have to make types GC'able, since
this is easily invoked in user code (e.g. a function defining a new
class will leak that class).


Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.16.8.65
retrieving revision 2.16.8.66
diff -C2 -r2.16.8.65 -r2.16.8.66
*** typeobject.c	2001/07/10 16:28:04	2.16.8.65
--- typeobject.c	2001/07/11 00:57:09	2.16.8.66
***************
*** 162,165 ****
--- 162,166 ----
  	/* This exists so we can DECREF self->ob_type */
  
+ 	/* Find the nearest base with a different tp_dealloc */
  	type = self->ob_type;
  	base = type->tp_base;
***************
*** 168,171 ****
--- 169,174 ----
  		assert(base);
  	}
+ 
+ 	/* If we added a dict, DECREF it */
  	if (dictoffset && !base->tp_dictoffset) {
  		PyObject **dictptr = (PyObject **) ((char *)self + dictoffset);
***************
*** 176,180 ****
--- 179,191 ----
  		}
  	}
+ 
+ 	/* Finalize GC if the base doesn't do GC and we do */
+ 	if (PyType_IS_GC(type) && !PyType_IS_GC(base))
+ 		PyObject_GC_Fini(self);
+ 
+ 	/* Call the base tp_dealloc() */
+ 	assert(f);
  	f(self);
+ 
  	/* Can't reference self beyond this point */
  	if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
***************
*** 638,645 ****
  			type->tp_setattro = PyObject_GenericSetAttr;
  	}
! 	if (base->tp_new == NULL)
! 		type->tp_new = PyType_GenericNew;
! 	if (base->tp_alloc == NULL)
! 		type->tp_alloc = PyType_GenericAlloc;
  
  	/* Initialize the rest */
--- 649,657 ----
  			type->tp_setattro = PyObject_GenericSetAttr;
  	}
! 	type->tp_dealloc = subtype_dealloc;
! 
! 	/* Always override allocation strategy to use regular heap */
! 	type->tp_alloc = PyType_GenericAlloc;
! 	type->tp_free = _PyObject_Del;
  
  	/* Initialize the rest */