mirror of
https://github.com/python/cpython.git
synced 2025-08-02 16:13:13 +00:00
GH-128563: Generate opcode = ...
in instructions that need opcode
(GH-129608)
* Remove support for GO_TO_INSTRUCTION
This commit is contained in:
parent
808071b994
commit
75b628adeb
12 changed files with 558 additions and 172 deletions
22
Include/internal/pycore_opcode_metadata.h
generated
22
Include/internal/pycore_opcode_metadata.h
generated
|
@ -226,9 +226,9 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
|
||||||
case INSTRUMENTED_CALL:
|
case INSTRUMENTED_CALL:
|
||||||
return 2 + oparg;
|
return 2 + oparg;
|
||||||
case INSTRUMENTED_CALL_FUNCTION_EX:
|
case INSTRUMENTED_CALL_FUNCTION_EX:
|
||||||
return 0;
|
return 4;
|
||||||
case INSTRUMENTED_CALL_KW:
|
case INSTRUMENTED_CALL_KW:
|
||||||
return 0;
|
return 3 + oparg;
|
||||||
case INSTRUMENTED_END_FOR:
|
case INSTRUMENTED_END_FOR:
|
||||||
return 2;
|
return 2;
|
||||||
case INSTRUMENTED_END_SEND:
|
case INSTRUMENTED_END_SEND:
|
||||||
|
@ -244,7 +244,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
|
||||||
case INSTRUMENTED_LINE:
|
case INSTRUMENTED_LINE:
|
||||||
return 0;
|
return 0;
|
||||||
case INSTRUMENTED_LOAD_SUPER_ATTR:
|
case INSTRUMENTED_LOAD_SUPER_ATTR:
|
||||||
return 0;
|
return 3;
|
||||||
case INSTRUMENTED_NOT_TAKEN:
|
case INSTRUMENTED_NOT_TAKEN:
|
||||||
return 0;
|
return 0;
|
||||||
case INSTRUMENTED_POP_ITER:
|
case INSTRUMENTED_POP_ITER:
|
||||||
|
@ -701,9 +701,9 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
|
||||||
case INSTRUMENTED_CALL:
|
case INSTRUMENTED_CALL:
|
||||||
return 1;
|
return 1;
|
||||||
case INSTRUMENTED_CALL_FUNCTION_EX:
|
case INSTRUMENTED_CALL_FUNCTION_EX:
|
||||||
return 0;
|
return 1;
|
||||||
case INSTRUMENTED_CALL_KW:
|
case INSTRUMENTED_CALL_KW:
|
||||||
return 0;
|
return 1;
|
||||||
case INSTRUMENTED_END_FOR:
|
case INSTRUMENTED_END_FOR:
|
||||||
return 1;
|
return 1;
|
||||||
case INSTRUMENTED_END_SEND:
|
case INSTRUMENTED_END_SEND:
|
||||||
|
@ -719,7 +719,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
|
||||||
case INSTRUMENTED_LINE:
|
case INSTRUMENTED_LINE:
|
||||||
return 0;
|
return 0;
|
||||||
case INSTRUMENTED_LOAD_SUPER_ATTR:
|
case INSTRUMENTED_LOAD_SUPER_ATTR:
|
||||||
return 0;
|
return 1 + (oparg & 1);
|
||||||
case INSTRUMENTED_NOT_TAKEN:
|
case INSTRUMENTED_NOT_TAKEN:
|
||||||
return 0;
|
return 0;
|
||||||
case INSTRUMENTED_POP_ITER:
|
case INSTRUMENTED_POP_ITER:
|
||||||
|
@ -1388,7 +1388,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case INSTRUMENTED_CALL_KW: {
|
case INSTRUMENTED_CALL_KW: {
|
||||||
*effect = 0;
|
*effect = Py_MAX(0, -2 - oparg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case INSTRUMENTED_END_FOR: {
|
case INSTRUMENTED_END_FOR: {
|
||||||
|
@ -1420,7 +1420,7 @@ int _PyOpcode_max_stack_effect(int opcode, int oparg, int *effect) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case INSTRUMENTED_LOAD_SUPER_ATTR: {
|
case INSTRUMENTED_LOAD_SUPER_ATTR: {
|
||||||
*effect = 0;
|
*effect = Py_MAX(-2, -2 + (oparg & 1));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case INSTRUMENTED_NOT_TAKEN: {
|
case INSTRUMENTED_NOT_TAKEN: {
|
||||||
|
@ -2104,8 +2104,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
|
||||||
[IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, 0 },
|
[INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG },
|
[INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG },
|
||||||
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -2113,7 +2113,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
|
||||||
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | 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_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IXC, 0 },
|
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_NOT_TAKEN] = { true, INSTR_FMT_IX, 0 },
|
[INSTRUMENTED_NOT_TAKEN] = { true, INSTR_FMT_IX, 0 },
|
||||||
[INSTRUMENTED_POP_ITER] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_POP_ITER] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
|
|
72
Include/internal/pycore_uop_ids.h
generated
72
Include/internal/pycore_uop_ids.h
generated
|
@ -152,13 +152,10 @@ extern "C" {
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_2 396
|
#define _INIT_CALL_PY_EXACT_ARGS_2 396
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_3 397
|
#define _INIT_CALL_PY_EXACT_ARGS_3 397
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_4 398
|
#define _INIT_CALL_PY_EXACT_ARGS_4 398
|
||||||
#define _INSTRUMENTED_CALL_FUNCTION_EX INSTRUMENTED_CALL_FUNCTION_EX
|
|
||||||
#define _INSTRUMENTED_CALL_KW INSTRUMENTED_CALL_KW
|
|
||||||
#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
|
#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
|
||||||
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
|
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
|
||||||
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
|
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
|
||||||
#define _INSTRUMENTED_LINE INSTRUMENTED_LINE
|
#define _INSTRUMENTED_LINE INSTRUMENTED_LINE
|
||||||
#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
|
|
||||||
#define _INSTRUMENTED_NOT_TAKEN INSTRUMENTED_NOT_TAKEN
|
#define _INSTRUMENTED_NOT_TAKEN INSTRUMENTED_NOT_TAKEN
|
||||||
#define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
|
#define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
|
||||||
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
|
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
|
||||||
|
@ -242,58 +239,59 @@ extern "C" {
|
||||||
#define _MAYBE_EXPAND_METHOD 447
|
#define _MAYBE_EXPAND_METHOD 447
|
||||||
#define _MAYBE_EXPAND_METHOD_KW 448
|
#define _MAYBE_EXPAND_METHOD_KW 448
|
||||||
#define _MONITOR_CALL 449
|
#define _MONITOR_CALL 449
|
||||||
#define _MONITOR_JUMP_BACKWARD 450
|
#define _MONITOR_CALL_KW 450
|
||||||
#define _MONITOR_RESUME 451
|
#define _MONITOR_JUMP_BACKWARD 451
|
||||||
|
#define _MONITOR_RESUME 452
|
||||||
#define _NOP NOP
|
#define _NOP NOP
|
||||||
#define _POP_EXCEPT POP_EXCEPT
|
#define _POP_EXCEPT POP_EXCEPT
|
||||||
#define _POP_JUMP_IF_FALSE 452
|
#define _POP_JUMP_IF_FALSE 453
|
||||||
#define _POP_JUMP_IF_TRUE 453
|
#define _POP_JUMP_IF_TRUE 454
|
||||||
#define _POP_TOP POP_TOP
|
#define _POP_TOP POP_TOP
|
||||||
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 454
|
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 455
|
||||||
#define _PUSH_EXC_INFO PUSH_EXC_INFO
|
#define _PUSH_EXC_INFO PUSH_EXC_INFO
|
||||||
#define _PUSH_FRAME 455
|
#define _PUSH_FRAME 456
|
||||||
#define _PUSH_NULL PUSH_NULL
|
#define _PUSH_NULL PUSH_NULL
|
||||||
#define _PUSH_NULL_CONDITIONAL 456
|
#define _PUSH_NULL_CONDITIONAL 457
|
||||||
#define _PY_FRAME_GENERAL 457
|
#define _PY_FRAME_GENERAL 458
|
||||||
#define _PY_FRAME_KW 458
|
#define _PY_FRAME_KW 459
|
||||||
#define _QUICKEN_RESUME 459
|
#define _QUICKEN_RESUME 460
|
||||||
#define _REPLACE_WITH_TRUE 460
|
#define _REPLACE_WITH_TRUE 461
|
||||||
#define _RESUME_CHECK RESUME_CHECK
|
#define _RESUME_CHECK RESUME_CHECK
|
||||||
#define _RETURN_GENERATOR RETURN_GENERATOR
|
#define _RETURN_GENERATOR RETURN_GENERATOR
|
||||||
#define _RETURN_VALUE RETURN_VALUE
|
#define _RETURN_VALUE RETURN_VALUE
|
||||||
#define _SAVE_RETURN_OFFSET 461
|
#define _SAVE_RETURN_OFFSET 462
|
||||||
#define _SEND 462
|
#define _SEND 463
|
||||||
#define _SEND_GEN_FRAME 463
|
#define _SEND_GEN_FRAME 464
|
||||||
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
|
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
|
||||||
#define _SET_ADD SET_ADD
|
#define _SET_ADD SET_ADD
|
||||||
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
|
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
|
||||||
#define _SET_UPDATE SET_UPDATE
|
#define _SET_UPDATE SET_UPDATE
|
||||||
#define _START_EXECUTOR 464
|
#define _START_EXECUTOR 465
|
||||||
#define _STORE_ATTR 465
|
#define _STORE_ATTR 466
|
||||||
#define _STORE_ATTR_INSTANCE_VALUE 466
|
#define _STORE_ATTR_INSTANCE_VALUE 467
|
||||||
#define _STORE_ATTR_SLOT 467
|
#define _STORE_ATTR_SLOT 468
|
||||||
#define _STORE_ATTR_WITH_HINT 468
|
#define _STORE_ATTR_WITH_HINT 469
|
||||||
#define _STORE_DEREF STORE_DEREF
|
#define _STORE_DEREF STORE_DEREF
|
||||||
#define _STORE_FAST 469
|
#define _STORE_FAST 470
|
||||||
#define _STORE_FAST_0 470
|
#define _STORE_FAST_0 471
|
||||||
#define _STORE_FAST_1 471
|
#define _STORE_FAST_1 472
|
||||||
#define _STORE_FAST_2 472
|
#define _STORE_FAST_2 473
|
||||||
#define _STORE_FAST_3 473
|
#define _STORE_FAST_3 474
|
||||||
#define _STORE_FAST_4 474
|
#define _STORE_FAST_4 475
|
||||||
#define _STORE_FAST_5 475
|
#define _STORE_FAST_5 476
|
||||||
#define _STORE_FAST_6 476
|
#define _STORE_FAST_6 477
|
||||||
#define _STORE_FAST_7 477
|
#define _STORE_FAST_7 478
|
||||||
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
|
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
|
||||||
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
|
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
|
||||||
#define _STORE_GLOBAL STORE_GLOBAL
|
#define _STORE_GLOBAL STORE_GLOBAL
|
||||||
#define _STORE_NAME STORE_NAME
|
#define _STORE_NAME STORE_NAME
|
||||||
#define _STORE_SLICE 478
|
#define _STORE_SLICE 479
|
||||||
#define _STORE_SUBSCR 479
|
#define _STORE_SUBSCR 480
|
||||||
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
|
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
|
||||||
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
|
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
|
||||||
#define _SWAP SWAP
|
#define _SWAP SWAP
|
||||||
#define _TIER2_RESUME_CHECK 480
|
#define _TIER2_RESUME_CHECK 481
|
||||||
#define _TO_BOOL 481
|
#define _TO_BOOL 482
|
||||||
#define _TO_BOOL_BOOL TO_BOOL_BOOL
|
#define _TO_BOOL_BOOL TO_BOOL_BOOL
|
||||||
#define _TO_BOOL_INT TO_BOOL_INT
|
#define _TO_BOOL_INT TO_BOOL_INT
|
||||||
#define _TO_BOOL_LIST TO_BOOL_LIST
|
#define _TO_BOOL_LIST TO_BOOL_LIST
|
||||||
|
@ -303,13 +301,13 @@ extern "C" {
|
||||||
#define _UNARY_NEGATIVE UNARY_NEGATIVE
|
#define _UNARY_NEGATIVE UNARY_NEGATIVE
|
||||||
#define _UNARY_NOT UNARY_NOT
|
#define _UNARY_NOT UNARY_NOT
|
||||||
#define _UNPACK_EX UNPACK_EX
|
#define _UNPACK_EX UNPACK_EX
|
||||||
#define _UNPACK_SEQUENCE 482
|
#define _UNPACK_SEQUENCE 483
|
||||||
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
|
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
|
||||||
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
|
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
|
||||||
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
|
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
|
||||||
#define _WITH_EXCEPT_START WITH_EXCEPT_START
|
#define _WITH_EXCEPT_START WITH_EXCEPT_START
|
||||||
#define _YIELD_VALUE YIELD_VALUE
|
#define _YIELD_VALUE YIELD_VALUE
|
||||||
#define MAX_UOP_ID 482
|
#define MAX_UOP_ID 483
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
30
Include/opcode_ids.h
generated
30
Include/opcode_ids.h
generated
|
@ -214,21 +214,21 @@ extern "C" {
|
||||||
#define INSTRUMENTED_END_FOR 235
|
#define INSTRUMENTED_END_FOR 235
|
||||||
#define INSTRUMENTED_POP_ITER 236
|
#define INSTRUMENTED_POP_ITER 236
|
||||||
#define INSTRUMENTED_END_SEND 237
|
#define INSTRUMENTED_END_SEND 237
|
||||||
#define INSTRUMENTED_LOAD_SUPER_ATTR 238
|
#define INSTRUMENTED_FOR_ITER 238
|
||||||
#define INSTRUMENTED_FOR_ITER 239
|
#define INSTRUMENTED_INSTRUCTION 239
|
||||||
#define INSTRUMENTED_CALL_KW 240
|
#define INSTRUMENTED_JUMP_FORWARD 240
|
||||||
#define INSTRUMENTED_CALL_FUNCTION_EX 241
|
#define INSTRUMENTED_NOT_TAKEN 241
|
||||||
#define INSTRUMENTED_INSTRUCTION 242
|
#define INSTRUMENTED_POP_JUMP_IF_TRUE 242
|
||||||
#define INSTRUMENTED_JUMP_FORWARD 243
|
#define INSTRUMENTED_POP_JUMP_IF_FALSE 243
|
||||||
#define INSTRUMENTED_NOT_TAKEN 244
|
#define INSTRUMENTED_POP_JUMP_IF_NONE 244
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_TRUE 245
|
#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 245
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_FALSE 246
|
#define INSTRUMENTED_RESUME 246
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_NONE 247
|
#define INSTRUMENTED_RETURN_VALUE 247
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 248
|
#define INSTRUMENTED_YIELD_VALUE 248
|
||||||
#define INSTRUMENTED_RESUME 249
|
#define INSTRUMENTED_LOAD_SUPER_ATTR 249
|
||||||
#define INSTRUMENTED_RETURN_VALUE 250
|
#define INSTRUMENTED_CALL 250
|
||||||
#define INSTRUMENTED_YIELD_VALUE 251
|
#define INSTRUMENTED_CALL_KW 251
|
||||||
#define INSTRUMENTED_CALL 252
|
#define INSTRUMENTED_CALL_FUNCTION_EX 252
|
||||||
#define INSTRUMENTED_JUMP_BACKWARD 253
|
#define INSTRUMENTED_JUMP_BACKWARD 253
|
||||||
#define INSTRUMENTED_LINE 254
|
#define INSTRUMENTED_LINE 254
|
||||||
#define ENTER_EXECUTOR 255
|
#define ENTER_EXECUTOR 255
|
||||||
|
|
30
Lib/_opcode_metadata.py
generated
30
Lib/_opcode_metadata.py
generated
|
@ -334,21 +334,21 @@ opmap = {
|
||||||
'INSTRUMENTED_END_FOR': 235,
|
'INSTRUMENTED_END_FOR': 235,
|
||||||
'INSTRUMENTED_POP_ITER': 236,
|
'INSTRUMENTED_POP_ITER': 236,
|
||||||
'INSTRUMENTED_END_SEND': 237,
|
'INSTRUMENTED_END_SEND': 237,
|
||||||
'INSTRUMENTED_LOAD_SUPER_ATTR': 238,
|
'INSTRUMENTED_FOR_ITER': 238,
|
||||||
'INSTRUMENTED_FOR_ITER': 239,
|
'INSTRUMENTED_INSTRUCTION': 239,
|
||||||
'INSTRUMENTED_CALL_KW': 240,
|
'INSTRUMENTED_JUMP_FORWARD': 240,
|
||||||
'INSTRUMENTED_CALL_FUNCTION_EX': 241,
|
'INSTRUMENTED_NOT_TAKEN': 241,
|
||||||
'INSTRUMENTED_INSTRUCTION': 242,
|
'INSTRUMENTED_POP_JUMP_IF_TRUE': 242,
|
||||||
'INSTRUMENTED_JUMP_FORWARD': 243,
|
'INSTRUMENTED_POP_JUMP_IF_FALSE': 243,
|
||||||
'INSTRUMENTED_NOT_TAKEN': 244,
|
'INSTRUMENTED_POP_JUMP_IF_NONE': 244,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_TRUE': 245,
|
'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 245,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_FALSE': 246,
|
'INSTRUMENTED_RESUME': 246,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_NONE': 247,
|
'INSTRUMENTED_RETURN_VALUE': 247,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 248,
|
'INSTRUMENTED_YIELD_VALUE': 248,
|
||||||
'INSTRUMENTED_RESUME': 249,
|
'INSTRUMENTED_LOAD_SUPER_ATTR': 249,
|
||||||
'INSTRUMENTED_RETURN_VALUE': 250,
|
'INSTRUMENTED_CALL': 250,
|
||||||
'INSTRUMENTED_YIELD_VALUE': 251,
|
'INSTRUMENTED_CALL_KW': 251,
|
||||||
'INSTRUMENTED_CALL': 252,
|
'INSTRUMENTED_CALL_FUNCTION_EX': 252,
|
||||||
'INSTRUMENTED_JUMP_BACKWARD': 253,
|
'INSTRUMENTED_JUMP_BACKWARD': 253,
|
||||||
'JUMP': 256,
|
'JUMP': 256,
|
||||||
'JUMP_IF_FALSE': 257,
|
'JUMP_IF_FALSE': 257,
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include "ceval_macros.h"
|
#include "ceval_macros.h"
|
||||||
|
|
||||||
/* Flow control macros */
|
/* Flow control macros */
|
||||||
#define GO_TO_INSTRUCTION(instname) ((void)0)
|
|
||||||
|
|
||||||
#define inst(name, ...) case name:
|
#define inst(name, ...) case name:
|
||||||
#define op(name, ...) /* NAME is ignored */
|
#define op(name, ...) /* NAME is ignored */
|
||||||
|
@ -2019,12 +2018,10 @@ dummy_func(
|
||||||
ERROR_IF(err != 0, error);
|
ERROR_IF(err != 0, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/1 -- )) {
|
macro(INSTRUMENTED_LOAD_SUPER_ATTR) =
|
||||||
// cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
|
counter/1 +
|
||||||
// don't want to specialize instrumented instructions
|
_LOAD_SUPER_ATTR +
|
||||||
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
|
_PUSH_NULL_CONDITIONAL;
|
||||||
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
family(LOAD_SUPER_ATTR, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
|
family(LOAD_SUPER_ATTR, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
|
||||||
LOAD_SUPER_ATTR_ATTR,
|
LOAD_SUPER_ATTR_ATTR,
|
||||||
|
@ -2088,7 +2085,10 @@ dummy_func(
|
||||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro(LOAD_SUPER_ATTR) = _SPECIALIZE_LOAD_SUPER_ATTR + _LOAD_SUPER_ATTR + _PUSH_NULL_CONDITIONAL;
|
macro(LOAD_SUPER_ATTR) =
|
||||||
|
_SPECIALIZE_LOAD_SUPER_ATTR +
|
||||||
|
_LOAD_SUPER_ATTR +
|
||||||
|
_PUSH_NULL_CONDITIONAL;
|
||||||
|
|
||||||
inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st)) {
|
inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st)) {
|
||||||
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
|
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
|
||||||
|
@ -4331,18 +4331,23 @@ dummy_func(
|
||||||
CALL_KW_NON_PY,
|
CALL_KW_NON_PY,
|
||||||
};
|
};
|
||||||
|
|
||||||
inst(INSTRUMENTED_CALL_KW, (counter/1, version/2 -- )) {
|
op(_MONITOR_CALL_KW, (callable[1], self_or_null[1], args[oparg], kwnames -- callable[1], self_or_null[1], args[oparg], kwnames)) {
|
||||||
int is_meth = !PyStackRef_IsNull(PEEK(oparg + 2));
|
int is_meth = !PyStackRef_IsNull(self_or_null[0]);
|
||||||
int total_args = oparg + is_meth;
|
PyObject *arg;
|
||||||
PyObject *function = PyStackRef_AsPyObjectBorrow(PEEK(oparg + 3));
|
if (is_meth) {
|
||||||
PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING
|
arg = PyStackRef_AsPyObjectBorrow(self_or_null[0]);
|
||||||
: PyStackRef_AsPyObjectBorrow(PEEK(total_args + 1));
|
}
|
||||||
|
else if (args) {
|
||||||
|
arg = PyStackRef_AsPyObjectBorrow(args[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arg = &_PyInstrumentation_MISSING;
|
||||||
|
}
|
||||||
|
PyObject *function = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
int err = _Py_call_instrumentation_2args(
|
int err = _Py_call_instrumentation_2args(
|
||||||
tstate, PY_MONITORING_EVENT_CALL,
|
tstate, PY_MONITORING_EVENT_CALL,
|
||||||
frame, this_instr, function, arg);
|
frame, this_instr, function, arg);
|
||||||
ERROR_IF(err, error);
|
ERROR_IF(err, error);
|
||||||
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
|
|
||||||
GO_TO_INSTRUCTION(CALL_KW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_MAYBE_EXPAND_METHOD_KW, (callable[1], self_or_null[1], args[oparg], kwnames_in -- func[1], maybe_self[1], args[oparg], kwnames_out)) {
|
op(_MAYBE_EXPAND_METHOD_KW, (callable[1], self_or_null[1], args[oparg], kwnames_in -- func[1], maybe_self[1], args[oparg], kwnames_out)) {
|
||||||
|
@ -4520,6 +4525,13 @@ dummy_func(
|
||||||
_MAYBE_EXPAND_METHOD_KW +
|
_MAYBE_EXPAND_METHOD_KW +
|
||||||
_DO_CALL_KW;
|
_DO_CALL_KW;
|
||||||
|
|
||||||
|
macro(INSTRUMENTED_CALL_KW) =
|
||||||
|
counter/1 +
|
||||||
|
unused/2 +
|
||||||
|
_MONITOR_CALL_KW +
|
||||||
|
_MAYBE_EXPAND_METHOD_KW +
|
||||||
|
_DO_CALL_KW;
|
||||||
|
|
||||||
op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable[1], unused[1], unused[oparg], kwnames -- callable[1], unused[1], unused[oparg], kwnames)) {
|
op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable[1], unused[1], unused[oparg], kwnames -- callable[1], unused[1], unused[oparg], kwnames)) {
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
EXIT_IF(PyFunction_Check(callable_o));
|
EXIT_IF(PyFunction_Check(callable_o));
|
||||||
|
@ -4566,10 +4578,6 @@ dummy_func(
|
||||||
_CALL_KW_NON_PY +
|
_CALL_KW_NON_PY +
|
||||||
_CHECK_PERIODIC;
|
_CHECK_PERIODIC;
|
||||||
|
|
||||||
inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) {
|
|
||||||
GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
|
|
||||||
}
|
|
||||||
|
|
||||||
op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in -- func, unused, tuple, kwargs_out)) {
|
op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in -- func, unused, tuple, kwargs_out)) {
|
||||||
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||||
if (PyTuple_CheckExact(callargs_o)) {
|
if (PyTuple_CheckExact(callargs_o)) {
|
||||||
|
@ -4678,6 +4686,10 @@ dummy_func(
|
||||||
_DO_CALL_FUNCTION_EX +
|
_DO_CALL_FUNCTION_EX +
|
||||||
_CHECK_PERIODIC;
|
_CHECK_PERIODIC;
|
||||||
|
|
||||||
|
macro(INSTRUMENTED_CALL_FUNCTION_EX) =
|
||||||
|
_MAKE_CALLARGS_A_TUPLE +
|
||||||
|
_DO_CALL_FUNCTION_EX +
|
||||||
|
_CHECK_PERIODIC;
|
||||||
|
|
||||||
inst(MAKE_FUNCTION, (codeobj_st -- func)) {
|
inst(MAKE_FUNCTION, (codeobj_st -- func)) {
|
||||||
PyObject *codeobj = PyStackRef_AsPyObjectBorrow(codeobj_st);
|
PyObject *codeobj = PyStackRef_AsPyObjectBorrow(codeobj_st);
|
||||||
|
|
6
Python/executor_cases.c.h
generated
6
Python/executor_cases.c.h
generated
|
@ -2706,8 +2706,6 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 because it is instrumented */
|
|
||||||
|
|
||||||
case _LOAD_SUPER_ATTR_ATTR: {
|
case _LOAD_SUPER_ATTR_ATTR: {
|
||||||
_PyStackRef self_st;
|
_PyStackRef self_st;
|
||||||
_PyStackRef class_st;
|
_PyStackRef class_st;
|
||||||
|
@ -5665,7 +5663,7 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 because it is instrumented */
|
/* _MONITOR_CALL_KW is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
case _MAYBE_EXPAND_METHOD_KW: {
|
case _MAYBE_EXPAND_METHOD_KW: {
|
||||||
_PyStackRef kwnames_in;
|
_PyStackRef kwnames_in;
|
||||||
|
@ -5896,8 +5894,6 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */
|
|
||||||
|
|
||||||
case _MAKE_CALLARGS_A_TUPLE: {
|
case _MAKE_CALLARGS_A_TUPLE: {
|
||||||
_PyStackRef kwargs_in;
|
_PyStackRef kwargs_in;
|
||||||
_PyStackRef callargs;
|
_PyStackRef callargs;
|
||||||
|
|
466
Python/generated_cases.c.h
generated
466
Python/generated_cases.c.h
generated
|
@ -966,6 +966,7 @@
|
||||||
PREDICTED_CALL:;
|
PREDICTED_CALL:;
|
||||||
_Py_CODEUNIT* const this_instr = next_instr - 4;
|
_Py_CODEUNIT* const this_instr = next_instr - 4;
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
|
opcode = CALL;
|
||||||
_PyStackRef *callable;
|
_PyStackRef *callable;
|
||||||
_PyStackRef *self_or_null;
|
_PyStackRef *self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
|
@ -1744,12 +1745,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(CALL_FUNCTION_EX) {
|
TARGET(CALL_FUNCTION_EX) {
|
||||||
frame->instr_ptr = next_instr;
|
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
|
||||||
|
(void)this_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(CALL_FUNCTION_EX);
|
INSTRUCTION_STATS(CALL_FUNCTION_EX);
|
||||||
PREDICTED_CALL_FUNCTION_EX:;
|
opcode = CALL_FUNCTION_EX;
|
||||||
_Py_CODEUNIT* const this_instr = next_instr - 1;
|
|
||||||
(void)this_instr;
|
|
||||||
_PyStackRef func;
|
_PyStackRef func;
|
||||||
_PyStackRef callargs;
|
_PyStackRef callargs;
|
||||||
_PyStackRef kwargs_in;
|
_PyStackRef kwargs_in;
|
||||||
|
@ -2030,6 +2030,7 @@
|
||||||
PREDICTED_CALL_KW:;
|
PREDICTED_CALL_KW:;
|
||||||
_Py_CODEUNIT* const this_instr = next_instr - 4;
|
_Py_CODEUNIT* const this_instr = next_instr - 4;
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
|
opcode = CALL_KW;
|
||||||
_PyStackRef *callable;
|
_PyStackRef *callable;
|
||||||
_PyStackRef *self_or_null;
|
_PyStackRef *self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
|
@ -2297,6 +2298,7 @@
|
||||||
frame->instr_ptr = next_instr;
|
frame->instr_ptr = next_instr;
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(CALL_KW_NON_PY);
|
INSTRUCTION_STATS(CALL_KW_NON_PY);
|
||||||
|
opcode = CALL_KW_NON_PY;
|
||||||
static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size");
|
||||||
_PyStackRef *callable;
|
_PyStackRef *callable;
|
||||||
_PyStackRef kwnames;
|
_PyStackRef kwnames;
|
||||||
|
@ -2914,6 +2916,7 @@
|
||||||
frame->instr_ptr = next_instr;
|
frame->instr_ptr = next_instr;
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(CALL_NON_PY_GENERAL);
|
INSTRUCTION_STATS(CALL_NON_PY_GENERAL);
|
||||||
|
opcode = CALL_NON_PY_GENERAL;
|
||||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||||
_PyStackRef *callable;
|
_PyStackRef *callable;
|
||||||
_PyStackRef *self_or_null;
|
_PyStackRef *self_or_null;
|
||||||
|
@ -4045,6 +4048,7 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(ENTER_EXECUTOR);
|
INSTRUCTION_STATS(ENTER_EXECUTOR);
|
||||||
|
opcode = ENTER_EXECUTOR;
|
||||||
#ifdef _Py_TIER2
|
#ifdef _Py_TIER2
|
||||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||||
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
|
_PyExecutorObject *executor = code->co_executors->executors[oparg & 255];
|
||||||
|
@ -4097,6 +4101,7 @@
|
||||||
frame->instr_ptr = next_instr;
|
frame->instr_ptr = next_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(EXTENDED_ARG);
|
INSTRUCTION_STATS(EXTENDED_ARG);
|
||||||
|
opcode = EXTENDED_ARG;
|
||||||
assert(oparg);
|
assert(oparg);
|
||||||
opcode = next_instr->op.code;
|
opcode = next_instr->op.code;
|
||||||
oparg = oparg << 8 | next_instr->op.arg;
|
oparg = oparg << 8 | next_instr->op.arg;
|
||||||
|
@ -4646,6 +4651,7 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_CALL);
|
INSTRUCTION_STATS(INSTRUMENTED_CALL);
|
||||||
|
opcode = INSTRUMENTED_CALL;
|
||||||
_PyStackRef *callable;
|
_PyStackRef *callable;
|
||||||
_PyStackRef *self_or_null;
|
_PyStackRef *self_or_null;
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
|
@ -4815,11 +4821,188 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(INSTRUMENTED_CALL_FUNCTION_EX) {
|
TARGET(INSTRUMENTED_CALL_FUNCTION_EX) {
|
||||||
frame->instr_ptr = next_instr;
|
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
|
||||||
|
(void)this_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_CALL_FUNCTION_EX);
|
INSTRUCTION_STATS(INSTRUMENTED_CALL_FUNCTION_EX);
|
||||||
|
opcode = INSTRUMENTED_CALL_FUNCTION_EX;
|
||||||
goto PREDICTED_CALL_FUNCTION_EX;
|
_PyStackRef func;
|
||||||
|
_PyStackRef callargs;
|
||||||
|
_PyStackRef kwargs_in;
|
||||||
|
_PyStackRef tuple;
|
||||||
|
_PyStackRef kwargs_out;
|
||||||
|
_PyStackRef func_st;
|
||||||
|
_PyStackRef null;
|
||||||
|
_PyStackRef callargs_st;
|
||||||
|
_PyStackRef kwargs_st;
|
||||||
|
_PyStackRef result;
|
||||||
|
// _MAKE_CALLARGS_A_TUPLE
|
||||||
|
{
|
||||||
|
kwargs_in = stack_pointer[-1];
|
||||||
|
callargs = stack_pointer[-2];
|
||||||
|
func = stack_pointer[-4];
|
||||||
|
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||||
|
if (PyTuple_CheckExact(callargs_o)) {
|
||||||
|
tuple = callargs;
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_Check_ArgsIterable(tstate, PyStackRef_AsPyObjectBorrow(func), callargs_o);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyObject *tuple_o = PySequence_Tuple(callargs_o);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (tuple_o == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
|
stack_pointer += -2;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyStackRef_CLOSE(callargs);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
||||||
|
stack_pointer += 2;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// _DO_CALL_FUNCTION_EX
|
||||||
|
{
|
||||||
|
kwargs_st = kwargs_out;
|
||||||
|
callargs_st = tuple;
|
||||||
|
null = stack_pointer[-3];
|
||||||
|
func_st = func;
|
||||||
|
(void)null;
|
||||||
|
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
|
||||||
|
// DICT_MERGE is called before this opcode if there are kwargs.
|
||||||
|
// It converts all dict subtypes in kwargs into regular dicts.
|
||||||
|
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func);
|
||||||
|
PyObject *result_o;
|
||||||
|
assert(!_PyErr_Occurred(tstate));
|
||||||
|
if (opcode == INSTRUMENTED_CALL_FUNCTION_EX) {
|
||||||
|
PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st);
|
||||||
|
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
||||||
|
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
|
||||||
|
PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
|
||||||
|
stack_pointer[-2] = callargs_st;
|
||||||
|
stack_pointer[-1] = kwargs_st;
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_CALL,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
result_o = PyObject_Call(func, callargs, kwargs);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (!PyFunction_Check(func) && !PyMethod_Check(func)) {
|
||||||
|
if (result_o == NULL) {
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
_Py_call_instrumentation_exc2(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RAISE,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RETURN,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err < 0) {
|
||||||
|
Py_CLEAR(result_o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Py_TYPE(func) == &PyFunction_Type &&
|
||||||
|
tstate->interp->eval_frame == NULL &&
|
||||||
|
((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) {
|
||||||
|
PyObject *callargs = PyStackRef_AsPyObjectSteal(callargs_st);
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
PyObject *kwargs = PyStackRef_IsNull(kwargs_st) ? NULL : PyStackRef_AsPyObjectSteal(kwargs_st);
|
||||||
|
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||||
|
Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
|
||||||
|
int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
|
||||||
|
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
|
||||||
|
stack_pointer += -2;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(
|
||||||
|
tstate, func_st, locals,
|
||||||
|
nargs, callargs, kwargs, frame);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
// Need to sync the stack since we exit with DISPATCH_INLINED.
|
||||||
|
stack_pointer += -2;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
if (new_frame == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
assert( 1 == 1);
|
||||||
|
frame->return_offset = 1;
|
||||||
|
DISPATCH_INLINED(new_frame);
|
||||||
|
}
|
||||||
|
PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st);
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
||||||
|
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||||
|
stack_pointer[-2] = callargs_st;
|
||||||
|
stack_pointer[-1] = kwargs_st;
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
result_o = PyObject_Call(func, callargs, kwargs);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
}
|
||||||
|
stack_pointer += -1;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyStackRef_XCLOSE(kwargs_st);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
stack_pointer += -1;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyStackRef_CLOSE(callargs_st);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
stack_pointer += -2;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyStackRef_CLOSE(func_st);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (result_o == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
result = PyStackRef_FromPyObjectSteal(result_o);
|
||||||
|
}
|
||||||
|
// _CHECK_PERIODIC
|
||||||
|
{
|
||||||
|
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
|
||||||
|
QSBR_QUIESCENT_STATE(tstate);
|
||||||
|
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
|
||||||
|
stack_pointer[0] = result;
|
||||||
|
stack_pointer += 1;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_HandlePending(tstate);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err != 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
stack_pointer += -1;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack_pointer[0] = result;
|
||||||
|
stack_pointer += 1;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(INSTRUMENTED_CALL_KW) {
|
TARGET(INSTRUMENTED_CALL_KW) {
|
||||||
|
@ -4827,25 +5010,170 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_CALL_KW);
|
INSTRUCTION_STATS(INSTRUMENTED_CALL_KW);
|
||||||
uint16_t counter = read_u16(&this_instr[1].cache);
|
opcode = INSTRUMENTED_CALL_KW;
|
||||||
(void)counter;
|
_PyStackRef *callable;
|
||||||
uint32_t version = read_u32(&this_instr[2].cache);
|
_PyStackRef *self_or_null;
|
||||||
(void)version;
|
_PyStackRef *args;
|
||||||
int is_meth = !PyStackRef_IsNull(PEEK(oparg + 2));
|
_PyStackRef kwnames;
|
||||||
int total_args = oparg + is_meth;
|
_PyStackRef kwnames_in;
|
||||||
PyObject *function = PyStackRef_AsPyObjectBorrow(PEEK(oparg + 3));
|
_PyStackRef *func;
|
||||||
PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING
|
_PyStackRef *maybe_self;
|
||||||
: PyStackRef_AsPyObjectBorrow(PEEK(total_args + 1));
|
_PyStackRef kwnames_out;
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyStackRef res;
|
||||||
int err = _Py_call_instrumentation_2args(
|
/* Skip 1 cache entry */
|
||||||
tstate, PY_MONITORING_EVENT_CALL,
|
/* Skip 2 cache entries */
|
||||||
frame, this_instr, function, arg);
|
// _MONITOR_CALL_KW
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
{
|
||||||
if (err) {
|
args = &stack_pointer[-1 - oparg];
|
||||||
goto error;
|
self_or_null = &stack_pointer[-2 - oparg];
|
||||||
|
callable = &stack_pointer[-3 - oparg];
|
||||||
|
int is_meth = !PyStackRef_IsNull(self_or_null[0]);
|
||||||
|
PyObject *arg;
|
||||||
|
if (is_meth) {
|
||||||
|
arg = PyStackRef_AsPyObjectBorrow(self_or_null[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (args) {
|
||||||
|
arg = PyStackRef_AsPyObjectBorrow(args[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arg = &_PyInstrumentation_MISSING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyObject *function = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_CALL,
|
||||||
|
frame, this_instr, function, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
|
// _MAYBE_EXPAND_METHOD_KW
|
||||||
goto PREDICTED_CALL_KW;
|
{
|
||||||
|
kwnames_in = stack_pointer[-1];
|
||||||
|
func = &stack_pointer[-3 - oparg];
|
||||||
|
maybe_self = &stack_pointer[-2 - oparg];
|
||||||
|
if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
|
||||||
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||||
|
maybe_self[0] = PyStackRef_FromPyObjectNew(self);
|
||||||
|
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||||
|
_PyStackRef temp = callable[0];
|
||||||
|
func[0] = PyStackRef_FromPyObjectNew(method);
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyStackRef_CLOSE(temp);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
}
|
||||||
|
kwnames_out = kwnames_in;
|
||||||
|
}
|
||||||
|
// _DO_CALL_KW
|
||||||
|
{
|
||||||
|
kwnames = kwnames_out;
|
||||||
|
args = &stack_pointer[-1 - oparg];
|
||||||
|
self_or_null = &stack_pointer[-2 - oparg];
|
||||||
|
callable = &stack_pointer[-3 - oparg];
|
||||||
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
||||||
|
// oparg counts all of the args, but *not* self:
|
||||||
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
|
arguments--;
|
||||||
|
total_args++;
|
||||||
|
}
|
||||||
|
int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames_o);
|
||||||
|
// Check if the call can be inlined or not
|
||||||
|
if (Py_TYPE(callable_o) == &PyFunction_Type &&
|
||||||
|
tstate->interp->eval_frame == NULL &&
|
||||||
|
((PyFunctionObject *)callable_o)->vectorcall == _PyFunction_Vectorcall)
|
||||||
|
{
|
||||||
|
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable_o))->co_flags;
|
||||||
|
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
|
||||||
|
stack_pointer[-1] = kwnames;
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
||||||
|
tstate, callable[0], locals,
|
||||||
|
arguments, positional_args, kwnames_o, frame
|
||||||
|
);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
stack_pointer += -1;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyStackRef_CLOSE(kwnames);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
// Sync stack explicitly since we leave using DISPATCH_INLINED().
|
||||||
|
stack_pointer += -2 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
// The frame has stolen all the arguments from the stack,
|
||||||
|
// so there is no need to clean them up.
|
||||||
|
if (new_frame == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
assert( 4 == 1 + INLINE_CACHE_ENTRIES_CALL_KW);
|
||||||
|
frame->return_offset = 4 ;
|
||||||
|
DISPATCH_INLINED(new_frame);
|
||||||
|
}
|
||||||
|
/* Callable is not a normal Python function */
|
||||||
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
|
PyStackRef_CLOSE(args[_i]);
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(kwnames);
|
||||||
|
stack_pointer += -3 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
stack_pointer[-1] = kwnames;
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyObject *res_o = PyObject_Vectorcall(
|
||||||
|
callable_o, args_o,
|
||||||
|
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||||
|
kwnames_o);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
|
if (opcode == INSTRUMENTED_CALL_KW) {
|
||||||
|
PyObject *arg = total_args == 0 ?
|
||||||
|
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
|
||||||
|
if (res_o == NULL) {
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
_Py_call_instrumentation_exc2(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RAISE,
|
||||||
|
frame, this_instr, callable_o, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RETURN,
|
||||||
|
frame, this_instr, callable_o, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err < 0) {
|
||||||
|
Py_CLEAR(res_o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
|
PyStackRef_CLOSE(args[_i]);
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(kwnames);
|
||||||
|
if (res_o == NULL) {
|
||||||
|
stack_pointer += -3 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
|
}
|
||||||
|
stack_pointer[-3 - oparg] = res;
|
||||||
|
stack_pointer += -2 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(INSTRUMENTED_END_FOR) {
|
TARGET(INSTRUMENTED_END_FOR) {
|
||||||
|
@ -4944,6 +5272,7 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_INSTRUCTION);
|
INSTRUCTION_STATS(INSTRUMENTED_INSTRUCTION);
|
||||||
|
opcode = INSTRUMENTED_INSTRUCTION;
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int next_opcode = _Py_call_instrumentation_instruction(
|
int next_opcode = _Py_call_instrumentation_instruction(
|
||||||
tstate, frame, this_instr);
|
tstate, frame, this_instr);
|
||||||
|
@ -5001,6 +5330,7 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_LINE);
|
INSTRUCTION_STATS(INSTRUMENTED_LINE);
|
||||||
|
opcode = INSTRUMENTED_LINE;
|
||||||
int original_opcode = 0;
|
int original_opcode = 0;
|
||||||
if (tstate->tracing) {
|
if (tstate->tracing) {
|
||||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||||
|
@ -5038,11 +5368,88 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 2;
|
next_instr += 2;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_LOAD_SUPER_ATTR);
|
INSTRUCTION_STATS(INSTRUMENTED_LOAD_SUPER_ATTR);
|
||||||
|
opcode = INSTRUMENTED_LOAD_SUPER_ATTR;
|
||||||
|
_PyStackRef global_super_st;
|
||||||
|
_PyStackRef class_st;
|
||||||
|
_PyStackRef self_st;
|
||||||
|
_PyStackRef attr;
|
||||||
|
_PyStackRef null = PyStackRef_NULL;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
// cancel out the decrement that will happen in LOAD_SUPER_ATTR; we
|
// _LOAD_SUPER_ATTR
|
||||||
// don't want to specialize instrumented instructions
|
{
|
||||||
PAUSE_ADAPTIVE_COUNTER(this_instr[1].counter);
|
self_st = stack_pointer[-1];
|
||||||
goto PREDICTED_LOAD_SUPER_ATTR;
|
class_st = stack_pointer[-2];
|
||||||
|
global_super_st = stack_pointer[-3];
|
||||||
|
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
|
||||||
|
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
|
||||||
|
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
|
||||||
|
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
|
||||||
|
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_CALL,
|
||||||
|
frame, this_instr, global_super, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err) {
|
||||||
|
PyStackRef_CLOSE(global_super_st);
|
||||||
|
PyStackRef_CLOSE(class_st);
|
||||||
|
PyStackRef_CLOSE(self_st);
|
||||||
|
goto pop_3_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we make no attempt to optimize here; specializations should
|
||||||
|
// handle any case whose performance we care about
|
||||||
|
PyObject *stack[] = {class, self};
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) {
|
||||||
|
PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING;
|
||||||
|
if (super == NULL) {
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
_Py_call_instrumentation_exc2(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RAISE,
|
||||||
|
frame, this_instr, global_super, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RETURN,
|
||||||
|
frame, this_instr, global_super, arg);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (err < 0) {
|
||||||
|
Py_CLEAR(super);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(global_super_st);
|
||||||
|
PyStackRef_CLOSE(class_st);
|
||||||
|
PyStackRef_CLOSE(self_st);
|
||||||
|
if (super == NULL) {
|
||||||
|
goto pop_3_error;
|
||||||
|
}
|
||||||
|
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 2);
|
||||||
|
stack_pointer += -3;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
PyObject *attr_o = PyObject_GetAttr(super, name);
|
||||||
|
Py_DECREF(super);
|
||||||
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
if (attr_o == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
|
}
|
||||||
|
// _PUSH_NULL_CONDITIONAL
|
||||||
|
{
|
||||||
|
null = PyStackRef_NULL;
|
||||||
|
}
|
||||||
|
stack_pointer[0] = attr;
|
||||||
|
if (oparg & 1) stack_pointer[1] = null;
|
||||||
|
stack_pointer += 1 + (oparg & 1);
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(INSTRUMENTED_NOT_TAKEN) {
|
TARGET(INSTRUMENTED_NOT_TAKEN) {
|
||||||
|
@ -6862,6 +7269,7 @@
|
||||||
PREDICTED_LOAD_SUPER_ATTR:;
|
PREDICTED_LOAD_SUPER_ATTR:;
|
||||||
_Py_CODEUNIT* const this_instr = next_instr - 2;
|
_Py_CODEUNIT* const this_instr = next_instr - 2;
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
|
opcode = LOAD_SUPER_ATTR;
|
||||||
_PyStackRef global_super_st;
|
_PyStackRef global_super_st;
|
||||||
_PyStackRef class_st;
|
_PyStackRef class_st;
|
||||||
_PyStackRef self_st;
|
_PyStackRef self_st;
|
||||||
|
|
6
Python/opcode_targets.h
generated
6
Python/opcode_targets.h
generated
|
@ -237,10 +237,7 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_INSTRUMENTED_END_FOR,
|
&&TARGET_INSTRUMENTED_END_FOR,
|
||||||
&&TARGET_INSTRUMENTED_POP_ITER,
|
&&TARGET_INSTRUMENTED_POP_ITER,
|
||||||
&&TARGET_INSTRUMENTED_END_SEND,
|
&&TARGET_INSTRUMENTED_END_SEND,
|
||||||
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
|
|
||||||
&&TARGET_INSTRUMENTED_FOR_ITER,
|
&&TARGET_INSTRUMENTED_FOR_ITER,
|
||||||
&&TARGET_INSTRUMENTED_CALL_KW,
|
|
||||||
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
|
|
||||||
&&TARGET_INSTRUMENTED_INSTRUCTION,
|
&&TARGET_INSTRUMENTED_INSTRUCTION,
|
||||||
&&TARGET_INSTRUMENTED_JUMP_FORWARD,
|
&&TARGET_INSTRUMENTED_JUMP_FORWARD,
|
||||||
&&TARGET_INSTRUMENTED_NOT_TAKEN,
|
&&TARGET_INSTRUMENTED_NOT_TAKEN,
|
||||||
|
@ -251,7 +248,10 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_INSTRUMENTED_RESUME,
|
&&TARGET_INSTRUMENTED_RESUME,
|
||||||
&&TARGET_INSTRUMENTED_RETURN_VALUE,
|
&&TARGET_INSTRUMENTED_RETURN_VALUE,
|
||||||
&&TARGET_INSTRUMENTED_YIELD_VALUE,
|
&&TARGET_INSTRUMENTED_YIELD_VALUE,
|
||||||
|
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
|
||||||
&&TARGET_INSTRUMENTED_CALL,
|
&&TARGET_INSTRUMENTED_CALL,
|
||||||
|
&&TARGET_INSTRUMENTED_CALL_KW,
|
||||||
|
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
|
||||||
&&TARGET_INSTRUMENTED_JUMP_BACKWARD,
|
&&TARGET_INSTRUMENTED_JUMP_BACKWARD,
|
||||||
&&TARGET_INSTRUMENTED_LINE,
|
&&TARGET_INSTRUMENTED_LINE,
|
||||||
&&TARGET_ENTER_EXECUTOR,
|
&&TARGET_ENTER_EXECUTOR,
|
||||||
|
|
6
Python/optimizer_cases.c.h
generated
6
Python/optimizer_cases.c.h
generated
|
@ -1105,8 +1105,6 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 */
|
|
||||||
|
|
||||||
case _LOAD_SUPER_ATTR_ATTR: {
|
case _LOAD_SUPER_ATTR_ATTR: {
|
||||||
JitOptSymbol *attr_st;
|
JitOptSymbol *attr_st;
|
||||||
attr_st = sym_new_not_null(ctx);
|
attr_st = sym_new_not_null(ctx);
|
||||||
|
@ -2153,7 +2151,7 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 */
|
/* _MONITOR_CALL_KW is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _MAYBE_EXPAND_METHOD_KW: {
|
case _MAYBE_EXPAND_METHOD_KW: {
|
||||||
JitOptSymbol **func;
|
JitOptSymbol **func;
|
||||||
|
@ -2222,8 +2220,6 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 */
|
|
||||||
|
|
||||||
case _MAKE_CALLARGS_A_TUPLE: {
|
case _MAKE_CALLARGS_A_TUPLE: {
|
||||||
JitOptSymbol *tuple;
|
JitOptSymbol *tuple;
|
||||||
JitOptSymbol *kwargs_out;
|
JitOptSymbol *kwargs_out;
|
||||||
|
|
|
@ -31,6 +31,7 @@ class Properties:
|
||||||
has_free: bool
|
has_free: bool
|
||||||
side_exit: bool
|
side_exit: bool
|
||||||
pure: bool
|
pure: bool
|
||||||
|
uses_opcode: bool
|
||||||
tier: int | None = None
|
tier: int | None = None
|
||||||
oparg_and_1: bool = False
|
oparg_and_1: bool = False
|
||||||
const_oparg: int = -1
|
const_oparg: int = -1
|
||||||
|
@ -66,6 +67,7 @@ class Properties:
|
||||||
uses_co_consts=any(p.uses_co_consts for p in properties),
|
uses_co_consts=any(p.uses_co_consts for p in properties),
|
||||||
uses_co_names=any(p.uses_co_names for p in properties),
|
uses_co_names=any(p.uses_co_names for p in properties),
|
||||||
uses_locals=any(p.uses_locals for p in properties),
|
uses_locals=any(p.uses_locals for p in properties),
|
||||||
|
uses_opcode=any(p.uses_opcode for p in properties),
|
||||||
has_free=any(p.has_free for p in properties),
|
has_free=any(p.has_free for p in properties),
|
||||||
side_exit=any(p.side_exit for p in properties),
|
side_exit=any(p.side_exit for p in properties),
|
||||||
pure=all(p.pure for p in properties),
|
pure=all(p.pure for p in properties),
|
||||||
|
@ -92,6 +94,7 @@ SKIP_PROPERTIES = Properties(
|
||||||
uses_co_consts=False,
|
uses_co_consts=False,
|
||||||
uses_co_names=False,
|
uses_co_names=False,
|
||||||
uses_locals=False,
|
uses_locals=False,
|
||||||
|
uses_opcode=False,
|
||||||
has_free=False,
|
has_free=False,
|
||||||
side_exit=False,
|
side_exit=False,
|
||||||
pure=True,
|
pure=True,
|
||||||
|
@ -755,7 +758,6 @@ def find_escaping_api_calls(instr: parser.InstDef) -> dict[lexer.Token, Escaping
|
||||||
|
|
||||||
EXITS = {
|
EXITS = {
|
||||||
"DISPATCH",
|
"DISPATCH",
|
||||||
"GO_TO_INSTRUCTION",
|
|
||||||
"Py_UNREACHABLE",
|
"Py_UNREACHABLE",
|
||||||
"DISPATCH_INLINED",
|
"DISPATCH_INLINED",
|
||||||
"DISPATCH_GOTO",
|
"DISPATCH_GOTO",
|
||||||
|
@ -865,7 +867,8 @@ def compute_properties(op: parser.InstDef) -> Properties:
|
||||||
uses_co_consts=variable_used(op, "FRAME_CO_CONSTS"),
|
uses_co_consts=variable_used(op, "FRAME_CO_CONSTS"),
|
||||||
uses_co_names=variable_used(op, "FRAME_CO_NAMES"),
|
uses_co_names=variable_used(op, "FRAME_CO_NAMES"),
|
||||||
uses_locals=(variable_used(op, "GETLOCAL") or variable_used(op, "SETLOCAL"))
|
uses_locals=(variable_used(op, "GETLOCAL") or variable_used(op, "SETLOCAL"))
|
||||||
and not has_free,
|
and not has_free,
|
||||||
|
uses_opcode=variable_used(op, "opcode"),
|
||||||
has_free=has_free,
|
has_free=has_free,
|
||||||
pure="pure" in op.annotations,
|
pure="pure" in op.annotations,
|
||||||
no_save_ip="no_save_ip" in op.annotations,
|
no_save_ip="no_save_ip" in op.annotations,
|
||||||
|
@ -1200,17 +1203,6 @@ def analyze_forest(forest: list[parser.AstNode]) -> Analysis:
|
||||||
add_label(node, labels)
|
add_label(node, labels)
|
||||||
case _:
|
case _:
|
||||||
pass
|
pass
|
||||||
for uop in uops.values():
|
|
||||||
tkn_iter = iter(uop.body)
|
|
||||||
for tkn in tkn_iter:
|
|
||||||
if tkn.kind == "IDENTIFIER" and tkn.text == "GO_TO_INSTRUCTION":
|
|
||||||
if next(tkn_iter).kind != "LPAREN":
|
|
||||||
continue
|
|
||||||
target = next(tkn_iter)
|
|
||||||
if target.kind != "IDENTIFIER":
|
|
||||||
continue
|
|
||||||
if target.text in instructions:
|
|
||||||
instructions[target.text].is_target = True
|
|
||||||
for uop in uops.values():
|
for uop in uops.values():
|
||||||
uop.instruction_size = get_instruction_size_for_uop(instructions, uop)
|
uop.instruction_size = get_instruction_size_for_uop(instructions, uop)
|
||||||
# Special case BINARY_OP_INPLACE_ADD_UNICODE
|
# Special case BINARY_OP_INPLACE_ADD_UNICODE
|
||||||
|
|
|
@ -124,8 +124,7 @@ class Emitter:
|
||||||
"PyStackRef_AsPyObjectSteal": self.stackref_steal,
|
"PyStackRef_AsPyObjectSteal": self.stackref_steal,
|
||||||
"DISPATCH": self.dispatch,
|
"DISPATCH": self.dispatch,
|
||||||
"INSTRUCTION_SIZE": self.instruction_size,
|
"INSTRUCTION_SIZE": self.instruction_size,
|
||||||
"POP_INPUT": self.pop_input,
|
"POP_INPUT": self.pop_input
|
||||||
"GO_TO_INSTRUCTION": self.go_to_instruction,
|
|
||||||
}
|
}
|
||||||
self.out = out
|
self.out = out
|
||||||
|
|
||||||
|
@ -381,23 +380,6 @@ class Emitter:
|
||||||
self._print_storage(storage)
|
self._print_storage(storage)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def go_to_instruction(
|
|
||||||
self,
|
|
||||||
tkn: Token,
|
|
||||||
tkn_iter: TokenIterator,
|
|
||||||
uop: Uop,
|
|
||||||
storage: Storage,
|
|
||||||
inst: Instruction | None,
|
|
||||||
) -> bool:
|
|
||||||
next(tkn_iter)
|
|
||||||
name = next(tkn_iter)
|
|
||||||
next(tkn_iter)
|
|
||||||
next(tkn_iter)
|
|
||||||
assert name.kind == "IDENTIFIER"
|
|
||||||
self.emit("\n")
|
|
||||||
self.emit(f"goto PREDICTED_{name.text};\n")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def emit_save(self, storage: Storage) -> None:
|
def emit_save(self, storage: Storage) -> None:
|
||||||
storage.save(self.out)
|
storage.save(self.out)
|
||||||
self._print_storage(storage)
|
self._print_storage(storage)
|
||||||
|
|
|
@ -220,6 +220,8 @@ def generate_tier1_cases(
|
||||||
if needs_this:
|
if needs_this:
|
||||||
out.emit(f"_Py_CODEUNIT* const this_instr = next_instr - {inst.size};\n")
|
out.emit(f"_Py_CODEUNIT* const this_instr = next_instr - {inst.size};\n")
|
||||||
out.emit(unused_guard)
|
out.emit(unused_guard)
|
||||||
|
if inst.properties.uses_opcode:
|
||||||
|
out.emit(f"opcode = {name};\n")
|
||||||
if inst.family is not None:
|
if inst.family is not None:
|
||||||
out.emit(
|
out.emit(
|
||||||
f"static_assert({inst.family.size} == {inst.size-1}"
|
f"static_assert({inst.family.size} == {inst.size-1}"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue