.. _jit-api-support: Just-In-Time (JIT) API ====================== Use the Just-In-Time (JIT) Profiling API to enable performance tools to collect information about just-in-time generated codes. You must insert JIT Profiling API calls in the code generator to report information before the JIT-compiled code goes to execution. This information is collected at runtime and used by tools like Intel® VTune™ Profiler to display performance metrics associated with JIT-compiled code. You can use the JIT Profiling API to profile scenarios like: - Dynamic JIT compilation of JavaScript code traces - JIT execution in OpenCL™ applications - Java*/.NET* managed execution environments - Custom ISV JIT engines You can use the JIT Profiling API to profile such environments as dynamic JIT compilation of JavaScript code traces, JIT execution in OpenCL™ applications, Java*/.NET* managed execution environments, and custom ISV JIT engines. The JIT engine generates code during runtime and communicates through the static part with a profiler object (Collector). During runtime, the JIT engine reports the information about JIT-compiled code that is stored in a trace file by the profiler object. After collection, the profiling tool uses the generated trace file to resolve the JIT-compiled code. Use the JIT Profiling API to: - :ref:`Profile trace-based and method-based JIT-compiled code` - :ref:`Analyze split functions` - :ref:`Explore inline functions` Environment Variables in the JIT Profiling API ---------------------------------------------- The JIT Profiling API contains two environment variables: - ``INTEL_JIT_PROFILER32`` - ``INTEL_JIT_PROFILER64`` In turn, these variables contain paths to specific runtime libraries. These variables are used to signal the replacement of the stub implementation of the JIT API with the JIT API collector. After you instrument your code with the JIT API and link it to the JIT API stub (``libjitprofiling.lib/libjitprofiling.a``), when the environment variables are set, your code loads the libraries defined in the variables. Make sure to set these environment variables for the ``ittnotify_collector`` to enable data collection: On Windows*: .. code-block:: bash INTEL_JIT_PROFILER32=\bin32\runtime\ittnotify_collector.dll INTEL_JIT_PROFILER64=\bin64\runtime\ittnotify_collector.dll On Linux*: .. code-block:: bash INTEL_JIT_PROFILER32=/lib32/runtime/libittnotify_collector.so INTEL_JIT_PROFILER64=/lib64/runtime/libittnotify_collector.so On FreeBSD*: .. code-block:: bash INTEL_JIT_PROFILER64=/lib64/runtime/libittnotify_collector.so .. _Profile trace-based and method-based JIT-compiled code : Profile Trace-based and Method-based JIT-compiled Code ------------------------------------------------------ This is the most common scenario for using JIT Profiling API to profile trace-based and method-based JIT-compiled code: .. code-block:: cpp #include if (iJIT_IsProfilingActive() != iJIT_SAMPLING_ON) { return; } iJIT_Method_Load jmethod = {0}; jmethod.method_id = iJIT_GetNewMethodID(); jmethod.method_name = "method_name"; jmethod.class_file_name = "class_name"; jmethod.source_file_name = "source_file_name"; jmethod.method_load_address = code_addr; jmethod.method_size = code_size; iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod); iJIT_NotifyEvent(iJVM_EVENT_TYPE_SHUTDOWN, NULL); **Usage Tips** - If any ``iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED`` event overwrites a method that has already been reported , that method becomes invalid. The memory region of the method is treated as unloaded. - If the line number information that was provided contains multiple source lines for the same assembly instruction (code location), the profiling tool selects the first line number. - You can associate dynamically generated code with a module name. Use the ``iJIT_Method_Load_V2`` structure for this purpose. - If you register a function with the same method ID multiple times and you specify different module names, the profiling tool selects the module name that was registered first. If you want to distinguish the same function between different JIT engines, provide different method IDs for each function. Other symbolic information, like source file, can be identical. .. _Analyze split functions : Analyze Split Functions ----------------------- You can use the JIT Profiling API to analyze split functions. This scenario often occurs in resource-limited environments where the code for the same function is generated or updated in separate segments. Sometimes this code generation can happen with overlapping lifetimes. .. code-block:: cpp #include unsigned int method_id = iJIT_GetNewMethodID(); iJIT_Method_Load a = {0}; a.method_id = method_id; a.method_load_address = 0x100; a.method_size = 0x20; iJIT_Method_Load b = {0}; b.method_id = method_id; b.method_load_address = 0x200; b.method_size = 0x30; iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&b) **Usage Tips** - If a ``iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED`` event overwrites a method that was already reported, that method becomes invalid and its memory region is treated as unloaded. - All code regions that are reported with the same method ID are considered to belong to the same method. Symbolic information (method name, source file name) is taken from the first notification. All subsequent notifications with the same method ID are processed only for the information in the line number table. - If you register a second code region with a different source file name and the same method ID, this information is saved and is not considered as an extension of the first code region. However, the profiling tool uses the source file of the first code region and can map performance metrics incorrectly. - If you register a second code region with the same source file as the one used for the first region and you use the same method ID, the source file is discarded but the profiling tool maps metrics to the source file correctly. - If you register a second code region with a null source file and the same method ID, provided line number info will be associated with the source file of the first code region. .. _Explore inline functions: Explore Inline Functions ------------------------ You can use the JIT Profiling API to explore inline functions including the multilevel hierarchy of nested inline methods that shows the distribution of performance metrics. .. code-block:: cpp #include // method_id parent_id // [-- c --] 3000 2000 // [---- d -----] 2001 1000 // [---- b ----] 2000 1000 // [------------ a ----------------] 1000 n/a iJIT_Method_Load a = {0}; a.method_id = 1000; iJIT_Method_Inline_Load b = {0}; b.method_id = 2000; b.parent_method_id = 1000; iJIT_Method_Inline_Load c = {0}; c.method_id = 3000; c.parent_method_id = 2000; iJIT_Method_Inline_Load d = {0}; d.method_id = 2001; d.parent_method_id = 1000; iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&b); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&c); iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&d); **Usage Tips** - Each inline (``iJIT_Method_Inline_Load``) method should be associated with two method IDs: one for itself; one for its immediate parent. - Address regions of inline methods of the same parent method cannot overlap each other. - Execution of the parent method must not start until the parent method and all its inline methods are reported. - For nested inline methods, the order of ``iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED`` events is not important. - If any event overwrites either inline method or top parent method, then the parent, including inline methods, becomes invalid and their memory region is treated as unloaded. Learn More ---------- .. toctree:: :maxdepth: 1 using-jit-api jit-api-reference