Skip to content

Commit

Permalink
pythonGH-122034: Add StackRef variants of type checks to reduce the n…
Browse files Browse the repository at this point in the history
…umber of PyStackRef_AsPyObjectBorrow calls (pythonGH-122037)
  • Loading branch information
markshannon committed Jul 25, 2024
1 parent aef95eb commit 5e686ff
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 27 deletions.
33 changes: 33 additions & 0 deletions Include/internal/pycore_stackref.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern "C" {
#include "pycore_object_deferred.h"

#include <stddef.h>
#include <stdbool.h>

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

// StackRef type checks

static inline bool
PyStackRef_GenCheck(_PyStackRef stackref)
{
return PyGen_Check(PyStackRef_AsPyObjectBorrow(stackref));
}

static inline bool
PyStackRef_BoolCheck(_PyStackRef stackref)
{
return PyBool_Check(PyStackRef_AsPyObjectBorrow(stackref));
}

static inline bool
PyStackRef_LongCheck(_PyStackRef stackref)
{
return PyLong_Check(PyStackRef_AsPyObjectBorrow(stackref));
}

static inline bool
PyStackRef_ExceptionInstanceCheck(_PyStackRef stackref)
{
return PyExceptionInstance_Check(PyStackRef_AsPyObjectBorrow(stackref));
}


static inline bool
PyStackRef_FunctionCheck(_PyStackRef stackref)
{
return PyFunction_Check(PyStackRef_AsPyObjectBorrow(stackref));
}

#ifdef __cplusplus
}
Expand Down
20 changes: 10 additions & 10 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ dummy_func(
tier1 inst(INSTRUMENTED_END_FOR, (receiver, value -- receiver)) {
/* Need to create a fake StopIteration error here,
* to conform to PEP 380 */
if (PyGen_Check(PyStackRef_AsPyObjectBorrow(receiver))) {
if (PyStackRef_GenCheck(receiver)) {
if (monitor_stop_iteration(tstate, frame, this_instr, PyStackRef_AsPyObjectBorrow(value))) {
ERROR_NO_POP();
}
Expand Down Expand Up @@ -317,7 +317,7 @@ dummy_func(
}

pure inst(UNARY_NOT, (value -- res)) {
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(value)));
assert(PyStackRef_BoolCheck(value));
res = PyStackRef_Is(value, PyStackRef_False)
? PyStackRef_True : PyStackRef_False;
}
Expand Down Expand Up @@ -353,7 +353,7 @@ dummy_func(
macro(TO_BOOL) = _SPECIALIZE_TO_BOOL + unused/2 + _TO_BOOL;

inst(TO_BOOL_BOOL, (unused/1, unused/2, value -- value)) {
EXIT_IF(!PyBool_Check(PyStackRef_AsPyObjectBorrow(value)));
EXIT_IF(!PyStackRef_BoolCheck(value));
STAT_INC(TO_BOOL, hit);
}

Expand Down Expand Up @@ -2688,7 +2688,7 @@ dummy_func(
}

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

replaced op(_POP_JUMP_IF_TRUE, (cond -- )) {
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(cond)));
assert(PyStackRef_BoolCheck(cond));
int flag = PyStackRef_Is(cond, PyStackRef_True);
#if ENABLE_SPECIALIZATION
this_instr[1].cache = (this_instr[1].cache << 1) | flag;
Expand Down Expand Up @@ -3121,7 +3121,7 @@ dummy_func(
else {
Py_DECREF(tb);
}
assert(PyLong_Check(PyStackRef_AsPyObjectBorrow(lasti)));
assert(PyStackRef_LongCheck(lasti));
(void)lasti; // Shut up compiler warning if asserts are off
PyObject *stack[5] = {NULL, PyStackRef_AsPyObjectBorrow(exit_self), exc, val_o, tb};
int has_self = !PyStackRef_IsNull(exit_self);
Expand Down Expand Up @@ -3163,7 +3163,7 @@ dummy_func(
else {
prev_exc = PyStackRef_None;
}
assert(PyExceptionInstance_Check(PyStackRef_AsPyObjectBorrow(new_exc)));
assert(PyStackRef_ExceptionInstanceCheck(new_exc));
exc_info->exc_value = PyStackRef_AsPyObjectNew(new_exc);
}

Expand Down Expand Up @@ -3459,7 +3459,7 @@ dummy_func(
assert(Py_TYPE(callable_o) == &PyMethod_Type);
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
assert(PyFunction_Check(PyStackRef_AsPyObjectBorrow(method)));
assert(PyStackRef_FunctionCheck(method));
PyStackRef_CLOSE(callable);
}

Expand Down Expand Up @@ -4467,7 +4467,7 @@ dummy_func(

inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
_PyStackRef cond = POP();
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(cond)));
assert(PyStackRef_BoolCheck(cond));
int flag = PyStackRef_Is(cond, PyStackRef_True);
int offset = flag * oparg;
#if ENABLE_SPECIALIZATION
Expand All @@ -4478,7 +4478,7 @@ dummy_func(

inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) {
_PyStackRef cond = POP();
assert(PyBool_Check(PyStackRef_AsPyObjectBorrow(cond)));
assert(PyStackRef_BoolCheck(cond));
int flag = PyStackRef_Is(cond, PyStackRef_False);
int offset = flag * oparg;
#if ENABLE_SPECIALIZATION
Expand Down
10 changes: 5 additions & 5 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5e686ff

Please sign in to comment.