diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 32 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 42 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 90 | ||||
-rw-r--r-- | Python/optimizer_bytecodes.c | 10 | ||||
-rw-r--r-- | Python/optimizer_cases.c.h | 15 | ||||
-rw-r--r-- | Python/specialize.c | 2 |
6 files changed, 108 insertions, 83 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index cc47e57175d..90234b2d5bd 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4337,22 +4337,25 @@ dummy_func( _CALL_BUILTIN_FAST_WITH_KEYWORDS + _CHECK_PERIODIC; - inst(CALL_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { - /* len(o) */ - PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); + macro(CALL_LEN) = + unused/1 + + unused/2 + + _GUARD_NOS_NULL + + _GUARD_CALLABLE_LEN + + _CALL_LEN; - int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { - args--; - total_args++; - } - DEOPT_IF(total_args != 1); + op(_GUARD_CALLABLE_LEN, (callable, unused, unused -- callable, unused, unused)){ + PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable_o != interp->callable_cache.len); + } + + op(_CALL_LEN, (callable, null, arg -- res)) { + /* len(o) */ + (void)null; STAT_INC(CALL, hit); - _PyStackRef arg_stackref = args[0]; - PyObject *arg = PyStackRef_AsPyObjectBorrow(arg_stackref); - Py_ssize_t len_i = PyObject_Length(arg); + PyObject *arg_o = PyStackRef_AsPyObjectBorrow(arg); + Py_ssize_t len_i = PyObject_Length(arg_o); if (len_i < 0) { ERROR_NO_POP(); } @@ -4361,9 +4364,8 @@ dummy_func( if (res_o == NULL) { ERROR_NO_POP(); } - PyStackRef_CLOSE(arg_stackref); - DEAD(args); - DEAD(self_or_null); + PyStackRef_CLOSE(arg); + DEAD(null); PyStackRef_CLOSE(callable); res = PyStackRef_FromPyObjectSteal(res_o); } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 662e050c5c4..c1829717e49 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5788,35 +5788,31 @@ break; } - case _CALL_LEN: { - _PyStackRef *args; - _PyStackRef self_or_null; + case _GUARD_CALLABLE_LEN: { _PyStackRef callable; - _PyStackRef res; - oparg = CURRENT_OPARG(); - args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; - callable = stack_pointer[-2 - oparg]; + callable = stack_pointer[-3]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { - args--; - total_args++; - } - if (total_args != 1) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } PyInterpreterState *interp = tstate->interp; if (callable_o != interp->callable_cache.len) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } + break; + } + + case _CALL_LEN: { + _PyStackRef arg; + _PyStackRef null; + _PyStackRef callable; + _PyStackRef res; + arg = stack_pointer[-1]; + null = stack_pointer[-2]; + callable = stack_pointer[-3]; + (void)null; STAT_INC(CALL, hit); - _PyStackRef arg_stackref = args[0]; - PyObject *arg = PyStackRef_AsPyObjectBorrow(arg_stackref); + PyObject *arg_o = PyStackRef_AsPyObjectBorrow(arg); _PyFrame_SetStackPointer(frame, stack_pointer); - Py_ssize_t len_i = PyObject_Length(arg); + Py_ssize_t len_i = PyObject_Length(arg_o); stack_pointer = _PyFrame_GetStackPointer(frame); if (len_i < 0) { JUMP_TO_ERROR(); @@ -5826,10 +5822,12 @@ if (res_o == NULL) { JUMP_TO_ERROR(); } + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(arg_stackref); + PyStackRef_CLOSE(arg); stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; + stack_pointer += -2; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); PyStackRef_CLOSE(callable); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 072951d2a5f..ca077dabad7 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -3414,55 +3414,61 @@ next_instr += 4; INSTRUCTION_STATS(CALL_LEN); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + _PyStackRef null; _PyStackRef callable; - _PyStackRef self_or_null; - _PyStackRef *args; + _PyStackRef arg; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ - args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; - callable = stack_pointer[-2 - oparg]; - PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { - args--; - total_args++; - } - if (total_args != 1) { - UPDATE_MISS_STATS(CALL); - assert(_PyOpcode_Deopt[opcode] == (CALL)); - JUMP_TO_PREDICTED(CALL); - } - PyInterpreterState *interp = tstate->interp; - if (callable_o != interp->callable_cache.len) { - UPDATE_MISS_STATS(CALL); - assert(_PyOpcode_Deopt[opcode] == (CALL)); - JUMP_TO_PREDICTED(CALL); + // _GUARD_NOS_NULL + { + null = stack_pointer[-2]; + if (!PyStackRef_IsNull(null)) { + UPDATE_MISS_STATS(CALL); + assert(_PyOpcode_Deopt[opcode] == (CALL)); + JUMP_TO_PREDICTED(CALL); + } } - STAT_INC(CALL, hit); - _PyStackRef arg_stackref = args[0]; - PyObject *arg = PyStackRef_AsPyObjectBorrow(arg_stackref); - _PyFrame_SetStackPointer(frame, stack_pointer); - Py_ssize_t len_i = PyObject_Length(arg); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (len_i < 0) { - JUMP_TO_LABEL(error); + // _GUARD_CALLABLE_LEN + { + callable = stack_pointer[-3]; + PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); + PyInterpreterState *interp = tstate->interp; + if (callable_o != interp->callable_cache.len) { + UPDATE_MISS_STATS(CALL); + assert(_PyOpcode_Deopt[opcode] == (CALL)); + JUMP_TO_PREDICTED(CALL); + } } - PyObject *res_o = PyLong_FromSsize_t(len_i); - assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - if (res_o == NULL) { - JUMP_TO_LABEL(error); + // _CALL_LEN + { + arg = stack_pointer[-1]; + (void)null; + STAT_INC(CALL, hit); + PyObject *arg_o = PyStackRef_AsPyObjectBorrow(arg); + _PyFrame_SetStackPointer(frame, stack_pointer); + Py_ssize_t len_i = PyObject_Length(arg_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (len_i < 0) { + JUMP_TO_LABEL(error); + } + PyObject *res_o = PyLong_FromSsize_t(len_i); + assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + if (res_o == NULL) { + JUMP_TO_LABEL(error); + } + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(arg); + stack_pointer = _PyFrame_GetStackPointer(frame); + stack_pointer += -2; + assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_CLOSE(callable); + stack_pointer = _PyFrame_GetStackPointer(frame); + res = PyStackRef_FromPyObjectSteal(res_o); } - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(arg_stackref); - stack_pointer = _PyFrame_GetStackPointer(frame); - stack_pointer += -2 - oparg; - assert(WITHIN_STACK_BOUNDS()); - _PyFrame_SetStackPointer(frame, stack_pointer); - PyStackRef_CLOSE(callable); - stack_pointer = _PyFrame_GetStackPointer(frame); - res = PyStackRef_FromPyObjectSteal(res_o); stack_pointer[0] = res; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 567caad2255..e99421a3aff 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1084,10 +1084,18 @@ dummy_func(void) { sym_set_const(callable, (PyObject *)&PyUnicode_Type); } - op(_CALL_LEN, (callable[1], self_or_null[1], args[oparg] -- res)) { + op(_CALL_LEN, (unused, unused, unused -- res)) { res = sym_new_type(ctx, &PyLong_Type); } + op(_GUARD_CALLABLE_LEN, (callable, unused, unused -- callable, unused, unused)) { + PyObject *len = _PyInterpreterState_GET()->callable_cache.len; + if (sym_get_const(ctx, callable) == len) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + sym_set_const(callable, len); + } + // END BYTECODES // } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 8e8b2ecfa5b..a9bb67d9605 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2065,11 +2065,22 @@ break; } + case _GUARD_CALLABLE_LEN: { + JitOptSymbol *callable; + callable = stack_pointer[-3]; + PyObject *len = _PyInterpreterState_GET()->callable_cache.len; + if (sym_get_const(ctx, callable) == len) { + REPLACE_OP(this_instr, _NOP, 0, 0); + } + sym_set_const(callable, len); + break; + } + case _CALL_LEN: { JitOptSymbol *res; res = sym_new_type(ctx, &PyLong_Type); - stack_pointer[-2 - oparg] = res; - stack_pointer += -1 - oparg; + stack_pointer[-3] = res; + stack_pointer += -2; assert(WITHIN_STACK_BOUNDS()); break; } diff --git a/Python/specialize.c b/Python/specialize.c index fe4a65ee5f8..7861f3845bf 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2147,7 +2147,7 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs) } /* len(o) */ PyInterpreterState *interp = _PyInterpreterState_GET(); - if (callable == interp->callable_cache.len) { + if (callable == interp->callable_cache.len && instr->op.arg == 1) { specialize(instr, CALL_LEN); return 0; } |