-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-44338: Port LOAD_GLOBAL to PEP 659 adaptive interpreter #26638
bpo-44338: Port LOAD_GLOBAL to PEP 659 adaptive interpreter #26638
Conversation
🤖 New build scheduled with the buildbot fleet by @markshannon for commit 8ad3e55 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few spots where things are a little unclear but mostly I was able to follow the change.
Python/ceval.c
Outdated
STAT_INC(loadglobal_deferred); | ||
cache->adaptive.counter--; | ||
oparg = cache->adaptive.original_oparg; | ||
JUMP_TO_INSTRUCTION(LOAD_GLOBAL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also virtual identical, right? Will that be the case for all the XXXX_ADAPTIVE
opcodes?
Python/specialize.c
Outdated
goto fail; | ||
} | ||
cache1->module_keys_version = keys_version; | ||
cache0->index = index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was going to ask about this (Py_ssize_t
-> uint16_t
) but looks like GHA beat me to it. :) Does this limit us on the size of the builtins/globals dicts or are dicts already constrained to 2^16 entries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We just can't optimize access to variables with index > 64k.
If your module has more than 64k variables, then you have plenty of other problems 🙂
SpecializedCacheEntry *caches = GET_CACHE(); | ||
_PyAdaptiveEntry *cache0 = &caches[0].adaptive; | ||
_PyLoadGlobalCache *cache1 = &caches[-1].load_global; | ||
DEOPT_IF(dict->ma_keys->dk_version != cache1->module_keys_version, LOAD_GLOBAL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also need to check the case where it's a different globals dict? It can't be done from Python (except if someone creates a new function using the code object from another function, or passes the code object to exec()
) but can easily be done from C. There is the remote chance that (in that already unlikely case) the keys version is the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the keys version is the same, then it has the same keys in the same order and is the same kind of dict.
In which case it doesn't matter if it is a different dictionary, because we cache the index, not the value.
As an aside, you can get different dictionaries with the same keys as module dicts at different times.
class C: pass
d1 = C().__dict__
d2 = C().__dict__
# d1 and d2 should share keys
m = ModuleType()
m.__dict__ = d1
# Specialize
m.__dict__ = d2
# globals in m would see same keys as when specialized
…-26638) * Add specializations of LOAD_GLOBAL. * Add more stats. * Remove old opcache; it is no longer used. * Add NEWS
Adds two specializations of
LOAD_GLOBAL
:LOAD_GLOBAL_MODULE
for module variablesLOAD_GLOBAL_BUILTIN
for builtins.Removes the old "opcache" mechanism.
Adds a few more stats (hidden behind a compile-time flag).
https://bugs.python.org/issue44338