Bug 1745117 Comment 1 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

The reason why this happens is:

js/src/vm/ArrayBufferObject.h:193
```
188	  // The length of an ArrayBuffer or SharedArrayBuffer can be at most
189	  // INT32_MAX. Allow a larger limit on friendly 64-bit platforms if the
190	  // experimental large-buffers flag is used.
191	  static size_t maxBufferByteLength() {
192	#ifdef JS_64BIT
193	    if (supportLargeBuffers) {
194	      return size_t(8) * 1024 * 1024 * 1024;  // 8 GB.
195	    }
196	#endif
197	    return MaxByteLengthForSmallBuffer;
198	  }
```

Due to `--no-large-arraybuffers`, MaxByteLengthForSmallBuffer is `2**31 - 1` (2GB - 1) instead of `2**33` (8GB).

This means that:

js/src/wasm/WasmMemory.cpp:265 (non-cranelift code)
```
263	wasm::Pages wasm::MaxMemoryPages(IndexType t) {
264	  MOZ_ASSERT_IF(t == IndexType::I64, !IsHugeMemoryEnabled(t));
265	  MOZ_ASSERT_IF(t == IndexType::I64,
266	                ArrayBufferObject::maxBufferByteLength() % PageSize == 0);
267	  size_t desired = MaxMemoryLimitField(t);
268	  size_t actual = ArrayBufferObject::maxBufferByteLength() / PageSize;
269	  return wasm::Pages(std::min(desired, actual));
270	}
271	#  endif
```

The modulus check for `ArrayBufferObject::maxBufferByteLength() % PageSize` fails as the value is 1 instead of 0. In a release build, `actual` will then be 32767 which is not a `2**n` value.

Assuming the assertion message always has to be true, we could try removing the `if (supportLargeBuffers) {` guard check to always emit 8GB from maxBufferByteLength() on 64-bit systems. Or, emit `MaxByteLengthForSmallBuffer + 1` if on `--no-large-arraybuffers` for those 64-bit systems instead, as `MaxByteLengthForSmallBuffer % PageSize` is 1 instead of 0.

Otherwise, the assertion at https://searchfox.org/mozilla-central/rev/1674b86019a96f076e0f98f1d0f5f3ab9d4e9020/js/src/wasm/WasmMemory.h#79 also fails, as `32767 % PageSize` is no longer equal to zero.
The reason why this happens is:

js/src/vm/ArrayBufferObject.h:193
```
188	  // The length of an ArrayBuffer or SharedArrayBuffer can be at most
189	  // INT32_MAX. Allow a larger limit on friendly 64-bit platforms if the
190	  // experimental large-buffers flag is used.
191	  static size_t maxBufferByteLength() {
192	#ifdef JS_64BIT
193	    if (supportLargeBuffers) {
194	      return size_t(8) * 1024 * 1024 * 1024;  // 8 GB.
195	    }
196	#endif
197	    return MaxByteLengthForSmallBuffer;
198	  }
```

Due to `--no-large-arraybuffers`, MaxByteLengthForSmallBuffer is `2**31 - 1` (2GB - 1) instead of `2**33` (8GB).

This means that:

js/src/wasm/WasmMemory.cpp:265 (non-cranelift code)
```
263	wasm::Pages wasm::MaxMemoryPages(IndexType t) {
264	  MOZ_ASSERT_IF(t == IndexType::I64, !IsHugeMemoryEnabled(t));
265	  MOZ_ASSERT_IF(t == IndexType::I64,
266	                ArrayBufferObject::maxBufferByteLength() % PageSize == 0);
267	  size_t desired = MaxMemoryLimitField(t);
268	  size_t actual = ArrayBufferObject::maxBufferByteLength() / PageSize;
269	  return wasm::Pages(std::min(desired, actual));
270	}
271	#  endif
```

The modulus check for `ArrayBufferObject::maxBufferByteLength() % PageSize` fails as the value is 1 instead of 0. In a release build, `actual` will then be 32767 which is not a `2**n` value.

~~Assuming the assertion message always has to be true, we could try removing the `if (supportLargeBuffers) {` guard check to always emit 8GB from maxBufferByteLength() on 64-bit systems. Or, emit `MaxByteLengthForSmallBuffer + 1` if on `--no-large-arraybuffers` for those 64-bit systems instead, as `MaxByteLengthForSmallBuffer % PageSize` is 1 instead of 0.~~ (Edit: I don't think the fix should be in `ArrayBufferObject`, it should be in wasm code instead)

Otherwise, the assertion at https://searchfox.org/mozilla-central/rev/1674b86019a96f076e0f98f1d0f5f3ab9d4e9020/js/src/wasm/WasmMemory.h#79 also fails, as `32767 % PageSize` is no longer equal to zero.

Back to Bug 1745117 Comment 1