mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-128923: Use zero to indicate unassigned unique id (#128925)
In the free threading build, the per thread reference counting uses a unique id for some objects to index into the local reference count table. Use 0 instead of -1 to indicate that the id is not assigned. This avoids bugs where zero-initialized heap type objects look like they have a unique id assigned.
This commit is contained in:
parent
767c89ba7c
commit
d66c08aa75
9 changed files with 110 additions and 33 deletions
|
@ -4149,6 +4149,61 @@ static PyTypeObject ContainerNoGC_type = {
|
|||
.tp_new = ContainerNoGC_new,
|
||||
};
|
||||
|
||||
/* Manually allocated heap type */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *dict;
|
||||
} ManualHeapType;
|
||||
|
||||
static int
|
||||
ManualHeapType_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
ManualHeapType *mht = (ManualHeapType *)self;
|
||||
Py_VISIT(mht->dict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ManualHeapType_dealloc(PyObject *self)
|
||||
{
|
||||
ManualHeapType *mht = (ManualHeapType *)self;
|
||||
PyObject_GC_UnTrack(self);
|
||||
Py_XDECREF(mht->dict);
|
||||
PyTypeObject *type = Py_TYPE(self);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
Py_DECREF(type);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
create_manual_heap_type(void)
|
||||
{
|
||||
// gh-128923: Ensure that a heap type allocated through PyType_Type.tp_alloc
|
||||
// with minimal initialization works correctly.
|
||||
PyHeapTypeObject *heap_type = (PyHeapTypeObject *)PyType_Type.tp_alloc(&PyType_Type, 0);
|
||||
if (heap_type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
PyTypeObject* type = &heap_type->ht_type;
|
||||
type->tp_basicsize = sizeof(ManualHeapType);
|
||||
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | Py_TPFLAGS_HAVE_GC;
|
||||
type->tp_new = PyType_GenericNew;
|
||||
type->tp_name = "ManualHeapType";
|
||||
type->tp_dictoffset = offsetof(ManualHeapType, dict);
|
||||
type->tp_traverse = ManualHeapType_traverse;
|
||||
type->tp_dealloc = ManualHeapType_dealloc;
|
||||
heap_type->ht_name = PyUnicode_FromString(type->tp_name);
|
||||
if (!heap_type->ht_name) {
|
||||
Py_DECREF(type);
|
||||
return NULL;
|
||||
}
|
||||
heap_type->ht_qualname = Py_NewRef(heap_type->ht_name);
|
||||
if (PyType_Ready(type) < 0) {
|
||||
Py_DECREF(type);
|
||||
return NULL;
|
||||
}
|
||||
return (PyObject *)type;
|
||||
}
|
||||
|
||||
static struct PyModuleDef _testcapimodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
|
@ -4283,6 +4338,15 @@ PyInit__testcapi(void)
|
|||
(PyObject *) &ContainerNoGC_type) < 0)
|
||||
return NULL;
|
||||
|
||||
PyObject *manual_heap_type = create_manual_heap_type();
|
||||
if (manual_heap_type == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyModule_Add(m, "ManualHeapType", manual_heap_type) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Include tests from the _testcapi/ directory */
|
||||
if (_PyTestCapi_Init_Vectorcall(m) < 0) {
|
||||
return NULL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue