Skip to content

Commit 2d29813

Browse files
committed
Add ExecutionContext documentation
1 parent 0e1b315 commit 2d29813

1 file changed

Lines changed: 41 additions & 2 deletions

File tree

lib/fizzy/execution_context.hpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,32 @@
55
#pragma once
66

77
#include "value.hpp"
8+
#include <algorithm>
89
#include <cassert>
910
#include <cstddef>
1011

1112
namespace fizzy
1213
{
1314
/// The storage for information shared by calls in the same execution "thread".
1415
/// Users may decide how to allocate the execution context, but some good defaults are available.
16+
///
17+
/// The ExecutionContext manages WebAssembly stack space shared between calls in the same execution
18+
/// thread. The shared stack space is allocated and managed by create_local_context() and
19+
/// LocalContext objects.
20+
///
21+
/// The shared stack space is conceptually implemented as linked list of stack space segments.
22+
/// If the required stack space for a new call fits in the current segment no new
23+
/// allocation is needed. Otherwise new segment is allocated. The size of the new segment is
24+
/// at least DefaultStackSpaceSegmentSize but can be larger if the call's requires stack space
25+
/// exceeds the default size (in this case the call occupies the segment exclusively).
26+
///
27+
/// When the LocalContext which allocated new stack segment is being destroyed (i.e. when the first
28+
/// call occupying this stack segment ends) this segment is freed. This may not be the optimal
29+
/// strategy in case the same segment is going to be allocated multiple times.
30+
/// There is alternative design when segments are not freed when not used any more and can be reused
31+
/// when more stack space is needed. However, this requires additional housekeeping (e.g. having
32+
/// forward pointer to the next segment) and handling some additional edge-cases (e.g. reallocate
33+
/// an unused segment in case it is smaller then the required stack space).
1534
class ExecutionContext
1635
{
1736
static constexpr size_t DefaultStackSpaceSegmentSize = 100;
@@ -21,11 +40,20 @@ class ExecutionContext
2140
/// when going out of scope.
2241
class [[nodiscard]] LocalContext
2342
{
24-
ExecutionContext& m_shared_ctx; ///< Reference to the shared execution context.
43+
/// Reference to the shared execution context.
44+
ExecutionContext& m_shared_ctx;
2545

2646
public:
47+
/// Pointer to the reserved "required" stack space.
2748
Value* stack_space = nullptr;
49+
50+
/// Pointer to the previous segment.
51+
/// This is not null only for LocalContexts which allocated new segment.
2852
Value* prev_stack_space_segment = nullptr;
53+
54+
/// Amount of free stack space before this LocalContext has been created.
55+
/// This is used to restore "free" space information in ExecutionContext (m_shared_ctx)
56+
/// when this LocalContext object is destroyed.
2957
size_t prev_free_stack_space = 0;
3058

3159
LocalContext(const LocalContext&) = delete;
@@ -73,14 +101,25 @@ class ExecutionContext
73101
};
74102

75103
public:
104+
/// Pre-allocated first segment of the shared stack space.
76105
Value first_stack_space_segment[DefaultStackSpaceSegmentSize];
106+
107+
/// Point to the current stack space segment.
77108
Value* stack_space_segment = first_stack_space_segment;
109+
110+
/// Amount of free stack space remaining in the current segment.
111+
/// It is better to keep information about "free" than "used" space
112+
/// because then we don't need to know the current segment size.
78113
size_t free_stack_space = DefaultStackSpaceSegmentSize;
79114

80-
int depth = 0; ///< Current call depth.
115+
/// Current call depth.
116+
int depth = 0;
81117

82118
/// Increments the call depth and returns the local call context which
83119
/// decrements the call depth back to the original value when going out of scope.
120+
/// This also allocates and manages the shared stack space.
121+
/// @param required_stack_space Size of the required stack space in bytes.
122+
/// @see ExecutionContext
84123
LocalContext create_local_context(size_t required_stack_space = 0)
85124
{
86125
return LocalContext{*this, required_stack_space};

0 commit comments

Comments
 (0)