diff options
author | Tomas R. <tomas.roun8@gmail.com> | 2025-05-08 23:26:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-08 14:26:30 -0700 |
commit | c492ac72525ea5887082ee991b45cc237cd02a40 (patch) | |
tree | 852add3d5172f601aa96d67d83466b882b78015d /Python/bytecodes.c | |
parent | b2fabce6abb24b2f2c3afae0edc5eb53729fc624 (diff) | |
download | cpython-c492ac72525ea5887082ee991b45cc237cd02a40.tar.gz cpython-c492ac72525ea5887082ee991b45cc237cd02a40.zip |
GH-131798: Split up and optimize CALL_ISINSTANCE (GH-133339)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 6a076662640..42e4f581894 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -4041,6 +4041,10 @@ dummy_func( DEOPT_IF(!PyStackRef_IsNull(null)); } + op(_GUARD_THIRD_NULL, (null, unused, unused -- null, unused, unused)) { + DEOPT_IF(!PyStackRef_IsNull(null)); + } + op(_GUARD_CALLABLE_TYPE_1, (callable, unused, unused -- callable, unused, unused)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); DEOPT_IF(callable_o != (PyObject *)&PyType_Type); @@ -4359,31 +4363,37 @@ dummy_func( res = PyStackRef_FromPyObjectSteal(res_o); } - inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { - /* isinstance(o, o2) */ + op(_GUARD_CALLABLE_ISINSTANCE, (callable, unused, unused, unused -- callable, unused, unused, unused)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - - int total_args = oparg; - _PyStackRef *arguments = args; - if (!PyStackRef_IsNull(self_or_null)) { - arguments--; - total_args++; - } - DEOPT_IF(total_args != 2); PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable_o != interp->callable_cache.isinstance); + } + + op(_CALL_ISINSTANCE, (callable, null, instance, cls -- res)) { + /* isinstance(o, o2) */ STAT_INC(CALL, hit); - _PyStackRef cls_stackref = arguments[1]; - _PyStackRef inst_stackref = arguments[0]; - int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref)); + PyObject *inst_o = PyStackRef_AsPyObjectBorrow(instance); + PyObject *cls_o = PyStackRef_AsPyObjectBorrow(cls); + int retval = PyObject_IsInstance(inst_o, cls_o); if (retval < 0) { ERROR_NO_POP(); } + (void)null; // Silence compiler warnings about unused variables + PyStackRef_CLOSE(cls); + PyStackRef_CLOSE(instance); + DEAD(null); + PyStackRef_CLOSE(callable); res = retval ? PyStackRef_True : PyStackRef_False; assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL)); - DECREF_INPUTS(); } + macro(CALL_ISINSTANCE) = + unused/1 + + unused/2 + + _GUARD_THIRD_NULL + + _GUARD_CALLABLE_ISINSTANCE + + _CALL_ISINSTANCE; + // This is secretly a super-instruction inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, arg -- )) { assert(oparg == 1); |