mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
GH-111848: Set the IP when de-optimizing (GH-112065)
* Replace jumps with deopts in tier 2 * Fewer special cases of uop names * Add target field to uop IR * Remove more redundant SET_IP and _CHECK_VALIDITY micro-ops * Extend whitelist of non-escaping API functions.
This commit is contained in:
parent
0cfdd6e3d1
commit
4bbb367ba6
6 changed files with 118 additions and 98 deletions
104
Include/internal/pycore_opcode_metadata.h
generated
104
Include/internal/pycore_opcode_metadata.h
generated
|
@ -1469,7 +1469,7 @@ extern const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SI
|
||||||
const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[NOP] = { true, INSTR_FMT_IX, 0 },
|
[NOP] = { true, INSTR_FMT_IX, 0 },
|
||||||
[RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_CLOSURE] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
|
[LOAD_CLOSURE] = { true, 0, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
|
||||||
[LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG },
|
[LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG },
|
||||||
|
@ -1488,24 +1488,24 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[END_SEND] = { true, INSTR_FMT_IX, 0 },
|
[END_SEND] = { true, INSTR_FMT_IX, 0 },
|
||||||
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[UNARY_NOT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[UNARY_NOT] = { true, INSTR_FMT_IX, 0 },
|
||||||
[_SPECIALIZE_TO_BOOL] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
|
[_SPECIALIZE_TO_BOOL] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
|
||||||
[_TO_BOOL] = { true, INSTR_FMT_IXC0, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_TO_BOOL] = { true, INSTR_FMT_IXC0, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
[TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
||||||
[TO_BOOL_INT] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[TO_BOOL_INT] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
||||||
[TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
[TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
||||||
[TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
||||||
[TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
||||||
[TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
[TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, HAS_DEOPT_FLAG },
|
||||||
[UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_GUARD_BOTH_INT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_GUARD_BOTH_INT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
|
||||||
[_BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
|
||||||
[_BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
|
||||||
[_GUARD_BOTH_FLOAT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_GUARD_BOTH_FLOAT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, 0 },
|
[_BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, 0 },
|
||||||
[_BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, 0 },
|
[_BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, 0 },
|
||||||
|
@ -1528,7 +1528,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
|
[BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
|
||||||
[BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
|
||||||
[SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_SPECIALIZE_STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
|
[_SPECIALIZE_STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ESCAPES_FLAG },
|
||||||
[_STORE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_STORE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1558,16 +1558,16 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX, 0 },
|
||||||
[LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[DELETE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[DELETE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_SPECIALIZE_UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_SPECIALIZE_UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_UNPACK_SEQUENCE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_UNPACK_SEQUENCE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_SPECIALIZE_STORE_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
|
[_SPECIALIZE_STORE_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_STORE_ATTR] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_STORE_ATTR] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1593,7 +1593,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG },
|
[STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[COPY_FREE_VARS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[COPY_FREE_VARS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[BUILD_STRING] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BUILD_STRING] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[BUILD_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BUILD_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1632,8 +1632,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[_LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
[_LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
[LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_CHECK_ATTR_CLASS] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
|
[_CHECK_ATTR_CLASS] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
|
||||||
[_LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
|
||||||
[LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_GUARD_DORV_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_GUARD_DORV_VALUES] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
|
@ -1648,7 +1648,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[CONTAINS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CONTAINS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1658,14 +1658,14 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[JUMP] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
[JUMP] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[JUMP_NO_INTERRUPT] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
[JUMP_NO_INTERRUPT] = { true, 0, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
|
||||||
[_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ESCAPES_FLAG },
|
[_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ESCAPES_FLAG },
|
[_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[_IS_NONE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[_IS_NONE] = { true, INSTR_FMT_IX, 0 },
|
||||||
[POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ESCAPES_FLAG },
|
[POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ESCAPES_FLAG },
|
[POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ESCAPES_FLAG },
|
[POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ESCAPES_FLAG },
|
[POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
[JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1681,13 +1681,13 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[_ITER_CHECK_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_ITER_CHECK_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_ITER_JUMP_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
[_ITER_JUMP_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[_GUARD_NOT_EXHAUSTED_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_GUARD_NOT_EXHAUSTED_LIST] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_ITER_NEXT_LIST] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[_ITER_NEXT_LIST] = { true, INSTR_FMT_IX, 0 },
|
||||||
[FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_ITER_CHECK_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_ITER_CHECK_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_ITER_JUMP_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
[_ITER_JUMP_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[_GUARD_NOT_EXHAUSTED_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_GUARD_NOT_EXHAUSTED_TUPLE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_ITER_NEXT_TUPLE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[_ITER_NEXT_TUPLE] = { true, INSTR_FMT_IX, 0 },
|
||||||
[FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_ITER_CHECK_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_ITER_CHECK_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_ITER_JUMP_RANGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
[_ITER_JUMP_RANGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[_GUARD_NOT_EXHAUSTED_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_GUARD_NOT_EXHAUSTED_RANGE] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
|
@ -1701,17 +1701,17 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[SETUP_CLEANUP] = { true, 0, 0 },
|
[SETUP_CLEANUP] = { true, 0, 0 },
|
||||||
[SETUP_WITH] = { true, 0, 0 },
|
[SETUP_WITH] = { true, 0, 0 },
|
||||||
[POP_BLOCK] = { true, 0, 0 },
|
[POP_BLOCK] = { true, 0, 0 },
|
||||||
[PUSH_EXC_INFO] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[PUSH_EXC_INFO] = { true, INSTR_FMT_IX, 0 },
|
||||||
[_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_GUARD_KEYS_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
|
[_GUARD_KEYS_VERSION] = { true, INSTR_FMT_IXC0, HAS_DEOPT_FLAG },
|
||||||
[_LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
|
||||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG },
|
||||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_CHECK_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[_CHECK_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1720,16 +1720,16 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[_CALL] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[_CALL] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[_CHECK_PEP_523] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[_CHECK_PEP_523] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_CHECK_FUNCTION_EXACT_ARGS] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
[_CHECK_FUNCTION_EXACT_ARGS] = { true, INSTR_FMT_IBC0, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_CHECK_STACK_SPACE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[_CHECK_STACK_SPACE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[_INIT_CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_INIT_CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_PUSH_FRAME] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[_PUSH_FRAME] = { true, INSTR_FMT_IX, 0 },
|
||||||
[CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1740,7 +1740,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
|
||||||
[CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1756,7 +1756,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[CONVERT_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
|
[CONVERT_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
|
||||||
[FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[COPY] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[COPY] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[_SPECIALIZE_BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_SPECIALIZE_BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_BINARY_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
|
[_BINARY_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1764,17 +1764,17 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
||||||
[INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG },
|
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
[EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[CACHE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[CACHE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
||||||
[RESERVED] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[RESERVED] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
||||||
[_GUARD_IS_TRUE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[_GUARD_IS_TRUE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_GUARD_IS_FALSE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[_GUARD_IS_FALSE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_GUARD_IS_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[_GUARD_IS_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_GUARD_IS_NOT_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
[_GUARD_IS_NOT_NONE_POP] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[_JUMP_TO_TOP] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG },
|
[_JUMP_TO_TOP] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG },
|
||||||
[_SET_IP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[_SET_IP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[_SAVE_RETURN_OFFSET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[_SAVE_RETURN_OFFSET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
|
|
|
@ -13,8 +13,9 @@ extern "C" {
|
||||||
#define _Py_UOP_MAX_TRACE_LENGTH 128
|
#define _Py_UOP_MAX_TRACE_LENGTH 128
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t opcode;
|
uint16_t opcode;
|
||||||
uint32_t oparg;
|
uint16_t oparg;
|
||||||
|
uint32_t target;
|
||||||
uint64_t operand; // A cache entry
|
uint64_t operand; // A cache entry
|
||||||
} _PyUOpInstruction;
|
} _PyUOpInstruction;
|
||||||
|
|
||||||
|
|
|
@ -1067,6 +1067,7 @@ deoptimize:
|
||||||
UOP_STAT_INC(opcode, miss);
|
UOP_STAT_INC(opcode, miss);
|
||||||
frame->return_offset = 0; // Dispatch to frame->instr_ptr
|
frame->return_offset = 0; // Dispatch to frame->instr_ptr
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
frame->instr_ptr = next_uop[-1].target + _PyCode_CODE((PyCodeObject *)frame->f_executable);
|
||||||
Py_DECREF(current_executor);
|
Py_DECREF(current_executor);
|
||||||
// Fall through
|
// Fall through
|
||||||
// Jump here from ENTER_EXECUTOR
|
// Jump here from ENTER_EXECUTOR
|
||||||
|
@ -1077,6 +1078,7 @@ enter_tier_one:
|
||||||
// Jump here from _EXIT_TRACE
|
// Jump here from _EXIT_TRACE
|
||||||
exit_trace:
|
exit_trace:
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
frame->instr_ptr = next_uop[-1].target + _PyCode_CODE((PyCodeObject *)frame->f_executable);
|
||||||
Py_DECREF(current_executor);
|
Py_DECREF(current_executor);
|
||||||
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
|
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
|
||||||
goto enter_tier_one;
|
goto enter_tier_one;
|
||||||
|
|
|
@ -446,7 +446,8 @@ translate_bytecode_to_trace(
|
||||||
#define DPRINTF(level, ...)
|
#define DPRINTF(level, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND) \
|
|
||||||
|
#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND, TARGET) \
|
||||||
DPRINTF(2, \
|
DPRINTF(2, \
|
||||||
" ADD_TO_TRACE(%s, %d, %" PRIu64 ")\n", \
|
" ADD_TO_TRACE(%s, %d, %" PRIu64 ")\n", \
|
||||||
uop_name(OPCODE), \
|
uop_name(OPCODE), \
|
||||||
|
@ -458,23 +459,12 @@ translate_bytecode_to_trace(
|
||||||
trace[trace_length].opcode = (OPCODE); \
|
trace[trace_length].opcode = (OPCODE); \
|
||||||
trace[trace_length].oparg = (OPARG); \
|
trace[trace_length].oparg = (OPARG); \
|
||||||
trace[trace_length].operand = (OPERAND); \
|
trace[trace_length].operand = (OPERAND); \
|
||||||
|
trace[trace_length].target = (TARGET); \
|
||||||
trace_length++;
|
trace_length++;
|
||||||
|
|
||||||
#define INSTR_IP(INSTR, CODE) \
|
#define INSTR_IP(INSTR, CODE) \
|
||||||
((uint32_t)((INSTR) - ((_Py_CODEUNIT *)(CODE)->co_code_adaptive)))
|
((uint32_t)((INSTR) - ((_Py_CODEUNIT *)(CODE)->co_code_adaptive)))
|
||||||
|
|
||||||
#define ADD_TO_STUB(INDEX, OPCODE, OPARG, OPERAND) \
|
|
||||||
DPRINTF(2, " ADD_TO_STUB(%d, %s, %d, %" PRIu64 ")\n", \
|
|
||||||
(INDEX), \
|
|
||||||
uop_name(OPCODE), \
|
|
||||||
(OPARG), \
|
|
||||||
(uint64_t)(OPERAND)); \
|
|
||||||
assert(reserved > 0); \
|
|
||||||
reserved--; \
|
|
||||||
trace[(INDEX)].opcode = (OPCODE); \
|
|
||||||
trace[(INDEX)].oparg = (OPARG); \
|
|
||||||
trace[(INDEX)].operand = (OPERAND);
|
|
||||||
|
|
||||||
// Reserve space for n uops
|
// Reserve space for n uops
|
||||||
#define RESERVE_RAW(n, opname) \
|
#define RESERVE_RAW(n, opname) \
|
||||||
if (trace_length + (n) > max_length) { \
|
if (trace_length + (n) > max_length) { \
|
||||||
|
@ -483,7 +473,7 @@ translate_bytecode_to_trace(
|
||||||
OPT_STAT_INC(trace_too_long); \
|
OPT_STAT_INC(trace_too_long); \
|
||||||
goto done; \
|
goto done; \
|
||||||
} \
|
} \
|
||||||
reserved = (n); // Keep ADD_TO_TRACE / ADD_TO_STUB honest
|
reserved = (n); // Keep ADD_TO_TRACE honest
|
||||||
|
|
||||||
// Reserve space for main+stub uops, plus 3 for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
|
// Reserve space for main+stub uops, plus 3 for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
|
||||||
#define RESERVE(main, stub) RESERVE_RAW((main) + (stub) + 3, uop_name(opcode))
|
#define RESERVE(main, stub) RESERVE_RAW((main) + (stub) + 3, uop_name(opcode))
|
||||||
|
@ -493,7 +483,7 @@ translate_bytecode_to_trace(
|
||||||
if (trace_stack_depth >= TRACE_STACK_SIZE) { \
|
if (trace_stack_depth >= TRACE_STACK_SIZE) { \
|
||||||
DPRINTF(2, "Trace stack overflow\n"); \
|
DPRINTF(2, "Trace stack overflow\n"); \
|
||||||
OPT_STAT_INC(trace_stack_overflow); \
|
OPT_STAT_INC(trace_stack_overflow); \
|
||||||
ADD_TO_TRACE(_SET_IP, 0, 0); \
|
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0); \
|
||||||
goto done; \
|
goto done; \
|
||||||
} \
|
} \
|
||||||
trace_stack[trace_stack_depth].code = code; \
|
trace_stack[trace_stack_depth].code = code; \
|
||||||
|
@ -513,22 +503,28 @@ translate_bytecode_to_trace(
|
||||||
PyUnicode_AsUTF8(code->co_filename),
|
PyUnicode_AsUTF8(code->co_filename),
|
||||||
code->co_firstlineno,
|
code->co_firstlineno,
|
||||||
2 * INSTR_IP(initial_instr, code));
|
2 * INSTR_IP(initial_instr, code));
|
||||||
|
uint32_t target = 0;
|
||||||
top: // Jump here after _PUSH_FRAME or likely branches
|
top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
target = INSTR_IP(instr, code);
|
||||||
RESERVE_RAW(3, "epilogue"); // Always need space for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
|
RESERVE_RAW(3, "epilogue"); // Always need space for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE
|
||||||
ADD_TO_TRACE(_SET_IP, INSTR_IP(instr, code), 0);
|
ADD_TO_TRACE(_SET_IP, target, 0, target);
|
||||||
ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0);
|
ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target);
|
||||||
|
|
||||||
uint32_t opcode = instr->op.code;
|
uint32_t opcode = instr->op.code;
|
||||||
uint32_t oparg = instr->op.arg;
|
uint32_t oparg = instr->op.arg;
|
||||||
uint32_t extras = 0;
|
uint32_t extras = 0;
|
||||||
|
|
||||||
while (opcode == EXTENDED_ARG) {
|
|
||||||
|
if (opcode == EXTENDED_ARG) {
|
||||||
instr++;
|
instr++;
|
||||||
extras += 1;
|
extras += 1;
|
||||||
opcode = instr->op.code;
|
opcode = instr->op.code;
|
||||||
oparg = (oparg << 8) | instr->op.arg;
|
oparg = (oparg << 8) | instr->op.arg;
|
||||||
|
if (opcode == EXTENDED_ARG) {
|
||||||
|
instr--;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode == ENTER_EXECUTOR) {
|
if (opcode == ENTER_EXECUTOR) {
|
||||||
|
@ -554,7 +550,7 @@ top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
DPRINTF(4, "%s(%d): counter=%x, bitcount=%d, likely=%d, uopcode=%s\n",
|
DPRINTF(4, "%s(%d): counter=%x, bitcount=%d, likely=%d, uopcode=%s\n",
|
||||||
uop_name(opcode), oparg,
|
uop_name(opcode), oparg,
|
||||||
counter, bitcount, jump_likely, uop_name(uopcode));
|
counter, bitcount, jump_likely, uop_name(uopcode));
|
||||||
ADD_TO_TRACE(uopcode, max_length, 0);
|
ADD_TO_TRACE(uopcode, max_length, 0, target);
|
||||||
if (jump_likely) {
|
if (jump_likely) {
|
||||||
_Py_CODEUNIT *target_instr = next_instr + oparg;
|
_Py_CODEUNIT *target_instr = next_instr + oparg;
|
||||||
DPRINTF(2, "Jump likely (%x = %d bits), continue at byte offset %d\n",
|
DPRINTF(2, "Jump likely (%x = %d bits), continue at byte offset %d\n",
|
||||||
|
@ -569,7 +565,7 @@ top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
{
|
{
|
||||||
if (instr + 2 - oparg == initial_instr && code == initial_code) {
|
if (instr + 2 - oparg == initial_instr && code == initial_code) {
|
||||||
RESERVE(1, 0);
|
RESERVE(1, 0);
|
||||||
ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0);
|
ADD_TO_TRACE(_JUMP_TO_TOP, 0, 0, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
OPT_STAT_INC(inner_loop);
|
OPT_STAT_INC(inner_loop);
|
||||||
|
@ -653,7 +649,7 @@ top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
expansion->uops[i].offset);
|
expansion->uops[i].offset);
|
||||||
Py_FatalError("garbled expansion");
|
Py_FatalError("garbled expansion");
|
||||||
}
|
}
|
||||||
ADD_TO_TRACE(uop, oparg, operand);
|
ADD_TO_TRACE(uop, oparg, operand, target);
|
||||||
if (uop == _POP_FRAME) {
|
if (uop == _POP_FRAME) {
|
||||||
TRACE_STACK_POP();
|
TRACE_STACK_POP();
|
||||||
DPRINTF(2,
|
DPRINTF(2,
|
||||||
|
@ -682,7 +678,7 @@ top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
PyUnicode_AsUTF8(new_code->co_filename),
|
PyUnicode_AsUTF8(new_code->co_filename),
|
||||||
new_code->co_firstlineno);
|
new_code->co_firstlineno);
|
||||||
OPT_STAT_INC(recursive_call);
|
OPT_STAT_INC(recursive_call);
|
||||||
ADD_TO_TRACE(_SET_IP, 0, 0);
|
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (new_code->co_version != func_version) {
|
if (new_code->co_version != func_version) {
|
||||||
|
@ -690,7 +686,7 @@ top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
// Perhaps it may happen again, so don't bother tracing.
|
// Perhaps it may happen again, so don't bother tracing.
|
||||||
// TODO: Reason about this -- is it better to bail or not?
|
// TODO: Reason about this -- is it better to bail or not?
|
||||||
DPRINTF(2, "Bailing because co_version != func_version\n");
|
DPRINTF(2, "Bailing because co_version != func_version\n");
|
||||||
ADD_TO_TRACE(_SET_IP, 0, 0);
|
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
// Increment IP to the return address
|
// Increment IP to the return address
|
||||||
|
@ -707,7 +703,7 @@ top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
2 * INSTR_IP(instr, code));
|
2 * INSTR_IP(instr, code));
|
||||||
goto top;
|
goto top;
|
||||||
}
|
}
|
||||||
ADD_TO_TRACE(_SET_IP, 0, 0);
|
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, 0);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -732,7 +728,7 @@ done:
|
||||||
assert(code == initial_code);
|
assert(code == initial_code);
|
||||||
// Skip short traces like _SET_IP, LOAD_FAST, _SET_IP, _EXIT_TRACE
|
// Skip short traces like _SET_IP, LOAD_FAST, _SET_IP, _EXIT_TRACE
|
||||||
if (trace_length > 4) {
|
if (trace_length > 4) {
|
||||||
ADD_TO_TRACE(_EXIT_TRACE, 0, 0);
|
ADD_TO_TRACE(_EXIT_TRACE, 0, 0, target);
|
||||||
DPRINTF(1,
|
DPRINTF(1,
|
||||||
"Created a trace for %s (%s:%d) at byte offset %d -- length %d+%d\n",
|
"Created a trace for %s (%s:%d) at byte offset %d -- length %d+%d\n",
|
||||||
PyUnicode_AsUTF8(code->co_qualname),
|
PyUnicode_AsUTF8(code->co_qualname),
|
||||||
|
|
|
@ -17,21 +17,15 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
|
||||||
{
|
{
|
||||||
// Note that we don't enter stubs, those SET_IPs are needed.
|
// Note that we don't enter stubs, those SET_IPs are needed.
|
||||||
int last_set_ip = -1;
|
int last_set_ip = -1;
|
||||||
bool need_ip = true;
|
|
||||||
bool maybe_invalid = false;
|
bool maybe_invalid = false;
|
||||||
for (int pc = 0; pc < buffer_size; pc++) {
|
for (int pc = 0; pc < buffer_size; pc++) {
|
||||||
int opcode = buffer[pc].opcode;
|
int opcode = buffer[pc].opcode;
|
||||||
if (opcode == _SET_IP) {
|
if (opcode == _SET_IP) {
|
||||||
if (!need_ip && last_set_ip >= 0) {
|
buffer[pc].opcode = NOP;
|
||||||
buffer[last_set_ip].opcode = NOP;
|
|
||||||
}
|
|
||||||
need_ip = false;
|
|
||||||
last_set_ip = pc;
|
last_set_ip = pc;
|
||||||
}
|
}
|
||||||
else if (opcode == _CHECK_VALIDITY) {
|
else if (opcode == _CHECK_VALIDITY) {
|
||||||
if (maybe_invalid) {
|
if (maybe_invalid) {
|
||||||
/* Exiting the trace requires that IP is correct */
|
|
||||||
need_ip = true;
|
|
||||||
maybe_invalid = false;
|
maybe_invalid = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -42,12 +36,16 @@ remove_unneeded_uops(_PyUOpInstruction *buffer, int buffer_size)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If opcode has ERROR or DEOPT, set need_ip to true
|
if (OPCODE_HAS_ESCAPES(opcode)) {
|
||||||
if (_PyOpcode_opcode_metadata[opcode].flags & (HAS_ERROR_FLAG | HAS_DEOPT_FLAG) || opcode == _PUSH_FRAME) {
|
|
||||||
need_ip = true;
|
|
||||||
}
|
|
||||||
if (_PyOpcode_opcode_metadata[opcode].flags & HAS_ESCAPES_FLAG) {
|
|
||||||
maybe_invalid = true;
|
maybe_invalid = true;
|
||||||
|
if (last_set_ip >= 0) {
|
||||||
|
buffer[last_set_ip].opcode = _SET_IP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (OPCODE_HAS_ERROR(opcode) || opcode == _PUSH_FRAME) {
|
||||||
|
if (last_set_ip >= 0) {
|
||||||
|
buffer[last_set_ip].opcode = _SET_IP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import lexer as lx
|
||||||
import parsing
|
import parsing
|
||||||
from typing import AbstractSet
|
from typing import AbstractSet
|
||||||
|
|
||||||
WHITELIST = (
|
NON_ESCAPING_FUNCTIONS = (
|
||||||
"Py_INCREF",
|
"Py_INCREF",
|
||||||
"_PyDictOrValues_IsValues",
|
"_PyDictOrValues_IsValues",
|
||||||
"_PyObject_DictOrValuesPointer",
|
"_PyObject_DictOrValuesPointer",
|
||||||
|
@ -31,9 +31,29 @@ WHITELIST = (
|
||||||
"_PyLong_IsNonNegativeCompact",
|
"_PyLong_IsNonNegativeCompact",
|
||||||
"_PyLong_CompactValue",
|
"_PyLong_CompactValue",
|
||||||
"_Py_NewRef",
|
"_Py_NewRef",
|
||||||
|
"_Py_IsImmortal",
|
||||||
|
"_Py_STR",
|
||||||
|
"_PyLong_Add",
|
||||||
|
"_PyLong_Multiply",
|
||||||
|
"_PyLong_Subtract",
|
||||||
|
"Py_NewRef",
|
||||||
|
"_PyList_ITEMS",
|
||||||
|
"_PyTuple_ITEMS",
|
||||||
|
"_PyList_AppendTakeRef",
|
||||||
|
"_Py_atomic_load_uintptr_relaxed",
|
||||||
|
"_PyFrame_GetCode",
|
||||||
|
"_PyThreadState_HasStackSpace",
|
||||||
)
|
)
|
||||||
|
|
||||||
def makes_escaping_api_call(instr: parsing.Node) -> bool:
|
ESCAPING_FUNCTIONS = (
|
||||||
|
"import_name",
|
||||||
|
"import_from",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def makes_escaping_api_call(instr: parsing.InstDef) -> bool:
|
||||||
|
if "CALL_INTRINSIC" in instr.name:
|
||||||
|
return True;
|
||||||
tkns = iter(instr.tokens)
|
tkns = iter(instr.tokens)
|
||||||
for tkn in tkns:
|
for tkn in tkns:
|
||||||
if tkn.kind != lx.IDENTIFIER:
|
if tkn.kind != lx.IDENTIFIER:
|
||||||
|
@ -44,13 +64,17 @@ def makes_escaping_api_call(instr: parsing.Node) -> bool:
|
||||||
return False
|
return False
|
||||||
if next_tkn.kind != lx.LPAREN:
|
if next_tkn.kind != lx.LPAREN:
|
||||||
continue
|
continue
|
||||||
|
if tkn.text in ESCAPING_FUNCTIONS:
|
||||||
|
return True
|
||||||
if not tkn.text.startswith("Py") and not tkn.text.startswith("_Py"):
|
if not tkn.text.startswith("Py") and not tkn.text.startswith("_Py"):
|
||||||
continue
|
continue
|
||||||
if tkn.text.endswith("Check"):
|
if tkn.text.endswith("Check"):
|
||||||
continue
|
continue
|
||||||
|
if tkn.text.startswith("Py_Is"):
|
||||||
|
continue
|
||||||
if tkn.text.endswith("CheckExact"):
|
if tkn.text.endswith("CheckExact"):
|
||||||
continue
|
continue
|
||||||
if tkn.text in WHITELIST:
|
if tkn.text in NON_ESCAPING_FUNCTIONS:
|
||||||
continue
|
continue
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -74,7 +98,7 @@ class InstructionFlags:
|
||||||
self.bitmask = {name: (1 << i) for i, name in enumerate(self.names())}
|
self.bitmask = {name: (1 << i) for i, name in enumerate(self.names())}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fromInstruction(instr: parsing.Node) -> "InstructionFlags":
|
def fromInstruction(instr: parsing.InstDef) -> "InstructionFlags":
|
||||||
has_free = (
|
has_free = (
|
||||||
variable_used(instr, "PyCell_New")
|
variable_used(instr, "PyCell_New")
|
||||||
or variable_used(instr, "PyCell_GET")
|
or variable_used(instr, "PyCell_GET")
|
||||||
|
@ -101,8 +125,7 @@ class InstructionFlags:
|
||||||
or variable_used(instr, "resume_with_error")
|
or variable_used(instr, "resume_with_error")
|
||||||
),
|
),
|
||||||
HAS_ESCAPES_FLAG=(
|
HAS_ESCAPES_FLAG=(
|
||||||
variable_used(instr, "tstate")
|
makes_escaping_api_call(instr)
|
||||||
or makes_escaping_api_call(instr)
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue