1313#include "pycore_ceval.h" // _PyEval_GetBuiltin()
1414#include "pycore_modsupport.h" // _PyArg_NoKeywords()
1515#include "pycore_moduleobject.h" // _PyModule_GetState()
16+ #include "pycore_object.h" // _PyObject_GC_TRACK()
1617#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
1718
1819#include <stddef.h> // offsetof()
@@ -677,7 +678,8 @@ class array.array "arrayobject *" "ArrayType"
677678/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a5c29edf59f176a3]*/
678679
679680static PyObject *
680- newarrayobject (PyTypeObject * type , Py_ssize_t size , const struct arraydescr * descr )
681+ newarrayobject_untracked (PyTypeObject * type , Py_ssize_t size ,
682+ const struct arraydescr * descr )
681683{
682684 arrayobject * op ;
683685 size_t nbytes ;
@@ -692,7 +694,7 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
692694 return PyErr_NoMemory ();
693695 }
694696 nbytes = size * descr -> itemsize ;
695- op = (arrayobject * ) type -> tp_alloc (type , 0 );
697+ op = (arrayobject * ) _PyType_AllocNoTrack (type , 0 );
696698 if (op == NULL ) {
697699 return NULL ;
698700 }
@@ -714,6 +716,16 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const struct arraydescr *des
714716 return (PyObject * ) op ;
715717}
716718
719+ static PyObject *
720+ newarrayobject (PyTypeObject * type , Py_ssize_t size , const struct arraydescr * descr )
721+ {
722+ PyObject * op = newarrayobject_untracked (type , size , descr );
723+ if (op != NULL ) {
724+ _PyObject_GC_TRACK (op );
725+ }
726+ return op ;
727+ }
728+
717729static PyObject *
718730getarrayitem (PyObject * op , Py_ssize_t i )
719731{
@@ -921,13 +933,14 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
921933 ihigh = ilow ;
922934 else if (ihigh > Py_SIZE (a ))
923935 ihigh = Py_SIZE (a );
924- np = (arrayobject * ) newarrayobject (state -> ArrayType , ihigh - ilow , a -> ob_descr );
936+ np = (arrayobject * ) newarrayobject_untracked (state -> ArrayType , ihigh - ilow , a -> ob_descr );
925937 if (np == NULL )
926938 return NULL ;
927939 if (ihigh > ilow ) {
928940 memcpy (np -> ob_item , a -> ob_item + ilow * a -> ob_descr -> itemsize ,
929941 (ihigh - ilow ) * a -> ob_descr -> itemsize );
930942 }
943+ _PyObject_GC_TRACK (np );
931944 return (PyObject * )np ;
932945}
933946
@@ -997,7 +1010,7 @@ array_concat(arrayobject *a, PyObject *bb)
9971010 return PyErr_NoMemory ();
9981011 }
9991012 size = Py_SIZE (a ) + Py_SIZE (b );
1000- np = (arrayobject * ) newarrayobject (state -> ArrayType , size , a -> ob_descr );
1013+ np = (arrayobject * ) newarrayobject_untracked (state -> ArrayType , size , a -> ob_descr );
10011014 if (np == NULL ) {
10021015 return NULL ;
10031016 }
@@ -1008,6 +1021,7 @@ array_concat(arrayobject *a, PyObject *bb)
10081021 memcpy (np -> ob_item + Py_SIZE (a )* a -> ob_descr -> itemsize ,
10091022 b -> ob_item , Py_SIZE (b )* b -> ob_descr -> itemsize );
10101023 }
1024+ _PyObject_GC_TRACK (np );
10111025 return (PyObject * )np ;
10121026#undef b
10131027}
@@ -1024,16 +1038,19 @@ array_repeat(arrayobject *a, Py_ssize_t n)
10241038 return PyErr_NoMemory ();
10251039 }
10261040 Py_ssize_t size = array_length * n ;
1027- arrayobject * np = (arrayobject * ) newarrayobject (state -> ArrayType , size , a -> ob_descr );
1041+ arrayobject * np = (arrayobject * ) newarrayobject_untracked (state -> ArrayType , size , a -> ob_descr );
10281042 if (np == NULL )
10291043 return NULL ;
1030- if (size == 0 )
1044+ if (size == 0 ) {
1045+ _PyObject_GC_TRACK (np );
10311046 return (PyObject * )np ;
1047+ }
10321048
10331049 const Py_ssize_t oldbytes = array_length * a -> ob_descr -> itemsize ;
10341050 const Py_ssize_t newbytes = oldbytes * n ;
10351051 _PyBytes_Repeat (np -> ob_item , newbytes , a -> ob_item , oldbytes );
10361052
1053+ _PyObject_GC_TRACK (np );
10371054 return (PyObject * )np ;
10381055}
10391056
@@ -2504,17 +2521,17 @@ array_subscr(arrayobject* self, PyObject* item)
25042521 return newarrayobject (state -> ArrayType , 0 , self -> ob_descr );
25052522 }
25062523 else if (step == 1 ) {
2507- PyObject * result = newarrayobject (state -> ArrayType ,
2508- slicelength , self -> ob_descr );
2524+ PyObject * result = newarrayobject_untracked (state -> ArrayType , slicelength , self -> ob_descr );
25092525 if (result == NULL )
25102526 return NULL ;
25112527 memcpy (((arrayobject * )result )-> ob_item ,
25122528 self -> ob_item + start * itemsize ,
25132529 slicelength * itemsize );
2530+ _PyObject_GC_TRACK (result );
25142531 return result ;
25152532 }
25162533 else {
2517- result = newarrayobject (state -> ArrayType , slicelength , self -> ob_descr );
2534+ result = newarrayobject_untracked (state -> ArrayType , slicelength , self -> ob_descr );
25182535 if (!result ) return NULL ;
25192536
25202537 ar = (arrayobject * )result ;
@@ -2526,6 +2543,7 @@ array_subscr(arrayobject* self, PyObject* item)
25262543 itemsize );
25272544 }
25282545
2546+ _PyObject_GC_TRACK (result );
25292547 return result ;
25302548 }
25312549 }
@@ -2822,7 +2840,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
28222840 else
28232841 len = 0 ;
28242842
2825- a = newarrayobject (type , len , descr );
2843+ a = newarrayobject_untracked (type , len , descr );
28262844 if (a == NULL ) {
28272845 Py_XDECREF (it );
28282846 return NULL ;
@@ -2911,6 +2929,8 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
29112929 }
29122930 Py_DECREF (it );
29132931 }
2932+ // Track only once fully built.
2933+ _PyObject_GC_TRACK (a );
29142934 return a ;
29152935 }
29162936 }
@@ -3003,7 +3023,7 @@ static PyType_Slot array_slots[] = {
30033023 {Py_tp_methods , array_methods },
30043024 {Py_tp_members , array_members },
30053025 {Py_tp_getset , array_getsets },
3006- {Py_tp_alloc , PyType_GenericAlloc },
3026+ {Py_tp_alloc , _PyType_AllocNoTrack },
30073027 {Py_tp_new , array_new },
30083028 {Py_tp_traverse , array_tp_traverse },
30093029
0 commit comments