]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-102300: Reuse objects with refcount == 1 in float specialized binary ops. (GH...
authorMark Shannon <mark@hotpy.org>
Mon, 13 Mar 2023 10:34:54 +0000 (10:34 +0000)
committerGitHub <noreply@github.com>
Mon, 13 Mar 2023 10:34:54 +0000 (10:34 +0000)
Misc/NEWS.d/next/Core and Builtins/2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst [new file with mode: 0644]
Python/bytecodes.c
Python/ceval_macros.h
Python/generated_cases.c.h

diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-27-15-48-31.gh-issue-102300.8o-_Mt.rst
new file mode 100644 (file)
index 0000000..4227014
--- /dev/null
@@ -0,0 +1 @@
+Reuse operands with refcount of 1 in float specializations of BINARY_OP.
index dc2a20f22b6038feed3482399f0de701d029d5ec..178519fcb63cedeceb53aeda49d9afa03d84454e 100644 (file)
@@ -195,10 +195,7 @@ dummy_func(
             STAT_INC(BINARY_OP, hit);
             double dprod = ((PyFloatObject *)left)->ob_fval *
                 ((PyFloatObject *)right)->ob_fval;
-            prod = PyFloat_FromDouble(dprod);
-            _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
-            ERROR_IF(prod == NULL, error);
+            DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dprod, prod);
         }
 
         inst(BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- sub)) {
@@ -218,10 +215,7 @@ dummy_func(
             DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
             double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval;
-            sub = PyFloat_FromDouble(dsub);
-            _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
-            ERROR_IF(sub == NULL, error);
+            DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsub, sub);
         }
 
         inst(BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) {
@@ -278,10 +272,7 @@ dummy_func(
             STAT_INC(BINARY_OP, hit);
             double dsum = ((PyFloatObject *)left)->ob_fval +
                 ((PyFloatObject *)right)->ob_fval;
-            sum = PyFloat_FromDouble(dsum);
-            _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
-            ERROR_IF(sum == NULL, error);
+            DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsum, sum);
         }
 
         inst(BINARY_OP_ADD_INT, (unused/1, left, right -- sum)) {
index ac1fec77daca8a2ca7850d8892fc7807dd3bbee4..98b72ec1b364285d86a2d3ce9329b1d2b8033680 100644 (file)
@@ -350,3 +350,23 @@ GETITEM(PyObject *v, Py_ssize_t i) {
 
 #define KWNAMES_LEN() \
     (kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(kwnames)))
+
+#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; \
+        _Py_DECREF_NO_DEALLOC(left); \
+        _Py_DECREF_NO_DEALLOC(right); \
+    } \
+} while (0)
index 3839aeecb912a100773e9449b28d1acaf2804c4e..21073cbf978ce0e949652edbe7acd4a4aed5e543 100644 (file)
             STAT_INC(BINARY_OP, hit);
             double dprod = ((PyFloatObject *)left)->ob_fval *
                 ((PyFloatObject *)right)->ob_fval;
-            prod = PyFloat_FromDouble(dprod);
-            _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
-            if (prod == NULL) goto pop_2_error;
+            DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dprod, prod);
             STACK_SHRINK(1);
             stack_pointer[-1] = prod;
             next_instr += 1;
             DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
             double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval;
-            sub = PyFloat_FromDouble(dsub);
-            _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
-            if (sub == NULL) goto pop_2_error;
+            DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsub, sub);
             STACK_SHRINK(1);
             stack_pointer[-1] = sub;
             next_instr += 1;
             STAT_INC(BINARY_OP, hit);
             double dsum = ((PyFloatObject *)left)->ob_fval +
                 ((PyFloatObject *)right)->ob_fval;
-            sum = PyFloat_FromDouble(dsum);
-            _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
-            _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
-            if (sum == NULL) goto pop_2_error;
+            DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsum, sum);
             STACK_SHRINK(1);
             stack_pointer[-1] = sum;
             next_instr += 1;