Commit d08b4c45 authored by Jeremy Hylton's avatar Jeremy Hylton

part 2 of Neil Schemenauer's GC patches:

This patch modifies the type structures of objects that
participate in GC.  The object's tp_basicsize is increased when
GC is enabled.  GC information is prefixed to the object to
maintain binary compatibility.  GC objects also define the
tp_flag Py_TPFLAGS_GC.
parent d22162ba
...@@ -325,6 +325,13 @@ given type object has a specified feature. ...@@ -325,6 +325,13 @@ given type object has a specified feature.
/* PySequenceMethods contains sq_contains */ /* PySequenceMethods contains sq_contains */
#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1) #define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1)
/* Objects which participate in garbage collection (see objimp.h) */
#ifdef WITH_CYCLE_GC
#define Py_TPFLAGS_GC (1L<<2)
#else
#define Py_TPFLAGS_GC 0
#endif
#define Py_TPFLAGS_DEFAULT (Py_TPFLAGS_HAVE_GETCHARBUFFER | \ #define Py_TPFLAGS_DEFAULT (Py_TPFLAGS_HAVE_GETCHARBUFFER | \
Py_TPFLAGS_HAVE_SEQUENCE_IN) Py_TPFLAGS_HAVE_SEQUENCE_IN)
......
...@@ -234,6 +234,12 @@ extern DL_IMPORT(void) _PyObject_Del Py_PROTO((PyObject *)); ...@@ -234,6 +234,12 @@ extern DL_IMPORT(void) _PyObject_Del Py_PROTO((PyObject *));
the 1st step is performed automatically for you, so in a C++ class the 1st step is performed automatically for you, so in a C++ class
constructor you would start directly with PyObject_Init/InitVar. */ constructor you would start directly with PyObject_Init/InitVar. */
#ifndef WITH_CYCLE_GC
#define PyGC_INFO_SIZE 0
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -428,7 +428,7 @@ PyTypeObject PyClass_Type = { ...@@ -428,7 +428,7 @@ PyTypeObject PyClass_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"class", "class",
sizeof(PyClassObject), sizeof(PyClassObject) + PyGC_INFO_SIZE,
0, 0,
(destructor)class_dealloc, /*tp_dealloc*/ (destructor)class_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
...@@ -445,7 +445,7 @@ PyTypeObject PyClass_Type = { ...@@ -445,7 +445,7 @@ PyTypeObject PyClass_Type = {
(getattrofunc)class_getattr, /*tp_getattro*/ (getattrofunc)class_getattr, /*tp_getattro*/
(setattrofunc)class_setattr, /*tp_setattro*/ (setattrofunc)class_setattr, /*tp_setattro*/
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)class_traverse, /* tp_traverse */ (traverseproc)class_traverse, /* tp_traverse */
}; };
...@@ -1513,7 +1513,7 @@ PyTypeObject PyInstance_Type = { ...@@ -1513,7 +1513,7 @@ PyTypeObject PyInstance_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"instance", "instance",
sizeof(PyInstanceObject), sizeof(PyInstanceObject) + PyGC_INFO_SIZE,
0, 0,
(destructor)instance_dealloc, /*tp_dealloc*/ (destructor)instance_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
...@@ -1530,7 +1530,7 @@ PyTypeObject PyInstance_Type = { ...@@ -1530,7 +1530,7 @@ PyTypeObject PyInstance_Type = {
(getattrofunc)instance_getattr, /*tp_getattro*/ (getattrofunc)instance_getattr, /*tp_getattro*/
(setattrofunc)instance_setattr, /*tp_setattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)instance_traverse, /* tp_traverse */ (traverseproc)instance_traverse, /* tp_traverse */
}; };
...@@ -1748,7 +1748,7 @@ PyTypeObject PyMethod_Type = { ...@@ -1748,7 +1748,7 @@ PyTypeObject PyMethod_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"instance method", "instance method",
sizeof(PyMethodObject), sizeof(PyMethodObject) + PyGC_INFO_SIZE,
0, 0,
(destructor)instancemethod_dealloc, /*tp_dealloc*/ (destructor)instancemethod_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
...@@ -1765,7 +1765,7 @@ PyTypeObject PyMethod_Type = { ...@@ -1765,7 +1765,7 @@ PyTypeObject PyMethod_Type = {
(getattrofunc)instancemethod_getattr, /*tp_getattro*/ (getattrofunc)instancemethod_getattr, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)instancemethod_traverse, /* tp_traverse */ (traverseproc)instancemethod_traverse, /* tp_traverse */
}; };
......
...@@ -1087,7 +1087,7 @@ PyTypeObject PyDict_Type = { ...@@ -1087,7 +1087,7 @@ PyTypeObject PyDict_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"dictionary", "dictionary",
sizeof(dictobject), sizeof(dictobject) + PyGC_INFO_SIZE,
0, 0,
(destructor)dict_dealloc, /*tp_dealloc*/ (destructor)dict_dealloc, /*tp_dealloc*/
(printfunc)dict_print, /*tp_print*/ (printfunc)dict_print, /*tp_print*/
...@@ -1104,7 +1104,7 @@ PyTypeObject PyDict_Type = { ...@@ -1104,7 +1104,7 @@ PyTypeObject PyDict_Type = {
0, /* tp_getattro */ 0, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)dict_traverse, /* tp_traverse */ (traverseproc)dict_traverse, /* tp_traverse */
(inquiry)dict_tp_clear, /* tp_clear */ (inquiry)dict_tp_clear, /* tp_clear */
......
...@@ -275,7 +275,7 @@ PyTypeObject PyFunction_Type = { ...@@ -275,7 +275,7 @@ PyTypeObject PyFunction_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"function", "function",
sizeof(PyFunctionObject), sizeof(PyFunctionObject) + PyGC_INFO_SIZE,
0, 0,
(destructor)func_dealloc, /*tp_dealloc*/ (destructor)func_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
...@@ -292,7 +292,7 @@ PyTypeObject PyFunction_Type = { ...@@ -292,7 +292,7 @@ PyTypeObject PyFunction_Type = {
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)func_traverse, /* tp_traverse */ (traverseproc)func_traverse, /* tp_traverse */
}; };
...@@ -71,7 +71,8 @@ PyList_New(size) ...@@ -71,7 +71,8 @@ PyList_New(size)
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
/* PyObject_NewVar is inlined */ /* PyObject_NewVar is inlined */
op = (PyListObject *) PyObject_MALLOC(sizeof(PyListObject)); op = (PyListObject *) PyObject_MALLOC(sizeof(PyListObject)
+ PyGC_INFO_SIZE);
if (op == NULL) { if (op == NULL) {
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
...@@ -1497,7 +1498,7 @@ PyTypeObject PyList_Type = { ...@@ -1497,7 +1498,7 @@ PyTypeObject PyList_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"list", "list",
sizeof(PyListObject), sizeof(PyListObject) + PyGC_INFO_SIZE,
0, 0,
(destructor)list_dealloc, /*tp_dealloc*/ (destructor)list_dealloc, /*tp_dealloc*/
(printfunc)list_print, /*tp_print*/ (printfunc)list_print, /*tp_print*/
...@@ -1514,7 +1515,7 @@ PyTypeObject PyList_Type = { ...@@ -1514,7 +1515,7 @@ PyTypeObject PyList_Type = {
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)list_traverse, /* tp_traverse */ (traverseproc)list_traverse, /* tp_traverse */
(inquiry)list_clear, /* tp_clear */ (inquiry)list_clear, /* tp_clear */
...@@ -1576,7 +1577,7 @@ static PyTypeObject immutable_list_type = { ...@@ -1576,7 +1577,7 @@ static PyTypeObject immutable_list_type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"list (immutable, during sort)", "list (immutable, during sort)",
sizeof(PyListObject), sizeof(PyListObject) + PyGC_INFO_SIZE,
0, 0,
0, /*tp_dealloc*/ /* Cannot happen */ 0, /*tp_dealloc*/ /* Cannot happen */
(printfunc)list_print, /*tp_print*/ (printfunc)list_print, /*tp_print*/
...@@ -1593,7 +1594,7 @@ static PyTypeObject immutable_list_type = { ...@@ -1593,7 +1594,7 @@ static PyTypeObject immutable_list_type = {
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)list_traverse, /* tp_traverse */ (traverseproc)list_traverse, /* tp_traverse */
}; };
......
...@@ -93,7 +93,8 @@ PyTuple_New(size) ...@@ -93,7 +93,8 @@ PyTuple_New(size)
int nbytes = size * sizeof(PyObject *); int nbytes = size * sizeof(PyObject *);
/* Check for overflow */ /* Check for overflow */
if (nbytes / sizeof(PyObject *) != (size_t)size || if (nbytes / sizeof(PyObject *) != (size_t)size ||
(nbytes += sizeof(PyTupleObject) - sizeof(PyObject *)) (nbytes += sizeof(PyTupleObject) - sizeof(PyObject *)
+ PyGC_INFO_SIZE)
<= 0) <= 0)
{ {
return PyErr_NoMemory(); return PyErr_NoMemory();
...@@ -452,7 +453,7 @@ PyTypeObject PyTuple_Type = { ...@@ -452,7 +453,7 @@ PyTypeObject PyTuple_Type = {
PyObject_HEAD_INIT(&PyType_Type) PyObject_HEAD_INIT(&PyType_Type)
0, 0,
"tuple", "tuple",
sizeof(PyTupleObject) - sizeof(PyObject *), sizeof(PyTupleObject) - sizeof(PyObject *) + PyGC_INFO_SIZE,
sizeof(PyObject *), sizeof(PyObject *),
(destructor)tupledealloc, /*tp_dealloc*/ (destructor)tupledealloc, /*tp_dealloc*/
(printfunc)tupleprint, /*tp_print*/ (printfunc)tupleprint, /*tp_print*/
...@@ -469,7 +470,7 @@ PyTypeObject PyTuple_Type = { ...@@ -469,7 +470,7 @@ PyTypeObject PyTuple_Type = {
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
0, /*tp_doc*/ 0, /*tp_doc*/
(traverseproc)tupletraverse, /* tp_traverse */ (traverseproc)tupletraverse, /* tp_traverse */
}; };
...@@ -557,8 +558,9 @@ _PyTuple_Resize(pv, newsize, last_is_sticky) ...@@ -557,8 +558,9 @@ _PyTuple_Resize(pv, newsize, last_is_sticky)
#endif #endif
{ {
sv = (PyTupleObject *) sv = (PyTupleObject *)
PyObject_REALLOC((char *)v, PyObject_REALLOC((char *)v, sizeof(PyTupleObject)
sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); + PyGC_INFO_SIZE
+ newsize * sizeof(PyObject *));
*pv = (PyObject *) sv; *pv = (PyObject *) sv;
if (sv == NULL) { if (sv == NULL) {
PyObject_DEL(v); PyObject_DEL(v);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment