Skip to content

Commit 3e4753e

Browse files
committed
Fix missing presizing in PyTruffle_Tuple_Alloc
1 parent f147931 commit 3e4753e

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

graalpython/com.oracle.graal.python.cext/src/tupleobject.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#include "pycore_abstract.h" // _PyIndex_Check()
1313
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
1414
#include "pycore_initconfig.h" // _PyStatus_OK()
15-
#include "pycore_object.h" // _PyObject_GC_TRACK(), _Py_FatalRefcountError()
1615
#endif // GraalPy change
16+
#include "pycore_object.h" // _PyObject_GC_TRACK(), _Py_FatalRefcountError()
1717

1818
#if 0 // GraalPy change
1919
/*[clinic input]
@@ -1303,22 +1303,47 @@ _PyTuple_DebugMallocStats(FILE *out)
13031303
#endif // GraalPy change
13041304

13051305
// GraalPy additions
1306-
PyObject* PyTruffle_Tuple_Alloc(PyTypeObject* cls, Py_ssize_t nitems) {
1306+
PyObject* PyTruffle_Tuple_Alloc(PyTypeObject* type, Py_ssize_t nitems) {
13071307
/*
13081308
* TODO(fa): For 'PyVarObjects' (i.e. 'nitems > 0') we increase the size by 'sizeof(void *)'
13091309
* because this additional pointer can then be used as pointer to the element array.
13101310
* CPython usually embeds the array in the struct but Sulong doesn't currently support that.
13111311
* So we allocate space for the additional array pointer.
13121312
* Also consider any 'PyVarObject' (in particular 'PyTupleObject') if this is fixed.
1313+
*
1314+
* This function is mostly an inlined copy-paste of PyType_GenericAlloc, with different size
1315+
* and added initialization of ob_item
13131316
*/
1314-
Py_ssize_t size = cls->tp_basicsize + cls->tp_itemsize * nitems + sizeof(PyObject **);
1315-
PyObject* newObj = (PyObject*)PyObject_Malloc(size);
1316-
if(cls->tp_dictoffset) {
1317-
*((PyObject **) ((char *)newObj + cls->tp_dictoffset)) = NULL;
1318-
}
1319-
PyObject_INIT_VAR(newObj, cls, nitems);
1320-
((PyTupleObject*)newObj)->ob_item = (PyObject **) ((char *)newObj + offsetof(PyTupleObject, ob_item) + sizeof(PyObject **));
1321-
return newObj;
1317+
PyObject *obj;
1318+
const size_t size = _PyObject_VAR_SIZE(type, nitems+1) + sizeof(PyObject **);
1319+
/* note that we need to add one, for the sentinel */
1320+
1321+
const size_t presize = _PyType_PreHeaderSize(type);
1322+
char *alloc = PyObject_Malloc(size + presize);
1323+
if (alloc == NULL) {
1324+
return PyErr_NoMemory();
1325+
}
1326+
obj = (PyObject *)(alloc + presize);
1327+
if (presize) {
1328+
// GraalPy change: different header layout, no GC link
1329+
((PyObject **)alloc)[0] = NULL;
1330+
}
1331+
memset(obj, '\0', size);
1332+
1333+
if (type->tp_itemsize == 0) {
1334+
_PyObject_Init(obj, type);
1335+
}
1336+
else {
1337+
_PyObject_InitVar((PyVarObject *)obj, type, nitems);
1338+
}
1339+
1340+
if (_PyType_IS_GC(type)) {
1341+
_PyObject_GC_TRACK(obj);
1342+
}
1343+
1344+
((PyTupleObject*)obj)->ob_item = (PyObject **) ((char *)obj + offsetof(PyTupleObject, ob_item) + sizeof(PyObject **));
1345+
1346+
return obj;
13221347
}
13231348

13241349
void PyTruffle_Tuple_Dealloc(PyTupleObject* self) {

0 commit comments

Comments
 (0)