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-43846: Use less stack for large literals and calls #25403

Merged
merged 6 commits into from Apr 15, 2021

Conversation

markshannon
Copy link
Member

@markshannon markshannon commented Apr 14, 2021

Prevents excessive stack usage for oversized calls and literals.
Having a soft upper limit on stack usage allows us to design more efficient stack layouts
without worrying about code that uses huge amounts of stack.

As giant literals and calls are rare, this PR should have negligible effect on performance.

https://bugs.python.org/issue43846

Copy link
Member

@gvanrossum gvanrossum left a comment

LG, just a few extreme nits.

Python/compile.c Outdated
if (n+pushed >= STACK_USE_GUIDELINE) {
ADDOP_I(c, build, pushed);
seen_star = 1;
}
else {
seen_star = 0;
}
Copy link
Member

@gvanrossum gvanrossum Apr 14, 2021

Choose a reason for hiding this comment

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

Hm, I suppose you could just set seen_star = 0 here and emit the push in the for-loop below when i+n exceeds the limit (and it hasn't been emitted yet). FWIW I wish during this phase the variable was called something like 'build_emitted', since that is really what it's keeping track of.

Copy link
Member Author

@markshannon markshannon Apr 15, 2021

Choose a reason for hiding this comment

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

Done.
I used sequence_built and also cleaned up the surrounding code a bit.

ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));

Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
if (value_count > STACK_USE_GUIDELINE) {
Copy link
Member

@gvanrossum gvanrossum Apr 14, 2021

Choose a reason for hiding this comment

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

Maybe use >= for consistency with earlier locations?

Copy link
Member Author

@markshannon markshannon Apr 15, 2021

Choose a reason for hiding this comment

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

I've used > throughout. It seems to fit better with STACK_USE_GUIDELINE being the maximum stack use.

Python/compile.c Outdated
@@ -4251,7 +4329,8 @@ compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t be
keyword_ty kw;
PyObject *keys, *key;
assert(n > 0);
if (n > 1) {
int big = n > STACK_USE_GUIDELINE/2;
Copy link
Member

@gvanrossum gvanrossum Apr 14, 2021

Choose a reason for hiding this comment

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

Ditto?

@markshannon markshannon merged commit 11e0b29 into python:master Apr 15, 2021
12 checks passed
@markshannon markshannon deleted the use-less-stack-for-literals branch Apr 15, 2021
kreathon pushed a commit to kreathon/cpython that referenced this pull request May 2, 2021
* Modify compiler to reduce stack consumption for large expressions.

* Add more tests for stack usage.

* Add NEWS item.

* Raise SystemError for truly excessive stack use.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants