https://github.com/python/cpython/commit/06ca33020e1168459fc6c3e0df93664daf801339
commit: 06ca33020e1168459fc6c3e0df93664daf801339
branch: main
author: Mark Shannon <[email protected]>
committer: markshannon <[email protected]>
date: 2024-10-14T14:18:57+01:00
summary:
GH-125323: Convert DECREF_INPUTS_AND_REUSE_FLOAT into a function that takes
PyStackRefs. (GH-125439)
files:
M Include/internal/pycore_ceval.h
M Include/internal/pycore_opcode_metadata.h
M Include/internal/pycore_stackref.h
M Include/internal/pycore_uop_metadata.h
M Objects/floatobject.c
M Python/bytecodes.c
M Python/ceval_macros.h
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Tools/cases_generator/analyzer.py
diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h
index 594fbb1c8e443b..cff2b1f7114793 100644
--- a/Include/internal/pycore_ceval.h
+++ b/Include/internal/pycore_ceval.h
@@ -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
}
diff --git a/Include/internal/pycore_opcode_metadata.h
b/Include/internal/pycore_opcode_metadata.h
index 8fec45b1e8d5c3..c18423476d3962 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1015,13 +1015,13 @@ extern const struct opcode_metadata
_PyOpcode_opcode_metadata[266];
#ifdef NEED_OPCODE_METADATA
const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
[BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG |
HAS_ESCAPES_FLAG },
- [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG |
HAS_ERROR_FLAG },
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG |
HAS_ERROR_FLAG },
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG |
HAS_ERROR_FLAG },
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG |
HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG |
HAS_ERROR_FLAG },
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG |
HAS_ERROR_FLAG },
- [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG |
HAS_ERROR_FLAG },
[BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG |
HAS_ERROR_FLAG },
[BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG
},
diff --git a/Include/internal/pycore_stackref.h
b/Include/internal/pycore_stackref.h
index 0e6410466b924b..588e57f6cd97e0 100644
--- a/Include/internal/pycore_stackref.h
+++ b/Include/internal/pycore_stackref.h
@@ -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)
{
diff --git a/Include/internal/pycore_uop_metadata.h
b/Include/internal/pycore_uop_metadata.h
index fd41e9a5fe862b..2f0a7fb2f6e549 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -69,9 +69,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_GUARD_BOTH_FLOAT] = HAS_EXIT_FLAG,
[_GUARD_NOS_FLOAT] = HAS_EXIT_FLAG,
[_GUARD_TOS_FLOAT] = HAS_EXIT_FLAG,
- [_BINARY_OP_MULTIPLY_FLOAT] = HAS_PURE_FLAG,
- [_BINARY_OP_ADD_FLOAT] = HAS_PURE_FLAG,
- [_BINARY_OP_SUBTRACT_FLOAT] = HAS_PURE_FLAG,
+ [_BINARY_OP_MULTIPLY_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG,
[_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG |
HAS_ERROR_FLAG,
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index a48a210adee3b9..d66863febe8c86 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -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)
{
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 299608f252c546..b22916aeaa248b 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -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);
}
@@ -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);
}
@@ -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);
}
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index e0e9cc156ed62f..6674c4ccf9f693 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -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
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 5532c04e497a75..0ed361a2ee7fb0 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -643,8 +643,8 @@
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);
+ if (res_o == NULL) JUMP_TO_ERROR();
res = PyStackRef_FromPyObjectSteal(res_o);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -664,8 +664,8 @@
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);
+ if (res_o == NULL) JUMP_TO_ERROR();
res = PyStackRef_FromPyObjectSteal(res_o);
stack_pointer[-2] = res;
stack_pointer += -1;
@@ -685,8 +685,8 @@
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);
+ if (res_o == NULL) JUMP_TO_ERROR();
res = PyStackRef_FromPyObjectSteal(res_o);
stack_pointer[-2] = res;
stack_pointer += -1;
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 0eeb566a0adadc..7bd1b7dd5aba27 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -84,8 +84,8 @@
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);
+ if (res_o == NULL) goto pop_2_error;
res = PyStackRef_FromPyObjectSteal(res_o);
}
stack_pointer[-2] = res;
@@ -251,8 +251,8 @@
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);
+ if (res_o == NULL) goto pop_2_error;
res = PyStackRef_FromPyObjectSteal(res_o);
}
stack_pointer[-2] = res;
@@ -322,8 +322,8 @@
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);
+ if (res_o == NULL) goto pop_2_error;
res = PyStackRef_FromPyObjectSteal(res_o);
}
stack_pointer[-2] = res;
diff --git a/Tools/cases_generator/analyzer.py
b/Tools/cases_generator/analyzer.py
index 19fdeac65cf2df..381ad3a4e2082c 100644
--- a/Tools/cases_generator/analyzer.py
+++ b/Tools/cases_generator/analyzer.py
@@ -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",
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]