@@ -69,10 +69,10 @@ module gc
69
69
#define NEXT_MASK_UNREACHABLE (1)
70
70
71
71
/* 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)) )
73
73
74
74
/* 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) ))
76
76
77
77
static inline int
78
78
gc_is_collecting (PyGC_Head * g )
@@ -2231,28 +2231,14 @@ PyObject_IS_GC(PyObject *obj)
2231
2231
return _PyObject_IS_GC (obj );
2232
2232
}
2233
2233
2234
- static PyObject *
2235
- _PyObject_GC_Alloc ( int use_calloc , size_t basicsize )
2234
+ void
2235
+ _PyObject_GC_Link ( PyObject * op )
2236
2236
{
2237
+ PyGC_Head * g = AS_GC (op );
2238
+ assert (((uintptr_t )g & (sizeof (uintptr_t )-1 )) == 0 ); // g must be correctly aligned
2239
+
2237
2240
PyThreadState * tstate = _PyThreadState_GET ();
2238
2241
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
-
2256
2242
g -> _gc_next = 0 ;
2257
2243
g -> _gc_prev = 0 ;
2258
2244
gcstate -> generations [0 ].count ++ ; /* number of allocated GC objects */
@@ -2266,26 +2252,32 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize)
2266
2252
gc_collect_generations (tstate );
2267
2253
gcstate -> collecting = 0 ;
2268
2254
}
2269
- PyObject * op = FROM_GC (g );
2270
- return op ;
2271
2255
}
2272
2256
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 )
2281
2259
{
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 ;
2283
2274
}
2284
2275
2285
2276
PyObject *
2286
2277
_PyObject_GC_New (PyTypeObject * tp )
2287
2278
{
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 );
2289
2281
if (op == NULL ) {
2290
2282
return NULL ;
2291
2283
}
@@ -2303,8 +2295,9 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
2303
2295
PyErr_BadInternalCall ();
2304
2296
return NULL ;
2305
2297
}
2298
+ size_t presize = _PyType_PreHeaderSize (tp );
2306
2299
size = _PyObject_VAR_SIZE (tp , nitems );
2307
- op = (PyVarObject * ) _PyObject_GC_Malloc (size );
2300
+ op = (PyVarObject * )gc_alloc (size , presize );
2308
2301
if (op == NULL ) {
2309
2302
return NULL ;
2310
2303
}
@@ -2333,6 +2326,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems)
2333
2326
void
2334
2327
PyObject_GC_Del (void * op )
2335
2328
{
2329
+ size_t presize = _PyType_PreHeaderSize (((PyObject * )op )-> ob_type );
2336
2330
PyGC_Head * g = AS_GC (op );
2337
2331
if (_PyObject_GC_IS_TRACKED (op )) {
2338
2332
gc_list_remove (g );
@@ -2341,7 +2335,7 @@ PyObject_GC_Del(void *op)
2341
2335
if (gcstate -> generations [0 ].count > 0 ) {
2342
2336
gcstate -> generations [0 ].count -- ;
2343
2337
}
2344
- PyObject_Free (g );
2338
+ PyObject_Free ((( char * ) op ) - presize );
2345
2339
}
2346
2340
2347
2341
int
0 commit comments