Skip to content

Commit 011f39c

Browse files
committed
Use custom tuple allocation function.
1 parent ca8b1b9 commit 011f39c

File tree

6 files changed

+51
-6
lines changed

6 files changed

+51
-6
lines changed

graalpython/com.oracle.graal.python.cext/include/tupleobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ returned item's reference count.
3030
typedef struct {
3131
PyObject_VAR_HEAD
3232
// Truffle change: PyObject *ob_item[1] doesn't work for us in Sulong
33-
PyObject *ob_item[];
33+
PyObject **ob_item;
3434

3535
/* ob_item contains space for 'ob_size' elements.
3636
* Items must normally not be NULL, except during construction when

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,14 @@ void initialize_type_structure(PyTypeObject* structure, PyTypeObject* ptype, pol
8585

8686
unsigned long original_flags = structure->tp_flags;
8787
Py_ssize_t basicsize = structure->tp_basicsize;
88+
allocfunc alloc = structure->tp_alloc;
8889
PyTypeObject* type_handle = truffle_assign_managed(structure, ptype);
8990
// write flags as specified in the dummy to the PythonClass object
9091
type_handle->tp_flags = original_flags | Py_TPFLAGS_READY;
9192
type_handle->tp_basicsize = basicsize;
93+
if (alloc) {
94+
type_handle->tp_alloc = alloc;
95+
}
9296
}
9397

9498
static void initialize_builtin_type(PyTypeObject* structure, const char* typname, polyglot_typeid tid) {

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ void* wrap_unsupported(void *fun, ...);
263263
wrap_direct : \
264264
wrap_unsupported))))))))
265265

266-
#define PY_TRUFFLE_TYPE(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__) {\
266+
#define PY_TRUFFLE_TYPE_WITH_ALLOC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, __ALLOC__) {\
267267
PyVarObject_HEAD_INIT((__SUPER_TYPE__), 0)\
268268
__TYPE_NAME__, /* tp_name */\
269269
(__SIZE__), /* tp_basicsize */\
@@ -300,12 +300,14 @@ void* wrap_unsupported(void *fun, ...);
300300
0, /* tp_descr_set */\
301301
0, /* tp_dictoffset */\
302302
0, /* tp_init */\
303-
0, /* tp_alloc */\
303+
(__ALLOC__), /* tp_alloc */\
304304
0, /* tp_new */\
305305
0, /* tp_free */\
306306
0, /* tp_is_gc */\
307307
}
308308

309+
#define PY_TRUFFLE_TYPE(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__) PY_TRUFFLE_TYPE_WITH_ALLOC(__TYPE_NAME__, __SUPER_TYPE__, __FLAGS__, __SIZE__, 0)
310+
309311
/** to be used from Java code only; returns a type's basic size */
310312
#define BASICSIZE_GETTER(__typename__)extern Py_ssize_t get_ ## __typename__ ## _basicsize() { \
311313
return sizeof(__typename__); \

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ int PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)
7777
type->tp_members = NULL;
7878
type->tp_new = newType->tp_new;
7979
type->tp_base = &PyTuple_Type;
80-
type->tp_alloc = PyType_GenericAlloc;
80+
type->tp_alloc = newType->tp_alloc;
8181

8282
// now copy specific fields
8383
type->tp_name = newType->tp_name;

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@
4040
*/
4141
#include "capi.h"
4242

43-
PyTypeObject PyTuple_Type = PY_TRUFFLE_TYPE("tuple", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, sizeof(PyTupleObject) - sizeof(PyObject *));
43+
/* prototype */
44+
PyObject* PyTruffle_Tuple_Alloc(PyTypeObject* cls, Py_ssize_t nitems);
45+
46+
/* tuple type */
47+
PyTypeObject PyTuple_Type = PY_TRUFFLE_TYPE_WITH_ALLOC("tuple", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, sizeof(PyTupleObject) - sizeof(PyObject *), PyTruffle_Tuple_Alloc);
4448

4549
/* Tuples */
4650
UPCALL_ID(PyTuple_New);
@@ -106,6 +110,7 @@ PyObject * tuple_subtype_new(PyTypeObject *type, PyObject *iterable) {
106110
if (newobj == NULL) {
107111
return NULL;
108112
}
113+
newobj->ob_item = (PyObject **) ((char *)newobj + offsetof(PyTupleObject, ob_item) + sizeof(PyObject **));
109114
newobj = polyglot_from_PyTupleObject(newobj);
110115
for (i = 0; i < n; i++) {
111116
item = PyTuple_GetItem(tmp, i);
@@ -124,3 +129,24 @@ int PyTruffle_Tuple_SetItem(PyObject* tuple, Py_ssize_t position, PyObject* item
124129
PyTuple_SET_ITEM(tuple, position, item);
125130
return 0;
126131
}
132+
133+
PyObject* PyTruffle_Tuple_Alloc(PyTypeObject* cls, Py_ssize_t nitems) {
134+
/*
135+
* TODO(fa): For 'PyVarObjects' (i.e. 'nitems > 0') we increase the size by 'sizeof(void *)'
136+
* because this additional pointer can then be used as pointer to the element array.
137+
* CPython usually embeds the array in the struct but Sulong doesn't currently support that.
138+
* So we allocate space for the additional array pointer.
139+
* Also consider any 'PyVarObject' (in particular 'PyTupleObject') if this is fixed.
140+
*/
141+
Py_ssize_t size = cls->tp_basicsize + cls->tp_itemsize * nitems + sizeof(PyObject **);
142+
PyObject* newObj = (PyObject*)PyObject_Malloc(size);
143+
if(cls->tp_dictoffset) {
144+
*((PyObject **) ((char *)newObj + cls->tp_dictoffset)) = NULL;
145+
}
146+
Py_TYPE(newObj) = cls;
147+
if (nitems > 0) {
148+
((PyVarObject*)newObj)->ob_size = nitems;
149+
}
150+
return newObj;
151+
}
152+

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/DynamicObjectNativeWrapper.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import static com.oracle.graal.python.builtins.objects.cext.NativeMemberNames.TP_SUBCLASSES;
5252
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__BASICSIZE__;
5353
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICTOFFSET__;
54-
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
5554
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__ITEMSIZE__;
5655
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__WEAKLISTOFFSET__;
5756
import static com.oracle.graal.python.nodes.SpecialMethodNames.RICHCMP;
@@ -79,6 +78,7 @@
7978
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.IsPointerNode;
8079
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.PCallCapiFunction;
8180
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.SetSpecialSingletonPtrNode;
81+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToJavaNode;
8282
import com.oracle.graal.python.builtins.objects.cext.DynamicObjectNativeWrapperFactory.ReadTypeNativeMemberNodeGen;
8383
import com.oracle.graal.python.builtins.objects.cext.UnicodeObjectNodes.UnicodeAsWideCharNode;
8484
import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage;
@@ -894,6 +894,19 @@ long doTpBasicsize(PythonAbstractClass object, @SuppressWarnings("unused") Strin
894894
return basicsize;
895895
}
896896

897+
@Specialization(guards = "eq(TP_ALLOC, key)")
898+
Object doTpAlloc(PythonAbstractClass object, @SuppressWarnings("unused") String key, Object allocFunc,
899+
@Cached WriteAttributeToObjectNode writeAttrNode,
900+
@Cached IsBuiltinClassProfile profile,
901+
@Cached CExtNodes.AsPythonObjectNode asPythonObjectNode) {
902+
if (profile.profileClass(object, PythonBuiltinClassType.PythonClass)) {
903+
writeAttrNode.execute(object, TypeBuiltins.TYPE_ALLOC, asPythonObjectNode.execute(allocFunc));
904+
} else {
905+
writeAttrNode.execute(object, SpecialMethodNames.__ALLOC__, asPythonObjectNode.execute(allocFunc));
906+
}
907+
return allocFunc;
908+
}
909+
897910
@Specialization(guards = "eq(TP_SUBCLASSES, key)")
898911
@TruffleBoundary
899912
Object doTpSubclasses(PythonClass object, @SuppressWarnings("unused") String key, DynamicObjectNativeWrapper.PythonObjectNativeWrapper value) {

0 commit comments

Comments
 (0)