mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
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.
This commit is contained in:
parent
d22162bac7
commit
d08b4c4524
7 changed files with 36 additions and 20 deletions
|
@ -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 *));
|
||||||
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 = {
|
||||||
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 = {
|
||||||
(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 = {
|
||||||
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 = {
|
||||||
(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 = {
|
||||||
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 = {
|
||||||
(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 = {
|
||||||
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 = {
|
||||||
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 = {
|
||||||
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 = {
|
||||||
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)
|
||||||
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 = {
|
||||||
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 = {
|
||||||
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 = {
|
||||||
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 = {
|
||||||
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)
|
||||||
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 = {
|
||||||
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 = {
|
||||||
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)
|
||||||
#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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue