diff options
author | Mark Shannon <mark@hotpy.org> | 2022-02-18 17:19:08 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-18 17:19:08 (GMT) |
commit | cf345e945f48f54785799390c2e92c5310847bd4 (patch) | |
tree | af28be223953ba50ff6d0c5110af7a8c2a6c4f84 /Python | |
parent | e2c28616ce6c3cdb1013c415125220a0b86b86a1 (diff) | |
download | cpython-cf345e945f48f54785799390c2e92c5310847bd4.zip cpython-cf345e945f48f54785799390c2e92c5310847bd4.tar.gz cpython-cf345e945f48f54785799390c2e92c5310847bd4.tar.bz2 |
bpo-46329: Change calling sequence (again) (GH-31373)
* Change calling sequence: Add PUSH_NULL. Merge PRECALL_FUNCTION and PRECALL_METHOD into PRECALL.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 32 | ||||
-rw-r--r-- | Python/compile.c | 32 | ||||
-rw-r--r-- | Python/opcode_targets.h | 38 | ||||
-rw-r--r-- | Python/specialize.c | 5 |
4 files changed, 49 insertions, 58 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 5a6de5b..471bbde 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1584,7 +1584,7 @@ pop_frame(PyThreadState *tstate, InterpreterFrame *frame) return prev_frame; } -/* It is only between a PRECALL_METHOD/FUNCTION instruction and the following CALL, +/* It is only between the PRECALL instruction and the following CALL, * that these values have any meaning. */ typedef struct { @@ -1872,6 +1872,12 @@ handle_eval_breaker: DISPATCH(); } + TARGET(PUSH_NULL) { + /* Use BASIC_PUSH as NULL is not a valid object pointer */ + BASIC_PUSH(NULL); + DISPATCH(); + } + TARGET(UNARY_POSITIVE) { PyObject *value = TOP(); PyObject *res = PyNumber_Positive(value); @@ -4476,25 +4482,7 @@ handle_eval_breaker: NOTRACE_DISPATCH(); } - TARGET(PRECALL_FUNCTION) { - /* Move ownership of reference from stack to call_shape */ - call_shape.callable = PEEK(oparg + 1); - call_shape.postcall_shrink = 1; - - call_shape.total_args = oparg; - assert(call_shape.kwnames == NULL); -#ifdef Py_STATS - extern int _PySpecialization_ClassifyCallable(PyObject *); - SpecializationStats *stats = - &_py_stats.opcode_stats[PRECALL_FUNCTION].specialization; - stats->failure++; - int kind = _PySpecialization_ClassifyCallable(call_shape.callable); - stats->failure_kinds[kind]++; -#endif - DISPATCH(); - } - - TARGET(PRECALL_METHOD) { + TARGET(PRECALL) { /* Designed to work in tamdem with LOAD_METHOD. */ /* `meth` is NULL when LOAD_METHOD thinks that it's not a method call. @@ -4533,7 +4521,7 @@ handle_eval_breaker: #ifdef Py_STATS extern int _PySpecialization_ClassifyCallable(PyObject *); SpecializationStats *stats = - &_py_stats.opcode_stats[PRECALL_METHOD].specialization; + &_py_stats.opcode_stats[PRECALL].specialization; stats->failure++; int kind = _PySpecialization_ClassifyCallable(call_shape.callable); stats->failure_kinds[kind]++; @@ -5118,6 +5106,8 @@ handle_eval_breaker: Py_DECREF(callargs); Py_XDECREF(kwargs); + STACK_SHRINK(1); + assert(TOP() == NULL); SET_TOP(result); if (result == NULL) { goto error; diff --git a/Python/compile.c b/Python/compile.c index 786ef4e..645213b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1012,17 +1012,15 @@ stack_effect(int opcode, int oparg, int jump) return -oparg; /* Functions and calls */ - case PRECALL_METHOD: - return -oparg-1; - case PRECALL_FUNCTION: + case PRECALL: return -oparg; case KW_NAMES: return 0; case CALL: - return 0; + return -1; case CALL_FUNCTION_EX: - return -1 - ((oparg & 0x01) != 0); + return -2 - ((oparg & 0x01) != 0); case MAKE_FUNCTION: return 0 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) - ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0); @@ -1084,6 +1082,7 @@ stack_effect(int opcode, int oparg, int jump) case MATCH_KEYS: return 1; case COPY: + case PUSH_NULL: return 1; case BINARY_OP: return -1; @@ -1800,7 +1799,7 @@ compiler_call_exit_with_nones(struct compiler *c) { ADDOP_LOAD_CONST(c, Py_None); ADDOP_LOAD_CONST(c, Py_None); ADDOP_LOAD_CONST(c, Py_None); - ADDOP_I(c, PRECALL_FUNCTION, 3); + ADDOP_I(c, PRECALL, 2); ADDOP_I(c, CALL, 0); return 1; } @@ -2178,7 +2177,7 @@ compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos) int old_end_col_offset = c->u->u_end_col_offset; for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) { SET_LOC(c, (expr_ty)asdl_seq_GET(decos, i)); - ADDOP_I(c, PRECALL_FUNCTION, 1); + ADDOP_I(c, PRECALL, 0); ADDOP_I(c, CALL, 0); } c->u->u_lineno = old_lineno; @@ -2630,6 +2629,7 @@ compiler_class(struct compiler *c, stmt_ty s) return 0; /* 2. load the 'build_class' function */ + ADDOP(c, PUSH_NULL); ADDOP(c, LOAD_BUILD_CLASS); /* 3. load a function (or closure) made from the code object */ @@ -2645,7 +2645,6 @@ compiler_class(struct compiler *c, stmt_ty s) /* 5. generate the rest of the code for the call */ if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords)) return 0; - /* 6. apply decorators */ if (!compiler_apply_decorators(c, decos)) return 0; @@ -3858,7 +3857,7 @@ compiler_assert(struct compiler *c, stmt_ty s) ADDOP(c, LOAD_ASSERTION_ERROR); if (s->v.Assert.msg) { VISIT(c, expr, s->v.Assert.msg); - ADDOP_I(c, PRECALL_FUNCTION, 1); + ADDOP_I(c, PRECALL, 0); ADDOP_I(c, CALL, 0); } ADDOP_I(c, RAISE_VARARGS, 1); @@ -4680,14 +4679,14 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) if (kwdsl) { VISIT_SEQ(c, keyword, kwds); - ADDOP_I(c, PRECALL_METHOD, argsl + kwdsl); + ADDOP_I(c, PRECALL, argsl + kwdsl); if (!compiler_call_simple_kw_helper(c, kwds, kwdsl)) { return 0; }; ADDOP_I(c, CALL, kwdsl); } else { - ADDOP_I(c, PRECALL_METHOD, argsl); + ADDOP_I(c, PRECALL, argsl); ADDOP_I(c, CALL, 0); } c->u->u_lineno = old_lineno; @@ -4731,6 +4730,9 @@ compiler_call(struct compiler *c, expr_ty e) if (!check_caller(c, e->v.Call.func)) { return 0; } + SET_LOC(c, e->v.Call.func); + ADDOP(c, PUSH_NULL); + SET_LOC(c, e); VISIT(c, expr, e->v.Call.func); return compiler_call_helper(c, 0, e->v.Call.args, @@ -4755,7 +4757,7 @@ compiler_joined_str(struct compiler *c, expr_ty e) VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i)); ADDOP_I(c, LIST_APPEND, 1); } - ADDOP_I(c, PRECALL_METHOD, 1); + ADDOP_I(c, PRECALL, 1); ADDOP_I(c, CALL, 0); } else { @@ -4925,7 +4927,7 @@ compiler_call_helper(struct compiler *c, } if (nkwelts) { VISIT_SEQ(c, keyword, keywords); - ADDOP_I(c, PRECALL_FUNCTION, n + nelts + nkwelts); + ADDOP_I(c, PRECALL, n + nelts + nkwelts); if (!compiler_call_simple_kw_helper(c, keywords, nkwelts)) { return 0; }; @@ -4933,7 +4935,7 @@ compiler_call_helper(struct compiler *c, return 1; } else { - ADDOP_I(c, PRECALL_FUNCTION, n + nelts); + ADDOP_I(c, PRECALL, n + nelts); ADDOP_I(c, CALL, 0); return 1; } @@ -5328,7 +5330,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, ADDOP(c, GET_ITER); } - ADDOP_I(c, PRECALL_FUNCTION, 1); + ADDOP_I(c, PRECALL, 0); ADDOP_I(c, CALL, 0); if (is_async_generator && type != COMP_GENEXP) { diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 1e137f9..f6cbec7 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -1,20 +1,21 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&TARGET_POP_TOP, + &&TARGET_PUSH_NULL, &&TARGET_BINARY_OP_ADAPTIVE, &&TARGET_BINARY_OP_ADD_INT, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_UNICODE, &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, &&TARGET_BINARY_OP_MULTIPLY_INT, - &&TARGET_BINARY_OP_MULTIPLY_FLOAT, &&TARGET_NOP, &&TARGET_UNARY_POSITIVE, &&TARGET_UNARY_NEGATIVE, &&TARGET_UNARY_NOT, + &&TARGET_BINARY_OP_MULTIPLY_FLOAT, &&TARGET_BINARY_OP_SUBTRACT_INT, - &&TARGET_BINARY_OP_SUBTRACT_FLOAT, &&TARGET_UNARY_INVERT, + &&TARGET_BINARY_OP_SUBTRACT_FLOAT, &&TARGET_COMPARE_OP_ADAPTIVE, &&TARGET_COMPARE_OP_FLOAT_JUMP, &&TARGET_COMPARE_OP_INT_JUMP, @@ -23,18 +24,18 @@ static void *opcode_targets[256] = { &&TARGET_BINARY_SUBSCR_GETITEM, &&TARGET_BINARY_SUBSCR_LIST_INT, &&TARGET_BINARY_SUBSCR_TUPLE_INT, - &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_BINARY_SUBSCR, + &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_STORE_SUBSCR_DICT, - &&TARGET_CALL_ADAPTIVE, &&TARGET_GET_LEN, &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_KEYS, - &&TARGET_CALL_BUILTIN_CLASS, + &&TARGET_CALL_ADAPTIVE, &&TARGET_PUSH_EXC_INFO, + &&TARGET_CALL_BUILTIN_CLASS, &&TARGET_CALL_NO_KW_BUILTIN_O, &&TARGET_CALL_NO_KW_BUILTIN_FAST, &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS, @@ -47,40 +48,39 @@ static void *opcode_targets[256] = { &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, &&TARGET_CALL_NO_KW_STR_1, &&TARGET_CALL_NO_KW_TUPLE_1, - &&TARGET_CALL_NO_KW_TYPE_1, &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, &&TARGET_BEFORE_ASYNC_WITH, &&TARGET_BEFORE_WITH, &&TARGET_END_ASYNC_FOR, + &&TARGET_CALL_NO_KW_TYPE_1, &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_FAST, &&TARGET_JUMP_ABSOLUTE_QUICK, &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_LOAD_ATTR_INSTANCE_VALUE, - &&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, + &&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_MODULE, &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_LOAD_GLOBAL_MODULE, &&TARGET_LOAD_GLOBAL_BUILTIN, - &&TARGET_LOAD_METHOD_ADAPTIVE, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_LOAD_METHOD_CACHED, + &&TARGET_LOAD_METHOD_ADAPTIVE, &&TARGET_GET_AWAITABLE, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, + &&TARGET_LOAD_METHOD_CACHED, &&TARGET_LOAD_METHOD_CLASS, &&TARGET_LOAD_METHOD_MODULE, &&TARGET_LOAD_METHOD_NO_DICT, &&TARGET_RESUME_QUICK, &&TARGET_STORE_ATTR_ADAPTIVE, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, @@ -130,7 +130,7 @@ static void *opcode_targets[256] = { &&TARGET_POP_JUMP_IF_NOT_NONE, &&TARGET_POP_JUMP_IF_NONE, &&TARGET_RAISE_VARARGS, - &&TARGET_STORE_ATTR_SLOT, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_MAKE_FUNCTION, &&TARGET_BUILD_SLICE, &&TARGET_JUMP_NO_INTERRUPT, @@ -139,35 +139,35 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_DEREF, &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, + &&TARGET_STORE_ATTR_SLOT, &&TARGET_STORE_ATTR_WITH_HINT, - &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, &&TARGET_CALL_FUNCTION_EX, - &&TARGET_UNPACK_SEQUENCE_LIST, + &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, &&TARGET_COPY_FREE_VARS, - &&TARGET_UNPACK_SEQUENCE_TUPLE, + &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, + &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, - &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LOAD_METHOD, - &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, + &&TARGET_PRECALL, + &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_STORE_FAST__STORE_FAST, - &&TARGET_PRECALL_FUNCTION, - &&TARGET_PRECALL_METHOD, &&_unknown_opcode, &&_unknown_opcode, &&TARGET_CALL, diff --git a/Python/specialize.c b/Python/specialize.c index 5fd7d09..7dd12c7 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -178,8 +178,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats) /* Mark some opcodes as specializable for stats, * even though we don't specialize them yet. */ fprintf(out, "opcode[%d].specializable : 1\n", FOR_ITER); - fprintf(out, "opcode[%d].specializable : 1\n", PRECALL_FUNCTION); - fprintf(out, "opcode[%d].specializable : 1\n", PRECALL_METHOD); + fprintf(out, "opcode[%d].specializable : 1\n", PRECALL); fprintf(out, "opcode[%d].specializable : 1\n", UNPACK_SEQUENCE); for (int i = 0; i < 256; i++) { if (adaptive_opcodes[i]) { @@ -1528,7 +1527,7 @@ specialize_method_descriptor( } assert(_list_append != NULL); if (nargs == 2 && descr == _list_append) { - assert(_Py_OPCODE(instr[-1]) == PRECALL_METHOD); + assert(_Py_OPCODE(instr[-1]) == PRECALL); cache[-1].obj.obj = (PyObject *)_list_append; *instr = _Py_MAKECODEUNIT(CALL_NO_KW_LIST_APPEND, _Py_OPARG(*instr)); return 0; |