Skip to content

Commit 06ca330

Browse files
authored
GH-125323: Convert DECREF_INPUTS_AND_REUSE_FLOAT into a function that takes PyStackRefs. (GH-125439)
1 parent 67f6e08 commit 06ca330

File tree

10 files changed

+69
-44
lines changed

10 files changed

+69
-44
lines changed

Include/internal/pycore_ceval.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ _Py_eval_breaker_bit_is_set(PyThreadState *tstate, uintptr_t bit)
316316
void _Py_set_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
317317
void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
318318

319+
PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value);
320+
319321

320322
#ifdef __cplusplus
321323
}

Include/internal/pycore_opcode_metadata.h

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

Include/internal/pycore_stackref.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ PyStackRef_AsPyObjectBorrow(_PyStackRef stackref)
7676

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

79+
static inline PyObject *
80+
PyStackRef_NotDeferred_AsPyObject(_PyStackRef stackref)
81+
{
82+
assert(!PyStackRef_IsDeferred(stackref));
83+
return (PyObject *)stackref.bits;
84+
}
85+
7986
static inline PyObject *
8087
PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
8188
{

Include/internal/pycore_uop_metadata.h

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

Objects/floatobject.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,41 @@ PyFloat_FromDouble(double fval)
134134
return (PyObject *) op;
135135
}
136136

137+
#ifdef Py_GIL_DISABLED
138+
139+
PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value)
140+
{
141+
PyStackRef_CLOSE(left);
142+
PyStackRef_CLOSE(right);
143+
return PyFloat_FromDouble(value);
144+
}
145+
146+
#else // Py_GIL_DISABLED
147+
148+
PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value)
149+
{
150+
PyObject *left_o = PyStackRef_AsPyObjectSteal(left);
151+
PyObject *right_o = PyStackRef_AsPyObjectSteal(right);
152+
if (Py_REFCNT(left_o) == 1) {
153+
((PyFloatObject *)left_o)->ob_fval = value;
154+
_Py_DECREF_SPECIALIZED(right_o, _PyFloat_ExactDealloc);
155+
return left_o;
156+
}
157+
else if (Py_REFCNT(right_o) == 1) {
158+
((PyFloatObject *)right_o)->ob_fval = value;
159+
_Py_DECREF_NO_DEALLOC(left_o);
160+
return right_o;
161+
}
162+
else {
163+
PyObject *result = PyFloat_FromDouble(value);
164+
_Py_DECREF_NO_DEALLOC(left_o);
165+
_Py_DECREF_NO_DEALLOC(right_o);
166+
return result;
167+
}
168+
}
169+
170+
#endif // Py_GIL_DISABLED
171+
137172
static PyObject *
138173
float_from_string_inner(const char *s, Py_ssize_t len, void *obj)
139174
{

Python/bytecodes.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,9 @@ dummy_func(
539539
double dres =
540540
((PyFloatObject *)left_o)->ob_fval *
541541
((PyFloatObject *)right_o)->ob_fval;
542-
PyObject *res_o;
543-
DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o);
542+
PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
544543
INPUTS_DEAD();
544+
ERROR_IF(res_o == NULL, error);
545545
res = PyStackRef_FromPyObjectSteal(res_o);
546546
}
547547

@@ -553,9 +553,9 @@ dummy_func(
553553
double dres =
554554
((PyFloatObject *)left_o)->ob_fval +
555555
((PyFloatObject *)right_o)->ob_fval;
556-
PyObject *res_o;
557-
DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o);
556+
PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
558557
INPUTS_DEAD();
558+
ERROR_IF(res_o == NULL, error);
559559
res = PyStackRef_FromPyObjectSteal(res_o);
560560
}
561561

@@ -567,9 +567,9 @@ dummy_func(
567567
double dres =
568568
((PyFloatObject *)left_o)->ob_fval -
569569
((PyFloatObject *)right_o)->ob_fval;
570-
PyObject *res_o;
571-
DECREF_INPUTS_AND_REUSE_FLOAT(left_o, right_o, dres, res_o);
570+
PyObject *res_o = _PyFloat_FromDouble_ConsumeInputs(left, right, dres);
572571
INPUTS_DEAD();
572+
ERROR_IF(res_o == NULL, error);
573573
res = PyStackRef_FromPyObjectSteal(res_o);
574574
}
575575

Python/ceval_macros.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -327,26 +327,6 @@ GETITEM(PyObject *v, Py_ssize_t i) {
327327
" in enclosing scope"
328328
#define NAME_ERROR_MSG "name '%.200s' is not defined"
329329

330-
#define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \
331-
do { \
332-
if (Py_REFCNT(left) == 1) { \
333-
((PyFloatObject *)left)->ob_fval = (dval); \
334-
_Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);\
335-
result = (left); \
336-
} \
337-
else if (Py_REFCNT(right) == 1) {\
338-
((PyFloatObject *)right)->ob_fval = (dval); \
339-
_Py_DECREF_NO_DEALLOC(left); \
340-
result = (right); \
341-
}\
342-
else { \
343-
result = PyFloat_FromDouble(dval); \
344-
if ((result) == NULL) GOTO_ERROR(error); \
345-
_Py_DECREF_NO_DEALLOC(left); \
346-
_Py_DECREF_NO_DEALLOC(right); \
347-
} \
348-
} while (0)
349-
350330
// If a trace function sets a new f_lineno and
351331
// *then* raises, we use the destination when searching
352332
// for an exception handler, displaying the traceback, and so on

Python/executor_cases.c.h

Lines changed: 6 additions & 6 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: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/analyzer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ def has_error_without_pop(op: parser.InstDef) -> bool:
575575
"_PyDictValues_AddToInsertionOrder",
576576
"_PyErr_Occurred",
577577
"_PyEval_FrameClearAndPop",
578+
"_PyFloat_FromDouble_ConsumeInputs",
578579
"_PyFrame_GetCode",
579580
"_PyFrame_IsIncomplete",
580581
"_PyFrame_PushUnchecked",

0 commit comments

Comments
 (0)