Skip to content

Commit 28d630d

Browse files
committed
Avoid incref/decref pair in long_bitwise
1 parent 09044dd commit 28d630d

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

Objects/longobject.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5589,46 +5589,45 @@ long_bitwise(PyLongObject *a,
55895589
Py_ssize_t size_a, size_b, size_z, i;
55905590
PyLongObject *z;
55915591

5592+
PyLongObject *new_a = NULL;
5593+
PyLongObject *new_b = NULL;
5594+
55925595
/* Bitwise operations for negative numbers operate as though
55935596
on a two's complement representation. So convert arguments
55945597
from sign-magnitude to two's complement, and convert the
55955598
result back to sign-magnitude at the end. */
55965599

5597-
/* If a is negative, replace it by its two's complement. */
55985600
size_a = _PyLong_DigitCount(a);
5601+
size_b = _PyLong_DigitCount(b);
5602+
/* Swap a and b if necessary to ensure size_a >= size_b. */
5603+
if (size_a < size_b) {
5604+
z = a; a = b; b = z;
5605+
size_z = size_a; size_a = size_b; size_b = size_z;
5606+
}
5607+
5608+
/* If a is negative, replace it by its two's complement. */
55995609
nega = _PyLong_IsNegative(a);
56005610
if (nega) {
56015611
z = long_alloc(size_a);
56025612
if (z == NULL)
56035613
return NULL;
56045614
v_complement(z->long_value.ob_digit, a->long_value.ob_digit, size_a);
5615+
new_a = z; // reference to decrement instead of a itself
56055616
a = z;
56065617
}
5607-
else
5608-
/* Keep reference count consistent. */
5609-
Py_INCREF(a);
56105618

56115619
/* Same for b. */
5612-
size_b = _PyLong_DigitCount(b);
56135620
negb = _PyLong_IsNegative(b);
56145621
if (negb) {
56155622
z = long_alloc(size_b);
56165623
if (z == NULL) {
5617-
Py_DECREF(a);
5624+
Py_XDECREF(new_a);
56185625
return NULL;
56195626
}
56205627
v_complement(z->long_value.ob_digit, b->long_value.ob_digit, size_b);
5628+
new_b = z; // reference to decrement instead of b itself
56215629
b = z;
56225630
}
5623-
else
5624-
Py_INCREF(b);
5625-
5626-
/* Swap a and b if necessary to ensure size_a >= size_b. */
5627-
if (size_a < size_b) {
5628-
z = a; a = b; b = z;
5629-
size_z = size_a; size_a = size_b; size_b = size_z;
5630-
negz = nega; nega = negb; negb = negz;
5631-
}
56325631

56335632
/* JRH: The original logic here was to allocate the result value (z)
56345633
as the longer of the two operands. However, there are some cases
@@ -5658,8 +5657,8 @@ long_bitwise(PyLongObject *a,
56585657
the final two's complement of z doesn't overflow. */
56595658
z = long_alloc(size_z + negz);
56605659
if (z == NULL) {
5661-
Py_DECREF(a);
5662-
Py_DECREF(b);
5660+
Py_XDECREF(new_a);
5661+
Py_XDECREF(new_a);
56635662
return NULL;
56645663
}
56655664

@@ -5696,8 +5695,8 @@ long_bitwise(PyLongObject *a,
56965695
v_complement(z->long_value.ob_digit, z->long_value.ob_digit, size_z+1);
56975696
}
56985697

5699-
Py_DECREF(a);
5700-
Py_DECREF(b);
5698+
Py_XDECREF(new_a);
5699+
Py_XDECREF(new_b);
57015700
return (PyObject *)maybe_small_long(long_normalize(z));
57025701
}
57035702

0 commit comments

Comments
 (0)