Skip to content

Commit f1bdd8c

Browse files
gibson042ljharb
authored andcommitted
Editorial: Introduce term "memory range" to provide links for Shared Data Block event comparison (tc39#3396)
1 parent 6d9abef commit f1bdd8c

1 file changed

Lines changed: 24 additions & 24 deletions

File tree

spec.html

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14931,7 +14931,7 @@ <h1>
1493114931
1. Let _elementSize_ be TypedArrayElementSize(_O_).
1493214932
1. Let _arrayByteLength_ be _O_.[[ArrayLength]] × _elementSize_.
1493314933
1. Let _byteOffsetEnd_ be _byteOffsetStart_ + _arrayByteLength_.
14934-
1. NOTE: A 0-length TypedArray with [[ByteOffset]] equal to _bufferByteLength_ is not considered out-of-bounds.
14934+
1. NOTE: A 0-length TypedArray whose [[ByteOffset]] is _bufferByteLength_ is not considered out-of-bounds.
1493514935
1. If _byteOffsetStart_ > _bufferByteLength_ or _byteOffsetEnd_ > _bufferByteLength_, return *true*.
1493614936
1. Return *false*.
1493714937
</emu-alg>
@@ -43681,7 +43681,7 @@ <h1>%MapIteratorPrototype% [ %Symbol.toStringTag% ]</h1>
4368143681

4368243682
<emu-clause id="sec-set-objects">
4368343683
<h1>Set Objects</h1>
43684-
<p><dfn variants="Set object">Set objects</dfn> are collections of ECMAScript language values. A distinct value may only occur once as an element of a Set's collection. Distinct values are discriminated using the semantics of the SameValueZero comparison algorithm.</p>
43684+
<p><dfn variants="Set object">Set objects</dfn> are collections of ECMAScript language values. A Set may contain each distinct value at most once. Distinct values are discriminated using the semantics of the SameValueZero comparison algorithm.</p>
4368543685
<p>Set objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this specification is only intended to describe the required observable semantics of Set objects. It is not intended to be a viable implementation model.</p>
4368643686

4368743687
<emu-clause id="sec-abstract-operations-for-set-objects">
@@ -45742,7 +45742,7 @@ <h1>
4574245742
1. Let _byteOffsetEnd_ be _bufferByteLength_.
4574345743
1. Else,
4574445744
1. Let _byteOffsetEnd_ be _byteOffsetStart_ + _view_.[[ByteLength]].
45745-
1. NOTE: A 0-length DataView with [[ByteOffset]] equal to _bufferByteLength_ is not considered out-of-bounds.
45745+
1. NOTE: A 0-length DataView whose [[ByteOffset]] is _bufferByteLength_ is not considered out-of-bounds.
4574645746
1. If _byteOffsetStart_ > _bufferByteLength_ or _byteOffsetEnd_ > _bufferByteLength_, return *true*.
4574745747
1. Return *false*.
4574845748
</emu-alg>
@@ -51238,7 +51238,7 @@ <h1>Memory Model Fundamentals</h1>
5123851238
<tr>
5123951239
<td>[[NoTear]]</td>
5124051240
<td>a Boolean</td>
51241-
<td>Whether this event is allowed to read from multiple write events with equal range as this event.</td>
51241+
<td>Whether this event is allowed to read from multiple write events with equal memory range as this event.</td>
5124251242
</tr>
5124351243
<tr>
5124451244
<td>[[Block]]</td>
@@ -51275,7 +51275,7 @@ <h1>Memory Model Fundamentals</h1>
5127551275
<tr>
5127651276
<td>[[NoTear]]</td>
5127751277
<td>a Boolean</td>
51278-
<td>Whether this event is allowed to be read from multiple read events with equal range as this event.</td>
51278+
<td>Whether this event is allowed to be read from multiple read events with equal memory range as this event.</td>
5127951279
</tr>
5128051280
<tr>
5128151281
<td>[[Block]]</td>
@@ -51348,7 +51348,7 @@ <h1>Memory Model Fundamentals</h1>
5134851348
</emu-table>
5134951349

5135051350
<p>Shared Data Block events are introduced to candidate execution Agent Events Records by abstract operations or by methods on the Atomics object. Some operations also introduce <dfn variants="Synchronize,Synchronize event">Synchronize events</dfn>, which have no fields and exist purely to directly constrain the permitted orderings of other events. And finally, there are host-specific events. A <dfn variants="Memory events">Memory event</dfn> is either a Shared Data Block event, Synchronize event, or such a host-specific event.</p>
51351-
<p>Let the range of a Shared Data Block event be the Set of contiguous integers from its [[ByteIndex]] to [[ByteIndex]] + [[ElementSize]] - 1. Two events' ranges are equal when the events have the same [[Block]], [[ByteIndex]], and [[ElementSize]]. Two events' ranges are overlapping when the events have the same [[Block]], the ranges are not equal, and their intersection is non-empty. Two events' ranges are disjoint when the events do not have the same [[Block]] or their ranges are neither equal nor overlapping.</p>
51351+
<p>Let the <dfn variants="memory ranges">memory range</dfn> of a Shared Data Block event _e_ be the Set of all integers in the interval from _e_.[[ByteIndex]] (inclusive) to _e_.[[ByteIndex]] + _e_.[[ElementSize]] (exclusive). Two events' memory ranges are equal when the events have the same [[Block]], [[ByteIndex]], and [[ElementSize]]. Two events' memory ranges are overlapping when the events have the same [[Block]], the ranges are not equal, and their intersection is non-empty. Two events' memory ranges are disjoint when the events do not have the same [[Block]] or their ranges are neither equal nor overlapping.</p>
5135251352
<emu-note>
5135351353
<p>Examples of host-specific synchronizing events that should be accounted for are: sending a SharedArrayBuffer from one agent to another (e.g., by `postMessage` in a browser), starting and stopping agents, and communicating within the agent cluster via channels other than shared memory. For a particular execution _execution_, those events are provided by the host via the host-synchronizes-with strict partial order. Additionally, hosts can add host-specific synchronizing events to _execution_.[[EventList]] so as to participate in the is-agent-order-before Relation.</p>
5135451354
</emu-note>
@@ -51485,7 +51485,7 @@ <h1>
5148551485
<dl class="header">
5148651486
</dl>
5148751487
<emu-alg>
51488-
1. Return the subtraction of SharedDataBlockEventSet(_execution_) from EventSet(_execution_).
51488+
1. Return a new Set containing all elements of EventSet(_execution_) that are not in SharedDataBlockEventSet(_execution_).
5148951489
</emu-alg>
5149051490
</emu-clause>
5149151491

@@ -51503,7 +51503,7 @@ <h1>
5150351503
1. Let _byteLocation_ be _byteIndex_.
5150451504
1. Let _bytesRead_ be a new empty List.
5150551505
1. For each element _W_ of _Ws_, do
51506-
1. Assert: _W_ has _byteLocation_ in its range.
51506+
1. Assert: _W_ has _byteLocation_ in its memory range.
5150751507
1. Let _payloadIndex_ be _byteLocation_ - _W_.[[ByteIndex]].
5150851508
1. If _W_ is a WriteSharedMemory event, then
5150951509
1. Let _byte_ be _W_.[[Payload]][_payloadIndex_].
@@ -51565,7 +51565,7 @@ <h1>reads-bytes-from</h1>
5156551565
<li>
5156651566
<p>For each ReadSharedMemory or ReadModifyWriteSharedMemory event _R_ in SharedDataBlockEventSet(_execution_), reads-bytes-from(_R_) in _execution_ is a List of length _R_.[[ElementSize]] whose elements are WriteSharedMemory or ReadModifyWriteSharedMemory events _Ws_ such that all of the following are true.</p>
5156751567
<ul>
51568-
<li>Each event _W_ with index _i_ in _Ws_ has _R_.[[ByteIndex]] + _i_ in its range.</li>
51568+
<li>Each event _W_ with index _i_ in _Ws_ has _R_.[[ByteIndex]] + _i_ in its memory range.</li>
5156951569
<li>_R_ is not in _Ws_.</li>
5157051570
</ul>
5157151571
</li>
@@ -51602,7 +51602,7 @@ <h1>synchronizes-with</h1>
5160251602
<p>For a candidate execution _execution_, its <dfn>synchronizes-with</dfn> Relation is the least Relation on Memory events that satisfies the following.</p>
5160351603
<ul>
5160451604
<li>
51605-
For events _R_ and _W_, _W_ synchronizes-with _R_ in _execution_ if _R_ reads-from _W_ in _execution_, _R_.[[Order]] is ~seq-cst~, _W_.[[Order]] is ~seq-cst~, and _R_ and _W_ have equal ranges.
51605+
For events _R_ and _W_, _W_ synchronizes-with _R_ in _execution_ if _R_ reads-from _W_ in _execution_, _R_.[[Order]] is ~seq-cst~, _W_.[[Order]] is ~seq-cst~, and _R_ and _W_ have equal memory ranges.
5160651606
</li>
5160751607
<li>
5160851608
For each element _eventsRecord_ of _execution_.[[EventsRecords]], the following is true.
@@ -51622,7 +51622,7 @@ <h1>synchronizes-with</h1>
5162251622
</emu-note>
5162351623

5162451624
<emu-note>
51625-
<p>In a candidate execution _execution_, not all ~seq-cst~ events related by reads-from are related by synchronizes-with. Only events that also have equal ranges are related by synchronizes-with.</p>
51625+
<p>In a candidate execution _execution_, not all ~seq-cst~ events related by reads-from are related by synchronizes-with. Only events that also have equal memory ranges are related by synchronizes-with.</p>
5162651626
</emu-note>
5162751627

5162851628
<emu-note>
@@ -51640,7 +51640,7 @@ <h1>happens-before</h1>
5164051640
<ul>
5164151641
<li>_E_ is-agent-order-before _D_ in _execution_.</li>
5164251642
<li>_E_ synchronizes-with _D_ in _execution_.</li>
51643-
<li>SharedDataBlockEventSet(_execution_) contains both _E_ and _D_, _E_.[[Order]] is ~init~, and _E_ and _D_ have overlapping ranges.</li>
51643+
<li>SharedDataBlockEventSet(_execution_) contains both _E_ and _D_, _E_.[[Order]] is ~init~, and _E_ and _D_ have overlapping memory ranges.</li>
5164451644
<li>There is an event _F_ such that _E_ happens-before _F_ and _F_ happens-before _D_ in _execution_.</li>
5164551645
</ul>
5164651646
</li>
@@ -51683,7 +51683,7 @@ <h1>Coherent Reads</h1>
5168351683
1. For each element _W_ of _Ws_, do
5168451684
1. If _R_ happens-before _W_ in _execution_, then
5168551685
1. Return *false*.
51686-
1. If there exists a WriteSharedMemory or ReadModifyWriteSharedMemory event _V_ that has _byteLocation_ in its range such that _W_ happens-before _V_ in _execution_ and _V_ happens-before _R_ in _execution_, then
51686+
1. If there exists a WriteSharedMemory or ReadModifyWriteSharedMemory event _V_ that has _byteLocation_ in its memory range such that _W_ happens-before _V_ in _execution_ and _V_ happens-before _R_ in _execution_, then
5168751687
1. Return *false*.
5168851688
1. Set _byteLocation_ to _byteLocation_ + 1.
5168951689
1. Return *true*.
@@ -51698,7 +51698,7 @@ <h1>Tear Free Reads</h1>
5169851698
1. If _R_.[[NoTear]] is *true*, then
5169951699
1. Assert: The remainder of dividing _R_.[[ByteIndex]] by _R_.[[ElementSize]] is 0.
5170051700
1. For each Memory event _W_ such that _R_ reads-from _W_ in _execution_ and _W_.[[NoTear]] is *true*, do
51701-
1. If _R_ and _W_ have equal ranges and there exists a Memory event _V_ such that _V_ and _W_ have equal ranges, _V_.[[NoTear]] is *true*, _W_ and _V_ are not the same Shared Data Block event, and _R_ reads-from _V_ in _execution_, then
51701+
1. If _R_ and _W_ have equal memory ranges and there exists a Memory event _V_ such that _V_ and _W_ have equal memory ranges, _V_.[[NoTear]] is *true*, _W_ and _V_ are not the same Shared Data Block event, and _R_ reads-from _V_ in _execution_, then
5170251702
1. Return *false*.
5170351703
1. Return *true*.
5170451704
</emu-alg>
@@ -51717,18 +51717,18 @@ <h1>Sequentially Consistent Atomics</h1>
5171751717
<li>
5171851718
<p>For events _R_ and _W_ such that _R_ reads-from _W_ in _execution_, there is no WriteSharedMemory or ReadModifyWriteSharedMemory event _V_ in SharedDataBlockEventSet(_execution_) such that _V_.[[Order]] is ~seq-cst~, _W_ is-memory-order-before _V_ in _execution_, _V_ is-memory-order-before _R_ in _execution_, and any of the following conditions are true.</p>
5171951719
<ul>
51720-
<li>_W_ synchronizes-with _R_ in _execution_, and _V_ and _R_ have equal ranges.</li>
51721-
<li>_W_ happens-before _R_ and _V_ happens-before _R_ in _execution_, _W_.[[Order]] is ~seq-cst~, and _W_ and _V_ have equal ranges.</li>
51722-
<li>_W_ happens-before _R_ and _W_ happens-before _V_ in _execution_, _R_.[[Order]] is ~seq-cst~, and _V_ and _R_ have equal ranges.</li>
51720+
<li>_W_ synchronizes-with _R_ in _execution_, and _V_ and _R_ have equal memory ranges.</li>
51721+
<li>_W_ happens-before _R_ and _V_ happens-before _R_ in _execution_, _W_.[[Order]] is ~seq-cst~, and _W_ and _V_ have equal memory ranges.</li>
51722+
<li>_W_ happens-before _R_ and _W_ happens-before _V_ in _execution_, _R_.[[Order]] is ~seq-cst~, and _V_ and _R_ have equal memory ranges.</li>
5172351723
</ul>
5172451724
<emu-note>
51725-
<p>This clause additionally constrains ~seq-cst~ events on equal ranges.</p>
51725+
<p>This clause additionally constrains ~seq-cst~ events on equal memory ranges.</p>
5172651726
</emu-note>
5172751727
</li>
5172851728
<li>
51729-
<p>For each WriteSharedMemory or ReadModifyWriteSharedMemory event _W_ in SharedDataBlockEventSet(_execution_), if _W_.[[Order]] is ~seq-cst~, then it is not the case that there is an infinite number of ReadSharedMemory or ReadModifyWriteSharedMemory events in SharedDataBlockEventSet(_execution_) with equal range that is memory-order before _W_.</p>
51729+
<p>For each WriteSharedMemory or ReadModifyWriteSharedMemory event _W_ in SharedDataBlockEventSet(_execution_), if _W_.[[Order]] is ~seq-cst~, then it is not the case that there is an infinite number of ReadSharedMemory or ReadModifyWriteSharedMemory events in SharedDataBlockEventSet(_execution_) with equal memory range that is memory-order before _W_.</p>
5173051730
<emu-note>
51731-
<p>This clause together with the forward progress guarantee on agents ensure the liveness condition that ~seq-cst~ writes become visible to ~seq-cst~ reads with equal range in finite time.</p>
51731+
<p>This clause together with the forward progress guarantee on agents ensure the liveness condition that ~seq-cst~ writes become visible to ~seq-cst~ reads with equal memory range in finite time.</p>
5173251732
</emu-note>
5173351733
</li>
5173451734
</ul>
@@ -51760,7 +51760,7 @@ <h1>Races</h1>
5176051760
<emu-alg>
5176151761
1. If _E_ and _D_ are not the same Shared Data Block event, then
5176251762
1. If it is not the case that both _E_ happens-before _D_ in _execution_ and _D_ happens-before _E_ in _execution_, then
51763-
1. If _E_ and _D_ are both WriteSharedMemory or ReadModifyWriteSharedMemory events and _E_ and _D_ do not have disjoint ranges, then
51763+
1. If _E_ and _D_ are both WriteSharedMemory or ReadModifyWriteSharedMemory events and _E_ and _D_ do not have disjoint memory ranges, then
5176451764
1. Return *true*.
5176551765
1. If _E_ reads-from _D_ in _execution_ or _D_ reads-from _E_ in _execution_, then
5176651766
1. Return *true*.
@@ -51775,7 +51775,7 @@ <h1>Data Races</h1>
5177551775
1. If _E_ and _D_ are in a <emu-xref href="#sec-races">race</emu-xref> in _execution_, then
5177651776
1. If _E_.[[Order]] is not ~seq-cst~ or _D_.[[Order]] is not ~seq-cst~, then
5177751777
1. Return *true*.
51778-
1. If _E_ and _D_ have overlapping ranges, then
51778+
1. If _E_ and _D_ have overlapping memory ranges, then
5177951779
1. Return *true*.
5178051780
1. Return *false*.
5178151781
</emu-alg>
@@ -51804,7 +51804,7 @@ <h1>Shared Memory Guidelines</h1>
5180451804
<p>Any transformation of an agent-order slice that is valid in the absence of shared memory is valid in the presence of shared memory, with the following exceptions.</p>
5180551805
<ul>
5180651806
<li>
51807-
<p><em>Atomics are carved in stone</em>: Program transformations must not cause any Shared Data Block events having [[Order]] ~seq-cst~ to be removed from the is-agent-order-before Relation, nor to be reordered with respect to each other, nor to be reordered inside an agent-order slice with respect to events having [[Order]] ~unordered~.</p>
51807+
<p><em>Atomics are carved in stone</em>: Program transformations must not cause any Shared Data Block events whose [[Order]] is ~seq-cst~ to be removed from the is-agent-order-before Relation, nor to be reordered with respect to each other, nor to be reordered inside an agent-order slice with respect to events whose [[Order]] is ~unordered~.</p>
5180851808
<p>(In practice, the prohibition on reorderings forces a compiler to assume that every ~seq-cst~ operation is a synchronization and included in the final is-memory-order-before Relation, which it would usually have to assume anyway in the absence of inter-agent program analysis. It also forces the compiler to assume that every call where the callee's effects on the memory-order are unknown may contain ~seq-cst~ operations.)</p>
5180951809
</li>
5181051810
<li>
@@ -51840,7 +51840,7 @@ <h1>Shared Memory Guidelines</h1>
5184051840
<li>Lock-free atomic read-modify-write accesses compile to a full fence, an atomic read-modify-write instruction sequence, and a full fence.</li>
5184151841
<li>Non-lock-free atomics compile to a spinlock acquire, a full fence, a series of non-atomic load and store instructions, a full fence, and a spinlock release.</li>
5184251842
</ul>
51843-
<p>That mapping is correct so long as an atomic operation on an address range does not race with a non-atomic write or with an atomic operation of different size. However, that is all we need: the memory model effectively demotes the atomic operations involved in a race to non-atomic status. On the other hand, the naive mapping is quite strong: it allows atomic operations to be used as sequentially consistent fences, which the memory model does not actually guarantee.</p>
51843+
<p>That mapping is correct so long as an atomic operation on a memory range does not race with a non-atomic write or with an atomic operation of different size. However, that is all we need: the memory model effectively demotes the atomic operations involved in a race to non-atomic status. On the other hand, the naive mapping is quite strong: it allows atomic operations to be used as sequentially consistent fences, which the memory model does not actually guarantee.</p>
5184451844
<p>Local improvements to those basic patterns are also allowed, subject to the constraints of the memory model. For example:</p>
5184551845
<ul>
5184651846
<li>There are obvious platform-dependent improvements that remove redundant fences. For example, on x86 the fences around lock-free atomic loads and stores can always be omitted except for the fence following a store, and no fence is needed for lock-free read-modify-write instructions, as these all use <code>LOCK</code>-prefixed instructions. On many platforms there are fences of several strengths, and weaker fences can be used in certain contexts without destroying sequential consistency.</li>

0 commit comments

Comments
 (0)