gh-145866: Convert DICT_MERGE to leave its inputs on the stack to be cleaned up by _POP_TOP (GH-146329)

This commit is contained in:
Neko Asakura 2026-03-24 06:31:41 -04:00 committed by GitHub
parent 07a555d4fc
commit 6d73bc2267
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1236 additions and 1199 deletions

View file

@ -2324,7 +2324,7 @@ dummy_func(
PyStackRef_CLOSE(update);
}
inst(DICT_MERGE, (callable, unused, unused, dict, unused[oparg - 1], update -- callable, unused, unused, dict, unused[oparg - 1])) {
op(_DICT_MERGE, (callable, unused, unused, dict, unused[oparg - 1], update -- callable, unused, unused, dict, unused[oparg - 1], u)) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict);
PyObject *update_o = PyStackRef_AsPyObjectBorrow(update);
@ -2332,12 +2332,14 @@ dummy_func(
int err = _PyDict_MergeEx(dict_o, update_o, 2);
if (err < 0) {
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
PyStackRef_CLOSE(update);
ERROR_IF(true);
ERROR_NO_POP();
}
PyStackRef_CLOSE(update);
u = update;
DEAD(update);
}
macro(DICT_MERGE) = _DICT_MERGE + POP_TOP;
inst(MAP_ADD, (dict_st, unused[oparg - 1], key, value -- dict_st, unused[oparg - 1])) {
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
assert(PyDict_CheckExact(dict));

View file

@ -8937,12 +8937,13 @@
break;
}
case _DICT_MERGE_r10: {
case _DICT_MERGE_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef update;
_PyStackRef dict;
_PyStackRef callable;
_PyStackRef u;
_PyStackRef _stack_item_0 = _tos_cache0;
oparg = CURRENT_OPARG();
update = _stack_item_0;
@ -8961,23 +8962,16 @@
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(update);
stack_pointer = _PyFrame_GetStackPointer(frame);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_ERROR();
}
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(update);
stack_pointer = _PyFrame_GetStackPointer(frame);
_tos_cache0 = PyStackRef_ZERO_BITS;
u = update;
_tos_cache0 = u;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(0);
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}

View file

@ -5535,31 +5535,36 @@
_PyStackRef callable;
_PyStackRef dict;
_PyStackRef update;
update = stack_pointer[-1];
dict = stack_pointer[-2 - (oparg - 1)];
callable = stack_pointer[-5 - (oparg - 1)];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict);
PyObject *update_o = PyStackRef_AsPyObjectBorrow(update);
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _PyDict_MergeEx(dict_o, update_o, 2);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
_PyStackRef u;
_PyStackRef value;
// _DICT_MERGE
{
update = stack_pointer[-1];
dict = stack_pointer[-2 - (oparg - 1)];
callable = stack_pointer[-5 - (oparg - 1)];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *dict_o = PyStackRef_AsPyObjectBorrow(dict);
PyObject *update_o = PyStackRef_AsPyObjectBorrow(update);
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
int err = _PyDict_MergeEx(dict_o, update_o, 2);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (err < 0) {
_PyFrame_SetStackPointer(frame, stack_pointer);
_PyEval_FormatKwargsError(tstate, callable_o, update_o);
stack_pointer = _PyFrame_GetStackPointer(frame);
JUMP_TO_LABEL(error);
}
u = update;
}
// _POP_TOP
{
value = u;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(update);
PyStackRef_XCLOSE(value);
stack_pointer = _PyFrame_GetStackPointer(frame);
JUMP_TO_LABEL(error);
}
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(update);
stack_pointer = _PyFrame_GetStackPointer(frame);
DISPATCH();
}

View file

@ -1356,6 +1356,12 @@ dummy_func(void) {
i = iterable;
}
op(_DICT_MERGE, (callable, unused, unused, dict, unused[oparg - 1], update -- callable, unused, unused, dict, unused[oparg - 1], u)) {
(void)callable;
(void)dict;
u = update;
}
op(_UNPACK_SEQUENCE_TWO_TUPLE, (seq -- val1, val0)) {
if (PyJitRef_IsUnique(seq) && sym_tuple_length(seq) == 2) {
ADD_OP(_UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE, oparg, 0);

View file

@ -1933,9 +1933,17 @@
}
case _DICT_MERGE: {
CHECK_STACK_BOUNDS(-1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
JitOptRef update;
JitOptRef dict;
JitOptRef callable;
JitOptRef u;
update = stack_pointer[-1];
dict = stack_pointer[-2 - (oparg - 1)];
callable = stack_pointer[-5 - (oparg - 1)];
(void)callable;
(void)dict;
u = update;
stack_pointer[-1] = u;
break;
}