https://github.com/python/cpython/commit/afaf58b5739dabf50a5db69c301d547eb421b3bf
commit: afaf58b5739dabf50a5db69c301d547eb421b3bf
branch: main
author: Wulian233 <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-04-13T22:41:06+08:00
summary:
gh-131798: JIT: Optimize `_CHECK_IS_NOT_PY_CALLABLE_EX` and
`_CHECK_IS_NOT_PY_CALLABLE_KW` (GH-148494)
files:
M Lib/test/test_capi/test_opt.py
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 663783f435fe2a..0b112afb8181b1 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -2845,6 +2845,35 @@ def testfunc(n):
uops = get_opnames(ex)
self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE", uops)
+ def test_check_is_not_py_callable_ex(self):
+ def testfunc(n):
+ total = 0
+ xs = (1, 2, 3)
+ args = (xs,)
+ for _ in range(n):
+ total += len(*args)
+ return total
+
+ res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
+ self.assertEqual(res, 3 * TIER2_THRESHOLD)
+ self.assertIsNotNone(ex)
+ uops = get_opnames(ex)
+ self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE_EX", uops)
+
+ def test_check_is_not_py_callable_kw(self):
+ def testfunc(n):
+ total = 0
+ xs = (3, 1, 2)
+ for _ in range(n):
+ total += sorted(xs, reverse=False)[0]
+ return total
+
+ res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
+ self.assertEqual(res, TIER2_THRESHOLD)
+ self.assertIsNotNone(ex)
+ uops = get_opnames(ex)
+ self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE_KW", uops)
+
def test_call_len_string(self):
def testfunc(n):
for _ in range(n):
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index 18cb2e24690e04..3332a9627c1523 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -1320,6 +1320,20 @@ dummy_func(void) {
}
}
+ op(_CHECK_IS_NOT_PY_CALLABLE_EX, (func_st, unused, unused, unused --
func_st, unused, unused, unused)) {
+ PyTypeObject *type = sym_get_type(func_st);
+ if (type && type != &PyFunction_Type) {
+ ADD_OP(_NOP, 0, 0);
+ }
+ }
+
+ op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable, unused, unused[oparg], unused
-- callable, unused, unused[oparg], unused)) {
+ PyTypeObject *type = sym_get_type(callable);
+ if (type && type != &PyFunction_Type && type != &PyMethod_Type) {
+ ADD_OP(_NOP, 0, 0);
+ }
+ }
+
op(_PUSH_FRAME, (new_frame -- )) {
SYNC_SP();
if (!CURRENT_FRAME_IS_INIT_SHIM()) {
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 9ef7eafc2a3481..deb92f5d9ab0f1 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -4672,6 +4672,12 @@
}
case _CHECK_IS_NOT_PY_CALLABLE_KW: {
+ JitOptRef callable;
+ callable = stack_pointer[-3 - oparg];
+ PyTypeObject *type = sym_get_type(callable);
+ if (type && type != &PyFunction_Type && type != &PyMethod_Type) {
+ ADD_OP(_NOP, 0, 0);
+ }
break;
}
@@ -4708,6 +4714,12 @@
}
case _CHECK_IS_NOT_PY_CALLABLE_EX: {
+ JitOptRef func_st;
+ func_st = stack_pointer[-4];
+ PyTypeObject *type = sym_get_type(func_st);
+ if (type && type != &PyFunction_Type) {
+ ADD_OP(_NOP, 0, 0);
+ }
break;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]