Skip to content

Commit df1240f

Browse files
committed
move CallWithPolyglotArgs into capi.h and have a version using va_list
1 parent 8eb28d3 commit df1240f

File tree

4 files changed

+58
-44
lines changed

4 files changed

+58
-44
lines changed

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,4 +320,35 @@ int bytes_copy2mem(char* target, char* source, size_t nbytes);
320320
/* MEMORYVIEW, BUFFERDECORATOR */
321321
int bufferdecorator_getbuffer(PyBufferDecorator *self, Py_buffer *view, int flags);
322322

323+
#if 0
324+
/*
325+
* (tfel): On native Sulong, using va_list will force all arguments to native
326+
* memory, which hinders escape analysis and PE in a big way. To avoid this,
327+
* when we have function called with var args (rather than already with a
328+
* va_list), we allocate a managed array of void*, fill it with the arguments,
329+
* and pass that one on. In the target functions, we use the macros below to
330+
* access the variable arguments part depending on whether it is a va_list or a
331+
* managed void* array. The assumption is that once everything is compiled
332+
* together, the managed array with arguments will be escape analyzed away.
333+
*/
334+
#define CallWithPolyglotArgs(result, last, off, function, ...) \
335+
int __poly_argc = polyglot_get_arg_count(); \
336+
int __poly_args_s = sizeof(void*) * (__poly_argc - off); \
337+
void **__poly_args = truffle_managed_malloc(__poly_args_s); \
338+
for (int i = off; i < __poly_argc; i++) { \
339+
__poly_args[i - off] = polyglot_get_arg(i); \
340+
} \
341+
result = function(__VA_ARGS__, NULL, __poly_args, 0)
342+
#else
343+
/*
344+
* (tfel): Just skip the optimization with using a managed malloc and use
345+
* va_list always.
346+
*/
347+
#define CallWithPolyglotArgs(result, last, off, function, ...) \
348+
va_list __poly_args; \
349+
va_start(__poly_args, last); \
350+
result = function(__VA_ARGS__, __poly_args, NULL, 0); \
351+
va_end(__poly_args)
352+
#endif
353+
323354
#endif

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,7 @@ int PyErr_ExceptionMatches(PyObject *exc) {
163163
extern PyObject* PyTruffle_Unicode_FromFormat(const char*, va_list, void**, int);
164164

165165
PyObject* PyErr_Format(PyObject* exception, const char* fmt, ...) {
166-
int argc = polyglot_get_arg_count();
167-
void **args = truffle_managed_malloc(sizeof(void*) * (argc - 2));
168-
for (int i = 2; i < argc; i++) {
169-
args[i - 2] = polyglot_get_arg(i);
170-
}
171-
PyObject *formatted_msg = PyTruffle_Unicode_FromFormat(fmt, NULL, args, 0);
166+
CallWithPolyglotArgs(PyObject* formatted_msg, fmt, 2, PyTruffle_Unicode_FromFormat, fmt);
172167
UPCALL_CEXT_VOID(_jls_PyErr_CreateAndSetException, native_to_java(exception), native_to_java(formatted_msg));
173168
return NULL;
174169
}

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

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -67,26 +67,6 @@ PyObject* PyTruffle_GetArg(positional_argstack* p, PyObject* kwds, char** kwdnam
6767
return out;
6868
}
6969

70-
/*
71-
* (tfel): On native Sulong, using va_list will force all arguments to native
72-
* memory, which hinders escape analysis and PE in a big way. To avoid this,
73-
* when we have function called with var args (rather than already with a
74-
* va_list), we allocate a managed array of void*, fill it with the arguments,
75-
* and pass that one on. In the target functions, we use the macros below to
76-
* access the variable arguments part depending on whether it is a va_list or a
77-
* managed void* array. The assumption is that once everything is compiled
78-
* together, the managed array with arguments will be escape analyzed away.
79-
*/
80-
81-
#define CallAndReturnWithPolyglotArgs(off, function, ...) \
82-
int __poly_argc = polyglot_get_arg_count(); \
83-
int __poly_args_s = sizeof(void*) * (__poly_argc - off); \
84-
void **__poly_args = truffle_managed_malloc(__poly_args_s); \
85-
for (int i = off; i < __poly_argc; i++) { \
86-
__poly_args[i - off] = polyglot_get_arg(i); \
87-
} \
88-
return function(__VA_ARGS__, NULL, __poly_args, 0)
89-
9070
#define PyTruffleVaArg(poly_args, offset, va, T) (poly_args == NULL ? va_arg(va, T) : (T)(poly_args[offset++]))
9171

9272
#define PyTruffle_WriteOut(poly_args, offset, va, T, arg) { \
@@ -379,11 +359,13 @@ int _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *argv, PyObject *kwds, const c
379359

380360

381361
int PyArg_ParseTupleAndKeywords(PyObject *argv, PyObject *kwds, const char *format, char** kwdnames, ...) {
382-
CallAndReturnWithPolyglotArgs(4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, format, kwdnames);
362+
CallWithPolyglotArgs(int result, kwdnames, 4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, format, kwdnames);
363+
return result;
383364
}
384365

385366
int _PyArg_ParseTupleAndKeywords_SizeT(PyObject *argv, PyObject *kwds, const char *format, char** kwdnames, ...) {
386-
CallAndReturnWithPolyglotArgs(4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, format, kwdnames);
367+
CallWithPolyglotArgs(int result, kwdnames, 4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, format, kwdnames);
368+
return result;
387369
}
388370

389371
int PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, PyObject *kwds, struct _PyArg_Parser *parser, ...) {
@@ -392,7 +374,8 @@ int PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, PyObject *kwds, struct _
392374
for (i=0; i < nargs; i++) {
393375
PyTuple_SetItem(argv, i, args[i]);
394376
}
395-
CallAndReturnWithPolyglotArgs(4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, parser->format, parser->keywords);
377+
CallWithPolyglotArgs(int result, parser, 4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, parser->format, parser->keywords);
378+
return result;
396379
}
397380

398381
int _PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwds, struct _PyArg_Parser *parser, ...) {
@@ -402,7 +385,8 @@ int _PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwds, s
402385
PyTuple_SetItem(argv, i, args[i]);
403386
}
404387

405-
CallAndReturnWithPolyglotArgs(4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, parser->format, parser->keywords);
388+
CallWithPolyglotArgs(int result, parser, 4, _PyTruffleArg_ParseTupleAndKeywords, argv, kwds, parser->format, parser->keywords);
389+
return result;
406390
}
407391

408392
int _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *kwargs, struct _PyArg_Parser *parser, va_list va) {
@@ -414,19 +398,23 @@ int _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *kwargs, s
414398
}
415399

416400
int _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *kwargs, struct _PyArg_Parser *parser, ...) {
417-
CallAndReturnWithPolyglotArgs(3, _PyTruffleArg_ParseTupleAndKeywords, args, kwargs, parser->format, parser->keywords);
401+
CallWithPolyglotArgs(int result, parser, 3, _PyTruffleArg_ParseTupleAndKeywords, args, kwargs, parser->format, parser->keywords);
402+
return result;
418403
}
419404

420405
int _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *kwargs, struct _PyArg_Parser *parser, ...) {
421-
CallAndReturnWithPolyglotArgs(3, _PyTruffleArg_ParseTupleAndKeywords, args, kwargs, parser->format, parser->keywords);
406+
CallWithPolyglotArgs(int result, parser, 3, _PyTruffleArg_ParseTupleAndKeywords, args, kwargs, parser->format, parser->keywords);
407+
return result;
422408
}
423409

424410
int PyArg_ParseTuple(PyObject *args, const char *format, ...) {
425-
CallAndReturnWithPolyglotArgs(2, _PyTruffleArg_ParseTupleAndKeywords, args, NULL, format, NULL);
411+
CallWithPolyglotArgs(int result, format, 2, _PyTruffleArg_ParseTupleAndKeywords, args, NULL, format, NULL);
412+
return result;
426413
}
427414

428415
int _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...) {
429-
CallAndReturnWithPolyglotArgs(2, _PyTruffleArg_ParseTupleAndKeywords, args, NULL, format, NULL);
416+
CallWithPolyglotArgs(int result, format, 2, _PyTruffleArg_ParseTupleAndKeywords, args, NULL, format, NULL);
417+
return result;
430418
}
431419

432420
int PyArg_VaParse(PyObject *args, const char *format, va_list va) {
@@ -438,11 +426,13 @@ int _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va) {
438426
}
439427

440428
int PyArg_Parse(PyObject *args, const char *format, ...) {
441-
CallAndReturnWithPolyglotArgs(2, _PyTruffleArg_ParseTupleAndKeywords, PyTuple_Pack(1, args), NULL, format, NULL);
429+
CallWithPolyglotArgs(int result, format, 2, _PyTruffleArg_ParseTupleAndKeywords, PyTuple_Pack(1, args), NULL, format, NULL);
430+
return result;
442431
}
443432

444433
int _PyArg_Parse_SizeT(PyObject *args, const char *format, ...) {
445-
CallAndReturnWithPolyglotArgs(2, _PyTruffleArg_ParseTupleAndKeywords, PyTuple_Pack(1, args), NULL, format, NULL);
434+
CallWithPolyglotArgs(int result, format, 2, _PyTruffleArg_ParseTupleAndKeywords, PyTuple_Pack(1, args), NULL, format, NULL);
435+
return result;
446436
}
447437

448438
typedef struct _build_stack {
@@ -659,11 +649,13 @@ PyObject* _Py_VaBuildValue_SizeT(const char *format, va_list va) {
659649
}
660650

661651
PyObject* Py_BuildValue(const char *format, ...) {
662-
CallAndReturnWithPolyglotArgs(1, _PyTruffle_BuildValue, format);
652+
CallWithPolyglotArgs(PyObject* result, format, 1, _PyTruffle_BuildValue, format);
653+
return result;
663654
}
664655

665656
PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
666-
CallAndReturnWithPolyglotArgs(1, _PyTruffle_BuildValue, format);
657+
CallWithPolyglotArgs(PyObject* result, format, 1, _PyTruffle_BuildValue, format);
658+
return result;
667659
}
668660

669661
// taken from CPython "Python/modsupport.c"

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,8 @@ PyObject* PyUnicode_FromFormatV(const char* format, va_list va) {
203203
}
204204

205205
PyObject* PyUnicode_FromFormat(const char* format, ...) {
206-
int argc = polyglot_get_arg_count();
207-
void **args = truffle_managed_malloc(sizeof(void*) * (argc - 1));
208-
for (int i = 1; i < argc; i++) {
209-
args[i - 1] = polyglot_get_arg(i);
210-
}
211-
return PyTruffle_Unicode_FromFormat(format, NULL, args, 0);
206+
CallWithPolyglotArgs(PyObject* result, format, 1, PyTruffle_Unicode_FromFormat, format);
207+
return result;
212208
}
213209

214210
PyObject * PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) {

0 commit comments

Comments
 (0)