Skip to content

Commit b98c065

Browse files
authored
gh-158380: Fix the stack operand used by JIT dict access guards (GH-158381)
1 parent 7eada7c commit b98c065

8 files changed

Lines changed: 70 additions & 58 deletions

File tree

‎Include/internal/pycore_uop_ids.h‎

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

‎Include/internal/pycore_uop_metadata.h‎

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

‎Lib/test/test_capi/test_opt.py‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2445,7 +2445,18 @@ def f(n):
24452445
self.assertEqual(uops.count("_STORE_SUBSCR_DICT_KNOWN_HASH"), 1)
24462446
self.assertEqual(uops.count("_GUARD_NOS_DICT_SUBSCRIPT"), 0)
24472447
self.assertEqual(uops.count("_GUARD_NOS_DICT_STORE_SUBSCRIPT"), 0)
2448-
self.assertEqual(uops.count("_GUARD_TYPE"), 1)
2448+
self.assertEqual(uops.count("_GUARD_NOS_TYPE"), 1)
2449+
2450+
def test_dict_subscr_probable_type(self):
2451+
def f(d):
2452+
for _ in range(TIER2_THRESHOLD):
2453+
value = d["key"]
2454+
return value
2455+
2456+
res, ex = self._run_with_optimizer(f, {"key": 1})
2457+
self.assertEqual(res, 1)
2458+
self.assertIsNotNone(ex)
2459+
self.assertIn("_GUARD_NOS_TYPE", get_opnames(ex))
24492460

24502461
def test_dict_subclass_subscr_with_override(self):
24512462
class MyDict(dict):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix incorrect type guards for ``dict`` reads and writes in the experimental JIT.

‎Python/bytecodes.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3846,9 +3846,9 @@ dummy_func(
38463846
next = item;
38473847
}
38483848

3849-
tier2 op(_GUARD_TYPE_ITER, (expected_type/4, iter, null_or_index -- iter, null_or_index)) {
3850-
PyObject *iter_o = PyStackRef_AsPyObjectBorrow(iter);
3851-
EXIT_IF(Py_TYPE(iter_o) != (PyTypeObject *)expected_type);
3849+
tier2 op(_GUARD_NOS_TYPE, (expected_type/4, nos, unused -- nos, unused)) {
3850+
PyObject *nos_o = PyStackRef_AsPyObjectBorrow(nos);
3851+
EXIT_IF(Py_TYPE(nos_o) != (PyTypeObject *)expected_type);
38523852
}
38533853

38543854
tier2 op(_ITER_NEXT_INLINE, (iternext_fn/4, iter, null_or_index -- iter, null_or_index, next)) {

‎Python/executor_cases.c.h‎

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

‎Python/optimizer_bytecodes.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,7 +1472,7 @@ dummy_func(void) {
14721472
sym_set_type(iter, type);
14731473
assert((this_instr - 1)->opcode == _RECORD_NOS_TYPE);
14741474
int32_t orig_target = (this_instr - 1)->target;
1475-
ADD_OP(_GUARD_TYPE_ITER, 0, (uintptr_t)type);
1475+
ADD_OP(_GUARD_NOS_TYPE, 0, (uintptr_t)type);
14761476
uop_buffer_last(&ctx->out_buffer)->target = orig_target;
14771477
}
14781478
ADD_OP(_ITER_NEXT_INLINE, 0, (uintptr_t)type->tp_iternext);
@@ -2216,7 +2216,7 @@ dummy_func(void) {
22162216
ADD_OP(_NOP, 0, 0);
22172217
}
22182218
else {
2219-
ADD_OP(_GUARD_TYPE, 0, (uintptr_t)tp);
2219+
ADD_OP(_GUARD_NOS_TYPE, 0, (uintptr_t)tp);
22202220
sym_set_type(nos, tp);
22212221
}
22222222
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)tp);
@@ -2237,7 +2237,7 @@ dummy_func(void) {
22372237
ADD_OP(_NOP, 0, 0);
22382238
}
22392239
else {
2240-
ADD_OP(_GUARD_TYPE, 0, (uintptr_t)tp);
2240+
ADD_OP(_GUARD_NOS_TYPE, 0, (uintptr_t)tp);
22412241
sym_set_type(nos, tp);
22422242
}
22432243
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)tp);

‎Python/optimizer_cases.c.h‎

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

0 commit comments

Comments
 (0)