Skip to content

Commit a9632e4

Browse files
committed
Try to avoid upcalls for numeric ops on managed objects
1 parent 8146039 commit a9632e4

File tree

4 files changed

+150
-138
lines changed

4 files changed

+150
-138
lines changed

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

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
#include "Python.h"
99
#include "capi.h" // GraalPy change
10-
#if 0 // GraalPy change
1110
#include "pycore_abstract.h" // _PyIndex_Check()
11+
#if 0 // GraalPy change
1212
#include "pycore_call.h" // _PyObject_CallNoArgs()
1313
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
1414
#include "pycore_object.h" // _Py_CheckSlotResult()
@@ -844,6 +844,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec)
844844
Py_XDECREF(empty);
845845
return result;
846846
}
847+
#endif // GraalPy
847848
/* Operations on numbers */
848849

849850
int
@@ -854,7 +855,6 @@ PyNumber_Check(PyObject *o)
854855
PyNumberMethods *nb = Py_TYPE(o)->tp_as_number;
855856
return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o));
856857
}
857-
#endif // GraalPy
858858

859859
/* Binary operators */
860860

@@ -1072,13 +1072,16 @@ ternary_op(PyObject *v,
10721072
return NULL;
10731073
}
10741074

1075+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
10751076
#define BINARY_FUNC(func, op, op_name) \
10761077
PyObject * \
10771078
func(PyObject *v, PyObject *w) { \
1079+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) { \
1080+
return GraalPyTruffle##func(v, w); \
1081+
} \
10781082
return binary_op(v, w, NB_SLOT(op), op_name); \
10791083
}
10801084

1081-
#if 0 // GraalPy
10821085
BINARY_FUNC(PyNumber_Or, nb_or, "|")
10831086
BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
10841087
BINARY_FUNC(PyNumber_And, nb_and, "&")
@@ -1090,6 +1093,10 @@ BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
10901093
PyObject *
10911094
PyNumber_Add(PyObject *v, PyObject *w)
10921095
{
1096+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
1097+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) {
1098+
return GraalPyTrufflePyNumber_Add(v, w);
1099+
}
10931100
PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_add), "+");
10941101
if (result != Py_NotImplemented) {
10951102
return result;
@@ -1128,6 +1135,10 @@ sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
11281135
PyObject *
11291136
PyNumber_Multiply(PyObject *v, PyObject *w)
11301137
{
1138+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
1139+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) {
1140+
return GraalPyTrufflePyNumber_Multiply(v, w);
1141+
}
11311142
PyObject *result = BINARY_OP1(v, w, NB_SLOT(nb_multiply), "*");
11321143
if (result == Py_NotImplemented) {
11331144
PySequenceMethods *mv = Py_TYPE(v)->tp_as_sequence;
@@ -1147,30 +1158,50 @@ PyNumber_Multiply(PyObject *v, PyObject *w)
11471158
PyObject *
11481159
PyNumber_MatrixMultiply(PyObject *v, PyObject *w)
11491160
{
1161+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
1162+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) {
1163+
return GraalPyTrufflePyNumber_MatrixMultiply(v, w);
1164+
}
11501165
return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@");
11511166
}
11521167

11531168
PyObject *
11541169
PyNumber_FloorDivide(PyObject *v, PyObject *w)
11551170
{
1171+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
1172+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) {
1173+
return GraalPyTrufflePyNumber_FloorDivide(v, w);
1174+
}
11561175
return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
11571176
}
11581177

11591178
PyObject *
11601179
PyNumber_TrueDivide(PyObject *v, PyObject *w)
11611180
{
1181+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
1182+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) {
1183+
return GraalPyTrufflePyNumber_TrueDivide(v, w);
1184+
}
11621185
return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
11631186
}
11641187

11651188
PyObject *
11661189
PyNumber_Remainder(PyObject *v, PyObject *w)
11671190
{
1191+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
1192+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) {
1193+
return GraalPyTrufflePyNumber_Remainder(v, w);
1194+
}
11681195
return binary_op(v, w, NB_SLOT(nb_remainder), "%");
11691196
}
11701197

11711198
PyObject *
11721199
PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
11731200
{
1201+
// GraalPy change: upcall when both managed to save on doing multiple upcalls
1202+
if (points_to_py_handle_space(v) && points_to_py_handle_space(w)) {
1203+
return GraalPyTrufflePyNumber_Power(v, w, z);
1204+
}
11741205
return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
11751206
}
11761207

@@ -1258,9 +1289,13 @@ ternary_iop(PyObject *v, PyObject *w, PyObject *z, const int iop_slot, const int
12581289
return ternary_op(v, w, z, op_slot, op_name);
12591290
}
12601291

1292+
// GraalPy change: upcall when v is managed to avoid multiple upcalls
12611293
#define INPLACE_BINOP(func, iop, op, op_name) \
12621294
PyObject * \
12631295
func(PyObject *v, PyObject *w) { \
1296+
if (points_to_py_handle_space(v)) { \
1297+
return GraalPyTruffle##func(v, w); \
1298+
} \
12641299
return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
12651300
}
12661301

@@ -1278,6 +1313,10 @@ INPLACE_BINOP(PyNumber_InPlaceRemainder, nb_inplace_remainder, nb_remainder, "%=
12781313
PyObject *
12791314
PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
12801315
{
1316+
// GraalPy change: upcall when v is managed to avoid multiple upcalls
1317+
if (points_to_py_handle_space(v)) {
1318+
return GraalPyTrufflePyNumber_InPlaceAdd(v, w);
1319+
}
12811320
PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_add),
12821321
NB_SLOT(nb_add), "+=");
12831322
if (result == Py_NotImplemented) {
@@ -1301,6 +1340,10 @@ PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
13011340
PyObject *
13021341
PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
13031342
{
1343+
// GraalPy change: upcall when v is managed to avoid multiple upcalls
1344+
if (points_to_py_handle_space(v)) {
1345+
return GraalPyTrufflePyNumber_InPlaceMultiply(v, w);
1346+
}
13041347
PyObject *result = BINARY_IOP1(v, w, NB_SLOT(nb_inplace_multiply),
13051348
NB_SLOT(nb_multiply), "*=");
13061349
if (result == Py_NotImplemented) {
@@ -1330,6 +1373,10 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
13301373
PyObject *
13311374
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
13321375
{
1376+
// GraalPy change: upcall when v is managed to avoid multiple upcalls
1377+
if (points_to_py_handle_space(v)) {
1378+
return GraalPyTrufflePyNumber_InPlacePower(v, w, z);
1379+
}
13331380
return ternary_iop(v, w, z, NB_SLOT(nb_inplace_power),
13341381
NB_SLOT(nb_power), "**=");
13351382
}
@@ -1340,7 +1387,6 @@ _PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs)
13401387
return PyNumber_InPlacePower(lhs, rhs, Py_None);
13411388
}
13421389

1343-
13441390
/* Unary operators and functions */
13451391

13461392
PyObject *
@@ -1419,6 +1465,7 @@ PyIndex_Check(PyObject *obj)
14191465
}
14201466

14211467

1468+
#if 0 // GraalPy change
14221469
/* Return a Python int from the object item.
14231470
Can return an instance of int subclass.
14241471
Raise TypeError if the result is not an int
@@ -3027,6 +3074,6 @@ PyTruffleSequence_Fast_ITEMS(PyObject *o)
30273074
PyObject*
30283075
PyTruffleSequence_ITEM(PyObject* obj, Py_ssize_t index)
30293076
{
3030-
PySequenceMethods* methods = Py_TYPE(obj)->tp_as_sequence;
3031-
return methods->sq_item(obj, index);
3077+
PySequenceMethods* methods = Py_TYPE(obj)->tp_as_sequence;
3078+
return methods->sq_item(obj, index);
30323079
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2023, 2024, Oracle and/or its affiliates.
1+
/* Copyright (c) 2023, 2025, Oracle and/or its affiliates.
22
* Copyright (C) 1996-2022 Python Software Foundation
33
*
44
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -87,7 +87,6 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
8787
}
8888

8989

90-
#if 0 // GraalPy change
9190
int
9291
_Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success)
9392
{
@@ -110,7 +109,6 @@ _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success)
110109
}
111110
return 1;
112111
}
113-
#endif // GraalPy change
114112

115113

116114
/* --- Core PyObject call functions ------------------------------- */

0 commit comments

Comments
 (0)