Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions AstSemantics.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,18 @@ Out of bounds accesses trap.

In the MVP, linear memory can be resized by a `grow_memory` operator. The
operand to this operator is in units of the WebAssembly page size,
which is 64KiB on all engines (though large page support may be added in
which is defined to be 64KiB (though large page support may be added in
the [future](FutureFeatures.md#large-page-support)).

* `grow_memory` : grow linear memory by a given unsigned delta of pages.
Return the previous memory size in bytes.
Return the previous memory size in units of pages or -1 on failure.

When a maximum memory size is declared in the [memory section](Module.md#linear-memory-section),
`grow_memory` must fail if it would grow past the maximum. However,
`grow_memory` may still fail before the maximum if it was not possible to
reserve the space up front or if enabling the reserved memory fails.
When there is no maximum memory size declared, `grow_memory` is expected
to perform a system allocation which may fail.

As stated [above](AstSemantics.md#linear-memory), linear memory is contiguous,
meaning there are no "holes" in the linear address space. After the
Expand Down
13 changes: 9 additions & 4 deletions Modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,20 @@ by the module. If the section is absent, the linear memory operators
The linear memory section declares the initial [memory size](AstSemantics.md#linear-memory)
(which may be subsequently increased by [`grow_memory`](AstSemantics.md#resizing)).

The linear memory section may optionally declare a maximum memory size.
[`grow_memory`](AstSemantics.md#resizing) is guaranteed to fail if attempting to
grow past the declared maximum. When declared, implementations *should*
(non-normative) attempt to reserve virtual memory up to the maximum size. While
failure to allocate the *initial* memory size is a runtime error, failure to
reserve up to the *maximum* is not. When a maximum memory size is *not* declared,
on architectures with limited virtual address space, engines should allocate
only the initial size and reallocate on demand.
Copy link
Member

Choose a reason for hiding this comment

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

Virtual and physical? I'm confused now.

Copy link
Member

Choose a reason for hiding this comment

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

OK I'm confusing myself... I understand now.


The initial contents of linear memory are zero by default. However, the memory
section contains a possibly-empty array of *segments* (analogous to `.data`)
which can specify the initial contents of fixed `(offset, length)` ranges of
memory.

The linear memory section may also contain an optional hint declaring the expected
maximum heap usage. This hint is not semantically visible but can help a
WebAssembly engine to optimize `grow_memory`.

The linear memory section may optionally declare that the instance's
linear memory is *externally aliasable*. How linear memory is aliased is up
to the host environment (as with all module exports). The
Expand Down
32 changes: 32 additions & 0 deletions Rationale.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,38 @@ already be communicating between threads in order to properly allocate the sum
of the allocation requests, so it's expected that they can provide the needed
information without significant extra effort.

The [optional maximum size](Modules.md#linear-memory-section) is designed to
address a number of competing constraints:
1. Allow WebAssembly modules to grab large regions of contiguous memory in a
32-bit address space early in an application's startup before the virtual
address space becomes fragmented by execution of the application.
2. Allow many small WebAssembly instances to execute in a single 32-bit process.
(For example, it is common for a single web application to use dozens of
libraries, each of which may, over time, include WebAssembly modules as
implementation details.)
3. Avoid *forcing* every developer using WebAssembly to understand their precise
maximum heap usage.
4. When threading and shared memory are added to WebAssembly
[post-MVP](PostMVP.md#threads), the design should not require memory growth
to `realloc` since this implies significant implementation complexity,
security hazards, and optimization challenges.

The optional maximum addresses these constraints:
* (1) is addressed by specifying a large maximum memory size. Simply setting a
large *initial* memory size has problems due to (3) and the fact that a
failure to allocate initial is a fatal error which makes the choice of "how
big?" difficult.
* (2) and (3) are addressed by making the maximum optional combined with the
implied implementation that, on 32-bit, engines will not allocate
significantly more than the current memory size, *and* the compiler sets the
initial size to just enough to hold static data.
* (4) is addressed assuming that, when threading is added, a new, optional
"shared" flag is added to the memory section that must be set to enable shared
memory and the shared flag forces the maximum to be specified. In this case,
shared memory never moves; the only thing that changes is that the bounds
grows which does not have all the abovementioned hazards. In particular, any
extant `SharedArrayBuffer`s that alias linear memory stay valid without
any updates.

## Linear memory disabled if no linear memory section

Expand Down