Skip to content

Commit 4b358ee

Browse files
gh-125323: Remove some unsafe Py_DECREFs in bytecodes.c, replacing them with PyStackRef_CLOSEs (GH-125324)
1 parent b52c730 commit 4b358ee

File tree

6 files changed

+65
-60
lines changed

6 files changed

+65
-60
lines changed

Include/internal/pycore_stackref.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
153153
return PyStackRef_FromPyObjectSteal(PyStackRef_AsPyObjectSteal(stackref));
154154
}
155155

156+
#define PyStackRef_CLOSE_SPECIALIZED(stackref, dealloc) PyStackRef_CLOSE(stackref)
157+
156158

157159
#else // Py_GIL_DISABLED
158160

@@ -177,6 +179,7 @@ static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
177179

178180
#define PyStackRef_DUP(stackref) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)))
179181

182+
#define PyStackRef_CLOSE_SPECIALIZED(stackref, dealloc) _Py_DECREF_SPECIALIZED(PyStackRef_AsPyObjectBorrow(stackref), dealloc)
180183

181184
#endif // Py_GIL_DISABLED
182185

Python/bytecodes.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,8 @@ dummy_func(
474474

475475
STAT_INC(BINARY_OP, hit);
476476
PyObject *res_o = _PyLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
477-
_Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free);
478-
_Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free);
477+
PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free);
478+
PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free);
479479
INPUTS_DEAD();
480480
ERROR_IF(res_o == NULL, error);
481481
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -487,8 +487,8 @@ dummy_func(
487487

488488
STAT_INC(BINARY_OP, hit);
489489
PyObject *res_o = _PyLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
490-
_Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free);
491-
_Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free);
490+
PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free);
491+
PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free);
492492
INPUTS_DEAD();
493493
ERROR_IF(res_o == NULL, error);
494494
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -500,8 +500,8 @@ dummy_func(
500500

501501
STAT_INC(BINARY_OP, hit);
502502
PyObject *res_o = _PyLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
503-
_Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free);
504-
_Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free);
503+
PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free);
504+
PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free);
505505
INPUTS_DEAD();
506506
ERROR_IF(res_o == NULL, error);
507507
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -594,8 +594,8 @@ dummy_func(
594594

595595
STAT_INC(BINARY_OP, hit);
596596
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
597-
_Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc);
598-
_Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc);
597+
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
598+
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
599599
INPUTS_DEAD();
600600
ERROR_IF(res_o == NULL, error);
601601
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -636,12 +636,12 @@ dummy_func(
636636
* that the string is safe to mutate.
637637
*/
638638
assert(Py_REFCNT(left_o) >= 2);
639-
_Py_DECREF_NO_DEALLOC(left_o);
639+
PyStackRef_CLOSE(left);
640640
DEAD(left);
641641
PyObject *temp = PyStackRef_AsPyObjectBorrow(*target_local);
642642
PyUnicode_Append(&temp, right_o);
643643
*target_local = PyStackRef_FromPyObjectSteal(temp);
644-
_Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc);
644+
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
645645
DEAD(right);
646646
ERROR_IF(PyStackRef_IsNull(*target_local), error);
647647
#if TIER_ONE
@@ -755,7 +755,7 @@ dummy_func(
755755
PyObject *res_o = PyList_GET_ITEM(list, index);
756756
assert(res_o != NULL);
757757
Py_INCREF(res_o);
758-
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
758+
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
759759
DEAD(sub_st);
760760
PyStackRef_CLOSE(list_st);
761761
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -775,7 +775,7 @@ dummy_func(
775775
DEOPT_IF(Py_ARRAY_LENGTH(_Py_SINGLETON(strings).ascii) <= c);
776776
STAT_INC(BINARY_SUBSCR, hit);
777777
PyObject *res_o = (PyObject*)&_Py_SINGLETON(strings).ascii[c];
778-
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
778+
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
779779
DEAD(sub_st);
780780
PyStackRef_CLOSE(str_st);
781781
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -796,7 +796,7 @@ dummy_func(
796796
PyObject *res_o = PyTuple_GET_ITEM(tuple, index);
797797
assert(res_o != NULL);
798798
Py_INCREF(res_o);
799-
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
799+
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
800800
DEAD(sub_st);
801801
PyStackRef_CLOSE(tuple_st);
802802
res = PyStackRef_FromPyObjectSteal(res_o);
@@ -908,7 +908,7 @@ dummy_func(
908908
PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value));
909909
assert(old_value != NULL);
910910
Py_DECREF(old_value);
911-
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
911+
PyStackRef_CLOSE_SPECIALIZED(sub_st, (destructor)PyObject_Free);
912912
DEAD(sub_st);
913913
PyStackRef_CLOSE(list_st);
914914
}
@@ -2398,9 +2398,9 @@ dummy_func(
23982398
double dright = PyFloat_AS_DOUBLE(right_o);
23992399
// 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg
24002400
int sign_ish = COMPARISON_BIT(dleft, dright);
2401-
_Py_DECREF_SPECIALIZED(left_o, _PyFloat_ExactDealloc);
2401+
PyStackRef_CLOSE_SPECIALIZED(left, _PyFloat_ExactDealloc);
24022402
DEAD(left);
2403-
_Py_DECREF_SPECIALIZED(right_o, _PyFloat_ExactDealloc);
2403+
PyStackRef_CLOSE_SPECIALIZED(right, _PyFloat_ExactDealloc);
24042404
DEAD(right);
24052405
res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
24062406
// It's always a bool, so we don't care about oparg & 16.
@@ -2420,9 +2420,9 @@ dummy_func(
24202420
Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o);
24212421
// 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg
24222422
int sign_ish = COMPARISON_BIT(ileft, iright);
2423-
_Py_DECREF_SPECIALIZED(left_o, (destructor)PyObject_Free);
2423+
PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free);
24242424
DEAD(left);
2425-
_Py_DECREF_SPECIALIZED(right_o, (destructor)PyObject_Free);
2425+
PyStackRef_CLOSE_SPECIALIZED(right, (destructor)PyObject_Free);
24262426
DEAD(right);
24272427
res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
24282428
// It's always a bool, so we don't care about oparg & 16.
@@ -2436,9 +2436,9 @@ dummy_func(
24362436
STAT_INC(COMPARE_OP, hit);
24372437
int eq = _PyUnicode_Equal(left_o, right_o);
24382438
assert((oparg >> 5) == Py_EQ || (oparg >> 5) == Py_NE);
2439-
_Py_DECREF_SPECIALIZED(left_o, _PyUnicode_ExactDealloc);
2439+
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
24402440
DEAD(left);
2441-
_Py_DECREF_SPECIALIZED(right_o, _PyUnicode_ExactDealloc);
2441+
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
24422442
DEAD(right);
24432443
assert(eq == 0 || eq == 1);
24442444
assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS);

Python/executor_cases.c.h

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

0 commit comments

Comments
 (0)