@@ -69,10 +69,10 @@ module gc
6969#define NEXT_MASK_UNREACHABLE (1)
7070
7171/* Get an object's GC head */
72- #define AS_GC (o ) ((PyGC_Head *)(o)-1 )
72+ #define AS_GC (o ) ((PyGC_Head *)(((char *)(o))-sizeof(PyGC_Head)) )
7373
7474/* Get the object given the GC head */
75- #define FROM_GC (g ) ((PyObject *)(((PyGC_Head *)g)+1 ))
75+ #define FROM_GC (g ) ((PyObject *)(((char *)(g))+sizeof(PyGC_Head) ))
7676
7777static inline int
7878gc_is_collecting (PyGC_Head * g )
@@ -2231,28 +2231,14 @@ PyObject_IS_GC(PyObject *obj)
22312231 return _PyObject_IS_GC (obj );
22322232}
22332233
2234- static PyObject *
2235- _PyObject_GC_Alloc ( int use_calloc , size_t basicsize )
2234+ void
2235+ _PyObject_GC_Link ( PyObject * op )
22362236{
2237+ PyGC_Head * g = AS_GC (op );
2238+ assert (((uintptr_t )g & (sizeof (uintptr_t )-1 )) == 0 ); // g must be correctly aligned
2239+
22372240 PyThreadState * tstate = _PyThreadState_GET ();
22382241 GCState * gcstate = & tstate -> interp -> gc ;
2239- if (basicsize > PY_SSIZE_T_MAX - sizeof (PyGC_Head )) {
2240- return _PyErr_NoMemory (tstate );
2241- }
2242- size_t size = sizeof (PyGC_Head ) + basicsize ;
2243-
2244- PyGC_Head * g ;
2245- if (use_calloc ) {
2246- g = (PyGC_Head * )PyObject_Calloc (1 , size );
2247- }
2248- else {
2249- g = (PyGC_Head * )PyObject_Malloc (size );
2250- }
2251- if (g == NULL ) {
2252- return _PyErr_NoMemory (tstate );
2253- }
2254- assert (((uintptr_t )g & 3 ) == 0 ); // g must be aligned 4bytes boundary
2255-
22562242 g -> _gc_next = 0 ;
22572243 g -> _gc_prev = 0 ;
22582244 gcstate -> generations [0 ].count ++ ; /* number of allocated GC objects */
@@ -2266,26 +2252,32 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize)
22662252 gc_collect_generations (tstate );
22672253 gcstate -> collecting = 0 ;
22682254 }
2269- PyObject * op = FROM_GC (g );
2270- return op ;
22712255}
22722256
2273- PyObject *
2274- _PyObject_GC_Malloc (size_t basicsize )
2275- {
2276- return _PyObject_GC_Alloc (0 , basicsize );
2277- }
2278-
2279- PyObject *
2280- _PyObject_GC_Calloc (size_t basicsize )
2257+ static PyObject *
2258+ gc_alloc (size_t basicsize , size_t presize )
22812259{
2282- return _PyObject_GC_Alloc (1 , basicsize );
2260+ PyThreadState * tstate = _PyThreadState_GET ();
2261+ if (basicsize > PY_SSIZE_T_MAX - presize ) {
2262+ return _PyErr_NoMemory (tstate );
2263+ }
2264+ size_t size = presize + basicsize ;
2265+ char * mem = PyObject_Malloc (size );
2266+ if (mem == NULL ) {
2267+ return _PyErr_NoMemory (tstate );
2268+ }
2269+ ((PyObject * * )mem )[0 ] = NULL ;
2270+ ((PyObject * * )mem )[1 ] = NULL ;
2271+ PyObject * op = (PyObject * )(mem + presize );
2272+ _PyObject_GC_Link (op );
2273+ return op ;
22832274}
22842275
22852276PyObject *
22862277_PyObject_GC_New (PyTypeObject * tp )
22872278{
2288- PyObject * op = _PyObject_GC_Malloc (_PyObject_SIZE (tp ));
2279+ size_t presize = _PyType_PreHeaderSize (tp );
2280+ PyObject * op = gc_alloc (_PyObject_SIZE (tp ), presize );
22892281 if (op == NULL ) {
22902282 return NULL ;
22912283 }
@@ -2303,8 +2295,9 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
23032295 PyErr_BadInternalCall ();
23042296 return NULL ;
23052297 }
2298+ size_t presize = _PyType_PreHeaderSize (tp );
23062299 size = _PyObject_VAR_SIZE (tp , nitems );
2307- op = (PyVarObject * ) _PyObject_GC_Malloc (size );
2300+ op = (PyVarObject * )gc_alloc (size , presize );
23082301 if (op == NULL ) {
23092302 return NULL ;
23102303 }
@@ -2333,6 +2326,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems)
23332326void
23342327PyObject_GC_Del (void * op )
23352328{
2329+ size_t presize = _PyType_PreHeaderSize (((PyObject * )op )-> ob_type );
23362330 PyGC_Head * g = AS_GC (op );
23372331 if (_PyObject_GC_IS_TRACKED (op )) {
23382332 gc_list_remove (g );
@@ -2341,7 +2335,7 @@ PyObject_GC_Del(void *op)
23412335 if (gcstate -> generations [0 ].count > 0 ) {
23422336 gcstate -> generations [0 ].count -- ;
23432337 }
2344- PyObject_Free (g );
2338+ PyObject_Free ((( char * ) op ) - presize );
23452339}
23462340
23472341int
0 commit comments