Index: 0.12/Include/objimpl.h *** 0.12/Include/objimpl.h Fri, 23 Jun 2000 16:21:08 -0600 nas (python/o/19_objimpl.h 1.1.2.1.2.1 644) --- nogc.9(w)/Include/objimpl.h Thu, 29 Jun 2000 07:52:34 -0600 nas (python/o/19_objimpl.h 1.1.2.1.2.1.1.3 644) *************** *** 203,209 **** ( (type *) PyObject_InitVar( \ (PyVarObject *) PyObject_MALLOC( _PyObject_VAR_SIZE((typeobj),(n)) ),\ (typeobj), (n)) ) - #define PyObject_DEL(op) PyObject_FREE(op) /* This example code implements an object constructor with a custom allocator, where PyObject_New is inlined, and shows the important --- 203,208 ---- *************** *** 234,244 **** the 1st step is performed automatically for you, so in a C++ class constructor you would start directly with PyObject_Init/InitVar. */ ! #ifndef WITH_CYCLE_GC ! #define PyGC_INFO_SIZE 0 ! #endif #ifdef __cplusplus } --- 233,263 ---- the 1st step is performed automatically for you, so in a C++ class constructor you would start directly with PyObject_Init/InitVar. */ ! /* ! * Garbage Collection Support ! * ========================== ! */ ! ! /* To make a new object participate in garbage collection use ! PyObject_{New, NewVar, Del} to manage the memory. Set the type flag ! Py_TPFLAGS_GC and define the type method tp_traverse. You should also ! add the method tp_clear if your object is mutable. Include ! PyGC_INFO_SIZE in the calculation of tp_basicsize. Call ! PyObject_GC_Init after the pointers followed by tp_traverse become ! valid (usually just before returning the object from the allocation ! method. Call PyObject_GC_Fini before those pointers become invalid ! (usually at the top of the deallocation method). */ #ifndef WITH_CYCLE_GC ! ! #define PyGC_HEAD_SIZE 0 ! #define PyObject_GC_Init(op) ! #define PyObject_GC_Fini(op) ! #define PyObject_AS_GC(op) (op) ! #define PyObject_FROM_GC(op) (op) ! #define PyObject_DEL(op) PyObject_FREE(op) ! ! #endif /* WITH_CYCLE_GC */ #ifdef __cplusplus } Index: 0.12/Modules/cPickle.c *** 0.12/Modules/cPickle.c Thu, 29 Jun 2000 08:04:29 -0600 nas (python/C/27_cPickle.c 1.1.2.2.4.1 644) --- nogc.9(w)/Modules/cPickle.c Thu, 29 Jun 2000 08:05:44 -0600 nas (python/C/27_cPickle.c 1.1.2.2.4.2 644) *************** *** 2892,2898 **** Py_DECREF(inst); goto err; } ! return (PyObject *)inst; } Py_DECREF(__getinitargs__); --- 2892,2898 ---- Py_DECREF(inst); goto err; } ! PyObject_GC_Init(inst); return (PyObject *)inst; } Py_DECREF(__getinitargs__); Index: 0.12/Modules/newmodule.c *** 0.12/Modules/newmodule.c Mon, 08 May 2000 12:24:03 -0600 nas (python/D/13_newmodule. 1.1.2.1 644) --- nogc.9(w)/Modules/newmodule.c Tue, 27 Jun 2000 21:08:29 -0600 nas (python/D/13_newmodule. 1.1.2.1.3.1 644) *************** *** 56,61 **** --- 56,62 ---- Py_INCREF(dict); inst->in_class = (PyClassObject *)klass; inst->in_dict = dict; + PyObject_GC_Init(inst); return (PyObject *)inst; } Index: 0.12/Objects/classobject.c *** 0.12/Objects/classobject.c Thu, 29 Jun 2000 08:04:29 -0600 nas (python/E/16_classobjec 1.1.2.2.2.1.2.1 644) --- nogc.9(w)/Objects/classobject.c Thu, 29 Jun 2000 08:05:45 -0600 nas (python/E/16_classobjec 1.1.2.2.2.1.2.2 644) *************** *** 132,137 **** --- 132,138 ---- Py_XINCREF(op->cl_getattr); Py_XINCREF(op->cl_setattr); Py_XINCREF(op->cl_delattr); + PyObject_GC_Init(op); return (PyObject *) op; } *************** *** 141,146 **** --- 142,148 ---- class_dealloc(op) PyClassObject *op; { + PyObject_GC_Fini(op); Py_DECREF(op->cl_bases); Py_DECREF(op->cl_dict); Py_XDECREF(op->cl_name); *************** *** 428,434 **** PyObject_HEAD_INIT(&PyType_Type) 0, "class", ! sizeof(PyClassObject) + PyGC_INFO_SIZE, 0, (destructor)class_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ --- 430,436 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "class", ! sizeof(PyClassObject) + PyGC_HEAD_SIZE, 0, (destructor)class_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ *************** *** 490,495 **** --- 492,498 ---- if (inst == NULL) return NULL; inst->in_dict = PyDict_New(); + PyObject_GC_Init(inst); if (inst->in_dict == NULL) { PyObject_DEL(inst); return NULL; *************** *** 539,549 **** PyObject *error_type, *error_value, *error_traceback; PyObject *del; static PyObject *delstr; /* Call the __del__ method if it exists. First temporarily revive the object and save the current exception, if any. */ #ifdef Py_TRACE_REFS /* much too complicated if Py_TRACE_REFS defined */ - extern long _Py_RefTotal; inst->ob_type = &PyInstance_Type; _Py_NewReference((PyObject *)inst); _Py_RefTotal--; /* compensate for increment in NEWREF */ --- 542,553 ---- PyObject *error_type, *error_value, *error_traceback; PyObject *del; static PyObject *delstr; + extern long _Py_RefTotal; + PyObject_GC_Fini(inst); /* Call the __del__ method if it exists. First temporarily revive the object and save the current exception, if any. */ #ifdef Py_TRACE_REFS /* much too complicated if Py_TRACE_REFS defined */ inst->ob_type = &PyInstance_Type; _Py_NewReference((PyObject *)inst); _Py_RefTotal--; /* compensate for increment in NEWREF */ *************** *** 591,596 **** --- 595,601 ---- #ifdef COUNT_ALLOCS inst->ob_type->tp_free--; #endif + PyObject_GC_Init(inst); return; /* __del__ added a reference; don't delete now */ } #ifdef Py_TRACE_REFS *************** *** 598,604 **** --- 603,611 ---- inst->ob_type->tp_free--; /* compensate for increment in UNREF */ #endif _Py_ForgetReference((PyObject *)inst); + #ifndef WITH_CYCLE_GC inst->ob_type = NULL; + #endif #endif /* Py_TRACE_REFS */ Py_DECREF(inst->in_class); Py_XDECREF(inst->in_dict); *************** *** 1513,1519 **** PyObject_HEAD_INIT(&PyType_Type) 0, "instance", ! sizeof(PyInstanceObject) + PyGC_INFO_SIZE, 0, (destructor)instance_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ --- 1520,1526 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "instance", ! sizeof(PyInstanceObject) + PyGC_HEAD_SIZE, 0, (destructor)instance_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ *************** *** 1571,1576 **** --- 1578,1584 ---- im->im_self = self; Py_INCREF(class); im->im_class = class; + PyObject_GC_Init(im); return (PyObject *)im; } *************** *** 1646,1651 **** --- 1654,1660 ---- instancemethod_dealloc(im) register PyMethodObject *im; { + PyObject_GC_Fini(im); Py_DECREF(im->im_func); Py_XDECREF(im->im_self); Py_DECREF(im->im_class); *************** *** 1748,1754 **** PyObject_HEAD_INIT(&PyType_Type) 0, "instance method", ! sizeof(PyMethodObject) + PyGC_INFO_SIZE, 0, (destructor)instancemethod_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ --- 1757,1763 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "instance method", ! sizeof(PyMethodObject) + PyGC_HEAD_SIZE, 0, (destructor)instancemethod_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ Index: 0.12/Objects/dictobject.c *** 0.12/Objects/dictobject.c Fri, 23 Jun 2000 16:21:08 -0600 nas (python/E/19_dictobject 1.1.2.1.2.1 644) --- nogc.9(w)/Objects/dictobject.c Thu, 29 Jun 2000 07:51:07 -0600 nas (python/E/19_dictobject 1.1.2.1.2.1.1.2 644) *************** *** 129,134 **** --- 129,135 ---- mp->ma_table = NULL; mp->ma_fill = 0; mp->ma_used = 0; + PyObject_GC_Init(mp); return (PyObject *)mp; } *************** *** 481,486 **** --- 482,488 ---- register int i; register dictentry *ep; Py_TRASHCAN_SAFE_BEGIN(mp) + PyObject_GC_Fini(mp); for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { if (ep->me_key != NULL) { Py_DECREF(ep->me_key); *************** *** 1087,1093 **** PyObject_HEAD_INIT(&PyType_Type) 0, "dictionary", ! sizeof(dictobject) + PyGC_INFO_SIZE, 0, (destructor)dict_dealloc, /*tp_dealloc*/ (printfunc)dict_print, /*tp_print*/ --- 1089,1095 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "dictionary", ! sizeof(dictobject) + PyGC_HEAD_SIZE, 0, (destructor)dict_dealloc, /*tp_dealloc*/ (printfunc)dict_print, /*tp_print*/ Index: 0.12/Objects/funcobject.c *** 0.12/Objects/funcobject.c Fri, 23 Jun 2000 16:21:08 -0600 nas (python/E/23_funcobject 1.1.2.2.2.1 644) --- nogc.9(w)/Objects/funcobject.c Thu, 29 Jun 2000 07:51:12 -0600 nas (python/E/23_funcobject 1.1.2.2.2.1.1.2 644) *************** *** 63,68 **** --- 63,69 ---- Py_INCREF(doc); op->func_doc = doc; } + PyObject_GC_Init(op); return (PyObject *)op; } *************** *** 186,191 **** --- 187,193 ---- func_dealloc(op) PyFunctionObject *op; { + PyObject_GC_Fini(op); Py_DECREF(op->func_code); Py_DECREF(op->func_globals); Py_DECREF(op->func_name); *************** *** 275,281 **** PyObject_HEAD_INIT(&PyType_Type) 0, "function", ! sizeof(PyFunctionObject) + PyGC_INFO_SIZE, 0, (destructor)func_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ --- 277,283 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "function", ! sizeof(PyFunctionObject) + PyGC_HEAD_SIZE, 0, (destructor)func_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ Index: 0.12/Objects/listobject.c *** 0.12/Objects/listobject.c Fri, 23 Jun 2000 16:21:08 -0600 nas (python/E/25_listobject 1.1.2.3.2.1 644) --- nogc.9(w)/Objects/listobject.c Thu, 29 Jun 2000 07:51:16 -0600 nas (python/E/25_listobject 1.1.2.3.2.1.1.4 644) *************** *** 72,81 **** } /* PyObject_NewVar is inlined */ op = (PyListObject *) PyObject_MALLOC(sizeof(PyListObject) ! + PyGC_INFO_SIZE); if (op == NULL) { return PyErr_NoMemory(); } if (size <= 0) { op->ob_item = NULL; } --- 72,82 ---- } /* PyObject_NewVar is inlined */ op = (PyListObject *) PyObject_MALLOC(sizeof(PyListObject) ! + PyGC_HEAD_SIZE); if (op == NULL) { return PyErr_NoMemory(); } + op = (PyListObject *) PyObject_FROM_GC(op); if (size <= 0) { op->ob_item = NULL; } *************** *** 89,94 **** --- 90,96 ---- PyObject_INIT_VAR(op, &PyList_Type, size); for (i = 0; i < size; i++) op->ob_item[i] = NULL; + PyObject_GC_Init(op); return (PyObject *) op; } *************** *** 216,221 **** --- 218,224 ---- { int i; Py_TRASHCAN_SAFE_BEGIN(op) + PyObject_GC_Fini(op); if (op->ob_item != NULL) { /* Do it backwards, for Christian Tismer. There's a simple test case where somehow this reduces *************** *** 1498,1504 **** PyObject_HEAD_INIT(&PyType_Type) 0, "list", ! sizeof(PyListObject) + PyGC_INFO_SIZE, 0, (destructor)list_dealloc, /*tp_dealloc*/ (printfunc)list_print, /*tp_print*/ --- 1501,1507 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "list", ! sizeof(PyListObject) + PyGC_HEAD_SIZE, 0, (destructor)list_dealloc, /*tp_dealloc*/ (printfunc)list_print, /*tp_print*/ *************** *** 1577,1583 **** PyObject_HEAD_INIT(&PyType_Type) 0, "list (immutable, during sort)", ! sizeof(PyListObject) + PyGC_INFO_SIZE, 0, 0, /*tp_dealloc*/ /* Cannot happen */ (printfunc)list_print, /*tp_print*/ --- 1580,1586 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "list (immutable, during sort)", ! sizeof(PyListObject) + PyGC_HEAD_SIZE, 0, 0, /*tp_dealloc*/ /* Cannot happen */ (printfunc)list_print, /*tp_print*/ Index: 0.12/Objects/object.c *** 0.12/Objects/object.c Thu, 29 Jun 2000 08:04:29 -0600 nas (python/E/29_object.c 1.1.1.1.1.1.1.1.1.1 644) --- nogc.9(w)/Objects/object.c Thu, 29 Jun 2000 08:05:47 -0600 nas (python/E/29_object.c 1.1.1.1.1.1.1.1.1.2 644) *************** *** 176,181 **** --- 176,187 ---- PyObject_FREE(op); } + #ifndef WITH_CYCLE_GC + /* extension modules might need these */ + void _PyGC_Insert(PyObject *op) { } + void _PyGC_Remove(PyObject *op) { } + #endif + int PyObject_Print(op, fp, flags) PyObject *op; Index: 0.12/Objects/tupleobject.c *** 0.12/Objects/tupleobject.c Fri, 23 Jun 2000 16:21:08 -0600 nas (python/E/33_tupleobjec 1.1.2.3.2.1 644) --- nogc.9(w)/Objects/tupleobject.c Thu, 29 Jun 2000 09:44:32 -0600 nas (python/E/33_tupleobjec 1.1.2.3.2.1.1.4.1.2 644) *************** *** 94,100 **** /* Check for overflow */ if (nbytes / sizeof(PyObject *) != (size_t)size || (nbytes += sizeof(PyTupleObject) - sizeof(PyObject *) ! + PyGC_INFO_SIZE) <= 0) { return PyErr_NoMemory(); --- 94,100 ---- /* Check for overflow */ if (nbytes / sizeof(PyObject *) != (size_t)size || (nbytes += sizeof(PyTupleObject) - sizeof(PyObject *) ! + PyGC_HEAD_SIZE) <= 0) { return PyErr_NoMemory(); *************** *** 103,109 **** op = (PyTupleObject *) PyObject_MALLOC(nbytes); if (op == NULL) return PyErr_NoMemory(); ! PyObject_INIT_VAR(op, &PyTuple_Type, size); } for (i = 0; i < size; i++) --- 103,109 ---- op = (PyTupleObject *) PyObject_MALLOC(nbytes); if (op == NULL) return PyErr_NoMemory(); ! op = (PyTupleObject *) PyObject_FROM_GC(op); PyObject_INIT_VAR(op, &PyTuple_Type, size); } for (i = 0; i < size; i++) *************** *** 115,120 **** --- 115,121 ---- Py_INCREF(op); /* extra INCREF so that this is never freed */ } #endif + PyObject_GC_Init(op); return (PyObject *) op; } *************** *** 181,186 **** --- 182,188 ---- register int i; register int len = op->ob_size; Py_TRASHCAN_SAFE_BEGIN(op) + PyObject_GC_Fini(op); if (len > 0) { i = len; while (--i >= 0) *************** *** 453,459 **** PyObject_HEAD_INIT(&PyType_Type) 0, "tuple", ! sizeof(PyTupleObject) - sizeof(PyObject *) + PyGC_INFO_SIZE, sizeof(PyObject *), (destructor)tupledealloc, /*tp_dealloc*/ (printfunc)tupleprint, /*tp_print*/ --- 455,461 ---- PyObject_HEAD_INIT(&PyType_Type) 0, "tuple", ! sizeof(PyTupleObject) - sizeof(PyObject *) + PyGC_HEAD_SIZE, sizeof(PyObject *), (destructor)tupledealloc, /*tp_dealloc*/ (printfunc)tupleprint, /*tp_print*/ *************** *** 559,568 **** { sv = (PyTupleObject *) PyObject_REALLOC((char *)v, sizeof(PyTupleObject) ! + PyGC_INFO_SIZE + newsize * sizeof(PyObject *)); *pv = (PyObject *) sv; if (sv == NULL) { PyObject_DEL(v); PyErr_NoMemory(); return -1; --- 561,571 ---- { sv = (PyTupleObject *) PyObject_REALLOC((char *)v, sizeof(PyTupleObject) ! + PyGC_HEAD_SIZE + newsize * sizeof(PyObject *)); *pv = (PyObject *) sv; if (sv == NULL) { + PyObject_GC_Init(v); PyObject_DEL(v); PyErr_NoMemory(); return -1; *************** *** 578,583 **** --- 581,587 ---- sv->ob_item[i - sizediff] = NULL; } } + PyObject_GC_Init(sv); sv->ob_size = newsize; return 0; }