gh-145214: Narrow _GUARD_TOS_ANY_{SET,DICT} by using probable type (gh-145215)

This commit is contained in:
Donghee Na 2026-03-03 09:58:38 +09:00 committed by GitHub
parent ea90b032a0
commit 6908372fb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 1728 additions and 1061 deletions

View file

@ -1082,6 +1082,16 @@ dummy_func(
EXIT_IF(!PyAnyDict_CheckExact(o));
}
op(_GUARD_TOS_DICT, (tos -- tos)) {
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
EXIT_IF(!PyDict_CheckExact(o));
}
op(_GUARD_TOS_FROZENDICT, (tos -- tos)) {
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
EXIT_IF(!PyFrozenDict_CheckExact(o));
}
macro(BINARY_OP_SUBSCR_DICT) =
_GUARD_NOS_ANY_DICT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP;
@ -2931,6 +2941,16 @@ dummy_func(
DEOPT_IF(!PyAnySet_CheckExact(o));
}
op(_GUARD_TOS_SET, (tos -- tos)) {
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
DEOPT_IF(!PySet_CheckExact(o));
}
op(_GUARD_TOS_FROZENSET, (tos -- tos)) {
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
DEOPT_IF(!PyFrozenSet_CheckExact(o));
}
macro(CONTAINS_OP_SET) = _GUARD_TOS_ANY_SET + unused/1 + _CONTAINS_OP_SET + POP_TOP + POP_TOP;
op(_CONTAINS_OP_SET, (left, right -- b, l, r)) {

View file

@ -6221,6 +6221,176 @@
break;
}
case _GUARD_TOS_DICT_r01: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
tos = stack_pointer[-1];
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_DICT_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
tos = _stack_item_0;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_DICT_r22: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
tos = _stack_item_1;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_DICT_r33: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
tos = _stack_item_2;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENDICT_r01: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
tos = stack_pointer[-1];
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENDICT_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
tos = _stack_item_0;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENDICT_r22: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
tos = _stack_item_1;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENDICT_r33: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
tos = _stack_item_2;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenDict_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_SUBSCR_DICT_r23: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
@ -10470,6 +10640,176 @@
break;
}
case _GUARD_TOS_SET_r01: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
tos = stack_pointer[-1];
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PySet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_SET_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
tos = _stack_item_0;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PySet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_SET_r22: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
tos = _stack_item_1;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PySet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_SET_r33: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
tos = _stack_item_2;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PySet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENSET_r01: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
tos = stack_pointer[-1];
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenSet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENSET_r11: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
tos = _stack_item_0;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenSet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
_tos_cache0 = tos;
SET_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENSET_r22: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
tos = _stack_item_1;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenSet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
_tos_cache1 = tos;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _GUARD_TOS_FROZENSET_r33: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef tos;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
tos = _stack_item_2;
PyObject *o = PyStackRef_AsPyObjectBorrow(tos);
if (!PyFrozenSet_CheckExact(o)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
_tos_cache2 = tos;
_tos_cache1 = _stack_item_1;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _CONTAINS_OP_SET_r23: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());

View file

@ -262,6 +262,7 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr,
#define sym_new_null _Py_uop_sym_new_null
#define sym_has_type _Py_uop_sym_has_type
#define sym_get_type _Py_uop_sym_get_type
#define sym_get_probable_type _Py_uop_sym_get_probable_type
#define sym_matches_type _Py_uop_sym_matches_type
#define sym_matches_type_version _Py_uop_sym_matches_type_version
#define sym_set_null(SYM) _Py_uop_sym_set_null(ctx, SYM)

View file

@ -46,6 +46,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
#define sym_set_recorded_gen_func(SYM, VAL) _Py_uop_sym_set_recorded_gen_func(ctx, SYM, VAL)
#define sym_get_probable_func_code _Py_uop_sym_get_probable_func_code
#define sym_get_probable_value _Py_uop_sym_get_probable_value
#define sym_get_probable_type _Py_uop_sym_get_probable_type
#define sym_set_stack_depth(DEPTH, SP) _Py_uop_sym_set_stack_depth(ctx, DEPTH, SP)
extern int
@ -1324,28 +1325,36 @@ dummy_func(void) {
if (sym_matches_type(tos, &PyList_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(tos, &PyList_Type);
else {
sym_set_type(tos, &PyList_Type);
}
}
op(_GUARD_NOS_LIST, (nos, unused -- nos, unused)) {
if (sym_matches_type(nos, &PyList_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(nos, &PyList_Type);
else {
sym_set_type(nos, &PyList_Type);
}
}
op(_GUARD_TOS_TUPLE, (tos -- tos)) {
if (sym_matches_type(tos, &PyTuple_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(tos, &PyTuple_Type);
else {
sym_set_type(tos, &PyTuple_Type);
}
}
op(_GUARD_NOS_TUPLE, (nos, unused -- nos, unused)) {
if (sym_matches_type(nos, &PyTuple_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(nos, &PyTuple_Type);
else {
sym_set_type(nos, &PyTuple_Type);
}
}
op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) {
@ -1359,7 +1368,6 @@ dummy_func(void) {
PyTypeObject *tp = sym_get_type(nos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(nos, tp);
}
}
@ -1367,65 +1375,133 @@ dummy_func(void) {
PyTypeObject *tp = sym_get_type(tos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(tos, tp);
}
else {
// Narrowing the guard based on the probable type.
tp = sym_get_probable_type(tos);
if (tp == &PyDict_Type) {
ADD_OP(_GUARD_TOS_DICT, 0, 0);
}
else if (tp == &PyFrozenDict_Type) {
ADD_OP(_GUARD_TOS_FROZENDICT, 0, 0);
}
}
}
op(_GUARD_TOS_DICT, (tos -- tos)) {
if (sym_matches_type(tos, &PyDict_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PyDict_Type);
}
}
op(_GUARD_TOS_FROZENDICT, (tos -- tos)) {
if (sym_matches_type(tos, &PyFrozenDict_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PyFrozenDict_Type);
}
}
op(_GUARD_TOS_ANY_SET, (tos -- tos)) {
if (sym_matches_type(tos, &PySet_Type) ||
sym_matches_type(tos, &PyFrozenSet_Type))
{
PyTypeObject *tp = sym_get_type(tos);
if (tp == &PySet_Type || tp == &PyFrozenSet_Type) {
ADD_OP(_NOP, 0, 0);
}
else {
// Narrowing the guard based on the probable type.
tp = sym_get_probable_type(tos);
if (tp == &PySet_Type) {
ADD_OP(_GUARD_TOS_SET, 0, 0);
}
else if (tp == &PyFrozenSet_Type) {
ADD_OP(_GUARD_TOS_FROZENSET, 0, 0);
}
}
}
op(_GUARD_TOS_SET, (tos -- tos)) {
if (sym_matches_type(tos, &PySet_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PySet_Type);
}
}
op(_GUARD_TOS_FROZENSET, (tos -- tos)) {
if (sym_matches_type(tos, &PyFrozenSet_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PyFrozenSet_Type);
}
}
op(_GUARD_TOS_SLICE, (tos -- tos)) {
if (sym_matches_type(tos, &PySlice_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(tos, &PySlice_Type);
else {
sym_set_type(tos, &PySlice_Type);
}
}
op(_GUARD_NOS_NULL, (null, unused -- null, unused)) {
if (sym_is_null(null)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_null(null);
else {
sym_set_null(null);
}
}
op(_GUARD_NOS_NOT_NULL, (nos, unused -- nos, unused)) {
if (sym_is_not_null(nos)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_non_null(nos);
else {
sym_set_non_null(nos);
}
}
op(_GUARD_THIRD_NULL, (null, unused, unused -- null, unused, unused)) {
if (sym_is_null(null)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_null(null);
else {
sym_set_null(null);
}
}
op(_GUARD_CALLABLE_TYPE_1, (callable, unused, unused -- callable, unused, unused)) {
if (sym_get_const(ctx, callable) == (PyObject *)&PyType_Type) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, (PyObject *)&PyType_Type);
else {
sym_set_const(callable, (PyObject *)&PyType_Type);
}
}
op(_GUARD_CALLABLE_TUPLE_1, (callable, unused, unused -- callable, unused, unused)) {
if (sym_get_const(ctx, callable) == (PyObject *)&PyTuple_Type) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, (PyObject *)&PyTuple_Type);
else {
sym_set_const(callable, (PyObject *)&PyTuple_Type);
}
}
op(_GUARD_CALLABLE_STR_1, (callable, unused, unused -- callable, unused, unused)) {
if (sym_get_const(ctx, callable) == (PyObject *)&PyUnicode_Type) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, (PyObject *)&PyUnicode_Type);
else {
sym_set_const(callable, (PyObject *)&PyUnicode_Type);
}
}
op(_CALL_LEN, (callable, null, arg -- res, a, c)) {
@ -1484,7 +1560,9 @@ dummy_func(void) {
if (sym_get_const(ctx, callable) == len) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, len);
else {
sym_set_const(callable, len);
}
}
op(_GUARD_CALLABLE_ISINSTANCE, (callable, unused, unused, unused -- callable, unused, unused, unused)) {
@ -1492,7 +1570,9 @@ dummy_func(void) {
if (sym_get_const(ctx, callable) == isinstance) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, isinstance);
else {
sym_set_const(callable, isinstance);
}
}
op(_GUARD_CALLABLE_LIST_APPEND, (callable, unused, unused -- callable, unused, unused)) {
@ -1500,7 +1580,9 @@ dummy_func(void) {
if (sym_get_const(ctx, callable) == list_append) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, list_append);
else {
sym_set_const(callable, list_append);
}
}
op(_BINARY_SLICE, (container, start, stop -- res)) {

View file

@ -355,7 +355,9 @@
if (sym_matches_type(nos, &PyList_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(nos, &PyList_Type);
else {
sym_set_type(nos, &PyList_Type);
}
break;
}
@ -365,7 +367,9 @@
if (sym_matches_type(tos, &PyList_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(tos, &PyList_Type);
else {
sym_set_type(tos, &PyList_Type);
}
break;
}
@ -375,7 +379,9 @@
if (sym_matches_type(tos, &PySlice_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(tos, &PySlice_Type);
else {
sym_set_type(tos, &PySlice_Type);
}
break;
}
@ -1023,7 +1029,9 @@
if (sym_matches_type(nos, &PyTuple_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(nos, &PyTuple_Type);
else {
sym_set_type(nos, &PyTuple_Type);
}
break;
}
@ -1033,7 +1041,9 @@
if (sym_matches_type(tos, &PyTuple_Type)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_type(tos, &PyTuple_Type);
else {
sym_set_type(tos, &PyTuple_Type);
}
break;
}
@ -1107,7 +1117,6 @@
PyTypeObject *tp = sym_get_type(nos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(nos, tp);
}
break;
}
@ -1118,7 +1127,39 @@
PyTypeObject *tp = sym_get_type(tos);
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
ADD_OP(_NOP, 0, 0);
sym_set_type(tos, tp);
}
else {
tp = sym_get_probable_type(tos);
if (tp == &PyDict_Type) {
ADD_OP(_GUARD_TOS_DICT, 0, 0);
}
else if (tp == &PyFrozenDict_Type) {
ADD_OP(_GUARD_TOS_FROZENDICT, 0, 0);
}
}
break;
}
case _GUARD_TOS_DICT: {
JitOptRef tos;
tos = stack_pointer[-1];
if (sym_matches_type(tos, &PyDict_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PyDict_Type);
}
break;
}
case _GUARD_TOS_FROZENDICT: {
JitOptRef tos;
tos = stack_pointer[-1];
if (sym_matches_type(tos, &PyFrozenDict_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PyFrozenDict_Type);
}
break;
}
@ -2430,11 +2471,43 @@
case _GUARD_TOS_ANY_SET: {
JitOptRef tos;
tos = stack_pointer[-1];
if (sym_matches_type(tos, &PySet_Type) ||
sym_matches_type(tos, &PyFrozenSet_Type))
{
PyTypeObject *tp = sym_get_type(tos);
if (tp == &PySet_Type || tp == &PyFrozenSet_Type) {
ADD_OP(_NOP, 0, 0);
}
else {
tp = sym_get_probable_type(tos);
if (tp == &PySet_Type) {
ADD_OP(_GUARD_TOS_SET, 0, 0);
}
else if (tp == &PyFrozenSet_Type) {
ADD_OP(_GUARD_TOS_FROZENSET, 0, 0);
}
}
break;
}
case _GUARD_TOS_SET: {
JitOptRef tos;
tos = stack_pointer[-1];
if (sym_matches_type(tos, &PySet_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PySet_Type);
}
break;
}
case _GUARD_TOS_FROZENSET: {
JitOptRef tos;
tos = stack_pointer[-1];
if (sym_matches_type(tos, &PyFrozenSet_Type)) {
ADD_OP(_NOP, 0, 0);
}
else {
sym_set_type(tos, &PyFrozenSet_Type);
}
break;
}
@ -3071,7 +3144,9 @@
if (sym_is_null(null)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_null(null);
else {
sym_set_null(null);
}
break;
}
@ -3081,7 +3156,9 @@
if (sym_is_not_null(nos)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_non_null(nos);
else {
sym_set_non_null(nos);
}
break;
}
@ -3091,7 +3168,9 @@
if (sym_is_null(null)) {
ADD_OP(_NOP, 0, 0);
}
sym_set_null(null);
else {
sym_set_null(null);
}
break;
}
@ -3101,7 +3180,9 @@
if (sym_get_const(ctx, callable) == (PyObject *)&PyType_Type) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, (PyObject *)&PyType_Type);
else {
sym_set_const(callable, (PyObject *)&PyType_Type);
}
break;
}
@ -3134,7 +3215,9 @@
if (sym_get_const(ctx, callable) == (PyObject *)&PyUnicode_Type) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, (PyObject *)&PyUnicode_Type);
else {
sym_set_const(callable, (PyObject *)&PyUnicode_Type);
}
break;
}
@ -3164,7 +3247,9 @@
if (sym_get_const(ctx, callable) == (PyObject *)&PyTuple_Type) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, (PyObject *)&PyTuple_Type);
else {
sym_set_const(callable, (PyObject *)&PyTuple_Type);
}
break;
}
@ -3307,7 +3392,9 @@
if (sym_get_const(ctx, callable) == len) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, len);
else {
sym_set_const(callable, len);
}
break;
}
@ -3368,7 +3455,9 @@
if (sym_get_const(ctx, callable) == isinstance) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, isinstance);
else {
sym_set_const(callable, isinstance);
}
break;
}
@ -3403,7 +3492,9 @@
if (sym_get_const(ctx, callable) == list_append) {
ADD_OP(_NOP, 0, 0);
}
sym_set_const(callable, list_append);
else {
sym_set_const(callable, list_append);
}
break;
}

View file

@ -688,6 +688,34 @@ _Py_uop_sym_get_type(JitOptRef ref)
Py_UNREACHABLE();
}
PyTypeObject *
_Py_uop_sym_get_probable_type(JitOptRef ref)
{
JitOptSymbol *sym = PyJitRef_Unwrap(ref);
JitSymType tag = sym->tag;
switch(tag) {
case JIT_SYM_NULL_TAG:
case JIT_SYM_BOTTOM_TAG:
case JIT_SYM_NON_NULL_TAG:
case JIT_SYM_UNKNOWN_TAG:
case JIT_SYM_TYPE_VERSION_TAG:
case JIT_SYM_TUPLE_TAG:
case JIT_SYM_PREDICATE_TAG:
case JIT_SYM_TRUTHINESS_TAG:
case JIT_SYM_COMPACT_INT:
case JIT_SYM_KNOWN_CLASS_TAG:
case JIT_SYM_KNOWN_VALUE_TAG:
return _Py_uop_sym_get_type(ref);
case JIT_SYM_RECORDED_GEN_FUNC_TAG:
return NULL;
case JIT_SYM_RECORDED_VALUE_TAG:
return Py_TYPE(sym->recorded_value.value);
case JIT_SYM_RECORDED_TYPE_TAG:
return sym->recorded_type.type;
}
Py_UNREACHABLE();
}
unsigned int
_Py_uop_sym_get_type_version(JitOptRef ref)
{