Skip to content
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

[wasm] use sbrk instead of emscripten mmap or malloc when loading bytes into heap #100106

Merged
merged 4 commits into from
Apr 9, 2024
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
1 change: 1 addition & 0 deletions src/mono/browser/browser.proj
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
<EmccExportedFunction Include="_free" />
<EmccExportedFunction Include="_htons" />
<EmccExportedFunction Include="_malloc" />
<EmccExportedFunction Include="_sbrk" />
<EmccExportedFunction Include="_memalign" />
<EmccExportedFunction Include="_memset" />
<EmccExportedFunction Include="_ntohs" />
Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import cwraps from "./cwraps";
import { mono_wasm_load_icu_data } from "./icu";
import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals";
import { mono_log_info, mono_log_debug, parseSymbolMapFile } from "./logging";
import { mono_wasm_load_bytes_into_heap } from "./memory";
import { mono_wasm_load_bytes_into_heap_persistent } from "./memory";
import { endMeasure, MeasuredBlock, startMeasure } from "./profiler";
import { AssetEntry } from "./types";
import { VoidPtr } from "./types/emscripten";
Expand Down Expand Up @@ -37,7 +37,7 @@ export function instantiate_asset (asset: AssetEntry, url: string, bytes: Uint8A
// falls through
case "heap":
case "icu":
offset = mono_wasm_load_bytes_into_heap(bytes);
offset = mono_wasm_load_bytes_into_heap_persistent(bytes);
pavelsavara marked this conversation as resolved.
Show resolved Hide resolved
break;

case "vfs": {
Expand Down
1 change: 1 addition & 0 deletions src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ declare interface Int32Ptr extends NativePointer {
declare interface EmscriptenModule {
_malloc(size: number): VoidPtr;
_free(ptr: VoidPtr): void;
_sbrk(size: number): VoidPtr;
out(message: string): void;
err(message: string): void;
ccall<T>(ident: string, returnType?: string | null, argTypes?: string[], args?: any[], opts?: any): T;
Expand Down
19 changes: 18 additions & 1 deletion src/mono/browser/runtime/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,24 @@ export function withStackAlloc<T1, T2, T3, TResult> (bytesWanted: number, f: (pt
// @bytes must be a typed array. space is allocated for it in the native heap
// and it is copied to that location. returns the address of the allocation.
export function mono_wasm_load_bytes_into_heap (bytes: Uint8Array): VoidPtr {
const memoryOffset = Module._malloc(bytes.length);
// pad sizes by 16 bytes for simd
const memoryOffset = Module._malloc(bytes.length + 16);
const heapBytes = new Uint8Array(localHeapViewU8().buffer, <any>memoryOffset, bytes.length);
heapBytes.set(bytes);
return memoryOffset;
}

// @bytes must be a typed array. space is allocated for it in memory
// and it is copied to that location. returns the address of the data.
// the result pointer *cannot* be freed because malloc is bypassed for speed.
export function mono_wasm_load_bytes_into_heap_persistent (bytes: Uint8Array): VoidPtr {
// pad sizes by 16 bytes for simd
const desiredSize = bytes.length + 16;
// wasm memory page size is 64kb. allocations smaller than that are probably best
// serviced by malloc
const memoryOffset = (desiredSize < (64 * 1024))
? Module._malloc(desiredSize)
: Module._sbrk(desiredSize);
const heapBytes = new Uint8Array(localHeapViewU8().buffer, <any>memoryOffset, bytes.length);
heapBytes.set(bytes);
return memoryOffset;
Expand Down
1 change: 1 addition & 0 deletions src/mono/browser/runtime/types/emscripten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export declare interface EmscriptenModule {
// this should match emcc -s EXPORTED_FUNCTIONS
_malloc(size: number): VoidPtr;
_free(ptr: VoidPtr): void;
_sbrk(size: number): VoidPtr;

// this should match emcc -s EXPORTED_RUNTIME_METHODS
out(message: string): void;
Expand Down
Loading