Skip to content

Add fast paths for array's fill method #2307

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

Merged
merged 2 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions src/bindings/js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -871,8 +871,8 @@ export class JSBuilder extends ExportsWalker {
sb.push(`
} = await (async url => instantiate(
await (async () => {
try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)) }
catch { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)) }
try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }
catch { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)); }
})(), {
`);
let needsMaybeDefault = false;
Expand Down
28 changes: 28 additions & 0 deletions std/assembly/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,34 @@ export class Array<T> {
);
}
} else {
if (ASC_SHRINK_LEVEL <= 1) {
if (isInteger<T>()) {
// @ts-ignore
if (value == <T>0 | value == <T>-1) {
if (start < end) {
memory.fill(
ptr + (<usize>start << alignof<T>()),
u8(value),
<usize>(end - start) << alignof<T>()
);
}
return this;
}
} else if (isFloat<T>()) {
// for floating non-negative zeros we can use fast memory.fill
if ((sizeof<T>() == 4 && reinterpret<u32>(f32(value)) == 0) ||
(sizeof<T>() == 8 && reinterpret<u64>(f64(value)) == 0)) {
if (start < end) {
memory.fill(
ptr + (<usize>start << alignof<T>()),
0,
<usize>(end - start) << alignof<T>()
);
}
return this;
}
}
}
for (; start < end; ++start) {
store<T>(ptr + (<usize>start << alignof<T>()), value);
}
Expand Down
28 changes: 28 additions & 0 deletions std/assembly/staticarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,34 @@ export class StaticArray<T> {
);
}
} else {
if (ASC_SHRINK_LEVEL <= 1) {
if (isInteger<T>()) {
// @ts-ignore
if (value == <T>0 | value == <T>-1) {
if (start < end) {
memory.fill(
ptr + (<usize>start << alignof<T>()),
u8(value),
<usize>(end - start) << alignof<T>()
);
}
return this;
}
} else if (isFloat<T>()) {
// for floating non-negative zeros we can use fast memory.fill
if ((sizeof<T>() == 4 && reinterpret<u32>(f32(value)) == 0) ||
(sizeof<T>() == 8 && reinterpret<u64>(f64(value)) == 0)) {
if (start < end) {
memory.fill(
ptr + (<usize>start << alignof<T>()),
0,
<usize>(end - start) << alignof<T>()
);
}
return this;
}
}
}
for (; start < end; ++start) {
store<T>(ptr + (<usize>start << alignof<T>()), value);
}
Expand Down
28 changes: 28 additions & 0 deletions std/assembly/typedarray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,34 @@ function FILL<TArray extends ArrayBufferView, T extends number>(
if (sizeof<T>() == 1) {
if (start < end) memory.fill(ptr + <usize>start, <u8>value, <usize>(end - start));
} else {
if (ASC_SHRINK_LEVEL <= 1) {
if (isInteger<T>()) {
// @ts-ignore
if (value == <T>0 | value == <T>-1) {
if (start < end) {
memory.fill(
ptr + (<usize>start << alignof<T>()),
u8(value),
<usize>(end - start) << alignof<T>()
);
}
return array;
}
} else if (isFloat<T>()) {
// for floating non-negative zeros we can use fast memory.fill
if ((sizeof<T>() == 4 && reinterpret<u32>(f32(value)) == 0) ||
(sizeof<T>() == 8 && reinterpret<u64>(f64(value)) == 0)) {
if (start < end) {
memory.fill(
ptr + (<usize>start << alignof<T>()),
0,
<usize>(end - start) << alignof<T>()
);
}
return array;
}
}
}
for (; start < end; ++start) {
store<T>(ptr + (<usize>start << alignof<T>()), value);
}
Expand Down
9 changes: 4 additions & 5 deletions tests/compiler/bindings/esm.debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,10 +370,9 @@ export const {
newInternref,
internrefFunction
} = await (async url => instantiate(
await (
globalThis.fetch && globalThis.WebAssembly.compileStreaming
? globalThis.WebAssembly.compileStreaming(globalThis.fetch(url))
: globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url))
), {
await (async () => {
try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }
catch { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)); }
})(), {
}
))(new URL("esm.debug.wasm", import.meta.url));
9 changes: 4 additions & 5 deletions tests/compiler/bindings/esm.release.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,10 +370,9 @@ export const {
newInternref,
internrefFunction
} = await (async url => instantiate(
await (
globalThis.fetch && globalThis.WebAssembly.compileStreaming
? globalThis.WebAssembly.compileStreaming(globalThis.fetch(url))
: globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url))
), {
await (async () => {
try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }
catch { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)); }
})(), {
}
))(new URL("esm.release.wasm", import.meta.url));
8 changes: 4 additions & 4 deletions tests/compiler/std-wasi/crypto.debug.wat
Original file line number Diff line number Diff line change
Expand Up @@ -4912,7 +4912,7 @@
if
i32.const 448
i32.const 656
i32.const 1870
i32.const 1898
i32.const 5
call $~lib/wasi/index/abort
unreachable
Expand All @@ -4931,7 +4931,7 @@
if
i32.const 144
i32.const 656
i32.const 1875
i32.const 1903
i32.const 9
call $~lib/wasi/index/abort
unreachable
Expand All @@ -4943,7 +4943,7 @@
else
i32.const 144
i32.const 656
i32.const 1879
i32.const 1907
i32.const 7
call $~lib/wasi/index/abort
unreachable
Expand All @@ -4961,7 +4961,7 @@
if
i32.const 144
i32.const 656
i32.const 1884
i32.const 1912
i32.const 7
call $~lib/wasi/index/abort
unreachable
Expand Down
6 changes: 3 additions & 3 deletions tests/compiler/std-wasi/crypto.release.wat
Original file line number Diff line number Diff line change
Expand Up @@ -3715,7 +3715,7 @@
if
i32.const 1472
i32.const 1680
i32.const 1870
i32.const 1898
i32.const 5
call $~lib/wasi/index/abort
unreachable
Expand All @@ -3734,7 +3734,7 @@
else
i32.const 1168
i32.const 1680
i32.const 1879
i32.const 1907
i32.const 7
call $~lib/wasi/index/abort
unreachable
Expand All @@ -3749,7 +3749,7 @@
if
i32.const 1168
i32.const 1680
i32.const 1884
i32.const 1912
i32.const 7
call $~lib/wasi/index/abort
unreachable
Expand Down
Loading