Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-125323: Convert DECREF_INPUTS_AND_REUSE_FLOAT into a function that takes PyStackRefs. #125439

Merged
merged 2 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.

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

#ifdef Py_GIL_DISABLED

PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value)
{
PyObject *left_o = PyStackRef_NotDeferred_AsPyObject(left);
PyObject *right_o = PyStackRef_NotDeferred_AsPyObject(right);
assert(PyLong_Check(left_o));
assert(PyLong_Check(right_o));
if (Py_REFCNT(left_o) == 1) {
Fidget-Spinner marked this conversation as resolved.
Show resolved Hide resolved
((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;
}
}

#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
Loading