mirror of
https://github.com/python/cpython.git
synced 2026-06-05 01:10:53 +00:00
gh-143732: allow dict subclasses to be specialized (GH-148128)
This commit is contained in:
parent
de1769f700
commit
5847931d11
15 changed files with 461 additions and 206 deletions
|
|
@ -1277,14 +1277,16 @@ dummy_func(
|
|||
INPUTS_DEAD();
|
||||
}
|
||||
|
||||
op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) {
|
||||
op(_GUARD_NOS_DICT_SUBSCRIPT, (nos, unused -- nos, unused)) {
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
EXIT_IF(!PyDict_CheckExact(o));
|
||||
DEOPT_IF(!Py_TYPE(o)->tp_as_mapping);
|
||||
DEOPT_IF(Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript);
|
||||
}
|
||||
|
||||
op(_GUARD_NOS_ANY_DICT, (nos, unused -- nos, unused)) {
|
||||
op(_GUARD_NOS_DICT_STORE_SUBSCRIPT, (unused, nos, unused -- unused, nos, unused)) {
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
EXIT_IF(!PyAnyDict_CheckExact(o));
|
||||
DEOPT_IF(!Py_TYPE(o)->tp_as_mapping);
|
||||
DEOPT_IF(Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript);
|
||||
}
|
||||
|
||||
op(_GUARD_TOS_ANY_DICT, (tos -- tos)) {
|
||||
|
|
@ -1303,20 +1305,16 @@ dummy_func(
|
|||
}
|
||||
|
||||
macro(BINARY_OP_SUBSCR_DICT) =
|
||||
_GUARD_NOS_ANY_DICT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP;
|
||||
_RECORD_NOS_TYPE +
|
||||
_GUARD_NOS_DICT_SUBSCRIPT + unused/5 + _BINARY_OP_SUBSCR_DICT + POP_TOP + POP_TOP;
|
||||
|
||||
tier2 op(_BINARY_OP_SUBSCR_DICT_KNOWN_HASH, (dict_st, sub_st, hash/4 -- res, ds, ss)) {
|
||||
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
|
||||
assert(PyAnyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_subscript == _PyDict_Subscript);
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o;
|
||||
int rc = _PyDict_GetItemRef_KnownHash((PyDictObject *)dict, sub, (Py_hash_t)hash, &res_o);
|
||||
if (rc == 0) {
|
||||
_PyErr_SetKeyError(sub);
|
||||
}
|
||||
if (rc <= 0) {
|
||||
PyObject *res_o = _PyDict_SubscriptKnownHash(dict, sub, (Py_hash_t)hash);
|
||||
if (res_o == NULL) {
|
||||
ERROR_NO_POP();
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
|
|
@ -1328,15 +1326,10 @@ dummy_func(
|
|||
op(_BINARY_OP_SUBSCR_DICT, (dict_st, sub_st -- res, ds, ss)) {
|
||||
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
|
||||
assert(PyAnyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_subscript == _PyDict_Subscript);
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o;
|
||||
int rc = PyDict_GetItemRef(dict, sub, &res_o);
|
||||
if (rc == 0) {
|
||||
_PyErr_SetKeyError(sub);
|
||||
}
|
||||
if (rc <= 0) {
|
||||
PyObject *res_o = _PyDict_Subscript(dict, sub);
|
||||
if (res_o == NULL) {
|
||||
ERROR_NO_POP();
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
|
|
@ -1451,12 +1444,12 @@ dummy_func(
|
|||
}
|
||||
|
||||
macro(STORE_SUBSCR_DICT) =
|
||||
_GUARD_NOS_DICT + unused/1 + _STORE_SUBSCR_DICT + POP_TOP;
|
||||
_RECORD_NOS_TYPE +
|
||||
_GUARD_NOS_DICT_STORE_SUBSCRIPT + unused/1 + _STORE_SUBSCR_DICT + POP_TOP;
|
||||
|
||||
op(_STORE_SUBSCR_DICT, (value, dict_st, sub -- st)) {
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
|
||||
assert(PyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript);
|
||||
STAT_INC(STORE_SUBSCR, hit);
|
||||
int err = _PyDict_SetItem_Take2((PyDictObject *)dict,
|
||||
PyStackRef_AsPyObjectSteal(sub),
|
||||
|
|
@ -1471,8 +1464,7 @@ dummy_func(
|
|||
|
||||
tier2 op(_STORE_SUBSCR_DICT_KNOWN_HASH, (value, dict_st, sub, hash/4 -- st)) {
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
|
||||
assert(PyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript);
|
||||
STAT_INC(STORE_SUBSCR, hit);
|
||||
int err = _PyDict_SetItem_Take2_KnownHash((PyDictObject *)dict,
|
||||
PyStackRef_AsPyObjectSteal(sub),
|
||||
|
|
|
|||
139
Python/executor_cases.c.h
generated
139
Python/executor_cases.c.h
generated
|
|
@ -7460,13 +7460,18 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_DICT_r02: {
|
||||
case _GUARD_NOS_DICT_SUBSCRIPT_r02: {
|
||||
CHECK_CURRENT_CACHED_VALUES(0);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef nos;
|
||||
nos = stack_pointer[-2];
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
if (!PyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
|
|
@ -7480,14 +7485,20 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_DICT_r12: {
|
||||
case _GUARD_NOS_DICT_SUBSCRIPT_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 (!PyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(1);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(1);
|
||||
|
|
@ -7502,7 +7513,7 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_DICT_r22: {
|
||||
case _GUARD_NOS_DICT_SUBSCRIPT_r22: {
|
||||
CHECK_CURRENT_CACHED_VALUES(2);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef nos;
|
||||
|
|
@ -7510,7 +7521,14 @@
|
|||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
nos = _stack_item_0;
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
if (!PyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = nos;
|
||||
SET_CURRENT_CACHED_VALUES(2);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = nos;
|
||||
|
|
@ -7524,7 +7542,7 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_DICT_r33: {
|
||||
case _GUARD_NOS_DICT_SUBSCRIPT_r33: {
|
||||
CHECK_CURRENT_CACHED_VALUES(3);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef nos;
|
||||
|
|
@ -7533,7 +7551,15 @@
|
|||
_PyStackRef _stack_item_2 = _tos_cache2;
|
||||
nos = _stack_item_1;
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
if (!PyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
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();
|
||||
}
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache2 = _stack_item_2;
|
||||
_tos_cache1 = nos;
|
||||
|
|
@ -7549,49 +7575,62 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_ANY_DICT_r02: {
|
||||
case _GUARD_NOS_DICT_STORE_SUBSCRIPT_r03: {
|
||||
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)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
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;
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
_tos_cache2 = stack_pointer[-1];
|
||||
_tos_cache1 = nos;
|
||||
_tos_cache0 = stack_pointer[-3];
|
||||
SET_CURRENT_CACHED_VALUES(3);
|
||||
stack_pointer += -3;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_ANY_DICT_r12: {
|
||||
case _GUARD_NOS_DICT_STORE_SUBSCRIPT_r13: {
|
||||
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)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
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;
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache0 = _stack_item_0;
|
||||
SET_CURRENT_CACHED_VALUES(1);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
_tos_cache2 = _stack_item_0;
|
||||
_tos_cache1 = nos;
|
||||
_tos_cache0 = stack_pointer[-2];
|
||||
SET_CURRENT_CACHED_VALUES(3);
|
||||
stack_pointer += -2;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_ANY_DICT_r22: {
|
||||
case _GUARD_NOS_DICT_STORE_SUBSCRIPT_r23: {
|
||||
CHECK_CURRENT_CACHED_VALUES(2);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef nos;
|
||||
|
|
@ -7599,21 +7638,31 @@
|
|||
_PyStackRef _stack_item_1 = _tos_cache1;
|
||||
nos = _stack_item_0;
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
if (!PyAnyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
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);
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache1 = _stack_item_1;
|
||||
_tos_cache0 = nos;
|
||||
SET_CURRENT_CACHED_VALUES(2);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
_tos_cache2 = _stack_item_1;
|
||||
_tos_cache1 = nos;
|
||||
_tos_cache0 = stack_pointer[-1];
|
||||
SET_CURRENT_CACHED_VALUES(3);
|
||||
stack_pointer += -1;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_ANY_DICT_r33: {
|
||||
case _GUARD_NOS_DICT_STORE_SUBSCRIPT_r33: {
|
||||
CHECK_CURRENT_CACHED_VALUES(3);
|
||||
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
|
||||
_PyStackRef nos;
|
||||
|
|
@ -7622,7 +7671,15 @@
|
|||
_PyStackRef _stack_item_2 = _tos_cache2;
|
||||
nos = _stack_item_1;
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
if (!PyAnyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
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();
|
||||
}
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
_tos_cache2 = _stack_item_2;
|
||||
_tos_cache1 = nos;
|
||||
|
|
@ -7908,22 +7965,16 @@
|
|||
PyObject *hash = (PyObject *)CURRENT_OPERAND0_64();
|
||||
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
assert(PyAnyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_subscript == _PyDict_Subscript);
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o;
|
||||
stack_pointer[0] = dict_st;
|
||||
stack_pointer[1] = sub_st;
|
||||
stack_pointer += 2;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int rc = _PyDict_GetItemRef_KnownHash((PyDictObject *)dict, sub, (Py_hash_t)hash, &res_o);
|
||||
PyObject *res_o = _PyDict_SubscriptKnownHash(dict, sub, (Py_hash_t)hash);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (rc == 0) {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyErr_SetKeyError(sub);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
}
|
||||
if (rc <= 0) {
|
||||
if (res_o == NULL) {
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
JUMP_TO_ERROR();
|
||||
}
|
||||
|
|
@ -7954,22 +8005,16 @@
|
|||
dict_st = _stack_item_0;
|
||||
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
assert(PyAnyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_subscript == _PyDict_Subscript);
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o;
|
||||
stack_pointer[0] = dict_st;
|
||||
stack_pointer[1] = sub_st;
|
||||
stack_pointer += 2;
|
||||
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int rc = PyDict_GetItemRef(dict, sub, &res_o);
|
||||
PyObject *res_o = _PyDict_Subscript(dict, sub);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (rc == 0) {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyErr_SetKeyError(sub);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
}
|
||||
if (rc <= 0) {
|
||||
if (res_o == NULL) {
|
||||
SET_CURRENT_CACHED_VALUES(0);
|
||||
JUMP_TO_ERROR();
|
||||
}
|
||||
|
|
@ -8317,7 +8362,7 @@
|
|||
dict_st = _stack_item_1;
|
||||
value = _stack_item_0;
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
assert(PyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript);
|
||||
STAT_INC(STORE_SUBSCR, hit);
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer[1] = dict_st;
|
||||
|
|
@ -8364,7 +8409,7 @@
|
|||
value = _stack_item_0;
|
||||
PyObject *hash = (PyObject *)CURRENT_OPERAND0_64();
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
assert(PyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript);
|
||||
STAT_INC(STORE_SUBSCR, hit);
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer[1] = dict_st;
|
||||
|
|
|
|||
32
Python/generated_cases.c.h
generated
32
Python/generated_cases.c.h
generated
|
|
@ -645,11 +645,16 @@
|
|||
_PyStackRef ds;
|
||||
_PyStackRef ss;
|
||||
_PyStackRef value;
|
||||
// _GUARD_NOS_ANY_DICT
|
||||
// _GUARD_NOS_DICT_SUBSCRIPT
|
||||
{
|
||||
nos = stack_pointer[-2];
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
if (!PyAnyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
}
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_subscript != _PyDict_Subscript) {
|
||||
UPDATE_MISS_STATS(BINARY_OP);
|
||||
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
|
||||
JUMP_TO_PREDICTED(BINARY_OP);
|
||||
|
|
@ -662,18 +667,12 @@
|
|||
dict_st = nos;
|
||||
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
assert(PyAnyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_subscript == _PyDict_Subscript);
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int rc = PyDict_GetItemRef(dict, sub, &res_o);
|
||||
PyObject *res_o = _PyDict_Subscript(dict, sub);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (rc == 0) {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyErr_SetKeyError(sub);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
}
|
||||
if (rc <= 0) {
|
||||
if (res_o == NULL) {
|
||||
JUMP_TO_LABEL(error);
|
||||
}
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
|
|
@ -12002,11 +12001,16 @@
|
|||
_PyStackRef dict_st;
|
||||
_PyStackRef sub;
|
||||
_PyStackRef st;
|
||||
// _GUARD_NOS_DICT
|
||||
// _GUARD_NOS_DICT_STORE_SUBSCRIPT
|
||||
{
|
||||
nos = stack_pointer[-2];
|
||||
PyObject *o = PyStackRef_AsPyObjectBorrow(nos);
|
||||
if (!PyDict_CheckExact(o)) {
|
||||
if (!Py_TYPE(o)->tp_as_mapping) {
|
||||
UPDATE_MISS_STATS(STORE_SUBSCR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR));
|
||||
JUMP_TO_PREDICTED(STORE_SUBSCR);
|
||||
}
|
||||
if (Py_TYPE(o)->tp_as_mapping->mp_ass_subscript != _PyDict_StoreSubscript) {
|
||||
UPDATE_MISS_STATS(STORE_SUBSCR);
|
||||
assert(_PyOpcode_Deopt[opcode] == (STORE_SUBSCR));
|
||||
JUMP_TO_PREDICTED(STORE_SUBSCR);
|
||||
|
|
@ -12019,7 +12023,7 @@
|
|||
dict_st = nos;
|
||||
value = stack_pointer[-3];
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
assert(PyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript);
|
||||
STAT_INC(STORE_SUBSCR, hit);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int err = _PyDict_SetItem_Take2((PyDictObject *)dict,
|
||||
|
|
|
|||
|
|
@ -2166,17 +2166,45 @@ dummy_func(void) {
|
|||
}
|
||||
}
|
||||
|
||||
op(_GUARD_NOS_DICT, (nos, unused -- nos, unused)) {
|
||||
if (sym_matches_type(nos, &PyDict_Type)) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
op(_GUARD_NOS_DICT_SUBSCRIPT, (nos, unused -- nos, unused)) {
|
||||
PyTypeObject *tp = sym_get_type(nos);
|
||||
bool definite = true;
|
||||
if (!tp) {
|
||||
tp = sym_get_probable_type(nos);
|
||||
definite = false;
|
||||
}
|
||||
if (tp && tp->tp_as_mapping &&
|
||||
tp->tp_as_mapping->mp_subscript == _PyDict_Subscript) {
|
||||
if (definite) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
}
|
||||
else {
|
||||
ADD_OP(_GUARD_TYPE, 0, (uintptr_t)tp);
|
||||
sym_set_type(nos, tp);
|
||||
}
|
||||
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)tp);
|
||||
_Py_BloomFilter_Add(dependencies, tp);
|
||||
}
|
||||
sym_set_type(nos, &PyDict_Type);
|
||||
}
|
||||
|
||||
op(_GUARD_NOS_ANY_DICT, (nos, unused -- nos, unused)) {
|
||||
op(_GUARD_NOS_DICT_STORE_SUBSCRIPT, (unused, nos, unused -- unused, nos, unused)) {
|
||||
PyTypeObject *tp = sym_get_type(nos);
|
||||
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
bool definite = true;
|
||||
if (!tp) {
|
||||
tp = sym_get_probable_type(nos);
|
||||
definite = false;
|
||||
}
|
||||
if (tp && tp->tp_as_mapping &&
|
||||
tp->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) {
|
||||
if (definite) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
}
|
||||
else {
|
||||
ADD_OP(_GUARD_TYPE, 0, (uintptr_t)tp);
|
||||
sym_set_type(nos, tp);
|
||||
}
|
||||
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)tp);
|
||||
_Py_BloomFilter_Add(dependencies, tp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
64
Python/optimizer_cases.c.h
generated
64
Python/optimizer_cases.c.h
generated
|
|
@ -1475,22 +1475,50 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_DICT: {
|
||||
JitOptRef nos;
|
||||
nos = stack_pointer[-2];
|
||||
if (sym_matches_type(nos, &PyDict_Type)) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
}
|
||||
sym_set_type(nos, &PyDict_Type);
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_ANY_DICT: {
|
||||
case _GUARD_NOS_DICT_SUBSCRIPT: {
|
||||
JitOptRef nos;
|
||||
nos = stack_pointer[-2];
|
||||
PyTypeObject *tp = sym_get_type(nos);
|
||||
if (tp == &PyDict_Type || tp == &PyFrozenDict_Type) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
bool definite = true;
|
||||
if (!tp) {
|
||||
tp = sym_get_probable_type(nos);
|
||||
definite = false;
|
||||
}
|
||||
if (tp && tp->tp_as_mapping &&
|
||||
tp->tp_as_mapping->mp_subscript == _PyDict_Subscript) {
|
||||
if (definite) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
}
|
||||
else {
|
||||
ADD_OP(_GUARD_TYPE, 0, (uintptr_t)tp);
|
||||
sym_set_type(nos, tp);
|
||||
}
|
||||
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)tp);
|
||||
_Py_BloomFilter_Add(dependencies, tp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _GUARD_NOS_DICT_STORE_SUBSCRIPT: {
|
||||
JitOptRef nos;
|
||||
nos = stack_pointer[-2];
|
||||
PyTypeObject *tp = sym_get_type(nos);
|
||||
bool definite = true;
|
||||
if (!tp) {
|
||||
tp = sym_get_probable_type(nos);
|
||||
definite = false;
|
||||
}
|
||||
if (tp && tp->tp_as_mapping &&
|
||||
tp->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript) {
|
||||
if (definite) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
}
|
||||
else {
|
||||
ADD_OP(_GUARD_TYPE, 0, (uintptr_t)tp);
|
||||
sym_set_type(nos, tp);
|
||||
}
|
||||
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)tp);
|
||||
_Py_BloomFilter_Add(dependencies, tp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -1582,14 +1610,10 @@
|
|||
/* Start of uop copied from bytecodes for constant evaluation */
|
||||
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
|
||||
PyObject *dict = PyStackRef_AsPyObjectBorrow(dict_st);
|
||||
assert(PyAnyDict_CheckExact(dict));
|
||||
assert(Py_TYPE(dict)->tp_as_mapping->mp_subscript == _PyDict_Subscript);
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
PyObject *res_o;
|
||||
int rc = PyDict_GetItemRef(dict, sub, &res_o);
|
||||
if (rc == 0) {
|
||||
_PyErr_SetKeyError(sub);
|
||||
}
|
||||
if (rc <= 0) {
|
||||
PyObject *res_o = _PyDict_Subscript(dict, sub);
|
||||
if (res_o == NULL) {
|
||||
JUMP_TO_LABEL(error);
|
||||
}
|
||||
res_stackref = PyStackRef_FromPyObjectSteal(res_o);
|
||||
|
|
|
|||
21
Python/record_functions.c.h
generated
21
Python/record_functions.c.h
generated
|
|
@ -100,12 +100,13 @@ void _PyOpcode_RecordFunction_CODE(_PyInterpreterFrame *frame, _PyStackRef *stac
|
|||
|
||||
#define _RECORD_TOS_TYPE_INDEX 1
|
||||
#define _RECORD_NOS_INDEX 2
|
||||
#define _RECORD_3OS_GEN_FUNC_INDEX 3
|
||||
#define _RECORD_TOS_INDEX 4
|
||||
#define _RECORD_NOS_GEN_FUNC_INDEX 5
|
||||
#define _RECORD_CALLABLE_INDEX 6
|
||||
#define _RECORD_CALLABLE_KW_INDEX 7
|
||||
#define _RECORD_4OS_INDEX 8
|
||||
#define _RECORD_NOS_TYPE_INDEX 3
|
||||
#define _RECORD_3OS_GEN_FUNC_INDEX 4
|
||||
#define _RECORD_TOS_INDEX 5
|
||||
#define _RECORD_NOS_GEN_FUNC_INDEX 6
|
||||
#define _RECORD_CALLABLE_INDEX 7
|
||||
#define _RECORD_CALLABLE_KW_INDEX 8
|
||||
#define _RECORD_4OS_INDEX 9
|
||||
|
||||
const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = {
|
||||
[TO_BOOL_BOOL] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
|
|
@ -132,6 +133,9 @@ const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = {
|
|||
[BINARY_OP_SUBSCR_TUPLE_INT] = {2, {_RECORD_NOS_INDEX, _RECORD_TOS_TYPE_INDEX}},
|
||||
[BINARY_OP_SUBSCR_DICT] = {2, {_RECORD_NOS_INDEX, _RECORD_TOS_TYPE_INDEX}},
|
||||
[BINARY_OP_SUBSCR_GETITEM] = {2, {_RECORD_NOS_INDEX, _RECORD_TOS_TYPE_INDEX}},
|
||||
[STORE_SUBSCR] = {1, {_RECORD_NOS_TYPE_INDEX}},
|
||||
[STORE_SUBSCR_LIST_INT] = {1, {_RECORD_NOS_TYPE_INDEX}},
|
||||
[STORE_SUBSCR_DICT] = {1, {_RECORD_NOS_TYPE_INDEX}},
|
||||
[SEND] = {1, {_RECORD_3OS_GEN_FUNC_INDEX}},
|
||||
[SEND_GEN] = {1, {_RECORD_3OS_GEN_FUNC_INDEX}},
|
||||
[STORE_ATTR] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
|
|
@ -197,7 +201,9 @@ const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = {
|
|||
|
||||
const _PyOpcodeRecordSlotMap _PyOpcode_RecordSlotMaps[256] = {
|
||||
[TO_BOOL_ALWAYS_TRUE] = {1, 0, {0}},
|
||||
[BINARY_OP_SUBSCR_DICT] = {1, 1, {0}},
|
||||
[BINARY_OP_SUBSCR_GETITEM] = {1, 0, {0}},
|
||||
[STORE_SUBSCR_DICT] = {1, 0, {0}},
|
||||
[SEND_GEN] = {1, 0, {0}},
|
||||
[LOAD_SUPER_ATTR_METHOD] = {1, 0, {0}},
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = {1, 1, {0}},
|
||||
|
|
@ -239,10 +245,11 @@ const _PyOpcodeRecordSlotMap _PyOpcode_RecordSlotMaps[256] = {
|
|||
[BINARY_OP] = {2, 2, {1, 0}},
|
||||
};
|
||||
|
||||
const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[9] = {
|
||||
const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[10] = {
|
||||
[0] = NULL,
|
||||
[_RECORD_TOS_TYPE_INDEX] = _PyOpcode_RecordFunction_TOS_TYPE,
|
||||
[_RECORD_NOS_INDEX] = _PyOpcode_RecordFunction_NOS,
|
||||
[_RECORD_NOS_TYPE_INDEX] = _PyOpcode_RecordFunction_NOS_TYPE,
|
||||
[_RECORD_3OS_GEN_FUNC_INDEX] = _PyOpcode_RecordFunction_3OS_GEN_FUNC,
|
||||
[_RECORD_TOS_INDEX] = _PyOpcode_RecordFunction_TOS,
|
||||
[_RECORD_NOS_GEN_FUNC_INDEX] = _PyOpcode_RecordFunction_NOS_GEN_FUNC,
|
||||
|
|
|
|||
|
|
@ -1595,7 +1595,9 @@ _Py_Specialize_StoreSubscr(_PyStackRef container_st, _PyStackRef sub_st, _Py_COD
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (container_type == &PyDict_Type) {
|
||||
if (container_type->tp_as_mapping != NULL &&
|
||||
container_type->tp_as_mapping->mp_ass_subscript == _PyDict_StoreSubscript)
|
||||
{
|
||||
specialize(instr, STORE_SUBSCR_DICT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2429,7 +2431,9 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
|
|||
}
|
||||
}
|
||||
}
|
||||
if (PyAnyDict_CheckExact(lhs)) {
|
||||
if (Py_TYPE(lhs)->tp_as_mapping != NULL &&
|
||||
Py_TYPE(lhs)->tp_as_mapping->mp_subscript == _PyDict_Subscript)
|
||||
{
|
||||
specialize(instr, BINARY_OP_SUBSCR_DICT);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue