Skip to content
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-45256: Remove the usage of the C stack in Python to Python calls #28488

Merged
merged 17 commits into from Oct 9, 2021

Conversation

pablogsal
Copy link
Member

@pablogsal pablogsal commented Sep 21, 2021

  • Remove the usage of the cstack in Python to Python calls
  • Fix gdb
  • Move depth to frame structure for easier retrieval in debugging tools
  • Refactor and simplifications

https://bugs.python.org/issue45256

@pablogsal pablogsal requested a review from markshannon as a code owner Sep 21, 2021
@pablogsal pablogsal added skip news 🔨 test-with-buildbots Test PR w/ buildbots; report in status section and removed 🔨 test-with-buildbots Test PR w/ buildbots; report in status section labels Sep 21, 2021
@bedevere-bot
Copy link

bedevere-bot commented Sep 21, 2021

🤖 New build scheduled with the buildbot fleet by @pablogsal for commit b4149b6d80bc85c73104ca0f98ee3754cf5d485c 🤖

If you want to schedule another build, you need to add the "🔨 test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 21, 2021
Copy link
Member

@markshannon markshannon left a comment

Looking good. A few minor issues.

Tools/gdb/libpython.py Outdated Show resolved Hide resolved
Python/ceval.c Outdated
static InterpreterFrame*
_PyEval_FrameFromPyFunctionAndArgs(PyThreadState *tstate, PyObject* const *args, int nargs, PyObject *function) {
assert(PyFunction_Check(function));
size_t nargsf = nargs | PY_VECTORCALL_ARGUMENTS_OFFSET;
Copy link
Member

@markshannon markshannon Sep 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nargsf and vector_nargs below are only used in asserts.
I think all the asserts and assignments to nargsf and vector_nargs could be replaced with assert(nargs == 0 || args != NULL);

Include/internal/pycore_frame.h Show resolved Hide resolved
Python/ceval.c Show resolved Hide resolved
Python/ceval.c Show resolved Hide resolved
@bedevere-bot
Copy link

bedevere-bot commented Sep 21, 2021

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

@pablogsal
Copy link
Member Author

pablogsal commented Sep 21, 2021

@markshannon Damn, unfortunately something is going on with Windows:

D:\a\cpython\cpython\PCbuild\python.vcxproj(125,5): warning MSB3073: The command "setlocal
D:\a\cpython\cpython\PCbuild\python.vcxproj(125,5): warning MSB3073: set PYTHONPATH=D:\a\cpython\cpython\Lib
D:\a\cpython\cpython\PCbuild\python.vcxproj(125,5): warning MSB3073: "D:\a\cpython\cpython\PCbuild\win32\python.exe" "D:\a\cpython\cpython\PC\validate_ucrtbase.py" ucrtbase" exited with code -1073741819.
D:\a\cpython\cpython\PCbuild\python.vcxproj(125,5): warning MSB4181: The "Exec" task returned false but did not log an error.
D:\a\cpython\cpython\PCbuild\regen.targets(107,5): error MSB3073: The command "D:\a\cpython\cpython\PCbuild\win32\python.exe Programs\freeze_test_frozenmain.py Programs/test_frozenmain.h" exited with code -1073741819. [D:\a\cpython\cpython\PCbuild\python.vcxproj]
    6 Warning(s)
    1 Error(s)

Time Elapsed 00:04:54.99

Apparently that is a File System error but I don't understand why this may be happening :(

@pablogsal
Copy link
Member Author

pablogsal commented Sep 21, 2021

@markshannon Oh, I found the source of the Windows failure: it was an existing bug in the PREDICT() macro for the code path without computed gotos. Fixed it in 50276ad8813bfd0bb0455d0e699e2ee301071f00

That was challenging to find indeed!

@pablogsal pablogsal added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 21, 2021
@bedevere-bot
Copy link

bedevere-bot commented Sep 21, 2021

🤖 New build scheduled with the buildbot fleet by @pablogsal for commit 50276ad8813bfd0bb0455d0e699e2ee301071f00 🤖

If you want to schedule another build, you need to add the "🔨 test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 21, 2021
Copy link
Member

@Fidget-Spinner Fidget-Spinner left a comment

This is really cool. I just have a few comments on readability. No idea why ASAN is failing tbh.

One other concern I have is that this slows down non-python function calls very slightly (with the two additional checks). I highly doubt it's measurable on pyperformance though.

Python/ceval.c Outdated Show resolved Hide resolved
Python/ceval.c Outdated Show resolved Hide resolved
Python/ceval.c Outdated
Py_DECREF(function);
_PyFrame_SetStackPointer(frame, stack_pointer);
new_frame->depth = frame->depth + 1;
tstate->frame = frame = new_frame;
Copy link
Member

@Fidget-Spinner Fidget-Spinner Sep 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self, no need to pop frame here because it's done on eval frame exit at exit_eval_frame.

Python/ceval.c Outdated Show resolved Hide resolved
Python/ceval.c Outdated Show resolved Hide resolved
Tools/gdb/libpython.py Outdated Show resolved Hide resolved
@pablogsal
Copy link
Member Author

pablogsal commented Sep 21, 2021

I cannot reproduce the ASAN bug. :(

@Fidget-Spinner
Copy link
Member

Fidget-Spinner commented Sep 21, 2021

There're refleaks but I can't pinpoint where :(

python.exe -m test test_grammar test_builtin -R 3:3
0:00:00 Run tests sequentially
0:00:00 [1/2] test_grammar
beginning 6 repetitions
123456
......
test_grammar leaked [12, 12, 12] references, sum=36
0:00:01 [2/2/1] test_builtin -- test_grammar failed (reference leak)
beginning 6 repetitions
123456
......
test_builtin leaked [13, 13, 13] references, sum=39
test_builtin failed (reference leak)

== Tests result: FAILURE ==

@pablogsal
Copy link
Member Author

pablogsal commented Sep 29, 2021

Commit 0ddc46e fixes the reference leaks (but it needs some cleanup as it requires simplification):

❯ ./python -m test test_extcall test_inspect test_ntpath test_posixpath test_typing test_unittest -R :
0:00:00 load avg: 2.22 Run tests sequentially
0:00:00 load avg: 2.22 [1/6] test_extcall
beginning 9 repetitions
123456789
.........
0:00:00 load avg: 2.22 [2/6] test_inspect
beginning 9 repetitions
123456789
.........
0:00:06 load avg: 2.21 [3/6] test_ntpath
beginning 9 repetitions
123456789
.........
0:00:07 load avg: 2.35 [4/6] test_posixpath
beginning 9 repetitions
123456789
.........
0:00:08 load avg: 2.35 [5/6] test_typing
beginning 9 repetitions
123456789
.........
0:00:09 load avg: 2.35 [6/6] test_unittest
beginning 9 repetitions
123456789
.........
test_unittest passed in 34.2 sec

== Tests result: SUCCESS ==

All 6 tests OK.

Total duration: 43.6 sec
Tests result: SUCCESS

@pablogsal pablogsal added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 29, 2021
@bedevere-bot
Copy link

bedevere-bot commented Sep 29, 2021

🤖 New build scheduled with the buildbot fleet by @pablogsal for commit 0ddc46e25e4885562f7d1e962b9b30eea2b0283d 🤖

If you want to schedule another build, you need to add the "🔨 test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 29, 2021
@markshannon
Copy link
Member

markshannon commented Sep 29, 2021

https://wiki.python.org/moin/DebuggingWithGdb

which is quite suboptimal. Maybe I should add a new section to the official docs. I am happy to pack that into this PR but maybe we should do it separately.

What do you think @markshannon ?

I hadn't realized the docs were so sparse. Probably best to do it in another PR.
I've opened https://bugs.python.org/issue45317 so we don't forget.

@pablogsal
Copy link
Member Author

pablogsal commented Sep 29, 2021

@markshannon what do you think of 0ddc46e for now? I dislike this approach (is correct, but is difficult to reason about if you don't have the full picture in mind). Should we do the refactor now, should we do a smaller refactor or should we just do some celanup of 0ddc46e ?

@markshannon
Copy link
Member

markshannon commented Sep 30, 2021

@markshannon what do you think of 0ddc46e for now? I dislike this approach (is correct, but is difficult to reason about if you don't have the full picture in mind). Should we do the refactor now, should we do a smaller refactor or should we just do some celanup of 0ddc46e ?

Just do the minimal cleanup of 0ddc46e that you are happy with for now.
And add a comment as to why it is correct.

@pablogsal pablogsal added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Oct 7, 2021
@bedevere-bot
Copy link

bedevere-bot commented Oct 7, 2021

🤖 New build scheduled with the buildbot fleet by @pablogsal for commit 1de88f6 🤖

If you want to schedule another build, you need to add the "🔨 test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Oct 7, 2021
@pablogsal
Copy link
Member Author

pablogsal commented Oct 7, 2021

@markshannon I had to fix some merge conflicts and I have done the cleanup. I am building again with the buildbot fleet but this should be ready for a first version.

@pablogsal pablogsal added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Oct 7, 2021
@bedevere-bot
Copy link

bedevere-bot commented Oct 7, 2021

🤖 New build scheduled with the buildbot fleet by @pablogsal for commit f313e8c 🤖

If you want to schedule another build, you need to add the "🔨 test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Oct 7, 2021
Copy link
Member

@Fidget-Spinner Fidget-Spinner left a comment

The C changes LGTM. Some minor formatting nits at https://github.com/python/cpython/pull/28488/files#r717573235 and below.

Huge disclaimer: I am not a Python-GDB expert! It would be better to have someone else reviewing those changes.

PyObject *function = PEEK(oparg + 1);
if (Py_TYPE(function) == &PyFunction_Type) {
PyCodeObject *code = (PyCodeObject*)PyFunction_GET_CODE(function);
PyObject *locals = code->co_flags & CO_OPTIMIZED ? NULL : PyFunction_GET_GLOBALS(function);
Copy link
Member

@Fidget-Spinner Fidget-Spinner Oct 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code from here onwards has waay more than 80 characters.

@pablogsal
Copy link
Member Author

pablogsal commented Oct 7, 2021

@Fidget-Spinner Thanks for the review!

I am not going to push anything new until the buildbots pass to not restart the long refleak builds yet again. I will fix the formatting issues in a new PR unless @markshannon wants to change something fundamental (I also plan to rename the frame->depth in another PR).

@Fidget-Spinner
Copy link
Member

Fidget-Spinner commented Oct 7, 2021

I am not going to push anything new until the buildbots pass to not restart the long refleak builds yet again.

I was just about to mention that. Good call!

// *valid* arguments (i.e. the ones that fit into the frame).
PyCodeObject *co = (PyCodeObject*)con->fc_code;
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
for (Py_ssize_t i = 0; i < Py_MIN(argcount, total_args); i++) {
Copy link
Member

@Fidget-Spinner Fidget-Spinner Oct 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GHA is warning:

comparison of integer expressions of different signedness: ‘Py_ssize_t’ {aka ‘long int’} and ‘long unsigned int’ [-Wsign-compare

and

'>': signed/unsigned mismatch [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]
Suggested change
for (Py_ssize_t i = 0; i < Py_MIN(argcount, total_args); i++) {
for (size_t i = 0; i < Py_MIN(argcount, (size_t)total_args); i++) {

@pablogsal pablogsal merged commit b4903af into python:main Oct 9, 2021
76 checks passed
@pablogsal pablogsal deleted the simple_cframe branch Oct 9, 2021
@pablogsal
Copy link
Member Author

pablogsal commented Oct 9, 2021

Cleanups happening here: #28836

@markshannon After that is merged, I will create a PR to address the counter to convert it to a "entry frame" flag.

@vstinner
Copy link
Member

vstinner commented Oct 11, 2021

This is really cool, nice work @pablogsal ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants