使用 JIT 重新编译方法添加检测

从开始 .NET Framework 4.5,探查器可以检测已实时 (jit) 编译 (JIT)使用 ICorProfilerInfo4 方法重新编译程序的方法。

使用 JIT 重新编译

探查器可以请求 JIT 编译器随时重新编译功能。 当重新编译函数时,探查器指定代码生成标志和公共中间语言 (CIL)正文如下所示:

  1. 探查器指定其视图在启动时使用 JIT 重新编译方法。 它通过指定 COR_PRF_ENABLE_REJIT 标志执行此操作,在调用方法时 ICorProfilerInfo:: SetEventMask 。 探查器还指定 COR_PRF_DISABLE_ALL_NGEN_IMAGES 标志防止 NGEN 模块加载。

  2. 当模块完成加载时,它稍后将从该模块的方法的探查器执行所有元数据编辑和要求的添加支持所有检测。 随时后点,探查器调用它之前创建从线程的 ICorProfilerInfo4:: RequestReJIT 方法,并通过方法功能列表重新编译。

  3. ,下次它们调用,则公共语言运行 (CLR)时标识重新编译这些功能。 如果将功能 ( FunctionID表示的每个实例) 的多个实例,所有实例进行重新生成将被识别。 下次所有功能实例调用, CLR 将执行 JIT 重新编译。

  4. 如果函数实例是重新编译的第一个实例, CLR 问题 ICorProfilerCallback4:: GetReJITParameters 回调方法从探查器的 GET 命令。 GetReJITParameters 回调提供 ICorProfilerFunctionControl 接口。 ,当重新编译函数时,探查器此接口调用将代码生成参数和新的完整体使用。 这些参数应用于函数的所有实例。

  5. CLR 将问题 ICorProfilerCallback4:: ReJITCompilationStarted 回调。

  6. 当重新生成完成时, CLR 问题 ICorProfilerCallback4:: ReJITCompilationFinished 回调。 函数调用导致重新编译然后定向到新的 (重新编译的代码)。 任何进一步对此实例来转到新代码。

  7. 随时此后,探查器,运行该线程而以前创建的,可以调用 ICorProfilerInfo4:: RequestRevert 方法恢复最初 JIT 编译版本 (无探查器修改) 的指定的函数。

每个函数实例只有一最新版本,分别对应于下列操作之一:

  • 如果重新编译没有为该功能出现,它是原始版本。

  • 如果函数的最后一个 JIT 操作是重新编译,这是最近重新编译的版本。

  • 如果函数的最后一个 JIT 操作还原了重新编译,它是原始版本。

函数实例的新调用始终激活该功能的版本。

JIT 重新编译限制

使用 JIT 重新编译方法的探查器不能执行以下操作:

  • 修改模块的元数据 (除了添加新 LocalVarSigTokens),模块中的 ICorProfilerCallback:: ModuleLoadFinished 回调返回之后。

  • 重新生成由本机映像生成器的方法体 (ngen.exe) 创建的。

  • ,在使用附加/分离分析时,请重新编译方法。

  • recompile 内联函数。

  • 允许任何本机映像生成器程序集加载。 (在标记必须包含COR_PRF_DISABLE_ALL_NGEN_IMAGES 通过在启动的 ICorProfilerInfo:: SetEventMask 方法。)

  • 重新生成动态方法和动态程序集。

备注

,即包含的 AppDomain 卸载时, CLR 还原 JIT 重新编译使用的所有内存。CLR 不还原此内存任何之前,因此,即使该重新编译的方法还原了。

检测术语

  1. 检测探查器:允许其用户分析以及收集深入了解应用程序通过将针对的检测代码添加到应用程序的探查器,收集数据不足导致检测和分析或汇总数据。

  2. Common Intermediate Language (CIL):.NET framework 定义由 Common Language Infrastructure 规范和使用的最低级别的可读的编程语言。

  3. JIT recompilation:本机代码的重新编译从完整的使用 JIT 编译器。

  4. ReJITID:一个不透明的标识符 (定义为 typedef UINT_PTR ReJITID;) 特定的重新编译函数的版本。 (FunctionID, ReJITID) 对需要唯一标识重新编译的函数实例。 不同的 FunctionIDs 的ReJITIDs 与互相相关,因此,即使 FunctionIDs 相关。 例如,因此,如果 Function<T>() 重新编译, Function<Int>() 的结果 ReJITIDs 和 Function<String>() 不一定是相同的。 ReJITID=0 引用该函数的初始版本。

  5. 功能:使用单词的元数据意义。 例如, Function<T>() 唯一标识 (Module, MethodDef)。

  6. 函数实例:一个函数实例化特定类型的在运行时。 泛型功能可以包含多个实例;例如, Function<T>() 可以是 Function<Int>() 和 Function<String>()。 非泛型函数可以在每个实例的多个应用程序域。 函数实例是唯一的 FunctionID标识。

  7. 功能版本:(例如, Function<Int>() 的初始版本或 Function<String>()的第二个重新生成的版本),唯一标识功能的特定重新生成的版本 (FunctionID, ReJITID)。

请参见

参考

ICorProfilerInfo4 接口

ICorProfilerFunctionControl 接口

ICorProfilerInfo4::RequestReJIT 方法

ICorProfilerInfo4::RequestRevert 方法

其他资源

分析概述

分析(非托管 API 参考)

非托管 API 参考