Skip to content

Commit e2a2e5a

Browse files
committed
[GR-52144] Avoid upcalls for PyErr_Occurred.
PullRequest: graalpython/3273
2 parents 285ab98 + 3764fa4 commit e2a2e5a

34 files changed

+532
-345
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Copyright (c) 2024, Oracle and/or its affiliates.
2+
* Copyright (C) 1996-2023 Python Software Foundation
3+
*
4+
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
5+
*/
6+
#ifndef Py_INTERNAL_ABSTRACT_H
7+
#define Py_INTERNAL_ABSTRACT_H
8+
#ifdef __cplusplus
9+
extern "C" {
10+
#endif
11+
12+
#ifndef Py_BUILD_CORE
13+
# error "this header requires Py_BUILD_CORE define"
14+
#endif
15+
16+
// Fast inlined version of PyIndex_Check()
17+
static inline int
18+
_PyIndex_Check(PyObject *obj)
19+
{
20+
PyNumberMethods *tp_as_number = Py_TYPE(obj)->tp_as_number;
21+
return (tp_as_number != NULL && tp_as_number->nb_index != NULL);
22+
}
23+
24+
PyObject *_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs);
25+
PyObject *_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs);
26+
27+
#ifdef __cplusplus
28+
}
29+
#endif
30+
#endif /* !Py_INTERNAL_ABSTRACT_H */

graalpython/com.oracle.graal.python.cext/include/internal/pycore_pyerrors.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ extern void _PyErr_FiniTypes(PyInterpreterState *);
2424

2525
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
2626
{
27+
assert(tstate != NULL);
2728
// GraalPy change
28-
return PyErr_Occurred();
29+
assert(tstate->curexc_type == Graal_PyTruffleErr_Occurred(tstate));
30+
return tstate->curexc_type;
2931
}
3032

3133
static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success)
116116
/* --- Core PyObject call functions ------------------------------- */
117117

118118
// GraalPy addition
119-
inline int is_single_arg(const char* fmt) {
119+
static inline int is_single_arg(const char* fmt) {
120120
if (fmt[0] == 0) {
121121
return 0;
122122
}

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

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

43+
#include "pycore_abstract.h" // _PyIndex_Check()
4344
#include "pycore_ceval.h" // _PyEval_SignalAsyncExc()
45+
#include "pycore_pyerrors.h" // _PyErr_Fetch()
46+
#include "pycore_pystate.h" // _PyThreadState_GET()
4447

4548
PyObject* PyEval_CallObjectWithKeywords(PyObject *func, PyObject *args, PyObject *kwargs) {
4649
return PyObject_Call(func, args, kwargs);
@@ -160,19 +163,23 @@ void Py_LeaveRecursiveCall(void)
160163
nb_index slot defined, and store in *pi.
161164
Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
162165
and silently boost values less than PY_SSIZE_T_MIN to PY_SSIZE_T_MIN.
163-
Return 0 on error, 1 on success. */
164-
int _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) {
165-
if (v != Py_None) {
166+
Return 0 on error, 1 on success.
167+
*/
168+
int
169+
_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
170+
{
171+
PyThreadState *tstate = _PyThreadState_GET();
172+
if (!Py_IsNone(v)) {
166173
Py_ssize_t x;
167-
if (PyIndex_Check(v)) {
174+
if (_PyIndex_Check(v)) {
168175
x = PyNumber_AsSsize_t(v, NULL);
169-
if (x == -1 && PyErr_Occurred())
176+
if (x == -1 && _PyErr_Occurred(tstate))
170177
return 0;
171178
}
172179
else {
173-
PyErr_SetString(PyExc_TypeError,
174-
"slice indices must be integers or "
175-
"None or have an __index__ method");
180+
_PyErr_SetString(tstate, PyExc_TypeError,
181+
"slice indices must be integers or "
182+
"None or have an __index__ method");
176183
return 0;
177184
}
178185
*pi = x;

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

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ PyErr_SetString(PyObject *exception, const char *string)
162162
}
163163

164164

165-
#if 0 // GraalPy change
166165
PyObject* _Py_HOT_FUNCTION
167166
PyErr_Occurred(void)
168167
{
@@ -204,7 +203,6 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
204203

205204
return err == exc;
206205
}
207-
#endif // GraalPy change
208206

209207

210208
int
@@ -255,19 +253,13 @@ _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
255253
PyObject **p_traceback)
256254
{
257255
// GraalPy change: different implementation
258-
PyObject* result = GraalPyTruffleErr_Fetch();
259-
if(result == NULL) {
260-
*p_type = NULL;
261-
*p_value = NULL;
262-
*p_traceback = NULL;
256+
if (_PyErr_Occurred(tstate)) {
257+
// avoid the upcall if there is no current exception
258+
GraalPyTruffleErr_Fetch(p_type, p_value, p_traceback);
263259
} else {
264-
*p_type = PyTuple_GetItem(result, 0);
265-
*p_value = PyTuple_GetItem(result, 1);
266-
*p_traceback = PyTuple_GetItem(result, 2);
267-
Py_XINCREF(*p_type);
268-
Py_XINCREF(*p_value);
269-
Py_XINCREF(*p_traceback);
270-
Py_DecRef(result);
260+
*p_type = NULL;
261+
*p_value = NULL;
262+
*p_traceback = NULL;
271263
}
272264
}
273265

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,13 @@ skip_signature(const char *doc)
140140
return NULL;
141141
}
142142

143-
#if 0 // GraalPy change
144143
int
145144
_PyType_CheckConsistency(PyTypeObject *type)
146145
{
147146
#define CHECK(expr) \
148147
do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG((PyObject *)type, Py_STRINGIFY(expr)); } } while (0)
149148

149+
#if 0 // GraalPy change
150150
CHECK(!_PyObject_IsFreed((PyObject *)type));
151151

152152
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
@@ -170,11 +170,11 @@ _PyType_CheckConsistency(PyTypeObject *type)
170170
CHECK(type->tp_new == NULL);
171171
CHECK(PyDict_Contains(type->tp_dict, &_Py_ID(__new__)) == 0);
172172
}
173+
#endif // GraalPy change
173174

174175
return 1;
175176
#undef CHECK
176177
}
177-
#endif // GraalPy change
178178

179179
static const char *
180180
_PyType_DocWithoutSignature(const char *name, const char *internal_doc)
@@ -3654,7 +3654,7 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
36543654
}
36553655
}
36563656

3657-
// assert(_PyType_CheckConsistency(type));
3657+
assert(_PyType_CheckConsistency(type));
36583658
return (PyObject*)res;
36593659

36603660
fail:
@@ -6500,7 +6500,7 @@ int
65006500
PyType_Ready(PyTypeObject *type)
65016501
{
65026502
if (type->tp_flags & Py_TPFLAGS_READY) {
6503-
// assert(_PyType_CheckConsistency(type));
6503+
assert(_PyType_CheckConsistency(type));
65046504
return 0;
65056505
}
65066506
_PyObject_ASSERT((PyObject *)type,

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_concurrent_futures.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@
6666
*test.test_concurrent_futures.test_shutdown.ProcessPoolForkProcessPoolShutdownTest.test_run_after_shutdown
6767
*test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_cancel_futures
6868
*test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_context_manager_shutdown
69-
*test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_del_shutdown
7069
*test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_gh83386
7170
*test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_gh94440
7271
*test.test_concurrent_futures.test_shutdown.ProcessPoolSpawnProcessPoolShutdownTest.test_hang_issue12364

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,16 @@
118118
import com.oracle.graal.python.builtins.objects.cext.capi.CApiGuards;
119119
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ClearNativeWrapperNode;
120120
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.FromCharPointerNode;
121-
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.TransformExceptionToNativeNode;
122121
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.FromCharPointerNodeGen;
123-
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.TransformExceptionToNativeNodeGen;
124122
import com.oracle.graal.python.builtins.objects.cext.capi.PyTruffleObjectFree;
125123
import com.oracle.graal.python.builtins.objects.cext.capi.PythonClassNativeWrapper;
126124
import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper;
127125
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor;
128126
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
129127
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
130128
import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CArrayWrapper;
129+
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.TransformExceptionToNativeNode;
130+
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.TransformExceptionToNativeNodeGen;
131131
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode;
132132
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode.SplitFormatStringNode;
133133
import com.oracle.graal.python.builtins.objects.cext.common.CExtToJavaNode;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCEvalBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ abstract static class PyEval_SaveThread extends CApiNullaryBuiltinNode {
9595
@Specialization
9696
static Object save(@Cached GilNode gil) {
9797
PythonContext context = PythonContext.get(gil);
98-
Object threadState = PThreadState.getThreadState(PythonLanguage.get(gil), context);
98+
Object threadState = PThreadState.getOrCreateNativeThreadState(PythonLanguage.get(gil), context);
9999
LOGGER.fine("C extension releases GIL");
100100
gil.release(context, true);
101101
return threadState;

0 commit comments

Comments
 (0)