-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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-40222: "Zero cost" exception handling #25729
Conversation
…o restore when re-raising.
2e36c09
to
062ffa4
Compare
…e evaluation stack, not the block stack.
🤖 New build scheduled with the buildbot fleet by @markshannon for commit e1d6e1e 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
🤖 New build scheduled with the buildbot fleet by @markshannon for commit b92ada2 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
The failure on |
@markshannon Unfortunately the ASAN failure is legit. Check the BPO issue for more details. |
PyAPI_FUNC(PyCodeObject *) PyCode_New( | ||
int, int, int, int, int, PyObject *, PyObject *, | ||
PyObject *, PyObject *, PyObject *, PyObject *, | ||
PyObject *, PyObject *, int, PyObject *); | ||
PyObject *, PyObject *, int, PyObject *, PyObject *); | ||
|
||
PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs( | ||
int, int, int, int, int, int, PyObject *, PyObject *, | ||
PyObject *, PyObject *, PyObject *, PyObject *, | ||
PyObject *, PyObject *, int, PyObject *); | ||
PyObject *, PyObject *, int, PyObject *, PyObject *); |
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 C-API change seems worth mentioning somewhere.
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.
Check the discussion in https://bugs.python.org/issue40222
@@ -308,8 +311,33 @@ def _get_name_info(name_index, name_list): | |||
return argval, argrepr | |||
|
|||
|
|||
def parse_varint(iterator): | |||
b = next(iterator) | |||
val = b & 63 |
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.
Just curious, how does this work? I guess the constant numbers are about 64-bit?
would love to get your explanation, thanks. @markshannon
For example, this function:
compiles as follows on main:
with this PR it compiles as follows:
This is not quite zero-cost at the moment, as it leaves a
NOP
s for eachtry
, and possibly a few other.Removing
NOP
s that are on a line by themselves will require changes to the line number table, which has nothing to do with exception handling and I don't want to mix the two PRs.Although the code is slightly longer overall, there is less work done on the non-exceptional path, one
NOP
versus aSETUP_FINALLY
andPOP_BLOCK
.Not only is there a reduction in work done in the bytecode, but in the size of frames is reduced a lot:
On master:
with this PR:
https://bugs.python.org/issue40222