Skip to content

Commit 151042d

Browse files
committed
[GR-22811] Several performance improvements for C extensions.
PullRequest: graalpython/937
2 parents c381649 + a57a528 commit 151042d

19 files changed

+417
-206
lines changed

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

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -247,19 +247,6 @@ static void initialize_capi() {
247247
initialize_bufferprocs();
248248
}
249249

250-
void* native_to_java_exported(PyObject* obj) {
251-
return native_to_java(obj);
252-
}
253-
254-
void* native_to_java_stealing_exported(PyObject* obj) {
255-
return native_to_java_stealing(obj);
256-
}
257-
258-
// This function does not guarantee that a pointer object is returned.
259-
void* native_pointer_to_java_exported(void* val) {
260-
return native_pointer_to_java(val);
261-
}
262-
263250
// Workaround: use 'uint64' to avoid conversion to an LLVM boxed primitive such
264251
// that it is guaranteed to return a pointer object.
265252
void* native_long_to_java(uint64_t val) {
@@ -411,6 +398,26 @@ Py_ssize_t PyTruffle_SUBREF(PyObject* obj, Py_ssize_t value) {
411398
return new_value;
412399
}
413400

401+
/** to be used from Java code only; calls DECREF */
402+
Py_ssize_t PyTruffle_bulk_SUBREF(PyObject* ptrArray[], Py_ssize_t values[], int64_t len) {
403+
int64_t i;
404+
PyObject* obj;
405+
406+
for (i=0; i < len; i++) {
407+
obj = ptrArray[i];
408+
Py_ssize_t new_value = ((obj->ob_refcnt) -= values[i]);
409+
if (new_value == 0) {
410+
_Py_Dealloc(obj);
411+
}
412+
#ifdef Py_REF_DEBUG
413+
else if (new_value < 0) {
414+
_Py_NegativeRefcount(filename, lineno, op);
415+
}
416+
#endif
417+
}
418+
return 0;
419+
}
420+
414421
typedef struct PyObjectHandle {
415422
PyObject_HEAD
416423
} PyObjectHandle;

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,6 @@ PyObject* native_to_java_stealing(PyObject* obj) {
247247
}
248248

249249

250-
extern void* native_to_java_exported(PyObject* obj);
251-
extern void* native_to_java_stealing_exported(PyObject* obj);
252-
253250
MUST_INLINE
254251
PyTypeObject* native_type_to_java(PyTypeObject* type) {
255252
if (!truffle_cannot_be_handle(type)) {
@@ -266,8 +263,6 @@ void* native_pointer_to_java(void* obj) {
266263
return obj;
267264
}
268265

269-
extern void* native_pointer_to_java_exported(void* ptr);
270-
271266
extern void* to_java(PyObject* obj);
272267
extern void* to_java_type(PyTypeObject* cls);
273268
extern PyObject* to_sulong(void *o);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ PyObject* PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
4848
return to_sulong(polyglot_invoke(PY_TRUFFLE_CEXT,
4949
"PyCFunction_NewEx",
5050
polyglot_from_string((const char*)(ml->ml_name), SRC_CS),
51-
pytruffle_decorate_function(native_pointer_to_java(ml->ml_meth), native_to_java_stealing_exported),
51+
native_pointer_to_java(ml->ml_meth),
5252
get_method_flags_wrapper(ml->ml_flags),
5353
native_to_java(self),
5454
native_to_java(module),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ int PyModule_AddFunctions(PyObject* mod, PyMethodDef* methods) {
5555
native_to_java(mod),
5656
NULL,
5757
polyglot_from_string((const char*)(def.ml_name), SRC_CS),
58-
pytruffle_decorate_function(native_pointer_to_java(def.ml_meth), native_to_java_stealing_exported),
58+
native_pointer_to_java(def.ml_meth),
5959
get_method_flags_wrapper(def.ml_flags),
6060
polyglot_from_string((const char*)(def.ml_doc ? def.ml_doc : ""), SRC_CS));
6161
def = methods[++idx];

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ typedef struct {
5858
/* Get the object given the GC head */
5959
#define FROM_MEM_HEAD(g) ((void *)(((mem_head_t *)g)+1))
6060

61+
typedef void (*trace_free_fun_t)(void *, size_t);
62+
UPCALL_TYPED_ID(PyTruffle_Trace_Free, trace_free_fun_t);
63+
6164
/* This is our version of 'PyObject_Free' which is also able to free Sulong handles. */
6265
MUST_INLINE static
6366
void _PyObject_Free(void* ptr) {
@@ -71,7 +74,7 @@ void _PyObject_Free(void* ptr) {
7174
}
7275
}
7376
mem_head_t* ptr_with_head = AS_MEM_HEAD(ptr);
74-
(void) polyglot_invoke(PY_TRUFFLE_CEXT, "PyTruffle_Trace_Free", ptr, ptr_with_head->size);
77+
_jls_PyTruffle_Trace_Free(ptr, ptr_with_head->size);
7578
free(ptr_with_head);
7679
}
7780

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

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ static void add_method_or_slot(PyTypeObject* cls, PyObject* type_dict, char* nam
337337
cls,
338338
native_to_java(type_dict),
339339
polyglot_from_string(name, SRC_CS),
340-
native_pointer_to_java(result_conversion != NULL ? pytruffle_decorate_function(native_pointer_to_java(meth), result_conversion) : meth),
340+
native_pointer_to_java(result_conversion != NULL ? pytruffle_decorate_function(native_pointer_to_java(meth), result_conversion) : native_pointer_to_java(meth)),
341341
(signature != NULL ? signature : get_method_flags_wrapper(flags)),
342342
doc ? polyglot_from_string(doc, SRC_CS) : native_to_java(Py_None),
343343
(flags) > 0 && ((flags) & METH_CLASS) != 0,
@@ -363,8 +363,8 @@ int PyType_Ready(PyTypeObject* cls) {
363363
} while(0)
364364

365365
#define ADD_IF_MISSING(attr, def) if (!(attr)) { attr = def; }
366-
#define ADD_METHOD(m) ADD_METHOD_OR_SLOT(m.ml_name, native_to_java_stealing_exported, m.ml_meth, m.ml_flags, NULL, m.ml_doc)
367-
#define ADD_SLOT(name, meth, flags) ADD_METHOD_OR_SLOT(name, native_to_java_stealing_exported, meth, flags, NULL, name)
366+
#define ADD_METHOD(m) ADD_METHOD_OR_SLOT(m.ml_name, NULL, m.ml_meth, m.ml_flags, NULL, m.ml_doc)
367+
#define ADD_SLOT(name, meth, flags) ADD_METHOD_OR_SLOT(name, NULL, meth, flags, NULL, name)
368368
#define ADD_SLOT_PRIMITIVE(name, meth, flags) ADD_METHOD_OR_SLOT(name, NULL, meth, flags, NULL, name)
369369
#define ADD_SLOT_CONV(name, result_conversion, meth, flags, signature) ADD_METHOD_OR_SLOT(name, result_conversion, meth, flags, signature, name)
370370
#define ADD_METHOD_OR_SLOT(__name__, __res_conv__, __meth__, __flags__, __signature__, __doc__) \
@@ -510,7 +510,7 @@ int PyType_Ready(PyTypeObject* cls) {
510510

511511
// NOTE: The slots may be called from managed code, i.e., we need to wrap the functions
512512
// and convert arguments that should be C primitives.
513-
ADD_SLOT_CONV("__getattr__", native_to_java_stealing_exported, cls->tp_getattr, -2, JWRAPPER_GETATTR);
513+
ADD_SLOT_CONV("__getattr__", NULL, cls->tp_getattr, -2, JWRAPPER_GETATTR);
514514
ADD_SLOT_CONV("__setattr__", NULL, cls->tp_setattr, -3, JWRAPPER_SETATTR);
515515
ADD_SLOT("__repr__", cls->tp_repr, -1);
516516
ADD_SLOT_PRIMITIVE("__hash__", cls->tp_hash, -1);
@@ -525,20 +525,20 @@ int PyType_Ready(PyTypeObject* cls) {
525525
the default function dispatches to the individual comparison functions which would in
526526
this case again invoke 'object.__truffle_richcompare__'. */
527527
if (cls->tp_richcompare && cls->tp_richcompare != PyBaseObject_Type.tp_richcompare) {
528-
ADD_SLOT_CONV("__compare__", native_to_java_stealing_exported, cls->tp_richcompare, -3, JWRAPPER_RICHCMP);
529-
ADD_SLOT_CONV("__lt__", native_to_java_stealing_exported, cls->tp_richcompare, -2, JWRAPPER_LT);
530-
ADD_SLOT_CONV("__le__", native_to_java_stealing_exported, cls->tp_richcompare, -2, JWRAPPER_LE);
531-
ADD_SLOT_CONV("__eq__", native_to_java_stealing_exported, cls->tp_richcompare, -2, JWRAPPER_EQ);
532-
ADD_SLOT_CONV("__ne__", native_to_java_stealing_exported, cls->tp_richcompare, -2, JWRAPPER_NE);
533-
ADD_SLOT_CONV("__gt__", native_to_java_stealing_exported, cls->tp_richcompare, -2, JWRAPPER_GT);
534-
ADD_SLOT_CONV("__ge__", native_to_java_stealing_exported, cls->tp_richcompare, -2, JWRAPPER_GE);
528+
ADD_SLOT_CONV("__compare__", NULL, cls->tp_richcompare, -3, JWRAPPER_RICHCMP);
529+
ADD_SLOT_CONV("__lt__", NULL, cls->tp_richcompare, -2, JWRAPPER_LT);
530+
ADD_SLOT_CONV("__le__", NULL, cls->tp_richcompare, -2, JWRAPPER_LE);
531+
ADD_SLOT_CONV("__eq__", NULL, cls->tp_richcompare, -2, JWRAPPER_EQ);
532+
ADD_SLOT_CONV("__ne__", NULL, cls->tp_richcompare, -2, JWRAPPER_NE);
533+
ADD_SLOT_CONV("__gt__", NULL, cls->tp_richcompare, -2, JWRAPPER_GT);
534+
ADD_SLOT_CONV("__ge__", NULL, cls->tp_richcompare, -2, JWRAPPER_GE);
535535
}
536536
ADD_SLOT("__iter__", cls->tp_iter, -1);
537537
ADD_SLOT("__next__", cls->tp_iternext, -1);
538538
ADD_SLOT("__get__", cls->tp_descr_get, -3);
539539
ADD_SLOT_PRIMITIVE("__set__", cls->tp_descr_set, -3);
540540
ADD_SLOT_PRIMITIVE("__init__", cls->tp_init, METH_KEYWORDS | METH_VARARGS);
541-
ADD_SLOT_CONV("__alloc__", native_to_java_stealing_exported, cls->tp_alloc, -2, JWRAPPER_ALLOC);
541+
ADD_SLOT_CONV("__alloc__", NULL, cls->tp_alloc, -2, JWRAPPER_ALLOC);
542542
ADD_SLOT("__new__", cls->tp_new, METH_KEYWORDS | METH_VARARGS);
543543
ADD_SLOT_PRIMITIVE("__free__", cls->tp_free, -1);
544544
ADD_SLOT_PRIMITIVE("__del__", cls->tp_del, -1);
@@ -547,32 +547,32 @@ int PyType_Ready(PyTypeObject* cls) {
547547
PyNumberMethods* numbers = cls->tp_as_number;
548548
if (numbers) {
549549
ADD_SLOT("__add__", numbers->nb_add, -2);
550-
ADD_SLOT_CONV("__radd__", native_to_java_stealing_exported, numbers->nb_add, -2, JWRAPPER_REVERSE);
550+
ADD_SLOT_CONV("__radd__", NULL, numbers->nb_add, -2, JWRAPPER_REVERSE);
551551
ADD_SLOT("__sub__", numbers->nb_subtract, -2);
552-
ADD_SLOT_CONV("__rsub__", native_to_java_stealing_exported, numbers->nb_subtract, -2, JWRAPPER_REVERSE);
552+
ADD_SLOT_CONV("__rsub__", NULL, numbers->nb_subtract, -2, JWRAPPER_REVERSE);
553553
ADD_SLOT("__mul__", numbers->nb_multiply, -2);
554-
ADD_SLOT_CONV("__rmul__", native_to_java_stealing_exported, numbers->nb_multiply, -2, JWRAPPER_REVERSE);
554+
ADD_SLOT_CONV("__rmul__", NULL, numbers->nb_multiply, -2, JWRAPPER_REVERSE);
555555
ADD_SLOT("__mod__", numbers->nb_remainder, -2);
556-
ADD_SLOT_CONV("__rmod__", native_to_java_stealing_exported, numbers->nb_remainder, -2, JWRAPPER_REVERSE);
556+
ADD_SLOT_CONV("__rmod__", NULL, numbers->nb_remainder, -2, JWRAPPER_REVERSE);
557557
ADD_SLOT("__divmod__", numbers->nb_divmod, -2);
558-
ADD_SLOT_CONV("__rdivmod__", native_to_java_stealing_exported, numbers->nb_divmod, -2, JWRAPPER_REVERSE);
559-
ADD_SLOT_CONV("__pow__", native_to_java_stealing_exported, numbers->nb_power, -3, JWRAPPER_POW);
560-
ADD_SLOT_CONV("__rpow__", native_to_java_stealing_exported, numbers->nb_power, -3, JWRAPPER_REVERSE_POW);
558+
ADD_SLOT_CONV("__rdivmod__", NULL, numbers->nb_divmod, -2, JWRAPPER_REVERSE);
559+
ADD_SLOT_CONV("__pow__", NULL, numbers->nb_power, -3, JWRAPPER_POW);
560+
ADD_SLOT_CONV("__rpow__", NULL, numbers->nb_power, -3, JWRAPPER_REVERSE_POW);
561561
ADD_SLOT("__neg__", numbers->nb_negative, -1);
562562
ADD_SLOT("__pos__", numbers->nb_positive, -1);
563563
ADD_SLOT("__abs__", numbers->nb_absolute, -1);
564564
ADD_SLOT_CONV("__bool__", native_int_to_bool, numbers->nb_bool, -1, NULL);
565565
ADD_SLOT("__invert__", numbers->nb_invert, -1);
566566
ADD_SLOT("__lshift__", numbers->nb_lshift, -2);
567-
ADD_SLOT_CONV("__rlshift__", native_to_java_stealing_exported, numbers->nb_lshift, -2, JWRAPPER_REVERSE);
567+
ADD_SLOT_CONV("__rlshift__", NULL, numbers->nb_lshift, -2, JWRAPPER_REVERSE);
568568
ADD_SLOT("__rshift__", numbers->nb_rshift, -2);
569-
ADD_SLOT_CONV("__rrshift__", native_to_java_stealing_exported, numbers->nb_rshift, -2, JWRAPPER_REVERSE);
569+
ADD_SLOT_CONV("__rrshift__", NULL, numbers->nb_rshift, -2, JWRAPPER_REVERSE);
570570
ADD_SLOT("__and__", numbers->nb_and, -2);
571-
ADD_SLOT_CONV("__rand__", native_to_java_stealing_exported, numbers->nb_and, -2, JWRAPPER_REVERSE);
571+
ADD_SLOT_CONV("__rand__", NULL, numbers->nb_and, -2, JWRAPPER_REVERSE);
572572
ADD_SLOT("__xor__", numbers->nb_xor, -2);
573-
ADD_SLOT_CONV("__rxor__", native_to_java_stealing_exported, numbers->nb_xor, -2, JWRAPPER_REVERSE);
573+
ADD_SLOT_CONV("__rxor__", NULL, numbers->nb_xor, -2, JWRAPPER_REVERSE);
574574
ADD_SLOT("__or__", numbers->nb_or, -2);
575-
ADD_SLOT_CONV("__ror__", native_to_java_stealing_exported, numbers->nb_or, -2, JWRAPPER_REVERSE);
575+
ADD_SLOT_CONV("__ror__", NULL, numbers->nb_or, -2, JWRAPPER_REVERSE);
576576
ADD_SLOT("__int__", numbers->nb_int, -1);
577577
ADD_SLOT("__float__", numbers->nb_float, -1);
578578
ADD_SLOT("__iadd__", numbers->nb_inplace_add, -2);
@@ -586,27 +586,27 @@ int PyType_Ready(PyTypeObject* cls) {
586586
ADD_SLOT("__ixor__", numbers->nb_inplace_xor, -2);
587587
ADD_SLOT("__ior__", numbers->nb_inplace_or, -2);
588588
ADD_SLOT("__floordiv__", numbers->nb_floor_divide, -2);
589-
ADD_SLOT_CONV("__rfloordiv__", native_to_java_stealing_exported, numbers->nb_floor_divide, -2, JWRAPPER_REVERSE);
589+
ADD_SLOT_CONV("__rfloordiv__", NULL, numbers->nb_floor_divide, -2, JWRAPPER_REVERSE);
590590
ADD_SLOT("__truediv__", numbers->nb_true_divide, -2);
591-
ADD_SLOT_CONV("__rtruediv__", native_to_java_stealing_exported, numbers->nb_true_divide, -2, JWRAPPER_REVERSE);
591+
ADD_SLOT_CONV("__rtruediv__", NULL, numbers->nb_true_divide, -2, JWRAPPER_REVERSE);
592592
ADD_SLOT("__ifloordiv__", numbers->nb_inplace_floor_divide, -2);
593593
ADD_SLOT("__itruediv__", numbers->nb_inplace_true_divide, -2);
594594
ADD_SLOT("__index__", numbers->nb_index, -1);
595595
ADD_SLOT("__matmul__", numbers->nb_matrix_multiply, -2);
596-
ADD_SLOT_CONV("__rmatmul__", native_to_java_stealing_exported, numbers->nb_matrix_multiply, -2, JWRAPPER_REVERSE);
596+
ADD_SLOT_CONV("__rmatmul__", NULL, numbers->nb_matrix_multiply, -2, JWRAPPER_REVERSE);
597597
ADD_SLOT("__imatmul__", numbers->nb_inplace_matrix_multiply, -2);
598598
}
599599

600600
PySequenceMethods* sequences = cls->tp_as_sequence;
601601
if (sequences) {
602602
ADD_SLOT_PRIMITIVE("__len__", sequences->sq_length, -1);
603603
ADD_SLOT("__add__", sequences->sq_concat, -2);
604-
ADD_SLOT_CONV("__mul__", native_to_java_stealing_exported, sequences->sq_repeat, -2, JWRAPPER_SSIZE_ARG);
605-
ADD_SLOT_CONV("__getitem__", native_to_java_stealing_exported, sequences->sq_item, -2, JWRAPPER_SSIZE_ARG);
604+
ADD_SLOT_CONV("__mul__", NULL, sequences->sq_repeat, -2, JWRAPPER_SSIZE_ARG);
605+
ADD_SLOT_CONV("__getitem__", NULL, sequences->sq_item, -2, JWRAPPER_SSIZE_ARG);
606606
ADD_SLOT_CONV("__setitem__", NULL, sequences->sq_ass_item, -3, JWRAPPER_SSIZE_OBJ_ARG);
607607
ADD_SLOT_PRIMITIVE("__contains__", sequences->sq_contains, -2);
608608
ADD_SLOT("__iadd__", sequences->sq_inplace_concat, -2);
609-
ADD_SLOT_CONV("__imul__", native_to_java_stealing_exported, sequences->sq_inplace_repeat, -2, JWRAPPER_SSIZE_ARG);
609+
ADD_SLOT_CONV("__imul__", NULL, sequences->sq_inplace_repeat, -2, JWRAPPER_SSIZE_ARG);
610610
}
611611

612612
PyMappingMethods* mappings = cls->tp_as_mapping;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ExternalFunctionNodes.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@
4949
import com.oracle.graal.python.builtins.objects.PNone;
5050
import com.oracle.graal.python.builtins.objects.cext.CApiGuards;
5151
import com.oracle.graal.python.builtins.objects.cext.CExtNodes;
52-
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.AsPythonObjectStealingNode;
5352
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ConvertArgsToSulongNode;
5453
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.SubRefCntNode;
55-
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.AsPythonObjectStealingNodeGen;
54+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToJavaStealingNode;
55+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToJavaStealingNodeGen;
5656
import com.oracle.graal.python.builtins.objects.function.PArguments;
5757
import com.oracle.graal.python.builtins.objects.function.PKeyword;
5858
import com.oracle.graal.python.builtins.objects.function.Signature;
@@ -177,7 +177,7 @@ static final class ExternalFunctionInvokeNode extends PNodeWithContext implement
177177
@Child private CExtNodes.ConvertArgsToSulongNode toSulongNode;
178178
@Child private CheckFunctionResultNode checkResultNode = CheckFunctionResultNode.create();
179179
@Child private PForeignToPTypeNode fromForeign = PForeignToPTypeNode.create();
180-
@Child private AsPythonObjectStealingNode asPythonObjectNode = AsPythonObjectStealingNodeGen.create();
180+
@Child private ToJavaStealingNode asPythonObjectNode = ToJavaStealingNodeGen.create();
181181
@Child private InteropLibrary lib;
182182
@Child private PRaiseNode raiseNode;
183183
@Child private ReleaseNativeWrapperNode releaseNativeWrapperNode;

0 commit comments

Comments
 (0)