Skip to content

Commit 13e2608

Browse files
handle probable and non-probable cases
1 parent 7885033 commit 13e2608

File tree

2 files changed

+45
-36
lines changed

2 files changed

+45
-36
lines changed

Python/optimizer_bytecodes.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,40 +1071,39 @@ dummy_func(void) {
10711071
op(_CHECK_OBJECT, (type_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
10721072
PyObject *probable_callable = sym_get_probable_value(callable);
10731073
assert(probable_callable != NULL);
1074-
PyTypeObject *tp = (PyTypeObject *)probable_callable;
1075-
if (tp->tp_version_tag == type_version) {
1076-
// If the type version has not changed since we last saw it,
1077-
// then we know this __init__ is definitely the same one as in the cache.
1078-
// We can promote callable to a known constant. This does not need a
1079-
// type watcher, as we do not remove this _CHECK_AND_ALLOCATE_OBJECT guard.
1080-
if (sym_is_null(self_or_null) && sym_matches_type(callable, &PyType_Type)) {
1074+
PyObject *const_callable = sym_get_const(ctx, callable);
1075+
bool is_probable = const_callable == NULL && probable_callable != NULL;
1076+
PyObject *callable_o = const_callable != NULL ? const_callable : probable_callable;
1077+
if (sym_is_null(self_or_null) &&
1078+
callable_o != NULL &&
1079+
PyType_Check(callable_o) &&
1080+
((PyTypeObject *)callable_o)->tp_version_tag == type_version) {
1081+
// Probable types need the guard.
1082+
if (!is_probable) {
10811083
ADD_OP(_NOP, 0, 0);
10821084
}
1083-
PyHeapTypeObject *cls = (PyHeapTypeObject *)probable_callable;
1085+
else {
1086+
// Promote the probable type, as we have
1087+
// guarded on it.
1088+
sym_set_const(callable, callable_o);
1089+
}
1090+
PyHeapTypeObject *cls = (PyHeapTypeObject *)callable_o;
10841091
PyObject *init = cls->_spec_cache.init;
10851092
assert(init != NULL);
10861093
assert(PyFunction_Check(init));
1087-
sym_set_const(callable, init);
1094+
callable = sym_new_const(ctx, init);
1095+
PyType_Watch(TYPE_WATCHER_ID, callable_o);
1096+
_Py_BloomFilter_Add(dependencies, callable_o);;
10881097
}
10891098
else {
1090-
// add watcher so that whenever the type changes we invalidate this
1091-
PyTypeObject *type = _PyType_LookupByVersion(type_version);
1092-
// if the type is null, it was not found in the cache (there was a conflict)
1093-
// with the key, in which case we can't trust the version
1094-
if (type) {
1095-
// if the type version was set properly, then add a watcher
1096-
// if it wasn't this means that the type version was previously set to something else
1097-
// and we set the callable to bottom, so we don't need to add a watcher because we must have
1098-
// already added one earlier.
1099-
if (sym_set_type_version(callable, type_version)) {
1100-
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
1101-
_Py_BloomFilter_Add(dependencies, type);
1102-
}
1103-
}
1104-
self_or_null = sym_new_not_null(ctx);
1099+
callable = sym_new_not_null(ctx);
11051100
}
11061101
}
11071102

1103+
op(_ALLOCATE_OBJECT, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
1104+
self_or_null = sym_new_not_null(ctx);
1105+
}
1106+
11081107
op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame)) {
11091108
ctx->frame->stack_pointer = stack_pointer - oparg - 2;
11101109
_Py_UOpsAbstractFrame *shim = frame_new(ctx, (PyCodeObject *)&_Py_InitCleanup, NULL, 0);

Python/optimizer_cases.c.h

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

0 commit comments

Comments
 (0)