Skip to content

Commit 001d60a

Browse files
authored
[wasm] use sbrk instead of emscripten mmap or malloc when loading bytes into heap (#100106)
Use sbrk to allocate persistent space for large load_bytes_into_heap calls to avoid the startup overhead of emscripten's malloc and memset for the new space
1 parent 89ab2a9 commit 001d60a

File tree

5 files changed

+23
-3
lines changed

5 files changed

+23
-3
lines changed

src/mono/browser/browser.proj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
<EmccExportedFunction Include="_free" />
201201
<EmccExportedFunction Include="_htons" />
202202
<EmccExportedFunction Include="_malloc" />
203+
<EmccExportedFunction Include="_sbrk" />
203204
<EmccExportedFunction Include="_memalign" />
204205
<EmccExportedFunction Include="_memset" />
205206
<EmccExportedFunction Include="_ntohs" />

src/mono/browser/runtime/assets.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import cwraps from "./cwraps";
77
import { mono_wasm_load_icu_data } from "./icu";
88
import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals";
99
import { mono_log_info, mono_log_debug, parseSymbolMapFile } from "./logging";
10-
import { mono_wasm_load_bytes_into_heap } from "./memory";
10+
import { mono_wasm_load_bytes_into_heap_persistent } from "./memory";
1111
import { endMeasure, MeasuredBlock, startMeasure } from "./profiler";
1212
import { AssetEntry } from "./types";
1313
import { VoidPtr } from "./types/emscripten";
@@ -37,7 +37,7 @@ export function instantiate_asset (asset: AssetEntry, url: string, bytes: Uint8A
3737
// falls through
3838
case "heap":
3939
case "icu":
40-
offset = mono_wasm_load_bytes_into_heap(bytes);
40+
offset = mono_wasm_load_bytes_into_heap_persistent(bytes);
4141
break;
4242

4343
case "vfs": {

src/mono/browser/runtime/dotnet.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ declare interface Int32Ptr extends NativePointer {
2020
declare interface EmscriptenModule {
2121
_malloc(size: number): VoidPtr;
2222
_free(ptr: VoidPtr): void;
23+
_sbrk(size: number): VoidPtr;
2324
out(message: string): void;
2425
err(message: string): void;
2526
ccall<T>(ident: string, returnType?: string | null, argTypes?: string[], args?: any[], opts?: any): T;

src/mono/browser/runtime/memory.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,24 @@ export function withStackAlloc<T1, T2, T3, TResult> (bytesWanted: number, f: (pt
325325
// @bytes must be a typed array. space is allocated for it in the native heap
326326
// and it is copied to that location. returns the address of the allocation.
327327
export function mono_wasm_load_bytes_into_heap (bytes: Uint8Array): VoidPtr {
328-
const memoryOffset = Module._malloc(bytes.length);
328+
// pad sizes by 16 bytes for simd
329+
const memoryOffset = Module._malloc(bytes.length + 16);
330+
const heapBytes = new Uint8Array(localHeapViewU8().buffer, <any>memoryOffset, bytes.length);
331+
heapBytes.set(bytes);
332+
return memoryOffset;
333+
}
334+
335+
// @bytes must be a typed array. space is allocated for it in memory
336+
// and it is copied to that location. returns the address of the data.
337+
// the result pointer *cannot* be freed because malloc is bypassed for speed.
338+
export function mono_wasm_load_bytes_into_heap_persistent (bytes: Uint8Array): VoidPtr {
339+
// pad sizes by 16 bytes for simd
340+
const desiredSize = bytes.length + 16;
341+
// wasm memory page size is 64kb. allocations smaller than that are probably best
342+
// serviced by malloc
343+
const memoryOffset = (desiredSize < (64 * 1024))
344+
? Module._malloc(desiredSize)
345+
: Module._sbrk(desiredSize);
329346
const heapBytes = new Uint8Array(localHeapViewU8().buffer, <any>memoryOffset, bytes.length);
330347
heapBytes.set(bytes);
331348
return memoryOffset;

src/mono/browser/runtime/types/emscripten.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export declare interface EmscriptenModule {
2626
// this should match emcc -s EXPORTED_FUNCTIONS
2727
_malloc(size: number): VoidPtr;
2828
_free(ptr: VoidPtr): void;
29+
_sbrk(size: number): VoidPtr;
2930

3031
// this should match emcc -s EXPORTED_RUNTIME_METHODS
3132
out(message: string): void;

0 commit comments

Comments
 (0)