bpo-44531: Add _PyType_AllocNoTrack() function (GH-26947)

Add an internal _PyType_AllocNoTrack() function to allocate an object
without tracking it in the GC.

Modify dict_new() to use _PyType_AllocNoTrack(): dict subclasses are
now only tracked once all PyDictObject members are initialized.
Calling _PyObject_GC_UNTRACK() is no longer needed for the dict type.

Similar change in tuple_subtype_new() for tuple subclasses.

Replace tuple_gc_track() with _PyObject_GC_TRACK().
This commit is contained in:
Victor Stinner 2021-07-01 02:30:46 +02:00 committed by GitHub
parent 1b28187a0e
commit 818628c2da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 28 deletions

View file

@ -25,13 +25,6 @@ get_tuple_state(void)
#endif
static inline void
tuple_gc_track(PyTupleObject *op)
{
_PyObject_GC_TRACK(op);
}
/* Print summary info about the state of the optimized allocator */
void
_PyTuple_DebugMallocStats(FILE *out)
@ -48,10 +41,12 @@ _PyTuple_DebugMallocStats(FILE *out)
#endif
}
/* Allocate an uninitialized tuple object. Before making it public following
/* Allocate an uninitialized tuple object. Before making it public, following
steps must be done:
- initialize its items
- call tuple_gc_track() on it
- Initialize its items.
- Call _PyObject_GC_TRACK() on it.
Because the empty tuple is always reused and it's already tracked by GC,
this function must not be called with size == 0 (unless from PyTuple_New()
which wraps this function).
@ -161,7 +156,7 @@ PyTuple_New(Py_ssize_t size)
for (Py_ssize_t i = 0; i < size; i++) {
op->ob_item[i] = NULL;
}
tuple_gc_track(op);
_PyObject_GC_TRACK(op);
return (PyObject *) op;
}
@ -257,7 +252,7 @@ PyTuple_Pack(Py_ssize_t n, ...)
items[i] = o;
}
va_end(vargs);
tuple_gc_track(result);
_PyObject_GC_TRACK(result);
return (PyObject *)result;
}
@ -473,7 +468,7 @@ _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
Py_INCREF(item);
dst[i] = item;
}
tuple_gc_track(tuple);
_PyObject_GC_TRACK(tuple);
return (PyObject *)tuple;
}
@ -551,7 +546,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb)
Py_INCREF(v);
dest[i] = v;
}
tuple_gc_track(np);
_PyObject_GC_TRACK(np);
return (PyObject *)np;
}
@ -588,7 +583,7 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
p++;
}
}
tuple_gc_track(np);
_PyObject_GC_TRACK(np);
return (PyObject *) np;
}
@ -783,6 +778,9 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
Py_ssize_t i, n;
assert(PyType_IsSubtype(type, &PyTuple_Type));
// tuple subclasses must implement the GC protocol
assert(_PyType_IS_GC(type));
tmp = tuple_new_impl(&PyTuple_Type, iterable);
if (tmp == NULL)
return NULL;
@ -798,6 +796,11 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
PyTuple_SET_ITEM(newobj, i, item);
}
Py_DECREF(tmp);
// Don't track if a subclass tp_alloc is PyType_GenericAlloc()
if (!_PyObject_GC_IS_TRACKED(newobj)) {
_PyObject_GC_TRACK(newobj);
}
return newobj;
}
@ -857,7 +860,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
dest[i] = it;
}
tuple_gc_track(result);
_PyObject_GC_TRACK(result);
return (PyObject *)result;
}
}