JIT Profiling API

Note

The Instrumentation and Tracing Technology API (ITT API) and the Just-in-Time Profiling API (JIT API) are open source components. You can access the source code and make contributions in the GitHub* repository.

The JIT (Just-In-Time) Profiling API provides functionality to report information about just-in-time generated code that can be used by performance tools. You must insert JIT Profiling API calls in the code generator to report information before 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 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 standard VTune Profiler installation contains a static part (as a static library and source files) and a profiler object. The JIT engine generating code during runtime communicates with a profiler object through the static part. During runtime, the JIT engine reports the information about JIT-compiled code stored in a trace file by the profiler object. After collection, the VTune Profiler uses the generated trace file to resolve the JIT-compiled code. If VTune Profiler is not installed, profiling is disabled.

Use the JIT Profiling API to:

JIT profiling is supported with the Launch Application target option for event based sampling.

Environment Variables in the JIT Profiling API

The JIT Profiling API contains two environment variables, which in turn contain paths to specific runtime libraries.

These variables are used to signal the replacement of the stub implementation of the JIT API with the VTune Profiler JIT API collector. Once you instrument your code with the JIT API and link it to the VTune Profiler JIT API stub (libittnotify.lib/libittnotify.a), your code loads the libraries defined in these environment variables, once the variables are set.

Make sure to set these environment variables for the ittnotify_collector to enable data collection:   
On Windows*:
INTEL_JIT_PROFILER32=<install-dir>\bin32\runtime\ittnotify_collector.dll
INTEL_JIT_PROFILER64=<install-dir>\bin64\runtime\ittnotify_collector.dll
On Linux*:
INTEL_JIT_PROFILER32=<install-dir>/lib32/runtime/libittnotify_collector.so
INTEL_JIT_PROFILER64=<install-dir>/lib64/runtime/libittnotify_collector.so    
On FreeBSD*:
INTEL_JIT_PROFILER64=<target-package>/lib64/runtime/libittnotify_collector.so  

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:

#include <jitprofiling.h>

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

Analyze Split Functions

You can use the JIT Profiling API to analyze split functions (multiple joint or disjoint code regions belonging to the same function) including re-JITting with potential overlapping of code regions in time, which is common in resource-limited environments.

 
 #include <jitprofiling.h>
 
 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

Explore Inline Functions

You can use the JIT Profiling API to explore inline functions including multi-level hierarchy of nested inline methods that shows how performance metrics are distributed through them.

#include <jitprofiling.h>

  //                                    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

See Also