--- /dev/null
+Reuse operands with refcount of 1 in float specializations of BINARY_OP.
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)) {
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)) {
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)) {
#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)
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;