Add support for delegate GDV and method-based vtable GDV (#68703)
authorJakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
Fri, 17 Jun 2022 23:58:01 +0000 (01:58 +0200)
committerGitHub <noreply@github.com>
Fri, 17 Jun 2022 23:58:01 +0000 (01:58 +0200)
commitcae8546c5dad359c8983e8db2ee0657cce3494bc
treece87e396ef7ebcf323f0400be7522182b84f17bb
parent9dfdfbf1718c29f4c905bb6474e214fac9fe7910
Add support for delegate GDV and method-based vtable GDV (#68703)

Add support for instrumenting delegate calls and vtable calls into method handle histograms. Use these histograms to do GDV for delegate calls and also support method-based GDV for vtable calls.

For instrumentation we now support class probes at interface call sites, method probes at delegate call sites and both class probes and method probes at vtable call sites. For vtable calls, when turned on, instrumentation produces both histograms as PGO data so that the JIT can later make the choice about what is the best form of guard to use at that site.

For guarding, there are some things to take into account. Delegate calls currently (practically) always point to precode, so this PR is just guarding on getFunctionFixedEntryPoint which returns the precode address, and this is generally quite cheap (same cost as class-based GDV). That's the case for delegates pointing to instance methods anyway, this PR does not support static methods yet -- those will be more expensive.

For vtable calls the runtime will backpatch the slots when tiering, so the JIT guards the address retrieved from the vtable against an indirection of the slot, which is slightly more expensive than a class-based guard.

Currently the instrumentation is enabled conditionally with COMPlus_JitDelegateProfiling=1 (for delegates) and COMPlus_JitVTableProfiling=1 (for vtable calls). Currently delegate profiling is turned on by default while vtable profiling is off by default.
37 files changed:
eng/pipelines/common/templates/runtimes/run-test-job.yml
eng/pipelines/coreclr/libraries-pgo.yml
eng/pipelines/libraries/run-test-job.yml
src/coreclr/inc/corinfo.h
src/coreclr/inc/corjit.h
src/coreclr/inc/jiteeversionguid.h
src/coreclr/inc/jithelpers.h
src/coreclr/inc/readytorun.h
src/coreclr/jit/ClrJit.PAL.exports
src/coreclr/jit/ClrJit.exports
src/coreclr/jit/block.h
src/coreclr/jit/compiler.cpp
src/coreclr/jit/compiler.h
src/coreclr/jit/fgbasic.cpp
src/coreclr/jit/fgprofile.cpp
src/coreclr/jit/gentree.h
src/coreclr/jit/importer.cpp
src/coreclr/jit/indirectcalltransformer.cpp
src/coreclr/jit/inline.h
src/coreclr/jit/jit.h
src/coreclr/jit/jitconfigvalues.h
src/coreclr/jit/likelyclass.cpp
src/coreclr/jit/morph.cpp
src/coreclr/jit/patchpoint.cpp
src/coreclr/tools/Common/Internal/Runtime/ModuleHeaders.cs
src/coreclr/tools/Common/JitInterface/CorInfoHelpFunc.cs
src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/tools/Common/Pgo/PgoFormat.cs
src/coreclr/tools/superpmi/mcs/verbdumpmap.cpp
src/coreclr/tools/superpmi/mcs/verbjitflags.cpp
src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp
src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h
src/coreclr/tools/superpmi/superpmi-shared/spmidumphelper.cpp
src/coreclr/vm/jithelpers.cpp
src/coreclr/vm/method.cpp
src/coreclr/vm/pgo.cpp
src/tests/Common/testenvironment.proj