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

Execution context stack space #777

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

chfast
Copy link
Collaborator

@chfast chfast commented Mar 31, 2021

This implements segmented stack space inside ExecutionContext. I will add more documentation how it works later.
Replaces #529 and #572.

Generally, having unlimited stack space is PITA, but doable.

Before this lands I propose to generalize ExecutionContext:

  • move it to execution_context.hpp,
  • rename Guard to something like LocalContext,
  • rename increment_call_depth() to something like create_local_context().

@codecov
Copy link

codecov bot commented Mar 31, 2021

Codecov Report

Merging #777 (5c43bf4) into master (3afc039) will decrease coverage by 0.06%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #777      +/-   ##
==========================================
- Coverage   99.24%   99.18%   -0.07%     
==========================================
  Files          79       77       -2     
  Lines       11962    10948    -1014     
==========================================
- Hits        11872    10859    -1013     
+ Misses         90       89       -1     
Flag Coverage Δ
rust ?
spectests 90.61% <100.00%> (+0.06%) ⬆️
unittests 99.18% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
test/unittests/cxx20_span_test.cpp 100.00% <ø> (ø)
lib/fizzy/execute.cpp 99.53% <100.00%> (+<0.01%) ⬆️
lib/fizzy/execution_context.hpp 100.00% <100.00%> (ø)
lib/fizzy/stack.hpp 100.00% <100.00%> (ø)
bindings/rust/src/lib.rs

@chfast chfast force-pushed the execution_context_stack_space branch from fef2074 to 47111ae Compare March 31, 2021 17:44
@chfast chfast requested review from gumb0 and axic March 31, 2021 17:51
@chfast chfast force-pushed the execution_context_stack_space branch 2 times, most recently from 0e5287c to 85c5b53 Compare April 12, 2021 13:51
@chfast chfast marked this pull request as ready for review April 12, 2021 13:52
@chfast
Copy link
Collaborator Author

chfast commented Apr 12, 2021

Unit tests will be updated later.


OperandStack stack(args, func_type.inputs.size(), code.local_count,
static_cast<size_t>(code.max_stack_height));
const auto local_ctx = ctx.create_local_context(required_stack_space);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should handle somehow that this can throw now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It throws before too.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah right.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

To be precise: now create_local_context() throws, previously OperandStack was throwing (now noexcept).

Someone should handle this separately. But there is also easy solution: have fixed shared stack space. In case of out-of-space we can trap the execution.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Catching bad_alloc and trapping would also be easy

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But this is non-deterministic execution.

prev_stack_space_segment = m_shared_ctx.stack_space_segment;
const auto new_segment_size =
std::max(DefaultStackSpaceSegmentSize, required_stack_space);
m_shared_ctx.stack_space_segment = new Value[new_segment_size];
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would allow a performance degrading behaviour like growing stack to almost DefaultStackSpaceSegmentSize, then calling a function in a loop that goes over the limit, allocates new segment and immediately deallocates after return, and that's repeated in a loop.
Should this be a concern? I can imagine mitigation with increasing allocation size each time, and keeping the last allocation size in m_shared_ctx.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is a concern, but the same as before (where stack space was dynamically allocated in some cases).
I don't think the increasing allocation size is the solution - it will still continue to deallocating new segment, now bigger each time.
The solution I considered is never deallocate segments. They work as linked list of buffers. However, such solution might require more housekeeping.

@chfast chfast force-pushed the execution_context_stack_space branch from 85c5b53 to 31f44e0 Compare April 14, 2021 10:27
@chfast chfast force-pushed the execution_context_stack_space branch from 31f44e0 to 2d29813 Compare April 14, 2021 11:31
@axic axic added the optimization Performance optimization label May 5, 2021
@axic
Copy link
Member

axic commented May 29, 2022

Replaces #529 and #572.

Can we close those two?

This was referenced May 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
optimization Performance optimization
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants