Skip to content

Commit

Permalink
GH-125323: Convert DECREF_INPUTS_AND_REUSE_FLOAT into a function that…
Browse files Browse the repository at this point in the history
… takes PyStackRefs. (GH-125439)
  • Loading branch information
markshannon authored Oct 14, 2024
1 parent 67f6e08 commit 06ca330
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 44 deletions.
2 changes: 2 additions & 0 deletions Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ _Py_eval_breaker_bit_is_set(PyThreadState *tstate, uintptr_t bit)
void _Py_set_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);

PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value);


#ifdef __cplusplus
}
Expand Down
6 changes: 3 additions & 3 deletions Include/internal/pycore_opcode_metadata.h

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

7 changes: 7 additions & 0 deletions Include/internal/pycore_stackref.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ PyStackRef_AsPyObjectBorrow(_PyStackRef stackref)

#define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)

static inline PyObject *
PyStackRef_NotDeferred_AsPyObject(_PyStackRef stackref)
{
assert(!PyStackRef_IsDeferred(stackref));
return (PyObject *)stackref.bits;
}

static inline PyObject *
PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
{
Expand Down
6 changes: 3 additions & 3 deletions Include/internal/pycore_uop_metadata.h

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

35 changes: 35 additions & 0 deletions Objects/floatobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,41 @@ PyFloat_FromDouble(double fval)
return (PyObject *) op;
}

#ifdef Py_GIL_DISABLED

PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value)
{
PyStackRef_CLOSE(left);
PyStackRef_CLOSE(right);
return PyFloat_FromDouble(value);
}

#else // Py_GIL_DISABLED

PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value)
{
PyObject *left_o = PyStackRef_AsPyObjectSteal(left);
PyObject *right_o = PyStackRef_AsPyObjectSteal(right);
if (Py_REFCNT(left_o) == 1) {
((PyFloatObject *)left_o)->ob_fval = value;
_Py_DECREF_SPECIALIZED(right_o, _PyFloat_ExactDealloc);
return left_o;
}
else if (Py_REFCNT(right_o) == 1) {
((PyFloatObject *)right_o)->ob_fval = value;
_Py_DECREF_NO_DEALLOC(left_o);
return right_o;
}
else {
PyObject *result = PyFloat_FromDouble(value);
_Py_DECREF_NO_DEALLOC(left_o);
_Py_DECREF_NO_DEALLOC(right_o);
return result;
}
}

#endif // Py_GIL_DISABLED

static PyObject *
float_from_string_inner(const char *s, Py_ssize_t len, void *obj)
{
Expand Down
12 changes: 6 additions & 6 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,9 @@ dummy_func(
double dres =
((PyFloatObject *)left_o)->ob_fval *
((PyFloatObject *)right_o)->ob_fval;
PyObject *res_o;
DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o);
PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
ERROR_IF(res_o == NULL, error);
res = PyStackRef_FromPyObjectSteal(res_o);
}

Expand All @@ -553,9 +553,9 @@ dummy_func(
double dres =
((PyFloatObject *)left_o)->ob_fval +
((PyFloatObject *)right_o)->ob_fval;
PyObject *res_o;
DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o);
PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
ERROR_IF(res_o == NULL, error);
res = PyStackRef_FromPyObjectSteal(res_o);
}

Expand All @@ -567,9 +567,9 @@ dummy_func(
double dres =
((PyFloatObject *)left_o)->ob_fval -
((PyFloatObject *)right_o)->ob_fval;
PyObject *res_o;
DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o);
PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
INPUTS_DEAD();
ERROR_IF(res_o == NULL, error);
res = PyStackRef_FromPyObjectSteal(res_o);
}

Expand Down
20 changes: 0 additions & 20 deletions Python/ceval_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,26 +327,6 @@ GETITEM(PyObject *v, Py_ssize_t i) {
" in enclosing scope"
#define NAME_ERROR_MSG "name '%.200s' is not defined"

#define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \
do { \
if (Py_REFCNT(left) == 1) { \
((PyFloatObject *)left)->ob_fval = (dval); \
_Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);\
result = (left); \
} \
else if (Py_REFCNT(right) == 1) {\
((PyFloatObject *)right)->ob_fval = (dval); \
_Py_DECREF_NO_DEALLOC(left); \
result = (right); \
}\
else { \
result = PyFloat_FromDouble(dval); \
if ((result) == NULL) GOTO_ERROR(error); \
_Py_DECREF_NO_DEALLOC(left); \
_Py_DECREF_NO_DEALLOC(right); \
} \
} while (0)

// If a trace function sets a new f_lineno and
// *then* raises, we use the destination when searching
// for an exception handler, displaying the traceback, and so on
Expand Down
12 changes: 6 additions & 6 deletions Python/executor_cases.c.h

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

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

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

1 change: 1 addition & 0 deletions Tools/cases_generator/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ def has_error_without_pop(op: parser.InstDef) -> bool:
"_PyDictValues_AddToInsertionOrder",
"_PyErr_Occurred",
"_PyEval_FrameClearAndPop",
"_PyFloat_FromDouble_ConsumeInputs",
"_PyFrame_GetCode",
"_PyFrame_IsIncomplete",
"_PyFrame_PushUnchecked",
Expand Down

0 comments on commit 06ca330

Please sign in to comment.