mirror of
https://github.com/python/cpython.git
synced 2026-07-24 10:52:24 -04:00
[3.15] gh-153083: Defer GC tracking of an array to the end of construction. (gh-153284) (gh-153336)
gh-153083: Defer GC tracking of an array to the end of construction. (gh-153284)
(cherry picked from commit 8615062fd5)
Co-authored-by: Donghee Na <donghee.na@python.org>
This commit is contained in:
committed by
GitHub
parent
a9d4473232
commit
8cb4b84c69
@@ -873,7 +873,8 @@ static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
|
||||
return (type->tp_weaklistoffset != 0);
|
||||
}
|
||||
|
||||
extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
|
||||
// Export for 'array' shared extension.
|
||||
PyAPI_FUNC(PyObject*) _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
|
||||
PyAPI_FUNC(PyObject *) _PyType_NewManagedObject(PyTypeObject *type);
|
||||
|
||||
extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Defer GC tracking of an :class:`array.array` to the end of its construction.
|
||||
Patch by Donghee Na.
|
||||
+31
-11
@@ -14,6 +14,7 @@
|
||||
#include "pycore_floatobject.h" // _PY_FLOAT_BIG_ENDIAN
|
||||
#include "pycore_modsupport.h" // _PyArg_NoKeywords()
|
||||
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
||||
#include "pycore_object.h" // _PyObject_GC_TRACK()
|
||||
#include "pycore_tuple.h" // _PyTuple_FromPairSteal
|
||||
#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
|
||||
|
||||
@@ -796,7 +797,8 @@ class array.array "arrayobject *" "ArrayType"
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/
|
||||
|
||||
static PyObject *
|
||||
newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
|
||||
newarrayobject_untracked(PyTypeObject *type, Py_ssize_t size,
|
||||
const struct arraydescr *descr)
|
||||
{
|
||||
arrayobject *op;
|
||||
size_t nbytes;
|
||||
@@ -811,7 +813,7 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
nbytes = size * descr->itemsize;
|
||||
op = (arrayobject *) type->tp_alloc(type, 0);
|
||||
op = (arrayobject *) _PyType_AllocNoTrack(type, 0);
|
||||
if (op == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -833,6 +835,16 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
|
||||
return (PyObject *) op;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
|
||||
{
|
||||
PyObject *op = newarrayobject_untracked(type, size, descr);
|
||||
if (op != NULL) {
|
||||
_PyObject_GC_TRACK(op);
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
getarrayitem(PyObject *op, Py_ssize_t i)
|
||||
{
|
||||
@@ -1034,13 +1046,14 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
|
||||
ihigh = ilow;
|
||||
else if (ihigh > Py_SIZE(a))
|
||||
ihigh = Py_SIZE(a);
|
||||
np = (arrayobject *) newarrayobject(state->ArrayType, ihigh - ilow, a->ob_descr);
|
||||
np = (arrayobject *) newarrayobject_untracked(state->ArrayType, ihigh - ilow, a->ob_descr);
|
||||
if (np == NULL)
|
||||
return NULL;
|
||||
if (ihigh > ilow) {
|
||||
memcpy(np->ob_item, a->ob_item + ilow * a->ob_descr->itemsize,
|
||||
(ihigh-ilow) * a->ob_descr->itemsize);
|
||||
}
|
||||
_PyObject_GC_TRACK(np);
|
||||
return (PyObject *)np;
|
||||
}
|
||||
|
||||
@@ -1111,7 +1124,7 @@ array_concat(PyObject *op, PyObject *bb)
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
size = Py_SIZE(a) + Py_SIZE(b);
|
||||
np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
|
||||
np = (arrayobject *) newarrayobject_untracked(state->ArrayType, size, a->ob_descr);
|
||||
if (np == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1122,6 +1135,7 @@ array_concat(PyObject *op, PyObject *bb)
|
||||
memcpy(np->ob_item + Py_SIZE(a)*a->ob_descr->itemsize,
|
||||
b->ob_item, Py_SIZE(b)*b->ob_descr->itemsize);
|
||||
}
|
||||
_PyObject_GC_TRACK(np);
|
||||
return (PyObject *)np;
|
||||
#undef b
|
||||
}
|
||||
@@ -1139,16 +1153,19 @@ array_repeat(PyObject *op, Py_ssize_t n)
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
Py_ssize_t size = array_length * n;
|
||||
arrayobject* np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
|
||||
arrayobject* np = (arrayobject *) newarrayobject_untracked(state->ArrayType, size, a->ob_descr);
|
||||
if (np == NULL)
|
||||
return NULL;
|
||||
if (size == 0)
|
||||
if (size == 0) {
|
||||
_PyObject_GC_TRACK(np);
|
||||
return (PyObject *)np;
|
||||
}
|
||||
|
||||
const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize;
|
||||
const Py_ssize_t newbytes = oldbytes * n;
|
||||
_PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes);
|
||||
|
||||
_PyObject_GC_TRACK(np);
|
||||
return (PyObject *)np;
|
||||
}
|
||||
|
||||
@@ -2741,17 +2758,17 @@ array_subscr(PyObject *op, PyObject *item)
|
||||
return newarrayobject(state->ArrayType, 0, self->ob_descr);
|
||||
}
|
||||
else if (step == 1) {
|
||||
PyObject *result = newarrayobject(state->ArrayType,
|
||||
slicelength, self->ob_descr);
|
||||
PyObject *result = newarrayobject_untracked(state->ArrayType, slicelength, self->ob_descr);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
memcpy(((arrayobject *)result)->ob_item,
|
||||
self->ob_item + start * itemsize,
|
||||
slicelength * itemsize);
|
||||
_PyObject_GC_TRACK(result);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
result = newarrayobject(state->ArrayType, slicelength, self->ob_descr);
|
||||
result = newarrayobject_untracked(state->ArrayType, slicelength, self->ob_descr);
|
||||
if (!result) return NULL;
|
||||
|
||||
ar = (arrayobject*)result;
|
||||
@@ -2763,6 +2780,7 @@ array_subscr(PyObject *op, PyObject *item)
|
||||
itemsize);
|
||||
}
|
||||
|
||||
_PyObject_GC_TRACK(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -3060,7 +3078,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
else
|
||||
len = 0;
|
||||
|
||||
a = newarrayobject(type, len, descr);
|
||||
a = newarrayobject_untracked(type, len, descr);
|
||||
if (a == NULL) {
|
||||
Py_XDECREF(it);
|
||||
return NULL;
|
||||
@@ -3148,6 +3166,8 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
}
|
||||
Py_DECREF(it);
|
||||
}
|
||||
// Track only once fully built.
|
||||
_PyObject_GC_TRACK(a);
|
||||
return a;
|
||||
}
|
||||
}
|
||||
@@ -3243,7 +3263,7 @@ static PyType_Slot array_slots[] = {
|
||||
{Py_tp_methods, array_methods},
|
||||
{Py_tp_members, array_members},
|
||||
{Py_tp_getset, array_getsets},
|
||||
{Py_tp_alloc, PyType_GenericAlloc},
|
||||
{Py_tp_alloc, _PyType_AllocNoTrack},
|
||||
{Py_tp_new, array_new},
|
||||
{Py_tp_traverse, _PyObject_VisitType},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user