Skip to content

Commit 5e686ff

Browse files
authored
GH-122034: Add StackRef variants of type checks to reduce the number of PyStackRef_AsPyObjectBorrow calls (GH-122037)
1 parent aef95eb commit 5e686ff

File tree

4 files changed

+60
-27
lines changed

4 files changed

+60
-27
lines changed

Include/internal/pycore_stackref.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ extern "C" {
1111
#include "pycore_object_deferred.h"
1212

1313
#include <stddef.h>
14+
#include <stdbool.h>
1415

1516
/*
1617
This file introduces a new API for handling references on the stack, called
@@ -237,6 +238,38 @@ _PyObjectStack_FromStackRefStack(PyObject **dst, const _PyStackRef *src, size_t
237238
}
238239
}
239240

241+
// StackRef type checks
242+
243+
static inline bool
244+
PyStackRef_GenCheck(_PyStackRef stackref)
245+
{
246+
return PyGen_Check(PyStackRef_AsPyObjectBorrow(stackref));
247+
}
248+
249+
static inline bool
250+
PyStackRef_BoolCheck(_PyStackRef stackref)
251+
{
252+
return PyBool_Check(PyStackRef_AsPyObjectBorrow(stackref));
253+
}
254+
255+
static inline bool
256+
PyStackRef_LongCheck(_PyStackRef stackref)
257+
{
258+
return PyLong_Check(PyStackRef_AsPyObjectBorrow(stackref));
259+
}
260+
261+
static inline bool
262+
PyStackRef_ExceptionInstanceCheck(_PyStackRef stackref)
263+
{
264+
return PyExceptionInstance_Check(PyStackRef_AsPyObjectBorrow(stackref));
265+
}
266+
267+
268+
static inline bool
269+
PyStackRef_FunctionCheck(_PyStackRef stackref)
270+
{
271+
return PyFunction_Check(PyStackRef_AsPyObjectBorrow(stackref));
272+
}
240273

241274
#ifdef __cplusplus
242275
}

Python/bytecodes.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ dummy_func(
286286
tier1 inst(INSTRUMENTED_END_FOR, (receiver, value -- receiver)) {
287287
/* Need to create a fake StopIteration error here,
288288
* to conform to PEP 380 */
289-
if (PyGen_Check(PyStackRef_AsPyObjectBorrow(receiver))) {
289+
if (PyStackRef_GenCheck(receiver)) {
290290
if (monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value))) {
291291
ERROR_NO_POP();
292292
}
@@ -317,7 +317,7 @@ dummy_func(
317317
}
318318

319319
pure inst(UNARY_NOT, (value -- res)) {
320-
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(value)));
320+
assert(PyStackRef_BoolCheck(value));
321321
res = PyStackRef_Is(value, PyStackRef_False)
322322
? PyStackRef_True : PyStackRef_False;
323323
}
@@ -353,7 +353,7 @@ dummy_func(
353353
macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + unused/2 + _TO_BOOL;
354354

355355
inst(TO_BOOL_BOOL, (unused/1, unused/2, value -- value)) {
356-
EXIT_IF(!PyBool_Check(PyStackRef_AsPyObjectBorrow(value)));
356+
EXIT_IF(!PyStackRef_BoolCheck(value));
357357
STAT_INC(TO_BOOL, hit);
358358
}
359359

@@ -2688,7 +2688,7 @@ dummy_func(
26882688
}
26892689

26902690
replaced op(_POP_JUMP_IF_FALSE, (cond -- )) {
2691-
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(cond)));
2691+
assert(PyStackRef_BoolCheck(cond));
26922692
int flag = PyStackRef_Is(cond, PyStackRef_False);
26932693
#if ENABLE_SPECIALIZATION
26942694
this_instr[1].cache = (this_instr[1].cache << 1) | flag;
@@ -2697,7 +2697,7 @@ dummy_func(
26972697
}
26982698

26992699
replaced op(_POP_JUMP_IF_TRUE, (cond -- )) {
2700-
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(cond)));
2700+
assert(PyStackRef_BoolCheck(cond));
27012701
int flag = PyStackRef_Is(cond, PyStackRef_True);
27022702
#if ENABLE_SPECIALIZATION
27032703
this_instr[1].cache = (this_instr[1].cache << 1) | flag;
@@ -3121,7 +3121,7 @@ dummy_func(
31213121
else {
31223122
Py_DECREF(tb);
31233123
}
3124-
assert(PyLong_Check(PyStackRef_AsPyObjectBorrow(lasti)));
3124+
assert(PyStackRef_LongCheck(lasti));
31253125
(void)lasti; // Shut up compiler warning if asserts are off
31263126
PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
31273127
int has_self = !PyStackRef_IsNull(exit_self);
@@ -3163,7 +3163,7 @@ dummy_func(
31633163
else {
31643164
prev_exc = PyStackRef_None;
31653165
}
3166-
assert(PyExceptionInstance_Check(PyStackRef_AsPyObjectBorrow(new_exc)));
3166+
assert(PyStackRef_ExceptionInstanceCheck(new_exc));
31673167
exc_info->exc_value = PyStackRef_AsPyObjectNew(new_exc);
31683168
}
31693169

@@ -3459,7 +3459,7 @@ dummy_func(
34593459
assert(Py_TYPE(callable_o) == &PyMethod_Type);
34603460
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
34613461
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
3462-
assert(PyFunction_Check(PyStackRef_AsPyObjectBorrow(method)));
3462+
assert(PyStackRef_FunctionCheck(method));
34633463
PyStackRef_CLOSE(callable);
34643464
}
34653465

@@ -4467,7 +4467,7 @@ dummy_func(
44674467

44684468
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
44694469
_PyStackRef cond = POP();
4470-
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(cond)));
4470+
assert(PyStackRef_BoolCheck(cond));
44714471
int flag = PyStackRef_Is(cond, PyStackRef_True);
44724472
int offset = flag * oparg;
44734473
#if ENABLE_SPECIALIZATION
@@ -4478,7 +4478,7 @@ dummy_func(
44784478

44794479
inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) {
44804480
_PyStackRef cond = POP();
4481-
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(cond)));
4481+
assert(PyStackRef_BoolCheck(cond));
44824482
int flag = PyStackRef_Is(cond, PyStackRef_False);
44834483
int offset = flag * oparg;
44844484
#if ENABLE_SPECIALIZATION

Python/executor_cases.c.h

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)