Skip to content

Commit 77c3bf9

Browse files
committed
pythongh-153083: Defer GC tracking of an array to the end of construction.
1 parent ce96dd6 commit 77c3bf9

3 files changed

Lines changed: 20 additions & 4 deletions

File tree

Include/internal/pycore_object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
872872
return (type->tp_weaklistoffset != 0);
873873
}
874874

875-
extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
875+
PyAPI_FUNC(PyObject*) _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
876876
PyAPI_FUNC(PyObject *) _PyType_NewManagedObject(PyTypeObject *type);
877877

878878
extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Defer GC tracking of an :class:`array.array` to the end of its construction.
2+
Patch by Donghee Na.

Modules/arraymodule.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "pycore_floatobject.h" // _PY_FLOAT_BIG_ENDIAN
1515
#include "pycore_modsupport.h" // _PyArg_NoKeywords()
1616
#include "pycore_moduleobject.h" // _PyModule_GetState()
17+
#include "pycore_object.h" // _PyObject_GC_TRACK()
1718
#include "pycore_tuple.h" // _PyTuple_FromPairSteal
1819
#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
1920

@@ -752,7 +753,8 @@ class array.array "arrayobject *" "ArrayType"
752753
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/
753754

754755
static PyObject *
755-
newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
756+
newarrayobject_untracked(PyTypeObject *type, Py_ssize_t size,
757+
const struct arraydescr *descr)
756758
{
757759
arrayobject *op;
758760
size_t nbytes;
@@ -767,7 +769,7 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
767769
return PyErr_NoMemory();
768770
}
769771
nbytes = size * descr->itemsize;
770-
op = (arrayobject *) type->tp_alloc(type, 0);
772+
op = (arrayobject *) _PyType_AllocNoTrack(type, 0);
771773
if (op == NULL) {
772774
return NULL;
773775
}
@@ -789,6 +791,16 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
789791
return (PyObject *) op;
790792
}
791793

794+
static PyObject *
795+
newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *descr)
796+
{
797+
PyObject *op = newarrayobject_untracked(type, size, descr);
798+
if (op != NULL) {
799+
_PyObject_GC_TRACK(op);
800+
}
801+
return op;
802+
}
803+
792804
static PyObject *
793805
getarrayitem(PyObject *op, Py_ssize_t i)
794806
{
@@ -2973,7 +2985,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
29732985
else
29742986
len = 0;
29752987

2976-
a = newarrayobject(type, len, descr);
2988+
a = newarrayobject_untracked(type, len, descr);
29772989
if (a == NULL) {
29782990
Py_XDECREF(it);
29792991
return NULL;
@@ -3039,6 +3051,8 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
30393051
}
30403052
Py_DECREF(it);
30413053
}
3054+
// Track only once fully built.
3055+
_PyObject_GC_TRACK(a);
30423056
return a;
30433057
}
30443058
}

0 commit comments

Comments
 (0)