diff --git a/Include/opcode.h b/Include/opcode.h index f22f7e94f6190c..d670b11e66a2fe 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -112,6 +112,8 @@ extern "C" { #define DICT_MERGE 164 #define DICT_UPDATE 165 #define CALL_METHOD_KW 166 +#define START_FUNCTION 167 +#define RETURN_VALUE_QUICK 168 #define BINARY_OP_ADAPTIVE 7 #define BINARY_OP_ADD_INT 8 #define BINARY_OP_ADD_FLOAT 13 diff --git a/Lib/opcode.py b/Lib/opcode.py index e5889bca4c161c..4992e8509dbe33 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -193,6 +193,9 @@ def jabs_op(name, op): def_op('DICT_UPDATE', 165) def_op('CALL_METHOD_KW', 166) +def_op('START_FUNCTION', 167) # Check for tracing/profiling +def_op('RETURN_VALUE_QUICK', 168) # RETURN_VALUE without tracing/profiling checks + del def_op, name_op, jrel_op, jabs_op _nb_ops = [ diff --git a/Python/ceval.c b/Python/ceval.c index 05897c561a16ec..77fe1d663094e0 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1537,10 +1537,11 @@ eval_frame_handle_pending(PyThreadState *tstate) STAT_INC(LOAD_##attr_or_method, hit); \ Py_INCREF(res); -#define TRACE_FUNCTION_EXIT() \ +#define TRACE_FUNCTION_EXIT(return_value) \ if (cframe.use_tracing) { \ - if (trace_function_exit(tstate, frame, retval)) { \ - Py_DECREF(retval); \ + PyObject *trace_retval = (return_value); \ + if (trace_function_exit(tstate, frame, trace_retval)) { \ + Py_DECREF(trace_retval); \ goto exit_unwind; \ } \ } @@ -1668,7 +1669,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr int opcode; /* Current opcode */ int oparg; /* Current opcode argument, if any */ _Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker; - CFrame cframe; /* WARNING: Because the CFrame lives on the C stack, @@ -1734,12 +1734,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr assert(tstate->cframe == &cframe); assert(frame == cframe.current_frame); - TRACE_FUNCTION_ENTRY(); - DTRACE_FUNCTION_ENTRY(); - - if (_Py_IncrementCountAndMaybeQuicken(frame->f_code) < 0) { - goto exit_unwind; - } frame->f_state = FRAME_EXECUTING; resume_frame: @@ -1826,6 +1820,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr DISPATCH(); } + TARGET(START_FUNCTION) { + TRACE_FUNCTION_ENTRY(); + DTRACE_FUNCTION_ENTRY(); + + if (_Py_IncrementCountAndMaybeQuicken(frame->f_code) < 0) { + goto exit_unwind; + } + + DISPATCH(); + } + TARGET(LOAD_CLOSURE) { /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */ PyObject *value = GETLOCAL(oparg); @@ -2314,6 +2319,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr new_frame->previous = frame; frame = cframe.current_frame = new_frame; new_frame->depth = frame->depth + 1; + /* FIXME(lpereira): We're not tracing anymore by jumping to this label. */ goto start_frame; } @@ -2472,13 +2478,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr goto error; } - TARGET(RETURN_VALUE) { + TARGET(RETURN_VALUE_QUICK) + return_value_without_tracing: { PyObject *retval = POP(); assert(EMPTY()); frame->f_state = FRAME_RETURNED; _PyFrame_SetStackPointer(frame, stack_pointer); - TRACE_FUNCTION_EXIT(); - DTRACE_FUNCTION_EXIT(); _Py_LeaveRecursiveCall(tstate); if (frame->depth) { frame = cframe.current_frame = pop_frame(tstate, frame); @@ -2493,6 +2498,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr return retval; } + TARGET(RETURN_VALUE) { + frame->f_state = FRAME_RETURNED; + /* FIXME(lpereira): The stack pointer and f_state will be set to the same + * value here, and when jumping to return_value_without_tracing above. This + * is redundant, but saves us from copying some code. */ + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + TRACE_FUNCTION_EXIT(TOP()); + DTRACE_FUNCTION_EXIT(); + goto return_value_without_tracing; + } + TARGET(GET_AITER) { unaryfunc getter = NULL; PyObject *iter = NULL; @@ -2680,7 +2696,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr frame->f_lasti -= 1; frame->f_state = FRAME_SUSPENDED; _PyFrame_SetStackPointer(frame, stack_pointer); - TRACE_FUNCTION_EXIT(); + TRACE_FUNCTION_EXIT(retval); DTRACE_FUNCTION_EXIT(); _Py_LeaveRecursiveCall(tstate); /* Restore previous cframe and return. */ @@ -2706,7 +2722,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr } frame->f_state = FRAME_SUSPENDED; _PyFrame_SetStackPointer(frame, stack_pointer); - TRACE_FUNCTION_EXIT(); + TRACE_FUNCTION_EXIT(retval); DTRACE_FUNCTION_EXIT(); _Py_LeaveRecursiveCall(tstate); /* Restore previous cframe and return. */ @@ -4672,6 +4688,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr new_frame->previous = frame; cframe.current_frame = frame = new_frame; new_frame->depth = frame->depth + 1; + /* FIXME(lpereira): We're not tracing anymore by jumping to this label. */ goto start_frame; } } @@ -4761,6 +4778,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr new_frame->previous = frame; frame = cframe.current_frame = new_frame; new_frame->depth = frame->depth + 1; + /* FIXME(lpereira): We're not tracing anymore by jumping to this label. */ goto start_frame; } diff --git a/Python/compile.c b/Python/compile.c index 87de7baab4819e..98d5d61299bc02 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -993,6 +993,7 @@ stack_effect(int opcode, int oparg, int jump) { switch (opcode) { case NOP: + case START_FUNCTION: case EXTENDED_ARG: return 0; @@ -2365,7 +2366,7 @@ compiler_check_debug_args(struct compiler *c, arguments_ty args) } static int -compiler_function(struct compiler *c, stmt_ty s, int is_async) +compiler_function(struct compiler *c, stmt_ty s) { PyCodeObject *co; PyObject *qualname, *docstring = NULL; @@ -2379,9 +2380,8 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) int scope_type; int firstlineno; - if (is_async) { - assert(s->kind == AsyncFunctionDef_kind); - + switch (s->kind) { + case AsyncFunctionDef_kind: args = s->v.AsyncFunctionDef.args; returns = s->v.AsyncFunctionDef.returns; decos = s->v.AsyncFunctionDef.decorator_list; @@ -2389,9 +2389,8 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) body = s->v.AsyncFunctionDef.body; scope_type = COMPILER_SCOPE_ASYNC_FUNCTION; - } else { - assert(s->kind == FunctionDef_kind); - + break; + case FunctionDef_kind: args = s->v.FunctionDef.args; returns = s->v.FunctionDef.returns; decos = s->v.FunctionDef.decorator_list; @@ -2399,6 +2398,9 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) body = s->v.FunctionDef.body; scope_type = COMPILER_SCOPE_FUNCTION; + break; + default: + Py_UNREACHABLE(); } if (!compiler_check_debug_args(c, args)) @@ -2438,6 +2440,8 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) return 0; } + ADDOP(c, START_FUNCTION); + c->u->u_argcount = asdl_seq_LEN(args->args); c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); @@ -3571,8 +3575,9 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) SET_LOC(c, s); switch (s->kind) { + case AsyncFunctionDef_kind: case FunctionDef_kind: - return compiler_function(c, s, 0); + return compiler_function(c, s); case ClassDef_kind: return compiler_class(c, s); case Return_kind: @@ -3637,8 +3642,6 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) return compiler_continue(c); case With_kind: return compiler_with(c, s, 0); - case AsyncFunctionDef_kind: - return compiler_function(c, s, 1); case AsyncWith_kind: return compiler_async_with(c, s, 0); case AsyncFor_kind: diff --git a/Python/makeopcodetargets.py b/Python/makeopcodetargets.py index 3bf2e35ccb6dab..e86e7b5181acc9 100755 --- a/Python/makeopcodetargets.py +++ b/Python/makeopcodetargets.py @@ -40,8 +40,9 @@ def write_contents(f): while targets[next_op] != '_unknown_opcode': next_op += 1 targets[next_op] = "TARGET_%s" % opname - f.write("static void *opcode_targets[256] = {\n") - f.write(",\n".join([" &&%s" % s for s in targets])) + f.write("/* Automatically generated by makeopcodetargets.py. Do not edit! */\n") + f.write("static const void *opcode_targets[256] = {\n") + f.write(",\n".join([" [%d] = &&%s" % (index, s) for index, s in enumerate(targets)])) f.write("\n};\n") diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 872a6883119926..a005e3d7fbfbcd 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -1,258 +1,259 @@ -static void *opcode_targets[256] = { - &&_unknown_opcode, - &&TARGET_POP_TOP, - &&TARGET_ROT_TWO, - &&TARGET_ROT_THREE, - &&TARGET_DUP_TOP, - &&TARGET_DUP_TOP_TWO, - &&TARGET_ROT_FOUR, - &&TARGET_BINARY_OP_ADAPTIVE, - &&TARGET_BINARY_OP_ADD_INT, - &&TARGET_NOP, - &&TARGET_UNARY_POSITIVE, - &&TARGET_UNARY_NEGATIVE, - &&TARGET_UNARY_NOT, - &&TARGET_BINARY_OP_ADD_FLOAT, - &&TARGET_BINARY_OP_ADD_UNICODE, - &&TARGET_UNARY_INVERT, - &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, - &&TARGET_BINARY_OP_MULTIPLY_INT, - &&TARGET_BINARY_OP_MULTIPLY_FLOAT, - &&TARGET_BINARY_OP_SUBTRACT_INT, - &&TARGET_BINARY_OP_SUBTRACT_FLOAT, - &&TARGET_COMPARE_OP_ADAPTIVE, - &&TARGET_COMPARE_OP_FLOAT_JUMP, - &&TARGET_COMPARE_OP_INT_JUMP, - &&TARGET_COMPARE_OP_STR_JUMP, - &&TARGET_BINARY_SUBSCR, - &&TARGET_BINARY_SUBSCR_ADAPTIVE, - &&TARGET_BINARY_SUBSCR_GETITEM, - &&TARGET_BINARY_SUBSCR_LIST_INT, - &&TARGET_BINARY_SUBSCR_TUPLE_INT, - &&TARGET_GET_LEN, - &&TARGET_MATCH_MAPPING, - &&TARGET_MATCH_SEQUENCE, - &&TARGET_MATCH_KEYS, - &&TARGET_BINARY_SUBSCR_DICT, - &&TARGET_PUSH_EXC_INFO, - &&TARGET_STORE_SUBSCR_ADAPTIVE, - &&TARGET_POP_EXCEPT_AND_RERAISE, - &&TARGET_STORE_SUBSCR_LIST_INT, - &&TARGET_STORE_SUBSCR_DICT, - &&TARGET_CALL_FUNCTION_ADAPTIVE, - &&TARGET_CALL_FUNCTION_BUILTIN_O, - &&TARGET_CALL_FUNCTION_BUILTIN_FAST, - &&TARGET_CALL_FUNCTION_LEN, - &&TARGET_CALL_FUNCTION_ISINSTANCE, - &&TARGET_CALL_FUNCTION_PY_SIMPLE, - &&TARGET_JUMP_ABSOLUTE_QUICK, - &&TARGET_LOAD_ATTR_ADAPTIVE, - &&TARGET_LOAD_ATTR_INSTANCE_VALUE, - &&TARGET_WITH_EXCEPT_START, - &&TARGET_GET_AITER, - &&TARGET_GET_ANEXT, - &&TARGET_BEFORE_ASYNC_WITH, - &&TARGET_BEFORE_WITH, - &&TARGET_END_ASYNC_FOR, - &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_ATTR_SLOT, - &&TARGET_LOAD_ATTR_MODULE, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, - &&TARGET_LOAD_GLOBAL_MODULE, - &&TARGET_STORE_SUBSCR, - &&TARGET_DELETE_SUBSCR, - &&TARGET_LOAD_GLOBAL_BUILTIN, - &&TARGET_LOAD_METHOD_ADAPTIVE, - &&TARGET_LOAD_METHOD_CACHED, - &&TARGET_LOAD_METHOD_CLASS, - &&TARGET_LOAD_METHOD_MODULE, - &&TARGET_LOAD_METHOD_NO_DICT, - &&TARGET_GET_ITER, - &&TARGET_GET_YIELD_FROM_ITER, - &&TARGET_PRINT_EXPR, - &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_YIELD_FROM, - &&TARGET_GET_AWAITABLE, - &&TARGET_LOAD_ASSERTION_ERROR, - &&TARGET_STORE_ATTR_ADAPTIVE, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, - &&TARGET_STORE_ATTR_SLOT, - &&TARGET_STORE_ATTR_WITH_HINT, - &&TARGET_LOAD_FAST__LOAD_FAST, - &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LOAD_FAST__LOAD_CONST, - &&TARGET_LIST_TO_TUPLE, - &&TARGET_RETURN_VALUE, - &&TARGET_IMPORT_STAR, - &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_YIELD_VALUE, - &&TARGET_LOAD_CONST__LOAD_FAST, - &&TARGET_STORE_FAST__STORE_FAST, - &&TARGET_POP_EXCEPT, - &&TARGET_STORE_NAME, - &&TARGET_DELETE_NAME, - &&TARGET_UNPACK_SEQUENCE, - &&TARGET_FOR_ITER, - &&TARGET_UNPACK_EX, - &&TARGET_STORE_ATTR, - &&TARGET_DELETE_ATTR, - &&TARGET_STORE_GLOBAL, - &&TARGET_DELETE_GLOBAL, - &&TARGET_ROT_N, - &&TARGET_LOAD_CONST, - &&TARGET_LOAD_NAME, - &&TARGET_BUILD_TUPLE, - &&TARGET_BUILD_LIST, - &&TARGET_BUILD_SET, - &&TARGET_BUILD_MAP, - &&TARGET_LOAD_ATTR, - &&TARGET_COMPARE_OP, - &&TARGET_IMPORT_NAME, - &&TARGET_IMPORT_FROM, - &&TARGET_JUMP_FORWARD, - &&TARGET_JUMP_IF_FALSE_OR_POP, - &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_JUMP_ABSOLUTE, - &&TARGET_POP_JUMP_IF_FALSE, - &&TARGET_POP_JUMP_IF_TRUE, - &&TARGET_LOAD_GLOBAL, - &&TARGET_IS_OP, - &&TARGET_CONTAINS_OP, - &&TARGET_RERAISE, - &&TARGET_COPY, - &&TARGET_JUMP_IF_NOT_EXC_MATCH, - &&TARGET_BINARY_OP, - &&_unknown_opcode, - &&TARGET_LOAD_FAST, - &&TARGET_STORE_FAST, - &&TARGET_DELETE_FAST, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_GEN_START, - &&TARGET_RAISE_VARARGS, - &&TARGET_CALL_FUNCTION, - &&TARGET_MAKE_FUNCTION, - &&TARGET_BUILD_SLICE, - &&_unknown_opcode, - &&TARGET_MAKE_CELL, - &&TARGET_LOAD_CLOSURE, - &&TARGET_LOAD_DEREF, - &&TARGET_STORE_DEREF, - &&TARGET_DELETE_DEREF, - &&_unknown_opcode, - &&TARGET_CALL_FUNCTION_KW, - &&TARGET_CALL_FUNCTION_EX, - &&_unknown_opcode, - &&TARGET_EXTENDED_ARG, - &&TARGET_LIST_APPEND, - &&TARGET_SET_ADD, - &&TARGET_MAP_ADD, - &&TARGET_LOAD_CLASSDEREF, - &&TARGET_COPY_FREE_VARS, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_MATCH_CLASS, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_FORMAT_VALUE, - &&TARGET_BUILD_CONST_KEY_MAP, - &&TARGET_BUILD_STRING, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_LOAD_METHOD, - &&TARGET_CALL_METHOD, - &&TARGET_LIST_EXTEND, - &&TARGET_SET_UPDATE, - &&TARGET_DICT_MERGE, - &&TARGET_DICT_UPDATE, - &&TARGET_CALL_METHOD_KW, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_DO_TRACING +/* Automatically generated by makeopcodetargets.py. Do not edit! */ +static const void *opcode_targets[256] = { + [0] = &&_unknown_opcode, + [1] = &&TARGET_POP_TOP, + [2] = &&TARGET_ROT_TWO, + [3] = &&TARGET_ROT_THREE, + [4] = &&TARGET_DUP_TOP, + [5] = &&TARGET_DUP_TOP_TWO, + [6] = &&TARGET_ROT_FOUR, + [7] = &&TARGET_BINARY_OP_ADAPTIVE, + [8] = &&TARGET_BINARY_OP_ADD_INT, + [9] = &&TARGET_NOP, + [10] = &&TARGET_UNARY_POSITIVE, + [11] = &&TARGET_UNARY_NEGATIVE, + [12] = &&TARGET_UNARY_NOT, + [13] = &&TARGET_BINARY_OP_ADD_FLOAT, + [14] = &&TARGET_BINARY_OP_ADD_UNICODE, + [15] = &&TARGET_UNARY_INVERT, + [16] = &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, + [17] = &&TARGET_BINARY_OP_MULTIPLY_INT, + [18] = &&TARGET_BINARY_OP_MULTIPLY_FLOAT, + [19] = &&TARGET_BINARY_OP_SUBTRACT_INT, + [20] = &&TARGET_BINARY_OP_SUBTRACT_FLOAT, + [21] = &&TARGET_COMPARE_OP_ADAPTIVE, + [22] = &&TARGET_COMPARE_OP_FLOAT_JUMP, + [23] = &&TARGET_COMPARE_OP_INT_JUMP, + [24] = &&TARGET_COMPARE_OP_STR_JUMP, + [25] = &&TARGET_BINARY_SUBSCR, + [26] = &&TARGET_BINARY_SUBSCR_ADAPTIVE, + [27] = &&TARGET_BINARY_SUBSCR_GETITEM, + [28] = &&TARGET_BINARY_SUBSCR_LIST_INT, + [29] = &&TARGET_BINARY_SUBSCR_TUPLE_INT, + [30] = &&TARGET_GET_LEN, + [31] = &&TARGET_MATCH_MAPPING, + [32] = &&TARGET_MATCH_SEQUENCE, + [33] = &&TARGET_MATCH_KEYS, + [34] = &&TARGET_BINARY_SUBSCR_DICT, + [35] = &&TARGET_PUSH_EXC_INFO, + [36] = &&TARGET_STORE_SUBSCR_ADAPTIVE, + [37] = &&TARGET_POP_EXCEPT_AND_RERAISE, + [38] = &&TARGET_STORE_SUBSCR_LIST_INT, + [39] = &&TARGET_STORE_SUBSCR_DICT, + [40] = &&TARGET_CALL_FUNCTION_ADAPTIVE, + [41] = &&TARGET_CALL_FUNCTION_BUILTIN_O, + [42] = &&TARGET_CALL_FUNCTION_BUILTIN_FAST, + [43] = &&TARGET_CALL_FUNCTION_LEN, + [44] = &&TARGET_CALL_FUNCTION_ISINSTANCE, + [45] = &&TARGET_CALL_FUNCTION_PY_SIMPLE, + [46] = &&TARGET_JUMP_ABSOLUTE_QUICK, + [47] = &&TARGET_LOAD_ATTR_ADAPTIVE, + [48] = &&TARGET_LOAD_ATTR_INSTANCE_VALUE, + [49] = &&TARGET_WITH_EXCEPT_START, + [50] = &&TARGET_GET_AITER, + [51] = &&TARGET_GET_ANEXT, + [52] = &&TARGET_BEFORE_ASYNC_WITH, + [53] = &&TARGET_BEFORE_WITH, + [54] = &&TARGET_END_ASYNC_FOR, + [55] = &&TARGET_LOAD_ATTR_WITH_HINT, + [56] = &&TARGET_LOAD_ATTR_SLOT, + [57] = &&TARGET_LOAD_ATTR_MODULE, + [58] = &&TARGET_LOAD_GLOBAL_ADAPTIVE, + [59] = &&TARGET_LOAD_GLOBAL_MODULE, + [60] = &&TARGET_STORE_SUBSCR, + [61] = &&TARGET_DELETE_SUBSCR, + [62] = &&TARGET_LOAD_GLOBAL_BUILTIN, + [63] = &&TARGET_LOAD_METHOD_ADAPTIVE, + [64] = &&TARGET_LOAD_METHOD_CACHED, + [65] = &&TARGET_LOAD_METHOD_CLASS, + [66] = &&TARGET_LOAD_METHOD_MODULE, + [67] = &&TARGET_LOAD_METHOD_NO_DICT, + [68] = &&TARGET_GET_ITER, + [69] = &&TARGET_GET_YIELD_FROM_ITER, + [70] = &&TARGET_PRINT_EXPR, + [71] = &&TARGET_LOAD_BUILD_CLASS, + [72] = &&TARGET_YIELD_FROM, + [73] = &&TARGET_GET_AWAITABLE, + [74] = &&TARGET_LOAD_ASSERTION_ERROR, + [75] = &&TARGET_STORE_ATTR_ADAPTIVE, + [76] = &&TARGET_STORE_ATTR_INSTANCE_VALUE, + [77] = &&TARGET_STORE_ATTR_SLOT, + [78] = &&TARGET_STORE_ATTR_WITH_HINT, + [79] = &&TARGET_LOAD_FAST__LOAD_FAST, + [80] = &&TARGET_STORE_FAST__LOAD_FAST, + [81] = &&TARGET_LOAD_FAST__LOAD_CONST, + [82] = &&TARGET_LIST_TO_TUPLE, + [83] = &&TARGET_RETURN_VALUE, + [84] = &&TARGET_IMPORT_STAR, + [85] = &&TARGET_SETUP_ANNOTATIONS, + [86] = &&TARGET_YIELD_VALUE, + [87] = &&TARGET_LOAD_CONST__LOAD_FAST, + [88] = &&TARGET_STORE_FAST__STORE_FAST, + [89] = &&TARGET_POP_EXCEPT, + [90] = &&TARGET_STORE_NAME, + [91] = &&TARGET_DELETE_NAME, + [92] = &&TARGET_UNPACK_SEQUENCE, + [93] = &&TARGET_FOR_ITER, + [94] = &&TARGET_UNPACK_EX, + [95] = &&TARGET_STORE_ATTR, + [96] = &&TARGET_DELETE_ATTR, + [97] = &&TARGET_STORE_GLOBAL, + [98] = &&TARGET_DELETE_GLOBAL, + [99] = &&TARGET_ROT_N, + [100] = &&TARGET_LOAD_CONST, + [101] = &&TARGET_LOAD_NAME, + [102] = &&TARGET_BUILD_TUPLE, + [103] = &&TARGET_BUILD_LIST, + [104] = &&TARGET_BUILD_SET, + [105] = &&TARGET_BUILD_MAP, + [106] = &&TARGET_LOAD_ATTR, + [107] = &&TARGET_COMPARE_OP, + [108] = &&TARGET_IMPORT_NAME, + [109] = &&TARGET_IMPORT_FROM, + [110] = &&TARGET_JUMP_FORWARD, + [111] = &&TARGET_JUMP_IF_FALSE_OR_POP, + [112] = &&TARGET_JUMP_IF_TRUE_OR_POP, + [113] = &&TARGET_JUMP_ABSOLUTE, + [114] = &&TARGET_POP_JUMP_IF_FALSE, + [115] = &&TARGET_POP_JUMP_IF_TRUE, + [116] = &&TARGET_LOAD_GLOBAL, + [117] = &&TARGET_IS_OP, + [118] = &&TARGET_CONTAINS_OP, + [119] = &&TARGET_RERAISE, + [120] = &&TARGET_COPY, + [121] = &&TARGET_JUMP_IF_NOT_EXC_MATCH, + [122] = &&TARGET_BINARY_OP, + [123] = &&_unknown_opcode, + [124] = &&TARGET_LOAD_FAST, + [125] = &&TARGET_STORE_FAST, + [126] = &&TARGET_DELETE_FAST, + [127] = &&_unknown_opcode, + [128] = &&_unknown_opcode, + [129] = &&TARGET_GEN_START, + [130] = &&TARGET_RAISE_VARARGS, + [131] = &&TARGET_CALL_FUNCTION, + [132] = &&TARGET_MAKE_FUNCTION, + [133] = &&TARGET_BUILD_SLICE, + [134] = &&_unknown_opcode, + [135] = &&TARGET_MAKE_CELL, + [136] = &&TARGET_LOAD_CLOSURE, + [137] = &&TARGET_LOAD_DEREF, + [138] = &&TARGET_STORE_DEREF, + [139] = &&TARGET_DELETE_DEREF, + [140] = &&_unknown_opcode, + [141] = &&TARGET_CALL_FUNCTION_KW, + [142] = &&TARGET_CALL_FUNCTION_EX, + [143] = &&_unknown_opcode, + [144] = &&TARGET_EXTENDED_ARG, + [145] = &&TARGET_LIST_APPEND, + [146] = &&TARGET_SET_ADD, + [147] = &&TARGET_MAP_ADD, + [148] = &&TARGET_LOAD_CLASSDEREF, + [149] = &&TARGET_COPY_FREE_VARS, + [150] = &&_unknown_opcode, + [151] = &&_unknown_opcode, + [152] = &&TARGET_MATCH_CLASS, + [153] = &&_unknown_opcode, + [154] = &&_unknown_opcode, + [155] = &&TARGET_FORMAT_VALUE, + [156] = &&TARGET_BUILD_CONST_KEY_MAP, + [157] = &&TARGET_BUILD_STRING, + [158] = &&_unknown_opcode, + [159] = &&_unknown_opcode, + [160] = &&TARGET_LOAD_METHOD, + [161] = &&TARGET_CALL_METHOD, + [162] = &&TARGET_LIST_EXTEND, + [163] = &&TARGET_SET_UPDATE, + [164] = &&TARGET_DICT_MERGE, + [165] = &&TARGET_DICT_UPDATE, + [166] = &&TARGET_CALL_METHOD_KW, + [167] = &&TARGET_START_FUNCTION, + [168] = &&TARGET_RETURN_VALUE_QUICK, + [169] = &&_unknown_opcode, + [170] = &&_unknown_opcode, + [171] = &&_unknown_opcode, + [172] = &&_unknown_opcode, + [173] = &&_unknown_opcode, + [174] = &&_unknown_opcode, + [175] = &&_unknown_opcode, + [176] = &&_unknown_opcode, + [177] = &&_unknown_opcode, + [178] = &&_unknown_opcode, + [179] = &&_unknown_opcode, + [180] = &&_unknown_opcode, + [181] = &&_unknown_opcode, + [182] = &&_unknown_opcode, + [183] = &&_unknown_opcode, + [184] = &&_unknown_opcode, + [185] = &&_unknown_opcode, + [186] = &&_unknown_opcode, + [187] = &&_unknown_opcode, + [188] = &&_unknown_opcode, + [189] = &&_unknown_opcode, + [190] = &&_unknown_opcode, + [191] = &&_unknown_opcode, + [192] = &&_unknown_opcode, + [193] = &&_unknown_opcode, + [194] = &&_unknown_opcode, + [195] = &&_unknown_opcode, + [196] = &&_unknown_opcode, + [197] = &&_unknown_opcode, + [198] = &&_unknown_opcode, + [199] = &&_unknown_opcode, + [200] = &&_unknown_opcode, + [201] = &&_unknown_opcode, + [202] = &&_unknown_opcode, + [203] = &&_unknown_opcode, + [204] = &&_unknown_opcode, + [205] = &&_unknown_opcode, + [206] = &&_unknown_opcode, + [207] = &&_unknown_opcode, + [208] = &&_unknown_opcode, + [209] = &&_unknown_opcode, + [210] = &&_unknown_opcode, + [211] = &&_unknown_opcode, + [212] = &&_unknown_opcode, + [213] = &&_unknown_opcode, + [214] = &&_unknown_opcode, + [215] = &&_unknown_opcode, + [216] = &&_unknown_opcode, + [217] = &&_unknown_opcode, + [218] = &&_unknown_opcode, + [219] = &&_unknown_opcode, + [220] = &&_unknown_opcode, + [221] = &&_unknown_opcode, + [222] = &&_unknown_opcode, + [223] = &&_unknown_opcode, + [224] = &&_unknown_opcode, + [225] = &&_unknown_opcode, + [226] = &&_unknown_opcode, + [227] = &&_unknown_opcode, + [228] = &&_unknown_opcode, + [229] = &&_unknown_opcode, + [230] = &&_unknown_opcode, + [231] = &&_unknown_opcode, + [232] = &&_unknown_opcode, + [233] = &&_unknown_opcode, + [234] = &&_unknown_opcode, + [235] = &&_unknown_opcode, + [236] = &&_unknown_opcode, + [237] = &&_unknown_opcode, + [238] = &&_unknown_opcode, + [239] = &&_unknown_opcode, + [240] = &&_unknown_opcode, + [241] = &&_unknown_opcode, + [242] = &&_unknown_opcode, + [243] = &&_unknown_opcode, + [244] = &&_unknown_opcode, + [245] = &&_unknown_opcode, + [246] = &&_unknown_opcode, + [247] = &&_unknown_opcode, + [248] = &&_unknown_opcode, + [249] = &&_unknown_opcode, + [250] = &&_unknown_opcode, + [251] = &&_unknown_opcode, + [252] = &&_unknown_opcode, + [253] = &&_unknown_opcode, + [254] = &&_unknown_opcode, + [255] = &&TARGET_DO_TRACING }; diff --git a/Python/specialize.c b/Python/specialize.c index b384675560be79..f7e9d181bc30de 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -130,6 +130,8 @@ _Py_GetSpecializationStats(void) { err += add_stat_dict(stats, CALL_FUNCTION, "call_function"); err += add_stat_dict(stats, BINARY_OP, "binary_op"); err += add_stat_dict(stats, COMPARE_OP, "compare_op"); + err += add_stat_dict(stats, START_FUNCTION, "start_function"); + err += add_stat_dict(stats, RETURN_VALUE, "return_value"); if (err < 0) { Py_DECREF(stats); return NULL; @@ -189,6 +191,8 @@ _Py_PrintSpecializationStats(void) print_stats(out, &_specialization_stats[CALL_FUNCTION], "call_function"); print_stats(out, &_specialization_stats[BINARY_OP], "binary_op"); print_stats(out, &_specialization_stats[COMPARE_OP], "compare_op"); + print_stats(out, &_specialization_stats[START_FUNCTION], "start_function"); + print_stats(out, &_specialization_stats[RETURN_VALUE], "return_value"); if (out != stderr) { fclose(out); } @@ -232,7 +236,7 @@ get_cache_count(SpecializedCacheOrInstruction *quickened) { /* Map from opcode to adaptive opcode. Values of zero are ignored. */ -static uint8_t adaptive_opcodes[256] = { +static const uint8_t adaptive_opcodes[256] = { [LOAD_ATTR] = LOAD_ATTR_ADAPTIVE, [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, [LOAD_METHOD] = LOAD_METHOD_ADAPTIVE, @@ -242,10 +246,11 @@ static uint8_t adaptive_opcodes[256] = { [STORE_ATTR] = STORE_ATTR_ADAPTIVE, [BINARY_OP] = BINARY_OP_ADAPTIVE, [COMPARE_OP] = COMPARE_OP_ADAPTIVE, + [START_FUNCTION] = NOP, }; /* The number of cache entries required for a "family" of instructions. */ -static uint8_t cache_requirements[256] = { +static const uint8_t cache_requirements[256] = { [LOAD_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */ [LOAD_GLOBAL] = 2, /* _PyAdaptiveEntry and _PyLoadGlobalCache */ [LOAD_METHOD] = 3, /* _PyAdaptiveEntry, _PyAttrCache and _PyObjectCache */ @@ -253,8 +258,8 @@ static uint8_t cache_requirements[256] = { [STORE_SUBSCR] = 0, [CALL_FUNCTION] = 2, /* _PyAdaptiveEntry and _PyObjectCache/_PyCallCache */ [STORE_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */ - [BINARY_OP] = 1, // _PyAdaptiveEntry [COMPARE_OP] = 1, /* _PyAdaptiveEntry */ + [BINARY_OP] = 1, /* _PyAdaptiveEntry */ }; /* Return the oparg for the cache_offset and instruction index. @@ -358,6 +363,12 @@ optimize(SpecializedCacheOrInstruction *quickened, int len) /* Super instructions don't use the cache, * so no need to update the offset. */ switch (opcode) { + case START_FUNCTION: + instructions[i] = _Py_MAKECODEUNIT(NOP, 0); + break; + case RETURN_VALUE: + instructions[i] = _Py_MAKECODEUNIT(RETURN_VALUE_QUICK, oparg); + break; case JUMP_ABSOLUTE: instructions[i] = _Py_MAKECODEUNIT(JUMP_ABSOLUTE_QUICK, oparg); break;