Uh oh!
There was an error while loading. Please reload this page.
bpo-43693: Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. - #26388
Conversation
af397af to
fda53f1CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
c95f4cc to
0d1d6cdComparemarkshannon
commented
May 28, 2021
Some thoughts on the API. I don't like the word "fast". It has no meaning and just makes names longer. I'd much prefer "variables" to "fastlocals". So I was thinking... classCodeType:
defget_variable_name(self, n:int):
"Return the names of the nth variable"defget_variable_scope(self, n:int):
"Returns the scope of the nth var (one of LOCAL, ESCAPES, FREE)"defget_variable_kind(self, n:int):
"Return the kind of nth var (one of LOCAL, ARG, VARARG, etc)"or classCodeType:
defget_variable_metadata(self, n:int):
"Returns a triple (name, scope, kind) for nth variable"What do you think? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
gvanrossum
commented
May 28, 2021
Yeah, they were fast several decades ago when this was an improvement over storing locals in a dict. :-) But it's a traditional name, and changing it would just add a bunch of additional unneeded churn (e.g. we have LOAD_FAST etc. -- to be consistent you'd have to rename those too). Plus, these locals really are pretty fast. :-) [...]
At least some debuggers access this data in C, so we'd have to introduce C API functions as well. I don't think we'll actually be able to come up with abstractions that won't have to change if this stuff changes again in the future. I think that at least for this PR, we should leave well enough alone -- at some point in the future, |
markshannon
commented
May 28, 2021
If the abstraction models the language, then it shouldn't need to change (unless the language does). The scope (local, escapes, or free), the kind (arg, kwarg, non-arg, etc), and the name are all properties of the variable and independent of the data structures used. |
gvanrossum
commented
May 28, 2021
via email
Yeah, let's make sure to settle this API once we're farther along, but
within the 3.11 timeframe. |
markshannon
commented
May 29, 2021
Why not do it now? What is the advantage of exposing things to hide them later. |
ericsnowcurrently
commented
Jun 2, 2021
I'm fine with taking a more neutral approach, along the lines you suggested. However, I don't want to introduce a new public API (in Python or in C) in this PR. |
ericsnowcurrently
commented
Jun 2, 2021
@markshannon, please take another look at this PR when you get the chance. |
markshannon
commented
Jun 3, 2021
Windows warnings need fixing: https://github.com/python/cpython/pull/26388/files#diff-ebc983d9f91e5bcf73500e377ac65e85863c4f77fd5b6b6caf4fcdf7c0f0b057R7253 You say that you don't want to add a public API, but that is what you are doing by adding |
ericsnowcurrently
commented
Jun 3, 2021
You mean the fields on the struct? I was talking about the attributes exposed to Python code. As far as the struct goes, I'm fine with adding an underscore prefix but I don't see the point since using the fields is required and given the class of expected users. I'd rather make In the meantime I will add an undercore prefix to those fields so we can move this along. |
markshannon
commented
Jun 3, 2021
I meant the Python attributes, but it looks like you've already removed them 👍 |
9dcd35d to
fdf040aComparefdf040a to
87cb192Compareericsnowcurrently
commented
Jun 3, 2021
Thanks, @markshannon! |
…names and co_fastlocalkinds. (pythongh-26388)" This reverts commit 2c1e258.
These were reverted in pythonGH-26530 (commit 17c4edc). * Compute deref offsets in compiler (pythongh-25152) * Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. (pythongh-26388)
These were reverted in gh-26530 (commit 17c4edc) due to refleaks. * 2c1e258 - Compute deref offsets in compiler (gh-25152) * b2bf2bc - Add new internal code objects fields: co_fastlocalnames and co_fastlocalkinds. (gh-26388) This change fixes the refleaks. https://bugs.python.org/issue43693
Uh oh!
There was an error while loading. Please reload this page.
A number of places in the code base (notably ceval.c and frameobject.c) rely on mapping variable names to indices in the frame "locals plus" array (AKA fast locals), and thus opargs. Currently the compiler indirectly encodes that information on the code object as the tuples
co_varnames,co_cellvars, andco_freevars. At runtime the dependent code must calculate the proper mapping from those, which isn't ideal and impacts performance-sensitive sections. This is something we can easily address in the compiler instead.This PR addresses the situation by replacing internal use of
co_varnames, etc. with a single combined tuple of names in locals-plus order, along with a minimal array mapping each to its kind (local vs. cell vs. free). These two newPyCodeObjectfields,co_fastlocalnamesandco_fastllocalkinds, are not exposed to Python code for now, butco_varnames, etc. are still available with the same values as before (though computed lazily).Aside from the (mild) performance impact, there are a number of other benefits:
Also note that we can take this approach further by expanding the possible values in
co_fastlocalkindsto include specific argument types (e.g. positional-only, kwargs). Doing so would allow further speed-ups in_PyEval_MakeFrameVector(), which is where args get unpacked into the locals-plus array. It would also allow us to shrink marshaled code objects even further.(FYI, I have a later PR that relies on having this direct mapping instead of
co_varnames.)FWIW, if this PR is too big I can split it up between "add the fields" and "use the fields". However, typically in this project we keep those together in one change.
https://bugs.python.org/issue43693