[wasm-ep] Minimal diagnostic tracing configuration and sample (#69158)
* Adds a `/p:WasmEnablePerfTracing=true` configuration.
In this configuration the runtime is built with threading (`MonoWasmThreads` property is true), but user C# code is not allowed to start threads and doesn't use the portable threadpool (`MonoWasmThreadsNoUser` property is also true).
The upshot is that EventPipe can start threads but user code is still single-threaded.
* Adds a `MONO.diagnostics` interface in JavaScript. There's a single method for now `createEventPipeSession` which creates a session that can save a trace to a file on the virtual file system. JS code (or a user in a dev console) needs to call `start()` and `stop()` on the session object to begin collecting samples. The data is saved temporarily to the Emscripten VFS and can be retrived into a JavaScript Blob (and from there downloaded to a file outside the browser).
* Adds a sample that runs an async task for five seconds and collects samples and then triggers a `click()` to download the trace file out of the browser.
* Adds a TS module to help with working with uint64_t values in the emscripten heap.
* Exposes empscripten Module.stackSave, stackRestore and stackAlloc operations to the runtime TS modules. Use for working with event pipe session ID outparam.
---
* add DISABLE_WASM_USER_THREADS mono cmake option
* Disable Thread.StartInternal icall if DISABLE_WASM_USER_THREADS
if threading is enabled for the runtime internally, but disabled for user code, throw PNSE
* add an eventpipe sample
* [wasm-ep] (browser-eventpipe sample) run loop for longer
* [samples/wasm-eventpipe] make an async task sample
change the sample to do some work asynchronously using setTimeout instead of blocking
* [wasm] Add MONO.diagnostics interface
Binds enable, start, disable methods defaulting to non-streaming FILE mode
* if wasm threads are disabled, but perftracing is enabled, don't log overlapped io events
* fix whitespace and nits
* don't need try/finally in the sample anymore
* more whitespace
* add start method to EventPipeSession interface
* don't run wasm-eventpipe sample on CI lanes without perftracing
* more whitespace
* fix eslint warnings, default rundown to true, allow callback for traceFilePath option
* add EventPipeSession.getTraceBlob
for retrieving the collected traces instead of exposing the emscripten VFS directly.
update the sample to use URL.createObjectURL (session.getTraceBlob()) to create the download link
* [browser-eventpipe sample] remove unnecessary ref assemblies
* use ep_char8_t for C decls of event pipe wasm exports
* Use stack allocation for temporaries
Expose the emscripten stack allocation API
* Use 32-bit EventPipe session ID on WASM
64 bit integers are awkward to work with in JavaScript.
The EventPipe session ID is derived from a pointer address, so even though it is nominally a 64-bit value, in practice the top bits are zero.
Use a 32-bit int to represent the session ID on the javascript side and convert to 64-bit in C when calling down to the EventPipe APIs
* Make the sample do more work in managed
give the sample profiler some non-empty samples to collect
* Move withStackAlloc to memory.ts
* simplify VFS .nettrace file naming
Just use consecutive integers to uniquify the session traces. Dont' need a fancy timestamp in the VFS (which would also not be unique if you create sessions below the timestamp resolution)
* Add overloads to memory.withStackAlloc to avoid creating closures
Pass additional arguments to the callback function
* sample: explain why there's a 10s pause
* move createEventPipeSession callback to a function
ensures the closure is created once
* Use a tuple type for withStackAlloc
* use unsigned 32-bit get/set in cuint64 get/set
* fix whitespace
23 files changed: