gh-145122: Add _GUARD_NOS_ANY_DICT to prevent STORE_SUBSCR_DICT on frozendict (gh-145039)

This commit is contained in:
Donghee Na 2026-02-25 00:48:45 +09:00 committed by GitHub
parent 4c95ad8e49
commit 0f759f1171
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1244 additions and 1079 deletions

View file

@ -1057,17 +1057,22 @@ dummy_func(
}
op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) {
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
EXIT_IF(!PyDict_CheckExact(o));
}
op(_GUARD_NOS_ANY_DICT, (nos, unused -- nos, unused)) {
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
EXIT_IF(!PyAnyDict_CheckExact(o));
}
op(_GUARD_TOS_DICT, (tos -- tos)) {
op(_GUARD_TOS_ANY_DICT, (tos -- tos)) {
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
EXIT_IF(!PyAnyDict_CheckExact(o));
}
macro(BINARY_OP_SUBSCR_DICT) =
_GUARD_NOS_DICT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP;
_GUARD_NOS_ANY_DICT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP;
op(_BINARY_OP_SUBSCR_DICT, (dict_st, sub_st -- res, ds, ss)) {
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
@ -2934,7 +2939,7 @@ dummy_func(
INPUTS_DEAD();
}
macro(CONTAINS_OP_DICT) = _GUARD_TOS_DICT + unused/1 + _CONTAINS_OP_DICT + POP_TOP + POP_TOP;
macro(CONTAINS_OP_DICT) = _GUARD_TOS_ANY_DICT + unused/1 + _CONTAINS_OP_DICT + POP_TOP + POP_TOP;
op(_CONTAINS_OP_DICT, (left, right -- b, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);

View file

@ -5920,7 +5920,7 @@
_PyStackRef nos;
nos = stack_pointer[-2];
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyAnyDict_CheckExact(o)) {
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
@ -5941,7 +5941,7 @@
_PyStackRef _stack_item_0 = _tos_cache0;
nos = stack_pointer[-1];
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyAnyDict_CheckExact(o)) {
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(1);
@ -5964,7 +5964,7 @@
_PyStackRef _stack_item_1 = _tos_cache1;
nos = _stack_item_0;
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyAnyDict_CheckExact(o)) {
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache1 = _stack_item_1;
_tos_cache0 = nos;
@ -5979,6 +5979,95 @@
}
case _GUARD_NOS_DICT_r33: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef nos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
nos = _stack_item_1;
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = _stack_item_2;
_tos_cache1 = nos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
_tos_cache2 = _stack_item_2;
_tos_cache1 = nos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_NOS_ANY_DICT_r02: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef nos;
nos = stack_pointer[-2];
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyAnyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
_tos_cache1 = stack_pointer[-1];
_tos_cache0 = nos;
SET_CURRENT_CACHED_VALUES(2);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_NOS_ANY_DICT_r12: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef nos;
_PyStackRef _stack_item_0 = _tos_cache0;
nos = stack_pointer[-1];
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyAnyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
_tos_cache1 = _stack_item_0;
_tos_cache0 = nos;
SET_CURRENT_CACHED_VALUES(2);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_NOS_ANY_DICT_r22: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef nos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
nos = _stack_item_0;
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyAnyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache1 = _stack_item_1;
_tos_cache0 = nos;
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
_tos_cache1 = _stack_item_1;
_tos_cache0 = nos;
SET_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_NOS_ANY_DICT_r33: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef nos;
@ -6003,7 +6092,7 @@
break;
}
case _GUARD_TOS_DICT_r01: {
case _GUARD_TOS_ANY_DICT_r01: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
@ -6022,7 +6111,7 @@
break;
}
case _GUARD_TOS_DICT_r11: {
case _GUARD_TOS_ANY_DICT_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
@ -6041,7 +6130,7 @@
break;
}
case _GUARD_TOS_DICT_r22: {
case _GUARD_TOS_ANY_DICT_r22: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
@ -6063,7 +6152,7 @@
break;
}
case _GUARD_TOS_DICT_r33: {
case _GUARD_TOS_ANY_DICT_r33: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;

View file

@ -638,7 +638,7 @@
_PyStackRef ds;
_PyStackRef ss;
_PyStackRef value;
// _GUARD_NOS_DICT
// _GUARD_NOS_ANY_DICT
{
nos = stack_pointer[-2];
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
@ -5135,7 +5135,7 @@
_PyStackRef l;
_PyStackRef r;
_PyStackRef value;
// _GUARD_TOS_DICT
// _GUARD_TOS_ANY_DICT
{
tos = stack_pointer[-1];
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
@ -11480,7 +11480,7 @@
{
nos = stack_pointer[-2];
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
if (!PyAnyDict_CheckExact(o)) {
if (!PyDict_CheckExact(o)) {
UPDATE_MISS_STATS(STORE_SUBSCR);
assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR));
JUMP_TO_PREDICTED(STORE_SUBSCR);

View file

@ -1348,13 +1348,6 @@ dummy_func(void) {
sym_set_type(nos, &PyTuple_Type);
}
op(_GUARD_TOS_DICT, (tos -- tos)) {
if (sym_matches_type(tos, &PyDict_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(tos, &PyDict_Type);
}
op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) {
if (sym_matches_type(nos, &PyDict_Type)) {
ADD_OP(_NOP, 0, 0);
@ -1362,6 +1355,22 @@ dummy_func(void) {
sym_set_type(nos, &PyDict_Type);
}
op(_GUARD_NOS_ANY_DICT, (nos, unused -- nos, unused)) {
PyTypeObject *tp = sym_get_type(nos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(nos, tp);
}
}
op(_GUARD_TOS_ANY_DICT, (tos -- tos)) {
PyTypeObject *tp = sym_get_type(tos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(tos, tp);
}
}
op(_GUARD_TOS_ANY_SET, (tos -- tos)) {
if (sym_matches_type(tos, &PySet_Type) ||
sym_matches_type(tos, &PyFrozenSet_Type))

View file

@ -1101,13 +1101,25 @@
break;
}
case _GUARD_TOS_DICT: {
case _GUARD_NOS_ANY_DICT: {
JitOptRef nos;
nos = stack_pointer[-2];
PyTypeObject *tp = sym_get_type(nos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(nos, tp);
}
break;
}
case _GUARD_TOS_ANY_DICT: {
JitOptRef tos;
tos = stack_pointer[-1];
if (sym_matches_type(tos, &PyDict_Type)) {
PyTypeObject *tp = sym_get_type(tos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(tos, tp);
}
sym_set_type(tos, &PyDict_Type);
break;
}