Skip to content

Commit c82e57d

Browse files
check _LOAD_GLOBAL_BUILTINS in test
1 parent c5d5d75 commit c82e57d

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5255,7 +5255,7 @@ def g():
52555255

52565256
def test_call_kw(self):
52575257
def func(a):
5258-
return 42 * a
5258+
return int(a) * 42
52595259

52605260
def testfunc(n):
52615261
x = 0
@@ -5269,26 +5269,30 @@ def testfunc(n):
52695269
uops = get_opnames(ex)
52705270
self.assertIn("_PUSH_FRAME", uops)
52715271
self.assertIn("_CHECK_FUNCTION_VERSION_KW", uops)
5272+
self.assertNotIn("_LOAD_GLOBAL_BUILTINS", uops)
5273+
self.assertIn("_CALL_BUILTIN_CLASS", uops)
52725274

52735275
def test_call_kw_bound_method(self):
52745276
class C:
5275-
def method(self, a):
5276-
return 42 * a
5277+
def method(self, a, b):
5278+
return int(a) + int(b)
52775279

52785280
def testfunc(n):
52795281
obj = C()
52805282
x = 0
52815283
meth = obj.method
52825284
for _ in range(n):
5283-
x += meth(a=1)
5285+
x += meth(a=1, b=2)
52845286
return x
52855287

52865288
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
5287-
self.assertEqual(res, 42 * TIER2_THRESHOLD)
5289+
self.assertEqual(res, 3 * TIER2_THRESHOLD)
52885290
self.assertIsNotNone(ex)
52895291
uops = get_opnames(ex)
52905292
self.assertIn("_PUSH_FRAME", uops)
52915293
self.assertIn("_CHECK_METHOD_VERSION_KW", uops)
5294+
self.assertNotIn("_LOAD_GLOBAL_BUILTINS", uops)
5295+
self.assertIn("_CALL_BUILTIN_CLASS", uops)
52925296

52935297
def test_func_version_guarded_on_change(self):
52945298
def testfunc(n):

Python/optimizer_bytecodes.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,29 @@ dummy_func(void) {
10571057
sym_set_type(callable, &PyMethod_Type);
10581058
}
10591059

1060+
op(_CHECK_METHOD_VERSION_KW, (func_version/2, callable, null, unused[oparg], unused -- callable, null, unused[oparg], unused)) {
1061+
if (sym_is_const(ctx, callable) && sym_matches_type(callable, &PyMethod_Type)) {
1062+
PyMethodObject *method = (PyMethodObject *)sym_get_const(ctx, callable);
1063+
assert(PyMethod_Check(method));
1064+
ADD_OP(_CHECK_FUNCTION_VERSION_INLINE, 0, func_version);
1065+
uop_buffer_last(&ctx->out_buffer)->operand1 = (uintptr_t)method->im_func;
1066+
}
1067+
else {
1068+
// Guarding on the bound method, safe to promote.
1069+
PyObject *bound_method = sym_get_probable_value(callable);
1070+
if (bound_method != NULL && Py_TYPE(bound_method) == &PyMethod_Type) {
1071+
PyMethodObject *method = (PyMethodObject *)bound_method;
1072+
PyObject *func = method->im_func;
1073+
if (PyFunction_Check(func) &&
1074+
((PyFunctionObject *)func)->func_version == func_version) {
1075+
_Py_BloomFilter_Add(dependencies, func);
1076+
sym_set_const(callable, bound_method);
1077+
}
1078+
}
1079+
}
1080+
sym_set_type(callable, &PyMethod_Type);
1081+
}
1082+
10601083
op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
10611084
assert(sym_matches_type(callable, &PyFunction_Type));
10621085
if (sym_is_const(ctx, callable)) {

Python/optimizer_cases.c.h

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)