From: Bruce Forstall Date: Tue, 10 Mar 2020 15:53:57 +0000 (-0700) Subject: Move JIT documentation to new docs/design/coreclr/jit directory (#33321) X-Git-Tag: submit/tizen/20210909.063632~9245 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a21da8f6d945002bbb7cdb426c148867f60be528;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Move JIT documentation to new docs/design/coreclr/jit directory (#33321) Reduce clutter in the shared directory, and make it easier to find all the JIT-related documentation. --- diff --git a/docs/design/coreclr/botr/README.md b/docs/design/coreclr/botr/README.md index 5dfb3f9..58e7bad 100644 --- a/docs/design/coreclr/botr/README.md +++ b/docs/design/coreclr/botr/README.md @@ -12,8 +12,8 @@ Below is a table of contents. - [Introduction to the Common Language Runtime](intro-to-clr.md) - [Garbage Collection Design](garbage-collection.md) - [Threading](threading.md) -- [RyuJIT Overview](ryujit-overview.md) - - [Porting RyuJIT to other platforms](porting-ryujit.md) +- [RyuJIT Overview](../jit/ryujit-overview.md) + - [Porting RyuJIT to other platforms](../jit/porting-ryujit.md) - [Type System](type-system.md) - [Type Loader](type-loader.md) - [Method Descriptor](method-descriptor.md) diff --git a/docs/design/features/GuardedDevirtualization.md b/docs/design/coreclr/jit/GuardedDevirtualization.md similarity index 98% rename from docs/design/features/GuardedDevirtualization.md rename to docs/design/coreclr/jit/GuardedDevirtualization.md index fa3fb0d..95b3caa 100644 --- a/docs/design/features/GuardedDevirtualization.md +++ b/docs/design/coreclr/jit/GuardedDevirtualization.md @@ -76,7 +76,7 @@ it takes to invoke `F` on each member of the array (note the JIT will not ever be able to devirtualize these calls), and plot the times as a function of `p`. The result is something like the following: -![two classes baseline perf](TwoClassesBaseline.JPG) +![two classes baseline perf](images/TwoClassesBaseline.JPG) Modern hardware includes an indirect branch target predictor and we can see it in action here. When the array element type is predictable (`p` very close to @@ -95,7 +95,7 @@ performance, and if the element type is mostly `D` (that is `p` near 0.0) performance should perhaps slightly worse than the un-optimized case as there is now extra code to run check before the call. -![two classes devirt perf](TwoClassesDevirt.JPG) +![two classes devirt perf](images/TwoClassesDevirt.JPG) However as you can see the performance of devirtualized case (blue line) is as good or better than the un-optimized case for all values of `p`. This is perhaps @@ -178,7 +178,7 @@ there is a third class `E`. To avoid introducing a 3D plot we'll first simply average the results for the various values of `p1` and plot performance as a function of `p`: -![three classes devirt perf](ThreeClassesDevirt.JPG) +![three classes devirt perf](images/ThreeClassesDevirt.JPG) The right-hand side (`p` near 1.0) looks a lot like the previous chart. This is not surprising as there are relatively few instances of that third class. But the @@ -198,7 +198,7 @@ Because we've averaged over `p1` you might suspect that we're hiding something. The following chart shows the min and max values as well as the average, and also shows the two-class result (dashed lines). -![three classes devirt perf ranges](ThreeClassesDevirtFull.JPG) +![three classes devirt perf ranges](images/ThreeClassesDevirtFull.JPG) You can see the minimum values are very similar to the two class case; these are cases where the `p1` is close to 0 or close to 1. And that makes sense because @@ -214,7 +214,7 @@ For low values of `p` the actual class at the call site is some mixture of `D` and `E`. Here's some detail (the x axis now shows `p1` and `p` as upper and lower values respectively). -![three classes devirt perf detail](ThreeClassesDevirtDetail.JPG) +![three classes devirt perf detail](images/ThreeClassesDevirtDetail.JPG) The worst case for perf for both is when the mixture of `D` and `E` is unpredictably 50-50 and there are no `B`s. Once we mix in just 10% of `B` then @@ -299,7 +299,7 @@ an up-front guarded test. As noted there is some slowdown when the JIT always guesses the wrong class, but the break-even point (not shown) is at a relatively small probability of a correct guess. -![two classes interface devirt](TwoClassesInterface.JPG) +![two classes interface devirt](images/TwoClassesInterface.JPG) ### Interface Calls: The Three Class Case @@ -312,7 +312,7 @@ the JIT's guess doesn't have to be all that good to see payoffs. At around 10% correct, guessing wins on average, and around 30% correct guessing is always a perf win. -![three classes interface devirt](ThreeClassesInterface.JPG) +![three classes interface devirt](images/ThreeClassesInterface.JPG) ### Delegate Speculation @@ -530,4 +530,4 @@ methods off of the same object it would be nice to do just one test. - should we test for multiple types? Once we've peeled off the "most likely" case if the conditional probability of the next most likely case is high it is probably worth testing for it too. I believe the C++ compiler will test up to 3 candidates -this way... but that's a lot of code expansion. \ No newline at end of file +this way... but that's a lot of code expansion. diff --git a/docs/project/performance/JitOptimizerPlanningGuide.md b/docs/design/coreclr/jit/JitOptimizerPlanningGuide.md similarity index 100% rename from docs/project/performance/JitOptimizerPlanningGuide.md rename to docs/design/coreclr/jit/JitOptimizerPlanningGuide.md diff --git a/docs/project/performance/JitOptimizerTodoAssessment.md b/docs/design/coreclr/jit/JitOptimizerTodoAssessment.md similarity index 97% rename from docs/project/performance/JitOptimizerTodoAssessment.md rename to docs/design/coreclr/jit/JitOptimizerTodoAssessment.md index fa79fc8..7799abd 100644 --- a/docs/project/performance/JitOptimizerTodoAssessment.md +++ b/docs/design/coreclr/jit/JitOptimizerTodoAssessment.md @@ -12,7 +12,7 @@ Big-Ticket Items ### Improved Struct Handling -Most of the work required to improve struct handling in RyuJIT is captered in the [first-class structs](https://github.com/dotnet/runtime/blob/master/docs/design/features/first-class-structs.md) +Most of the work required to improve struct handling in RyuJIT is captered in the [first-class structs](first-class-structs.md) document, though that document needs to be updated to reflect the work that has already been done. Recent improvements include the struct promotion improvements that went in for `Span`. @@ -59,7 +59,7 @@ respond to any particular issues that come out of that work. This is increasingly important as C# language constructs like async/await and certain `foreach` incantations are implemented with EH constructs, making them difficult to avoid at source level. The recent work on finally cloning, empty -finally removal, and empty try removal targeted this. [Writethrough](https://github.com/dotnet/runtime/blob/master/docs/design/features/eh-writethru.md) +finally removal, and empty try removal targeted this. [Writethrough](eh-writethru.md) is another key optimization enabler here, and we are actively pursuing it. Other things we've discussed include inlining methods with EH and computing funclet callee-save register usage independently of main function callee-save register diff --git a/docs/design/features/Perf-Score.md b/docs/design/coreclr/jit/Perf-Score.md similarity index 100% rename from docs/design/features/Perf-Score.md rename to docs/design/coreclr/jit/Perf-Score.md diff --git a/docs/design/features/arm64-jit-frame-layout.md b/docs/design/coreclr/jit/arm64-jit-frame-layout.md similarity index 100% rename from docs/design/features/arm64-jit-frame-layout.md rename to docs/design/coreclr/jit/arm64-jit-frame-layout.md diff --git a/docs/design/features/eh-writethru.md b/docs/design/coreclr/jit/eh-writethru.md similarity index 100% rename from docs/design/features/eh-writethru.md rename to docs/design/coreclr/jit/eh-writethru.md diff --git a/docs/design/features/finally-optimizations.md b/docs/design/coreclr/jit/finally-optimizations.md similarity index 100% rename from docs/design/features/finally-optimizations.md rename to docs/design/coreclr/jit/finally-optimizations.md diff --git a/docs/design/features/first-class-structs.md b/docs/design/coreclr/jit/first-class-structs.md similarity index 100% rename from docs/design/features/first-class-structs.md rename to docs/design/coreclr/jit/first-class-structs.md diff --git a/docs/design/features/GreenNode_WriteTo_CallGraph.png b/docs/design/coreclr/jit/images/GreenNode_WriteTo_CallGraph.png similarity index 100% rename from docs/design/features/GreenNode_WriteTo_CallGraph.png rename to docs/design/coreclr/jit/images/GreenNode_WriteTo_CallGraph.png diff --git a/docs/design/features/ThreeClassesDevirt.JPG b/docs/design/coreclr/jit/images/ThreeClassesDevirt.JPG similarity index 100% rename from docs/design/features/ThreeClassesDevirt.JPG rename to docs/design/coreclr/jit/images/ThreeClassesDevirt.JPG diff --git a/docs/design/features/ThreeClassesDevirtDetail.JPG b/docs/design/coreclr/jit/images/ThreeClassesDevirtDetail.JPG similarity index 100% rename from docs/design/features/ThreeClassesDevirtDetail.JPG rename to docs/design/coreclr/jit/images/ThreeClassesDevirtDetail.JPG diff --git a/docs/design/features/ThreeClassesDevirtFull.JPG b/docs/design/coreclr/jit/images/ThreeClassesDevirtFull.JPG similarity index 100% rename from docs/design/features/ThreeClassesDevirtFull.JPG rename to docs/design/coreclr/jit/images/ThreeClassesDevirtFull.JPG diff --git a/docs/design/features/ThreeClassesInterface.JPG b/docs/design/coreclr/jit/images/ThreeClassesInterface.JPG similarity index 100% rename from docs/design/features/ThreeClassesInterface.JPG rename to docs/design/coreclr/jit/images/ThreeClassesInterface.JPG diff --git a/docs/design/features/TwoClassesBaseline.JPG b/docs/design/coreclr/jit/images/TwoClassesBaseline.JPG similarity index 100% rename from docs/design/features/TwoClassesBaseline.JPG rename to docs/design/coreclr/jit/images/TwoClassesBaseline.JPG diff --git a/docs/design/features/TwoClassesDevirt.JPG b/docs/design/coreclr/jit/images/TwoClassesDevirt.JPG similarity index 100% rename from docs/design/features/TwoClassesDevirt.JPG rename to docs/design/coreclr/jit/images/TwoClassesDevirt.JPG diff --git a/docs/design/features/TwoClassesInterface.JPG b/docs/design/coreclr/jit/images/TwoClassesInterface.JPG similarity index 100% rename from docs/design/features/TwoClassesInterface.JPG rename to docs/design/coreclr/jit/images/TwoClassesInterface.JPG diff --git a/docs/design/coreclr/botr/images/ryujit-backend-phases.png b/docs/design/coreclr/jit/images/ryujit-backend-phases.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-backend-phases.png rename to docs/design/coreclr/jit/images/ryujit-backend-phases.png diff --git a/docs/design/coreclr/botr/images/ryujit-flowgraph.png b/docs/design/coreclr/jit/images/ryujit-flowgraph.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-flowgraph.png rename to docs/design/coreclr/jit/images/ryujit-flowgraph.png diff --git a/docs/design/coreclr/botr/images/ryujit-high-level-overview.png b/docs/design/coreclr/jit/images/ryujit-high-level-overview.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-high-level-overview.png rename to docs/design/coreclr/jit/images/ryujit-high-level-overview.png diff --git a/docs/design/coreclr/botr/images/ryujit-initial-phases.png b/docs/design/coreclr/jit/images/ryujit-initial-phases.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-initial-phases.png rename to docs/design/coreclr/jit/images/ryujit-initial-phases.png diff --git a/docs/design/coreclr/botr/images/ryujit-ir-ordered.png b/docs/design/coreclr/jit/images/ryujit-ir-ordered.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-ir-ordered.png rename to docs/design/coreclr/jit/images/ryujit-ir-ordered.png diff --git a/docs/design/coreclr/botr/images/ryujit-ir-overview.png b/docs/design/coreclr/jit/images/ryujit-ir-overview.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-ir-overview.png rename to docs/design/coreclr/jit/images/ryujit-ir-overview.png diff --git a/docs/design/coreclr/botr/images/ryujit-lir.png b/docs/design/coreclr/jit/images/ryujit-lir.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-lir.png rename to docs/design/coreclr/jit/images/ryujit-lir.png diff --git a/docs/design/coreclr/botr/images/ryujit-optimization-phases.png b/docs/design/coreclr/jit/images/ryujit-optimization-phases.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-optimization-phases.png rename to docs/design/coreclr/jit/images/ryujit-optimization-phases.png diff --git a/docs/design/coreclr/botr/images/ryujit-phase-diagram.png b/docs/design/coreclr/jit/images/ryujit-phase-diagram.png similarity index 100% rename from docs/design/coreclr/botr/images/ryujit-phase-diagram.png rename to docs/design/coreclr/jit/images/ryujit-phase-diagram.png diff --git a/docs/design/features/inline-size-estimates.md b/docs/design/coreclr/jit/inline-size-estimates.md similarity index 100% rename from docs/design/features/inline-size-estimates.md rename to docs/design/coreclr/jit/inline-size-estimates.md diff --git a/docs/design/features/inlining-plans.md b/docs/design/coreclr/jit/inlining-plans.md similarity index 100% rename from docs/design/features/inlining-plans.md rename to docs/design/coreclr/jit/inlining-plans.md diff --git a/docs/design/features/jit-call-morphing.md b/docs/design/coreclr/jit/jit-call-morphing.md similarity index 100% rename from docs/design/features/jit-call-morphing.md rename to docs/design/coreclr/jit/jit-call-morphing.md diff --git a/docs/design/features/longs-on-32bit-arch.md b/docs/design/coreclr/jit/longs-on-32bit-arch.md similarity index 100% rename from docs/design/features/longs-on-32bit-arch.md rename to docs/design/coreclr/jit/longs-on-32bit-arch.md diff --git a/docs/design/features/lsra-detail.md b/docs/design/coreclr/jit/lsra-detail.md similarity index 99% rename from docs/design/features/lsra-detail.md rename to docs/design/coreclr/jit/lsra-detail.md index fae6d8f..7606574 100644 --- a/docs/design/features/lsra-detail.md +++ b/docs/design/coreclr/jit/lsra-detail.md @@ -28,7 +28,7 @@ Overview This document provides additional detail on the linear scan register allocator (LSRA) in RyuJIT. It is expected that the reader has already -read the [RyuJIT Overview document](https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/ryujit-overview.md). +read the [RyuJIT Overview document](ryujit-overview.md). Register allocation is performed using a linear scan register allocation scheme, implemented by the `LinearScan` class. diff --git a/docs/design/features/lsra-throughput.md b/docs/design/coreclr/jit/lsra-throughput.md similarity index 100% rename from docs/design/features/lsra-throughput.md rename to docs/design/coreclr/jit/lsra-throughput.md diff --git a/docs/design/features/multi-reg-call-nodes.md b/docs/design/coreclr/jit/multi-reg-call-nodes.md similarity index 100% rename from docs/design/features/multi-reg-call-nodes.md rename to docs/design/coreclr/jit/multi-reg-call-nodes.md diff --git a/docs/design/features/object-stack-allocation.md b/docs/design/coreclr/jit/object-stack-allocation.md similarity index 99% rename from docs/design/features/object-stack-allocation.md rename to docs/design/coreclr/jit/object-stack-allocation.md index a159234..ec6fe14 100644 --- a/docs/design/features/object-stack-allocation.md +++ b/docs/design/coreclr/jit/object-stack-allocation.md @@ -165,7 +165,7 @@ of all allocated bytes: 0.67% (6.24 Mb out of 920.1 Mb) but it's just a single s Below is the portion of the call graph the escape analysis will have to consider when proving this allocation is not escaping. Green arrows correspond to the call sites that are inlined and red arrows correspond to the call sites that are not inlined. -![Call Graph](GreenNode_WriteTo_CallGraph.png) +![Call Graph](images/GreenNode_WriteTo_CallGraph.png) ## Roadmap diff --git a/docs/design/coreclr/botr/porting-ryujit.md b/docs/design/coreclr/jit/porting-ryujit.md similarity index 100% rename from docs/design/coreclr/botr/porting-ryujit.md rename to docs/design/coreclr/jit/porting-ryujit.md diff --git a/docs/design/features/removing-embedded-statements.md b/docs/design/coreclr/jit/removing-embedded-statements.md similarity index 100% rename from docs/design/features/removing-embedded-statements.md rename to docs/design/coreclr/jit/removing-embedded-statements.md diff --git a/docs/design/coreclr/botr/ryujit-overview.md b/docs/design/coreclr/jit/ryujit-overview.md similarity index 99% rename from docs/design/coreclr/botr/ryujit-overview.md rename to docs/design/coreclr/jit/ryujit-overview.md index b91054d..bf0e1540 100644 --- a/docs/design/coreclr/botr/ryujit-overview.md +++ b/docs/design/coreclr/jit/ryujit-overview.md @@ -765,11 +765,11 @@ you want to dump. For example: set "COMPlus_JitDump=Main GetEnumerator" ``` -See [Setting configuration variables](../../../workflow/testing/coreclr/viewing-jit-dumps.md#setting-configuration-variables) for more +See [Setting configuration variables](viewing-jit-dumps.md#setting-configuration-variables) for more details on this. Full instructions for dumping the compilation of some managed code can be found here: -[viewing-jit-dumps.md](../../../workflow/testing/coreclr/viewing-jit-dumps.md) +[viewing-jit-dumps.md](viewing-jit-dumps.md) ## Reading expression trees diff --git a/docs/design/coreclr/botr/ryujit-tutorial.md b/docs/design/coreclr/jit/ryujit-tutorial.md similarity index 99% rename from docs/design/coreclr/botr/ryujit-tutorial.md rename to docs/design/coreclr/jit/ryujit-tutorial.md index 4d09b4d..7746204 100644 --- a/docs/design/coreclr/botr/ryujit-tutorial.md +++ b/docs/design/coreclr/jit/ryujit-tutorial.md @@ -342,7 +342,7 @@ This is used by all of the front-end optimizations. - It then imports the IL for the candidate, producing IR - This is inserted at the call site, if successful - This phase has been undergoing significant refactoring and enhancement: - - https://github.com/dotnet/runtime/blob/master/docs/design/features/inlining-plans.md + - See [inlining plans](inlining-plans.md) #### Notes The inliner re-invokes the importer for each method that is considered a suitable candidate. Along the way, it may determine that the method cannot, or should not, be inlined, at which case it abandons the constructed IR, and leaves the callsite as-is. Otherwise, it inserts the newly created IR at the callsite, adds the local variables of the called method to the callee, and fixes up the arguments and returns. @@ -676,8 +676,7 @@ Add Pattern Recognition (SampleStep2 shelveset): - Run & capture jitdump3.out, search for optCloneLoops ### Reference -- The RyuJIT Overview document is available here: - https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/ryujit-overview.md +- The RyuJIT overview document is available [here](ryujit-overview.md) ## Backup diff --git a/docs/design/features/struct-abi.md b/docs/design/coreclr/jit/struct-abi.md similarity index 100% rename from docs/design/features/struct-abi.md rename to docs/design/coreclr/jit/struct-abi.md diff --git a/docs/design/features/variabletracking.md b/docs/design/coreclr/jit/variabletracking.md similarity index 100% rename from docs/design/features/variabletracking.md rename to docs/design/coreclr/jit/variabletracking.md diff --git a/docs/workflow/testing/coreclr/viewing-jit-dumps.md b/docs/design/coreclr/jit/viewing-jit-dumps.md similarity index 97% rename from docs/workflow/testing/coreclr/viewing-jit-dumps.md rename to docs/design/coreclr/jit/viewing-jit-dumps.md index 6a5c41b..a60dd59 100644 --- a/docs/workflow/testing/coreclr/viewing-jit-dumps.md +++ b/docs/design/coreclr/jit/viewing-jit-dumps.md @@ -2,7 +2,7 @@ This document is intended for people interested in seeing the disassembly, GC info, or other details the JIT generates for a managed program. -To make sense of the results, it is recommended you also read the [Reading a JitDump](/docs/design/coreclr/botr/ryujit-overview.md#reading-a-jitdump) section of the RyuJIT Overview. +To make sense of the results, it is recommended you also read the [Reading a JitDump](ryujit-overview.md#reading-a-jitdump) section of the RyuJIT Overview. ## Setting up our environment @@ -148,7 +148,7 @@ The wildcard character `*` can be used for `` and ``. In Below are some of the most useful `COMPlus` variables. Where {method-list} is specified in the list below, you can supply a space-separated list of either fully-qualified or simple method names (the former is useful when running something that has many methods of the same name), or you can specify `*` to mean all methods. -* `COMPlus_JitDump`={method-list} – dump lots of useful information about what the JIT is doing. See [Reading a JitDump](/docs/design/coreclr/botr/ryujit-overview.md#reading-a-jitdump) for more on how to analyze this data. +* `COMPlus_JitDump`={method-list} – dump lots of useful information about what the JIT is doing. See [Reading a JitDump](ryujit-overview.md#reading-a-jitdump) for more on how to analyze this data. * `COMPlus_JitDisasm`={method-list} – dump a disassembly listing of each method. * `COMPlus_JitDiffableDasm` – set to 1 to tell the JIT to avoid printing things like pointer values that can change from one invocation to the next, so that the disassembly can be more easily compared. * `COMPlus_JitGCDump`={method-list} – dump the GC information. diff --git a/docs/design/features/hw-intrinsics.md b/docs/design/features/hw-intrinsics.md index 7559bdb..c86ebf5 100644 --- a/docs/design/features/hw-intrinsics.md +++ b/docs/design/features/hw-intrinsics.md @@ -88,7 +88,7 @@ The hardware intrinsics nodes are generally imported as `GenTreeHWIntrinsic` nod ### Lowering -As described here: https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/ryujit-overview.md#lowering, Lowering is responsible for transforming the IR in such a way that the control flow, and any register requirements, are fully exposed. This includes determining what instructions can be "contained" in another, such as immediates or addressing modes. For the hardware intrinsics, these are done in the target-specific methods `Lowering::LowerHWIntrinsic()` and `Lowering::ContainCheckHWIntrinsic()`. +As described [here](../coreclr/jit/ryujit-overview.md#lowering), Lowering is responsible for transforming the IR in such a way that the control flow, and any register requirements, are fully exposed. This includes determining what instructions can be "contained" in another, such as immediates or addressing modes. For the hardware intrinsics, these are done in the target-specific methods `Lowering::LowerHWIntrinsic()` and `Lowering::ContainCheckHWIntrinsic()`. The main consideration here is whether there are child nodes that are folded into the generated instruction. These may be: * An immediate operand diff --git a/docs/project/glossary.md b/docs/project/glossary.md index 16337f5..8e4a999 100644 --- a/docs/project/glossary.md +++ b/docs/project/glossary.md @@ -21,7 +21,7 @@ terminology. | EE | Execution Engine. | | GC | [Garbage Collector](https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/garbage-collection.md). | | IPC | Inter-Process Communication. | -| JIT | [Just-in-Time](https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/botr/ryujit-overview.md) compiler. RyuJIT is the code name for the next generation Just-in-Time(aka "JIT") for the .NET runtime. | +| JIT | [Just-in-Time](https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/jit/ryujit-overview.md) compiler. RyuJIT is the code name for the next generation Just-in-Time(aka "JIT") for the .NET runtime. | | LCG | Lightweight Code Generation. An early name for [dynamic methods](https://github.com/dotnet/runtime/blob/master/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicMethod.cs). | | MD | MetaData. | | MDA | Managed Debugging Assistant - see [details](https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/diagnosing-errors-with-managed-debugging-assistants) (Note: Not in .NET Core, equivalent diagnostic functionality is made available on a case-by-case basis, e.g. [#15465](https://github.com/dotnet/coreclr/issues/15465)) |