-
Notifications
You must be signed in to change notification settings - Fork 5k
[wasm][debugger] Improve debugger performance based on JMC #86982
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][debugger] Improve debugger performance based on JMC #86982
Conversation
Tagging subscribers to this area: @thaystg Issue DetailsIf JMC is enabled and runtime doesn't have debug symbols it means that the assembly being used is not from the customer, otherwise the pdb would be loaded by the runtime.
|
@lewing do you think this makes sense? |
Tagging subscribers to 'arch-wasm': @lewing Issue DetailsIf JMC is enabled and runtime doesn't have debug symbols it means that the assembly being used is not from the customer, otherwise the pdb would be loaded by the runtime.
|
yeah, I think it makes sense. There is no particular issue with loading them later once the switch changes right? |
No particular issue. When you disable JMC after the debugger session is started we will need to get the PDB from cache or from symbol server anyway. With this change we will also read the assembly bytes from runtime before try to get the symbols from cache / from symbol server. |
…t of time loading information from 149 assemblies if we will probably not need all of them.
internal System.Guid PdbGuid { get; set; } | ||
internal bool IsPortableCodeView { get; set; } | ||
internal string PdbName { get; set; } | ||
internal bool CodeViewInformationAvailable { get; set; } |
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 ever make use of these setters? It does not look like a necessary change.
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.
The property seems to be never read at all.
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.
The idea with strrchr
looks good as we use it in other places. Other than that, looks great.
break; | ||
} | ||
} | ||
|
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.
Maybe check if the string is empty here?
MonoAssemblyByNameRequest byname_req; | ||
mono_assembly_request_prepare_byname (&byname_req, mono_alc_get_default ()); | ||
MonoAssembly *assembly = mono_assembly_request_byname (aname, &byname_req, &status); | ||
g_free (lookup_name); |
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.
Can we do this right after the call to mono_assembly_name_new
?
g_ptr_array_free (assemblies, TRUE); | ||
if (!assembly) { | ||
PRINT_DEBUG_MSG (1, "Could not resolve assembly %s\n", assembly_name); | ||
mono_assembly_name_free_internal (aname); |
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.
Should this jump to 6988, which can free and return assembly (==NULL here)?
{ | ||
if (!assemblyName.StartsWith("System.Private.CoreLib") && !ignoreJMC && proxy.JustMyCode && !(await HasDebugInfoLoadedByRuntime(assemblyName, token))) |
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.
StringComparison.Ordinal with StartsWith
{ | ||
if (!assemblyName.StartsWith("System.Private.CoreLib") && !ignoreJMC && proxy.JustMyCode && !(await HasDebugInfoLoadedByRuntime(assemblyName, token))) |
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.
Also, I would suggest maybe splitting this only multiple lines, and comments for why the different parts of the condition are needed.
ret[1] = pdb_buf; | ||
AssemblyAndPdbData ret = new(assembly_buf, pdb_buf); | ||
|
||
if (MajorVersion == 2 && MinorVersion >= 64) |
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.
Should these checks be using MajorVersion >= 2
?
Also, can we (in a followup) convert such version checks into properties named for whatever feature we want to check for. It would essentially document why we are doing the version check. And also, in future if we need to change the versions checks for that feature then we can easily change it.
AssemblyAndPdbData ret = new(assembly_buf, pdb_buf); | ||
|
||
if (MajorVersion == 2 && MinorVersion >= 64) |
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.
nit:
if (MajorVersion != 2 || MinorVersion < 64)
return new(assembly_buf, pdb_buf);
AssemblyAndPdbData ret = new()
Co-authored-by: Ankit Jain <radical@gmail.com>
Co-authored-by: Ankit Jain <radical@gmail.com>
@@ -1909,7 +1944,7 @@ public async Task<string> InvokeToStringAsync(IEnumerable<int> typeIds, bool isV | |||
foreach (var methodId in methodIds) | |||
{ | |||
var methodInfoFromRuntime = await GetMethodInfo(methodId, token); | |||
if (methodInfoFromRuntime.Info.GetParametersInfo().Length > 0) | |||
if (methodInfoFromRuntime?.Info?.GetParametersInfo()?.Length > 0) |
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.
Should we also check that the return type is string
?
And this method (InvokeTostringAsync
) is only looking at instance methods, correct?
…hub.com:thaystg/runtime into thays_improve_debugger_performance_based_on_jmc
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.
LGTM! 👍
If JMC is enabled and runtime doesn't have debug symbols of an assembly it means that the assembly being used is not from the customer, otherwise the pdb would be loaded by the runtime.
In this case we don't need to load any information about the assembly avoiding spending a lot of time receiving all the bytes from all the assemblies that will not be used because JMC is disabled.
UPDATE: I'm loading the information by demand, if we need any information from an assembly that is not loaded, like to inspect variables of a specific type that is not in the user code, I'm loading, it's a better approach to avoid any side effect and we are still spending less time because we will not need to load 149 assemblies at the startup even if we will not use them.
Measurement: From 4 seconds to load all the symbols during the app startup to less than 1 second.
I'm not adding any new test because this is already tested.