-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[browser] samplepoint instrumentation into Mono profiler #112352
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
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
Hi @pavelsavara, |
# Conflicts: # src/mono/browser/runtime/exports-binding.ts
|
My testing shows that enter/leave events are unbalanced. I will test it further to see if this could be fixed in the instrumentation or if this must be detected and survived by the receiving side. |
|
I think you can't randomly record only a % of enter/leave events, or if you do you need to ensure that they are balanced - for example if you record an entry for method x the matching return also needs to be recorded. So you can only pick a % of enters to record but you need to do the check for every LEAVE as to whether this current stack frame previously recorded an enter. |
…CONTEXT - fix flag detection for both variants - insert enter_profiling only when not inlining, to match leave event behavior
…e_exception_internal - also when MONO_EXCEPTION_CLAUSE_NONE - more asserts in browser profiler
|
LGTM |
|
/ba-g CI timeouts and known issues |
lateralusX
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I was late to the party (was OOF last week), but add my comments/questions here anyways, either for future follow ups or PR's.
| #define INTERP_PROFILER_RAISE(name_lower, name_upper) \ | ||
| if ((flag & TRACING_FLAG) || ((flag & PROFILING_FLAG) && MONO_PROFILER_ENABLED (method_ ## name_lower) && \ | ||
| (frame->imethod->prof_flags & (MONO_PROFILER_CALL_INSTRUMENTATION_ ## name_upper ## _CONTEXT | MONO_PROFILER_CALL_INSTRUMENTATION_ ## name_upper)))) { \ | ||
| MonoProfilerCallContext *prof_ctx = g_new0 (MonoProfilerCallContext, 1);\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to heap allocate this? Looks like stack allocation should be enough, unless we are afraid consuming stack space since the MonoProfilerCallContext that includes MonoContext.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the place that possibly deals with MonoProfilerCallContext -> context
| emit_fill_call_ctx (MonoCompile *cfg, MonoInst *method, MonoInst *ret) |
What would happen if we removed context field completely ?
| return res; | ||
| } | ||
|
|
||
| EMSCRIPTEN_KEEPALIVE const char * mono_wasm_method_get_name_ex (MonoMethod *method) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you hand out ownership of this pointer and expect others to free it, it shouldn't be const.

Motivation
Collect sample stack traces in the single-threaded browser.
Single threaded environment can't have dedicated thread for "stop-the-world + collect stack traces" implementation.
So we need to collect samples by instrumenting the code instead.
Previously we implemented browser based profiler which collects "sample" on every method entry/leave. In realistic application, that generates too much traffic for the browser profiler.
This enhancement could also be used to implement sampling profiler with ST diagnostic server.
Goal
samplepointinstrumentation into Mono profiler, use the existing enter/leave too.method_enterevent/instrumentation.Contributes to #76316
Non-goal: the browser profiler is not compatible with MT.
Changes
Interop
MINT_PROF_SAMPLEPOINTmethod_samplepointINTERP_PROFILER_RAISEJiterp
append_profiler_eventcalling newmono_jiterp_prof_enter,mono_jiterp_prof_samplepoint,mono_jiterp_prof_leaveAOT
mini_profiler_emit_samplepointcall $mono_profiler_raise_method_samplepointbrowser profiler
sampleIntervalMsfor browser profiler. 1ms by default. All samples when set to0.mono_wasm_profiler_nowandmono_wasm_profiler_recordbrowser.cnewshould_record_frameprofiler_stack_framesand skip countersample_skip_countercallspecparametr to profiler allows to filter the instrumentation, for example by namespacecallspec=N:Sample.FooNsHow to use
Interpreter
dotnet workload install wasm-toolsIn the project file
In your
main.jsor in your Blazor app
AOT
You can add following, so that the native code produced by AOT has symbols, which are visible in the browser devtools profiler.
callspec
If you want to filter profiled methods, you can use
callspecCallspec is documented here https://github.com/dotnet/runtime/blob/main/docs/design/mono/diagnostics-tracing.md#trace-monovm-profiler-events-during-startup
Your for AOT needs to match callspec in the
browserProfilerOptionsin JS