Uh oh!
There was an error while loading. Please reload this page.
gh-148510: restore func_version check in _LOAD_ATTR_PROPERTY_FRAME - #148528
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Fidget-Spinner
left a comment
There was a problem hiding this comment.
Just one thing that should be addressed. Thanks!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
NekoAsakura
commented
Apr 14, 2026
Seems like cpython/Python/optimizer_bytecodes.c Lines 143 to 145 in 21da9d7 |
Fidget-Spinner
commented
Apr 14, 2026
Oops I think that was me. Can you please add a condition to that in another PR? |
NekoAsakura
commented
Apr 14, 2026
Sure. |
Fidget-Spinner
commented
Apr 14, 2026
@NekoAsakura sorry for the flip flop, but I think we can do this in this PR, I realised they're the same uop, just one is the other variant. |
NekoAsakura
commented
Apr 14, 2026
NP! Wait me a second. |
Uh oh!
There was an error while loading. Please reload this page.
| sym_set_type_version(owner, type_version)) { | ||
| PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type); | ||
| _Py_BloomFilter_Add(dependencies, probable_type); |
There was a problem hiding this comment.
Instead of setting the type verison, promote the type. Use sym_set_type(owner, probable_type) inside the if branch. Please update _GUARD_TYPE_VERSION_LOCKED to do that as well (and fix the NULL check).
There was a problem hiding this comment.
Wait I'm wrong here, we can't do that. I forgot what sym_set_type_version does. Sorry for misleading!
There was a problem hiding this comment.
I think we can do both in sequence like:
sym_set_type(owner, probable_type);
sym_set_type_version(owner, type_version);
This promotes type while keeping the version.
There was a problem hiding this comment.
If we do sym_set_type(owner, probable_type);, we don't need to set the type version after, as sym_get_type_version just grabs tp_version_tag from the type. It's essentially a no-op.
Also type is strictly more information than type version in our framework https://github.com/python/cpython/blob/main/Python/optimizer_symbols.c#L37
There was a problem hiding this comment.
I'm afraid sym_get_type_version returns sym->cls.version for KNOWN_CLASS_TAG, not cls.type->tp_version_tag:
cpython/Python/optimizer_symbols.c
Lines 750 to 751 in 21da9d7
And sym_set_type sets cls.version = 0 when promoting from RECORDED_TYPE_TAG:
cpython/Python/optimizer_symbols.c
Lines 351 to 355 in 21da9d7
Without sym_set_type_version afterwards, the version stays 0 and guard elimination breaks.
There was a problem hiding this comment.
Ah ok. Thanks for digging into this!
There was a problem hiding this comment.
Is there a reason for it to return cls.version when class is known? It seems better to return the version from tp_version_tag.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Fidget-Spinner
left a comment
There was a problem hiding this comment.
Thanks, LGTM. Just one comment.
| PyCodeObject *co = (PyCodeObject *)((PyFunctionObject *)fget)->func_code; | ||
| op(_LOAD_ATTR_PROPERTY_FRAME, (func_version/2, fget/4, owner -- new_frame)) { | ||
| if (sym_get_type_version(owner) == 0) { | ||
| ctx->done = true; |
There was a problem hiding this comment.
Why not ctx->contradiction to true as well? That would abandon the whole trace, which is what we dant. Done allows the trace to continue executing.
There was a problem hiding this comment.
Oops I accidentally deleted that. Thanks for catching it!
| # Check the optimizer traced through the property call. | ||
| self.assertIn("_CALL_BUILTIN_CLASS", uops) |
There was a problem hiding this comment.
No this doesn't check the optimizer actually ran inside the call. The easiest way is to check the global was promoted, ie the absence of _LOAD_GLOBAL_BUILTIN.
There was a problem hiding this comment.
Yes, was missing f->func = func on the abstract frame so globals couldn't be resolved. Sorted now, test asserts the absence of _LOAD_GLOBAL_BUILTINS.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Do not merge.Prerequisite: #148524 (Merged)
Mean +- std: [main] 12.8 ms +- 0.2 ms -> [branch] 12.3 ms +- 0.1 ms