Skip to content

Commit

Permalink
diag module
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelsavara committed Jan 28, 2025
1 parent 84a584e commit c9519a9
Show file tree
Hide file tree
Showing 31 changed files with 261 additions and 149 deletions.
2 changes: 2 additions & 0 deletions eng/liveBuilds.targets
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@
$(LibrariesNativeArtifactsPath)dotnet.native.js;
$(LibrariesNativeArtifactsPath)dotnet.runtime.js;
$(LibrariesNativeArtifactsPath)dotnet.runtime.js.map;
$(LibrariesNativeArtifactsPath)dotnet.diag.js;
$(LibrariesNativeArtifactsPath)dotnet.diag.js.map;
$(LibrariesNativeArtifactsPath)dotnet.d.ts;
$(LibrariesNativeArtifactsPath)package.json;
$(LibrariesNativeArtifactsPath)dotnet.native.wasm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@
<PlatformManifestFileEntry Include="dotnet.js.map" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.runtime.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.runtime.js.map" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.diag.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.diag.js.map" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.native.js" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.native.worker.mjs" IsNative="true" />
<PlatformManifestFileEntry Include="dotnet.native.js.symbols" IsNative="true" />
Expand Down
2 changes: 2 additions & 0 deletions src/mono/browser/browser.proj
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@
$(NativeBinDir)dotnet.js.map;
$(NativeBinDir)dotnet.runtime.js;
$(NativeBinDir)dotnet.runtime.js.map;
$(NativeBinDir)dotnet.diag.js;
$(NativeBinDir)dotnet.diag.js.map;
$(NativeBinDir)dotnet.native.js;
$(NativeBinDir)dotnet.d.ts;
$(NativeBinDir)package.json;
Expand Down
3 changes: 3 additions & 0 deletions src/mono/browser/build/BrowserWasmApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
<!-- If dotnet.{wasm,js} weren't added already (eg. AOT can add them), then add the default ones -->
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.js" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.runtime.js" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.diag.js" Condition="'$(FeaturePerfTracing)' == 'true'" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.native.wasm" Condition="'$(_HasDotnetWasm)' != 'true'" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.native.js" Condition="'$(_HasDotnetNativeJs)' != 'true'" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.native.worker.mjs" Condition="'$(_HasDotnetJsWorker)' != 'true' and Exists('$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.native.worker.mjs')" />
Expand All @@ -100,6 +101,8 @@
Condition="'$(WasmEmitSourceMap)' != 'false'" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.runtime.js.map"
Condition="'$(WasmEmitSourceMap)' != 'false'" />
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.diag.js.map"
Condition="'$(WasmEmitSourceMap)' != 'false' and '$(FeaturePerfTracing)' == 'true'" />
</ItemGroup>

<ItemGroup Condition="'$(InvariantGlobalization)' != 'true'">
Expand Down
1 change: 1 addition & 0 deletions src/mono/browser/runtime/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function instantiate_asset (asset: AssetEntry, url: string, bytes: Uint8A
switch (asset.behavior) {
case "dotnetwasm":
case "js-module-threads":
case "js-module-diag":
case "symbols":
// do nothing
break;
Expand Down
35 changes: 35 additions & 0 deletions src/mono/browser/runtime/diagnostics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import type { CharPtr, VoidPtr } from "./types/emscripten";
import type { DiagModuleExportsInternal } from "./types/internal";

import { diagHelpers, globalObjectsRoot, loaderHelpers, mono_assert } from "./globals";

export function ds_rt_websocket_create (urlPtr :CharPtr):number {
return diagHelpers.ds_rt_websocket_create(urlPtr);
}

export function ds_rt_websocket_send (client_socket :number, buffer:VoidPtr, bytes_to_write:number):number {
return diagHelpers.ds_rt_websocket_send(client_socket, buffer, bytes_to_write);
}

export function ds_rt_websocket_poll (client_socket :number):number {
return diagHelpers.ds_rt_websocket_poll(client_socket);
}

export function ds_rt_websocket_recv (client_socket :number, buffer:VoidPtr, bytes_to_read:number):number {
return diagHelpers.ds_rt_websocket_recv(client_socket, buffer, bytes_to_read);
}

export function ds_rt_websocket_close (client_socket :number):number {
return diagHelpers.ds_rt_websocket_close(client_socket);
}

export async function loadDiagnosticServer ():Promise<void> {
const asset = loaderHelpers.resolve_single_asset_path("js-module-diag");
const uri = asset.resolvedUrl;
mono_assert(uri !== undefined, "could not resolve the uri for the js-module-threads asset");
const mod:DiagModuleExportsInternal = await import(/*! webpackIgnore: true */uri);
mod.setRuntimeGlobals(globalObjectsRoot);
}
10 changes: 5 additions & 5 deletions src/mono/browser/runtime/diagnostics/common.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import cwraps from "../cwraps";
import { loaderHelpers, Module } from "../globals";
import { VoidPtr } from "../types/emscripten";
import { runtimeHelpers } from "./globals";
import type { VoidPtr } from "../types/emscripten";
import { loaderHelpers, Module } from "./globals";

let lastScheduledTimeoutId: any = undefined;

Expand All @@ -12,8 +12,8 @@ export function diagnostic_server_loop () {
lastScheduledTimeoutId = undefined;
if (loaderHelpers.is_runtime_running()) {
try {
cwraps.mono_background_exec();// give GC chance to run
cwraps.mono_wasm_ds_exec();
runtimeHelpers.mono_background_exec();// give GC chance to run
runtimeHelpers.mono_wasm_ds_exec();
schedule_diagnostic_server_loop(100);
} catch (ex) {
loaderHelpers.mono_exit(1, ex);
Expand Down
7 changes: 1 addition & 6 deletions src/mono/browser/runtime/diagnostics/diag-js.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import WasmEnablePerfTracing from "consts:wasmEnablePerfTracing";

import { advert1, dotnet_IPC_V1, ServerCommandId, CommandSetId } from "./client-commands";
import { DiagConnectionBase, fnClientProvider, IDiagClient, IDiagConnection, IDiagServer, IDiagSession, schedule_diagnostic_server_loop, SessionId } from "./common";
import { mono_log_info } from "../logging";
import { mono_log_info } from "./logging";
import { GcDumpDiagClient } from "./dotnet-gcdump";
import { CountersClient } from "./dotnet-counters";
import { SampleProfilerClient } from "./dotnet-profiler";
Expand All @@ -17,9 +15,6 @@ let server:DiagServer = undefined as any;
// .withEnvironmentVariable("DOTNET_DiagnosticPorts", "download:gcdump")
// or implement function globalThis.dotnetDiagnosticClient with IDiagClient interface
export function createDiagConnectionJs (socket_handle:number, scenarioName:string):DiagConnectionJs {
if (!WasmEnablePerfTracing) {
return undefined as any;
}
if (diagClient === undefined) {
diagClient = init_diag_client(scenarioName);
}
Expand Down
5 changes: 0 additions & 5 deletions src/mono/browser/runtime/diagnostics/diag-ws.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import WasmEnablePerfTracing from "consts:wasmEnablePerfTracing";

import { IDiagConnection, DiagConnectionBase, diagnostic_server_loop, schedule_diagnostic_server_loop } from "./common";

export function createDiagConnectionWs (socket_handle:number, url:string):IDiagConnection {
if (!WasmEnablePerfTracing) {
return undefined as any;
}
return new DiagConnectionWS(socket_handle, url);
}

Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/diagnostics/dotnet-counters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import { commandStopTracing, commandCounters } from "./client-commands";
import { IDiagClient, IDiagServer, IDiagSession } from "./common";
import { mono_log_warn } from "../logging";
import { Module } from "../globals";
import { mono_log_warn } from "./logging";
import { Module } from "./globals";

export class CountersClient implements IDiagClient {
private firstAdvert = false;
Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/diagnostics/dotnet-gcdump.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import { commandStopTracing, commandGcHeapDump, } from "./client-commands";
import { IDiagClient, IDiagServer, IDiagSession } from "./common";
import { mono_log_warn } from "../logging";
import { Module } from "../globals";
import { mono_log_warn } from "./logging";
import { Module } from "./globals";

export class GcDumpDiagClient implements IDiagClient {
private firstAdvert = false;
Expand Down
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/diagnostics/dotnet-profiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import { commandStopTracing, commandSampleProfiler } from "./client-commands";
import { IDiagClient, IDiagServer, IDiagSession } from "./common";
import { mono_log_warn } from "../logging";
import { Module } from "../globals";
import { mono_log_warn } from "./logging";
import { Module } from "./globals";

export class SampleProfilerClient implements IDiagClient {
private firstAdvert = false;
Expand Down
23 changes: 23 additions & 0 deletions src/mono/browser/runtime/diagnostics/globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import type { DiagHelpers, GlobalObjects, LoaderHelpers, RuntimeHelpers, DotnetModuleInternal } from "../types/internal";

export let _diagModuleLoaded = false; // please keep it in place also as rollup guard

export let diagHelpers: DiagHelpers = null as any;
export let runtimeHelpers: RuntimeHelpers = null as any;
export let loaderHelpers: LoaderHelpers = null as any;
export let Module: DotnetModuleInternal = null as any;

export function setRuntimeGlobalsImpl (globalObjects: GlobalObjects): void {
if (_diagModuleLoaded) {
throw new Error("Diag module already loaded");
}
_diagModuleLoaded = true;
diagHelpers = globalObjects.diagHelpers;
runtimeHelpers = globalObjects.runtimeHelpers;
loaderHelpers = globalObjects.loaderHelpers;
Module = globalObjects.module;
}
116 changes: 54 additions & 62 deletions src/mono/browser/runtime/diagnostics/index.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,70 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import WasmEnablePerfTracing from "consts:wasmEnablePerfTracing";
import type { GlobalObjects } from "../types/internal";
import type { CharPtr, VoidPtr } from "../types/emscripten";

import { Module } from "../globals";
import { utf8ToString } from "../strings";
import { CharPtr, VoidPtr } from "../types/emscripten";
import { Module, runtimeHelpers } from "./globals";
import { createDiagConnectionJs } from "./diag-js";
import { IDiagConnection } from "./common";
import { createDiagConnectionWs } from "./diag-ws";
import { diagHelpers, setRuntimeGlobalsImpl } from "./globals";

let socket_handles:Map<number, IDiagConnection> = undefined as any;
let next_socket_handle = 1;

export function ds_rt_websocket_create (urlPtr :CharPtr):number {
if (!WasmEnablePerfTracing) {
return -1;
}
if (!socket_handles) {
socket_handles = new Map<number, IDiagConnection>();
}
const url = utf8ToString(urlPtr);
const socket_handle = next_socket_handle++;
const isWebSocket = url.startsWith("ws://") || url.startsWith("wss://");
const wrapper = isWebSocket
? createDiagConnectionWs(socket_handle, url)
: createDiagConnectionJs(socket_handle, url);
socket_handles.set(socket_handle, wrapper);
return socket_handle;
}
export function setRuntimeGlobals (globalObjects: GlobalObjects): void {
setRuntimeGlobalsImpl(globalObjects);

export function ds_rt_websocket_send (client_socket :number, buffer:VoidPtr, bytes_to_write:number):number {
if (!WasmEnablePerfTracing) {
return -1;
}
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return -1;
}
const message = (new Uint8Array(Module.HEAPU8.buffer, buffer as any, bytes_to_write)).slice();
return wrapper.send(message);
}
diagHelpers.ds_rt_websocket_create = (urlPtr :CharPtr):number => {
if (!socket_handles) {
socket_handles = new Map<number, IDiagConnection>();
}
const url = runtimeHelpers.utf8ToString(urlPtr);
const socket_handle = next_socket_handle++;
const isWebSocket = url.startsWith("ws://") || url.startsWith("wss://");
const wrapper = isWebSocket
? createDiagConnectionWs(socket_handle, url)
: createDiagConnectionJs(socket_handle, url);
socket_handles.set(socket_handle, wrapper);
return socket_handle;
};

export function ds_rt_websocket_poll (client_socket :number):number {
if (!WasmEnablePerfTracing) {
return -1;
}
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return 0;
}
return wrapper.poll();
}
diagHelpers.ds_rt_websocket_send = (client_socket :number, buffer:VoidPtr, bytes_to_write:number):number => {
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return -1;
}
const message = (new Uint8Array(Module.HEAPU8.buffer, buffer as any, bytes_to_write)).slice();
return wrapper.send(message);
};

export function ds_rt_websocket_recv (client_socket :number, buffer:VoidPtr, bytes_to_read:number):number {
if (!WasmEnablePerfTracing) {
return -1;
}
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return -1;
}
return wrapper.recv(buffer, bytes_to_read);
}
diagHelpers.ds_rt_websocket_poll = (client_socket :number):number => {
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return 0;
}
return wrapper.poll();
};

export function ds_rt_websocket_close (client_socket :number):number {
if (!WasmEnablePerfTracing) {
return -1;
}
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return -1;
}
socket_handles.delete(client_socket);
return wrapper.close();
}
diagHelpers.ds_rt_websocket_recv = (client_socket :number, buffer:VoidPtr, bytes_to_read:number):number => {
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return -1;
}
return wrapper.recv(buffer, bytes_to_read);
};

diagHelpers. ds_rt_websocket_close = (client_socket :number):number => {
const wrapper = socket_handles.get(client_socket);
if (!wrapper) {
return -1;
}
socket_handles.delete(client_socket);
return wrapper.close();
};

globalObjects.api.collectTrace = () => {
//TODO
};
}
18 changes: 18 additions & 0 deletions src/mono/browser/runtime/diagnostics/logging.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// TODO
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unused-vars */

export function mono_log_debug (messageFactory: string | (() => string)) {
}

export function mono_log_info (msg: string, ...data: any) {
}

export function mono_log_warn (msg: string, ...data: any) {
}

export function mono_log_error (msg: string, ...data: any) {
}
12 changes: 12 additions & 0 deletions src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ type SingleAssetBehaviors =
* The javascript module for threads.
*/
| "js-module-threads"
/**
* The javascript module for diagnostic server and client.
*/
| "js-module-diag"
/**
* The javascript module for runtime.
*/
Expand Down Expand Up @@ -622,6 +626,14 @@ type APIType = {
* Returns a short term view of the WASM linear memory. Don't store the reference, don't use it after await.
*/
localHeapViewF64: () => Float64Array;
/**
* Loads the runtime module for diagnostic server and client.
*/
loadDiagnosticServer: () => Promise<void>;
/**
* creates diagnostic trace file and downloads it from the browser. Only after loadDiagnosticServer() is called.
*/
collectTrace(): void;
};
type RuntimeAPI = {
INTERNAL: any;
Expand Down
2 changes: 1 addition & 1 deletion src/mono/browser/runtime/es6/dotnet.es6.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function createWasmImportStubsFrom(collection) {
// we will replace them with the real implementation in replace_linker_placeholders
function injectDependencies() {
createWasmImportStubsFrom(methodIndexByName.mono_wasm_imports);
createWasmImportStubsFrom(methodIndexByName.mono_wasm_js_globalization_imports);
if (FEATURE_PERFTRACING) createWasmImportStubsFrom(methodIndexByName.mono_wasm_diag_imports);

#if USE_PTHREADS
createWasmImportStubsFrom(methodIndexByName.mono_wasm_threads_imports);
Expand Down
Loading

0 comments on commit c9519a9

Please sign in to comment.