Skip to content

Commit 9fa38f4

Browse files
committed
[GR-11423] Performance improvements for C calls
PullRequest: graalpython/167
2 parents fe7eb45 + 09ba268 commit 9fa38f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1185
-507
lines changed

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,6 @@
121121
#include "iterobject.h"
122122
#include "datetime.h"
123123

124-
#define PY_TRUFFLE_CEXT ((void*)polyglot_import("python_cext"))
125-
#define PY_BUILTIN ((void*)polyglot_import("python_builtins"))
126-
127-
#undef Py_NoValue
128-
#define Py_NoValue UPCALL_CEXT_O("Py_NoValue")
129-
130124
// TODO: we must extend the refcounting behavior to support handles to managed objects
131125
#undef Py_DECREF
132126
#define Py_DECREF(o) 0

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

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

43+
UPCALL_ID(_PyErr_Warn);
44+
4345
// partially taken from CPython "Python/_warnings.c"
4446
MUST_INLINE static int warn_unicode(PyObject *category, PyObject *message, Py_ssize_t stack_level, PyObject *source) {
4547
PyObject *res;
@@ -48,7 +50,7 @@ MUST_INLINE static int warn_unicode(PyObject *category, PyObject *message, Py_ss
4850
category = PyExc_RuntimeWarning;
4951
}
5052

51-
PyObject* result = UPCALL_CEXT_O("_PyErr_Warn", native_to_java(message), native_to_java(category), stack_level, native_to_java(source));
53+
PyObject* result = UPCALL_CEXT_O(_jls__PyErr_Warn, native_to_java(message), native_to_java(category), stack_level, native_to_java(source));
5254
if(result == NULL) {
5355
return -1;
5456
}

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

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,28 @@ static PyObject* null_error(void) {
5656
return NULL;
5757
}
5858

59+
UPCALL_ID(PyNumber_Check);
5960
int PyNumber_Check(PyObject *o) {
60-
PyObject *result = UPCALL_CEXT_O("PyNumber_Check", native_to_java(o));
61+
PyObject *result = UPCALL_CEXT_O(_jls_PyNumber_Check, native_to_java(o));
6162
if(result == Py_True) {
6263
return 1;
6364
}
6465
return 0;
6566
}
6667

68+
UPCALL_ID(PyNumber_UnaryOp);
6769
static PyObject * do_unaryop(PyObject *v, UnaryOp unaryop, char *unaryop_name) {
68-
return UPCALL_CEXT_O("PyNumber_UnaryOp", native_to_java(v), unaryop, polyglot_from_string(unaryop_name, SRC_CS));
70+
return UPCALL_CEXT_O(_jls_PyNumber_UnaryOp, native_to_java(v), unaryop, polyglot_from_string(unaryop_name, SRC_CS));
6971
}
7072

73+
UPCALL_ID(PyNumber_BinOp);
7174
static PyObject * do_binop(PyObject *v, PyObject *w, BinOp binop, char *binop_name) {
72-
return UPCALL_CEXT_O("PyNumber_BinOp", native_to_java(v), native_to_java(w), binop, polyglot_from_string(binop_name, SRC_CS));
75+
return UPCALL_CEXT_O(_jls_PyNumber_BinOp, native_to_java(v), native_to_java(w), binop, polyglot_from_string(binop_name, SRC_CS));
7376
}
7477

78+
UPCALL_ID(PyNumber_InPlaceBinOp);
7579
static PyObject * do_inplace_binop(PyObject *v, PyObject *w, BinOp binop, char *binop_name) {
76-
return UPCALL_CEXT_O("PyNumber_InPlaceBinOp", native_to_java(v), native_to_java(w), binop, polyglot_from_string(binop_name, SRC_CS));
80+
return UPCALL_CEXT_O(_jls_PyNumber_InPlaceBinOp, native_to_java(v), native_to_java(w), binop, polyglot_from_string(binop_name, SRC_CS));
7781
}
7882

7983
PyObject * PyNumber_Add(PyObject *o1, PyObject *o2) {
@@ -132,11 +136,12 @@ PyObject * PyNumber_Invert(PyObject *o) {
132136
return do_unaryop(o, INVERT, "~");
133137
}
134138

139+
UPCALL_ID(PyNumber_Index);
135140
PyObject * PyNumber_Index(PyObject *o) {
136141
if (o == NULL) {
137142
return null_error();
138143
}
139-
return UPCALL_CEXT_O("PyNumber_Index", native_to_java(o));
144+
return UPCALL_CEXT_O(_jls_PyNumber_Index, native_to_java(o));
140145
}
141146

142147
PyObject * PyNumber_InPlaceTrueDivide(PyObject *o1, PyObject *o2) {
@@ -185,40 +190,48 @@ Py_ssize_t PyNumber_AsSsize_t(PyObject *item, PyObject *err) {
185190
return -1;
186191
}
187192

193+
UPCALL_ID(PyNumber_Long);
188194
PyObject * PyNumber_Long(PyObject *o) {
189-
return UPCALL_CEXT_O("PyNumber_Long", native_to_java(o));
195+
return UPCALL_CEXT_O(_jls_PyNumber_Long, native_to_java(o));
190196
}
191197

198+
UPCALL_ID(PyNumber_Float);
192199
PyObject * PyNumber_Float(PyObject *o) {
193-
return UPCALL_CEXT_O("PyNumber_Float", native_to_java(o));
200+
return UPCALL_CEXT_O(_jls_PyNumber_Float, native_to_java(o));
194201
}
195202

203+
UPCALL_ID(PyNumber_Absolute);
196204
PyObject * PyNumber_Absolute(PyObject *o) {
197-
return UPCALL_CEXT_O("PyNumber_Absolute", native_to_java(o));
205+
return UPCALL_CEXT_O(_jls_PyNumber_Absolute, native_to_java(o));
198206
}
199207

208+
UPCALL_ID(PyNumber_Divmod);
200209
PyObject * PyNumber_Divmod(PyObject *a, PyObject *b) {
201-
return UPCALL_CEXT_O("PyNumber_Divmod", native_to_java(a), native_to_java(b));
210+
return UPCALL_CEXT_O(_jls_PyNumber_Divmod, native_to_java(a), native_to_java(b));
202211
}
203212

204213

214+
UPCALL_ID(PyIter_Next);
205215
PyObject * PyIter_Next(PyObject *iter) {
206-
return UPCALL_CEXT_O("PyIter_Next", native_to_java(iter));
216+
return UPCALL_CEXT_O(_jls_PyIter_Next, native_to_java(iter));
207217
}
208218

219+
UPCALL_ID(PySequence_Check);
209220
int PySequence_Check(PyObject *s) {
210-
if (s == NULL) {
211-
return 0;
212-
}
213-
return UPCALL_CEXT_I("PySequence_Check", native_to_java(s));
221+
if (s == NULL) {
222+
return 0;
223+
}
224+
return UPCALL_CEXT_I(_jls_PySequence_Check, native_to_java(s));
214225
}
215226

227+
UPCALL_ID(PyObject_Size);
216228
Py_ssize_t PySequence_Size(PyObject *s) {
217-
return UPCALL_CEXT_L("PyObject_Size", native_to_java(s));
229+
return UPCALL_CEXT_L(_jls_PyObject_Size, native_to_java(s));
218230
}
219231

232+
UPCALL_ID(PySequence_Contains);
220233
int PySequence_Contains(PyObject *seq, PyObject *obj) {
221-
return UPCALL_CEXT_I("PySequence_Contains", native_to_java(seq), native_to_java(obj));
234+
return UPCALL_CEXT_I(_jls_PySequence_Contains, native_to_java(seq), native_to_java(obj));
222235
}
223236

224237
// taken from CPython "Objects/abstract.c"
@@ -228,24 +241,29 @@ Py_ssize_t PySequence_Length(PyObject *s) {
228241
}
229242
#define PySequence_Length PySequence_Size
230243

244+
UPCALL_ID(PySequence_GetItem);
231245
PyObject* PySequence_GetItem(PyObject *s, Py_ssize_t i) {
232-
return UPCALL_CEXT_O("PySequence_GetItem", native_to_java(s), i);
246+
return UPCALL_CEXT_O(_jls_PySequence_GetItem, native_to_java(s), i);
233247
}
234248

249+
UPCALL_ID(PySequence_SetItem);
235250
int PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o) {
236-
return UPCALL_CEXT_I("PySequence_SetItem", native_to_java(s), i, native_to_java(o));
251+
return UPCALL_CEXT_I(_jls_PySequence_SetItem, native_to_java(s), i, native_to_java(o));
237252
}
238253

254+
UPCALL_ID(PySequence_Tuple);
239255
PyObject* PySequence_Tuple(PyObject *v) {
240-
return UPCALL_CEXT_O("PySequence_Tuple", native_to_java(v));
256+
return UPCALL_CEXT_O(_jls_PySequence_Tuple, native_to_java(v));
241257
}
242258

259+
UPCALL_ID(PySequence_Fast);
243260
PyObject * PySequence_Fast(PyObject *v, const char *m) {
244-
return UPCALL_CEXT_O("PySequence_Fast", native_to_java(v), polyglot_from_string(m, SRC_CS));
261+
return UPCALL_CEXT_O(_jls_PySequence_Fast, native_to_java(v), polyglot_from_string(m, SRC_CS));
245262
}
246263

264+
UPCALL_ID(PyObject_GetItem);
247265
PyObject * PyMapping_GetItemString(PyObject *o, const char *key) {
248-
return UPCALL_CEXT_O("PyObject_GetItem", native_to_java(o), polyglot_from_string(key, SRC_CS));
266+
return UPCALL_CEXT_O(_jls_PyObject_GetItem, native_to_java(o), polyglot_from_string(key, SRC_CS));
249267
}
250268

251269
// taken from CPython "Objects/abstract.c"

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

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,35 @@
4848

4949
PyTypeObject PyBytes_Type = PY_TRUFFLE_TYPE("bytes", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_BYTES_SUBCLASS, PyBytesObject_SIZE);
5050

51+
UPCALL_ID(PyBytes_FromStringAndSize);
5152
PyObject* PyBytes_FromStringAndSize(const char* str, Py_ssize_t sz) {
5253
setlocale(LC_ALL, NULL);
5354
const char* encoding = nl_langinfo(CODESET);
5455
void *jstr = str != NULL ? polyglot_from_string_n(str, sz, SRC_CS) : to_java(NULL);
55-
return UPCALL_CEXT_O("PyBytes_FromStringAndSize", jstr, sz, polyglot_from_string(encoding, SRC_CS));
56+
return UPCALL_CEXT_O(_jls_PyBytes_FromStringAndSize, jstr, sz, polyglot_from_string(encoding, SRC_CS));
5657
}
5758

5859
PyObject * PyBytes_FromString(const char *str) {
59-
setlocale(LC_ALL, NULL);
60-
const char* encoding = nl_langinfo(CODESET);
61-
return UPCALL_CEXT_O("PyBytes_FromStringAndSize", polyglot_from_string(str, SRC_CS), 0, polyglot_from_string(encoding, SRC_CS));
60+
setlocale(LC_ALL, NULL);
61+
const char* encoding = nl_langinfo(CODESET);
62+
return UPCALL_CEXT_O(_jls_PyBytes_FromStringAndSize, polyglot_from_string(str, SRC_CS), 0, polyglot_from_string(encoding, SRC_CS));
6263
}
6364

65+
UPCALL_ID(PyTruffle_Bytes_AsString);
6466
char* PyBytes_AsString(PyObject *obj) {
65-
return UPCALL_CEXT_NOCAST("PyTruffle_Bytes_AsString", native_to_java(obj), ERROR_MARKER);
67+
return UPCALL_CEXT_NOCAST(_jls_PyTruffle_Bytes_AsString, native_to_java(obj), ERROR_MARKER);
6668
}
6769

70+
UPCALL_ID(PyBytes_AsStringCheckEmbeddedNull);
6871
int PyBytes_AsStringAndSize(PyObject *obj, char **s, Py_ssize_t *len) {
69-
setlocale(LC_ALL, NULL);
70-
const char* encoding = nl_langinfo(CODESET);
71-
PyObject *result = UPCALL_CEXT_O("PyBytes_AsStringCheckEmbeddedNull", native_to_java(obj), polyglot_from_string(encoding, SRC_CS));
72-
if(result == NULL) {
73-
return -1;
74-
}
72+
setlocale(LC_ALL, NULL);
73+
const char* encoding = nl_langinfo(CODESET);
74+
PyObject *result = UPCALL_CEXT_O(_jls_PyBytes_AsStringCheckEmbeddedNull, native_to_java(obj), polyglot_from_string(encoding, SRC_CS));
75+
if(result == NULL) {
76+
return -1;
77+
}
7578

76-
*s = as_char_pointer(result);
79+
*s = as_char_pointer(result);
7780

7881
if (len != NULL) {
7982
*len = polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "PyTruffle_Object_LEN", native_to_java(obj)));
@@ -97,9 +100,10 @@ PyObject * PyBytes_FromFormat(const char *format, ...) {
97100
}
98101

99102

100-
PyObject *
101-
PyBytes_FromFormatV(const char *format, va_list vargs) {
102-
/* Unfortunately, we need to know the expected types of the arguments before we can do an upcall. */
103+
UPCALL_ID(PyBytes_FromFormat);
104+
UPCALL_ID(PyTuple_SetItem);
105+
PyObject* PyBytes_FromFormatV(const char *format, va_list vargs) {
106+
/* Unfortunately, we need to know the expected types of the arguments before we can do an upcall. */
103107
char *s;
104108
const char *f = format;
105109
int longflag;
@@ -202,12 +206,12 @@ PyBytes_FromFormatV(const char *format, va_list vargs) {
202206

203207
default:
204208
// TODO correctly handle this case
205-
return UPCALL_CEXT_O("PyBytes_FromFormat", polyglot_from_string(format, SRC_CS), f+i);
209+
return UPCALL_CEXT_O(_jls_PyBytes_FromFormat, polyglot_from_string(format, SRC_CS), f+i);
206210
}
207211
}
208212

209213

210-
#define SETARG(__args, __i, __arg) UPCALL_CEXT_I("PyTuple_SetItem", native_to_java(__args), (__i), (__arg))
214+
#define SETARG(__args, __i, __arg) UPCALL_CEXT_I(_jls_PyTuple_SetItem, native_to_java(__args), (__i), (__arg))
211215

212216
// do actual conversion using one-character type specifiers
213217
int conversions = strlen(buffer);
@@ -240,20 +244,22 @@ PyBytes_FromFormatV(const char *format, va_list vargs) {
240244
break;
241245
}
242246
}
243-
return UPCALL_CEXT_O("PyBytes_FromFormat", polyglot_from_string(format, SRC_CS), native_to_java(args));
247+
return UPCALL_CEXT_O(_jls_PyBytes_FromFormat, polyglot_from_string(format, SRC_CS), native_to_java(args));
244248
}
245249

250+
UPCALL_ID(PyBytes_Concat);
246251
void PyBytes_Concat(PyObject **bytes, PyObject *newpart) {
247-
*bytes = UPCALL_CEXT_O("PyBytes_Concat", native_to_java(*bytes), native_to_java(newpart));
252+
*bytes = UPCALL_CEXT_O(_jls_PyBytes_Concat, native_to_java(*bytes), native_to_java(newpart));
248253
}
249254

250255
void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart) {
251256
PyBytes_Concat(bytes, newpart);
252257
Py_DECREF(newpart);
253258
}
254259

260+
UPCALL_ID(PyBytes_Size);
255261
Py_ssize_t PyBytes_Size(PyObject *bytes) {
256-
return UPCALL_CEXT_L("PyBytes_Size", native_to_java(bytes));
262+
return UPCALL_CEXT_L(_jls_PyBytes_Size, native_to_java(bytes));
257263
}
258264

259265
int bytes_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags) {
@@ -268,6 +274,7 @@ int bytes_copy2mem(char* target, char* source, size_t nbytes) {
268274
return 0;
269275
}
270276

277+
UPCALL_ID(PyBytes_Join);
271278
PyObject *_PyBytes_Join(PyObject *sep, PyObject *x) {
272-
return UPCALL_CEXT_O("PyBytes_Join", native_to_java(sep), native_to_java(x));
279+
return UPCALL_CEXT_O(_jls_PyBytes_Join, native_to_java(sep), native_to_java(x));
273280
}

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

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,38 @@
4040
*/
4141
#include "capi.h"
4242

43+
void *PY_TRUFFLE_CEXT;
44+
void *PY_BUILTIN;
45+
void *Py_NoValue;
46+
47+
PyObject*(*PY_TRUFFLE_LANDING)(void *rcv, void* name, ...);
48+
PyObject*(*PY_TRUFFLE_LANDING_L)(void *rcv, void* name, ...);
49+
PyObject*(*PY_TRUFFLE_LANDING_D)(void *rcv, void* name, ...);
50+
void*(*PY_TRUFFLE_LANDING_PTR)(void *rcv, void* name, ...);
51+
PyObject*(*PY_TRUFFLE_CEXT_LANDING)(void* name, ...);
52+
uint64_t (*PY_TRUFFLE_CEXT_LANDING_L)(void* name, ...);
53+
double (*PY_TRUFFLE_CEXT_LANDING_D)(void* name, ...);
54+
void* (*PY_TRUFFLE_CEXT_LANDING_PTR)(void* name, ...);
55+
56+
__attribute__((constructor (__COUNTER__)))
57+
static void initialize_upcall_functions() {
58+
PY_TRUFFLE_CEXT = (void*)polyglot_import("python_cext");
59+
PY_BUILTIN = (void*)polyglot_import("python_builtins");
60+
61+
PY_TRUFFLE_LANDING = ((PyObject*(*)(void *rcv, void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Upcall", SRC_CS)));
62+
PY_TRUFFLE_LANDING_L = ((PyObject*(*)(void *rcv, void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Upcall_l", SRC_CS)));
63+
PY_TRUFFLE_LANDING_D = ((PyObject*(*)(void *rcv, void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Upcall_d", SRC_CS)));
64+
PY_TRUFFLE_LANDING_PTR = ((void*(*)(void *rcv, void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Upcall_ptr", SRC_CS)));
65+
PY_TRUFFLE_CEXT_LANDING = ((PyObject*(*)(void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Cext_Upcall", SRC_CS)));
66+
PY_TRUFFLE_CEXT_LANDING_L = ((uint64_t (*)(void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Cext_Upcall_l", SRC_CS)));
67+
PY_TRUFFLE_CEXT_LANDING_D = ((double (*)(void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Cext_Upcall_d", SRC_CS)));
68+
PY_TRUFFLE_CEXT_LANDING_PTR = ((void* (*)(void* name, ...))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_Cext_Upcall_ptr", SRC_CS)));
69+
70+
Py_NoValue = UPCALL_CEXT_O(polyglot_from_string("Py_NoValue", SRC_CS));
71+
}
4372

4473
static void initialize_type_structure(PyTypeObject* structure, const char* typname, void* typeid) {
45-
PyTypeObject* ptype = (PyTypeObject*)UPCALL_CEXT_O("PyTruffle_Type", polyglot_from_string(typname, SRC_CS));
74+
PyTypeObject* ptype = (PyTypeObject*)UPCALL_CEXT_O(polyglot_from_string("PyTruffle_Type", SRC_CS), polyglot_from_string(typname, SRC_CS));
4675

4776
// Store the Sulong struct type id to be used for instances of this class
4877
polyglot_invoke(PY_TRUFFLE_CEXT, "PyTruffle_Set_SulongType", ptype, typeid);
@@ -119,25 +148,25 @@ POLYGLOT_DECLARE_TYPE(PyObjectPtr);
119148

120149
static void initialize_globals() {
121150
// None
122-
PyObject* jnone = UPCALL_CEXT_O("Py_None");
151+
PyObject* jnone = UPCALL_CEXT_O(polyglot_from_string("Py_None", SRC_CS));
123152
truffle_assign_managed(&_Py_NoneStruct, jnone);
124153

125154
// NotImplemented
126-
void *jnotimpl = UPCALL_CEXT_O("Py_NotImplemented");
155+
void *jnotimpl = UPCALL_CEXT_O(polyglot_from_string("Py_NotImplemented", SRC_CS));
127156
truffle_assign_managed(&_Py_NotImplementedStruct, jnotimpl);
128157

129158
// Ellipsis
130-
void *jellipsis = UPCALL_CEXT_O("Py_Ellipsis");
159+
void *jellipsis = UPCALL_CEXT_O(polyglot_from_string("Py_Ellipsis", SRC_CS));
131160
truffle_assign_managed(&_Py_EllipsisObject, jellipsis);
132161

133162
// True, False
134-
void *jtrue = UPCALL_CEXT_O("Py_True");
163+
void *jtrue = UPCALL_CEXT_O(polyglot_from_string("Py_True", SRC_CS));
135164
truffle_assign_managed(&_Py_TrueStruct, jtrue);
136-
void *jfalse = UPCALL_CEXT_O("Py_False");
165+
void *jfalse = UPCALL_CEXT_O(polyglot_from_string("Py_False", SRC_CS));
137166
truffle_assign_managed(&_Py_FalseStruct, jfalse);
138167

139168
// error marker
140-
void *jerrormarker = UPCALL_CEXT_PTR("Py_ErrorHandler");
169+
void *jerrormarker = UPCALL_CEXT_PTR(polyglot_from_string("Py_ErrorHandler", SRC_CS));
141170
truffle_assign_managed(&marker_struct, jerrormarker);
142171
}
143172

@@ -432,8 +461,9 @@ PyObject* WriteULongMember(PyObject* object, PyObject* offset, PyObject* value)
432461
return value;
433462
}
434463

464+
UPCALL_ID(__bool__);
435465
PyObject* WriteBoolMember(PyObject* object, PyObject* offset, PyObject* value) {
436-
WriteMember(object, offset, UPCALL_O(native_to_java(value), "__bool__") == Py_True ? (char)1 : (char)0, char);
466+
WriteMember(object, offset, UPCALL_O(native_to_java(value), _jls___bool__) == Py_True ? (char)1 : (char)0, char);
437467
return value;
438468
}
439469

0 commit comments

Comments
 (0)