Skip to content

Commit 8fab9d3

Browse files
Do not use reverse-lookup cache, use recorded value instead
1 parent ec6eac8 commit 8fab9d3

File tree

5 files changed

+39
-46
lines changed

5 files changed

+39
-46
lines changed

Include/internal/pycore_opcode_metadata.h

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

Python/bytecodes.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2721,11 +2721,6 @@ dummy_func(
27212721
}
27222722

27232723
op(_GUARD_TYPE_VERSION_LOCKED, (type_version/2, owner -- owner)) {
2724-
// Guard that type version matches expected value. Object is assumed to be
2725-
// locked on entry. If version matches, lock is retained for subsequent
2726-
// operations. If mismatch, unlock and exit (deopt). This allows the JIT
2727-
// optimizer to eliminate this guard entirely if type version is proven,
2728-
// in which case the lock is held for the entire trace duration.
27292724
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
27302725
assert(type_version != 0);
27312726
PyTypeObject *tp = Py_TYPE(owner_o);
@@ -2999,6 +2994,7 @@ dummy_func(
29992994

30002995
macro(STORE_ATTR_INSTANCE_VALUE) =
30012996
unused/1 +
2997+
_RECORD_TOS_TYPE +
30022998
_LOCK_OBJECT +
30032999
_GUARD_TYPE_VERSION_LOCKED +
30043000
_GUARD_DORV_NO_DICT +

Python/optimizer_bytecodes.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,11 @@ dummy_func(void) {
139139
if (sym_matches_type_version(owner, type_version)) {
140140
ADD_OP(_NOP, 0, 0);
141141
} else {
142-
PyTypeObject *type = _PyType_LookupByVersion(type_version);
143-
if (type) {
144-
if (sym_set_type_version(owner, type_version)) {
145-
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
146-
_Py_BloomFilter_Add(dependencies, type);
147-
}
142+
PyTypeObject *probable_type = sym_get_probable_type(owner);
143+
if (probable_type->tp_version_tag == type_version && sym_set_type_version(owner, type_version)) {
144+
// Promote the probable type version to a known one.
145+
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type);
146+
_Py_BloomFilter_Add(dependencies, probable_type);
148147
}
149148
}
150149
}
@@ -1043,20 +1042,22 @@ dummy_func(void) {
10431042

10441043
op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) {
10451044
(void)args;
1046-
PyTypeObject *type = _PyType_LookupByVersion(type_version);
1047-
if (type) {
1048-
PyHeapTypeObject *cls = (PyHeapTypeObject *)type;
1049-
PyObject *init = FT_ATOMIC_LOAD_PTR_ACQUIRE(cls->_spec_cache.init);
1050-
if (init != NULL && PyFunction_Check(init)) {
1051-
// Propagate the __init__ function so _CREATE_INIT_FRAME can
1052-
// resolve the code object and continue optimizing.
1053-
callable = sym_new_const(ctx, init);
1054-
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
1055-
_Py_BloomFilter_Add(dependencies, type);
1056-
}
1057-
else {
1058-
callable = sym_new_not_null(ctx);
1059-
}
1045+
PyObject *probable_callable = sym_get_probable_value(callable);
1046+
assert(probable_callable != NULL);
1047+
assert(PyType_Check(probable_callable));
1048+
PyTypeObject *tp = (PyTypeObject *)probable_callable;
1049+
if (tp->tp_version_tag == type_version) {
1050+
// If the type version has not changed since we last saw it,
1051+
// then we know this __init__ is definitely the same one as in the cache.
1052+
// We can promote callable to a known constant. This does not need a
1053+
// type watcher, as we do not remove this _CHECK_AND_ALLOCATE_OBJECT guard.
1054+
// TODO: split up _CHECK_AND_ALLOCATE_OBJECT to the check then alloate, so we can
1055+
// eliminate the check.
1056+
PyHeapTypeObject *cls = (PyHeapTypeObject *)probable_callable;
1057+
PyObject *init = cls->_spec_cache.init;
1058+
assert(init != NULL);
1059+
assert(PyFunction_Check(init));
1060+
callable = sym_new_const(ctx, init);
10601061
}
10611062
else {
10621063
callable = sym_new_not_null(ctx);

Python/optimizer_cases.c.h

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

Python/record_functions.c.h

Lines changed: 1 addition & 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)