xref: /aosp_15_r20/external/llvm/lib/ExecutionEngine/IntelJITEvents/jitprofiling.c (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker /*===-- jitprofiling.c - JIT (Just-In-Time) Profiling API----------*- C -*-===*
2*9880d681SAndroid Build Coastguard Worker  *
3*9880d681SAndroid Build Coastguard Worker  *                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker  *
5*9880d681SAndroid Build Coastguard Worker  * This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker  * License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker  *
8*9880d681SAndroid Build Coastguard Worker  *===----------------------------------------------------------------------===*
9*9880d681SAndroid Build Coastguard Worker  *
10*9880d681SAndroid Build Coastguard Worker  * This file provides Intel(R) Performance Analyzer JIT (Just-In-Time)
11*9880d681SAndroid Build Coastguard Worker  * Profiling API implementation.
12*9880d681SAndroid Build Coastguard Worker  *
13*9880d681SAndroid Build Coastguard Worker  * NOTE: This file comes in a style different from the rest of LLVM
14*9880d681SAndroid Build Coastguard Worker  * source base since  this is a piece of code shared from Intel(R)
15*9880d681SAndroid Build Coastguard Worker  * products.  Please do not reformat / re-style this code to make
16*9880d681SAndroid Build Coastguard Worker  * subsequent merges and contributions from the original source base eaiser.
17*9880d681SAndroid Build Coastguard Worker  *
18*9880d681SAndroid Build Coastguard Worker  *===----------------------------------------------------------------------===*/
19*9880d681SAndroid Build Coastguard Worker #include "ittnotify_config.h"
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
22*9880d681SAndroid Build Coastguard Worker #include <windows.h>
23*9880d681SAndroid Build Coastguard Worker #pragma optimize("", off)
24*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
25*9880d681SAndroid Build Coastguard Worker #include <pthread.h>
26*9880d681SAndroid Build Coastguard Worker #include <dlfcn.h>
27*9880d681SAndroid Build Coastguard Worker #include <stdint.h>
28*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
29*9880d681SAndroid Build Coastguard Worker #include <malloc.h>
30*9880d681SAndroid Build Coastguard Worker #include <stdlib.h>
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker #include "jitprofiling.h"
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker static const char rcsid[] = "\n@(#) $Revision: 243501 $\n";
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker #define DLL_ENVIRONMENT_VAR             "VS_PROFILER"
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker #ifndef NEW_DLL_ENVIRONMENT_VAR
39*9880d681SAndroid Build Coastguard Worker #if ITT_ARCH==ITT_ARCH_IA32
40*9880d681SAndroid Build Coastguard Worker #define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER32"
41*9880d681SAndroid Build Coastguard Worker #else
42*9880d681SAndroid Build Coastguard Worker #define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER64"
43*9880d681SAndroid Build Coastguard Worker #endif
44*9880d681SAndroid Build Coastguard Worker #endif /* NEW_DLL_ENVIRONMENT_VAR */
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
47*9880d681SAndroid Build Coastguard Worker #define DEFAULT_DLLNAME                 "JitPI.dll"
48*9880d681SAndroid Build Coastguard Worker HINSTANCE m_libHandle = NULL;
49*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
50*9880d681SAndroid Build Coastguard Worker #define DEFAULT_DLLNAME                 "libJitPI.so"
51*9880d681SAndroid Build Coastguard Worker void* m_libHandle = NULL;
52*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker /* default location of JIT profiling agent on Android */
55*9880d681SAndroid Build Coastguard Worker #define ANDROID_JIT_AGENT_PATH  "/data/intel/libittnotify.so"
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker /* the function pointers */
58*9880d681SAndroid Build Coastguard Worker typedef unsigned int(*TPInitialize)(void);
59*9880d681SAndroid Build Coastguard Worker static TPInitialize FUNC_Initialize=NULL;
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker typedef unsigned int(*TPNotify)(unsigned int, void*);
62*9880d681SAndroid Build Coastguard Worker static TPNotify FUNC_NotifyEvent=NULL;
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker /* end collector dll part. */
67*9880d681SAndroid Build Coastguard Worker 
68*9880d681SAndroid Build Coastguard Worker /* loadiJIT_Funcs() : this function is called just in the beginning
69*9880d681SAndroid Build Coastguard Worker  *  and is responsible to load the functions from BistroJavaCollector.dll
70*9880d681SAndroid Build Coastguard Worker  * result:
71*9880d681SAndroid Build Coastguard Worker  *  on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
72*9880d681SAndroid Build Coastguard Worker  *  on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
73*9880d681SAndroid Build Coastguard Worker  */
74*9880d681SAndroid Build Coastguard Worker static int loadiJIT_Funcs(void);
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker /* global representing whether the BistroJavaCollector can't be loaded */
77*9880d681SAndroid Build Coastguard Worker static int iJIT_DLL_is_missing = 0;
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker /* Virtual stack - the struct is used as a virtual stack for each thread.
80*9880d681SAndroid Build Coastguard Worker  * Every thread initializes with a stack of size INIT_TOP_STACK.
81*9880d681SAndroid Build Coastguard Worker  * Every method entry decreases from the current stack point,
82*9880d681SAndroid Build Coastguard Worker  * and when a thread stack reaches its top of stack (return from the global
83*9880d681SAndroid Build Coastguard Worker  * function), the top of stack and the current stack increase. Notice that
84*9880d681SAndroid Build Coastguard Worker  * when returning from a function the stack pointer is the address of
85*9880d681SAndroid Build Coastguard Worker  * the function return.
86*9880d681SAndroid Build Coastguard Worker */
87*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
88*9880d681SAndroid Build Coastguard Worker static DWORD threadLocalStorageHandle = 0;
89*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
90*9880d681SAndroid Build Coastguard Worker static pthread_key_t threadLocalStorageHandle = (pthread_key_t)0;
91*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker #define INIT_TOP_Stack 10000
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker typedef struct
96*9880d681SAndroid Build Coastguard Worker {
97*9880d681SAndroid Build Coastguard Worker     unsigned int TopStack;
98*9880d681SAndroid Build Coastguard Worker     unsigned int CurrentStack;
99*9880d681SAndroid Build Coastguard Worker } ThreadStack, *pThreadStack;
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker /* end of virtual stack. */
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker /*
104*9880d681SAndroid Build Coastguard Worker  * The function for reporting virtual-machine related events to VTune.
105*9880d681SAndroid Build Coastguard Worker  * Note: when reporting iJVM_EVENT_TYPE_ENTER_NIDS, there is no need to fill
106*9880d681SAndroid Build Coastguard Worker  * in the stack_id field in the iJIT_Method_NIDS structure, as VTune fills it.
107*9880d681SAndroid Build Coastguard Worker  * The return value in iJVM_EVENT_TYPE_ENTER_NIDS &&
108*9880d681SAndroid Build Coastguard Worker  * iJVM_EVENT_TYPE_LEAVE_NIDS events will be 0 in case of failure.
109*9880d681SAndroid Build Coastguard Worker  * in iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event
110*9880d681SAndroid Build Coastguard Worker  * it will be -1 if EventSpecificData == 0 otherwise it will be 0.
111*9880d681SAndroid Build Coastguard Worker */
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker ITT_EXTERN_C int JITAPI
iJIT_NotifyEvent(iJIT_JVM_EVENT event_type,void * EventSpecificData)114*9880d681SAndroid Build Coastguard Worker iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
115*9880d681SAndroid Build Coastguard Worker {
116*9880d681SAndroid Build Coastguard Worker     int ReturnValue;
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker     /*
119*9880d681SAndroid Build Coastguard Worker      * This section is for debugging outside of VTune.
120*9880d681SAndroid Build Coastguard Worker      * It creates the environment variables that indicates call graph mode.
121*9880d681SAndroid Build Coastguard Worker      * If running outside of VTune remove the remark.
122*9880d681SAndroid Build Coastguard Worker      *
123*9880d681SAndroid Build Coastguard Worker      *
124*9880d681SAndroid Build Coastguard Worker      * static int firstTime = 1;
125*9880d681SAndroid Build Coastguard Worker      * char DoCallGraph[12] = "DoCallGraph";
126*9880d681SAndroid Build Coastguard Worker      * if (firstTime)
127*9880d681SAndroid Build Coastguard Worker      * {
128*9880d681SAndroid Build Coastguard Worker      * firstTime = 0;
129*9880d681SAndroid Build Coastguard Worker      * SetEnvironmentVariable( "BISTRO_COLLECTORS_DO_CALLGRAPH", DoCallGraph);
130*9880d681SAndroid Build Coastguard Worker      * }
131*9880d681SAndroid Build Coastguard Worker      *
132*9880d681SAndroid Build Coastguard Worker      * end of section.
133*9880d681SAndroid Build Coastguard Worker     */
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker     /* initialization part - the functions have not been loaded yet. This part
136*9880d681SAndroid Build Coastguard Worker      *        will load the functions, and check if we are in Call Graph mode.
137*9880d681SAndroid Build Coastguard Worker      *        (for special treatment).
138*9880d681SAndroid Build Coastguard Worker      */
139*9880d681SAndroid Build Coastguard Worker     if (!FUNC_NotifyEvent)
140*9880d681SAndroid Build Coastguard Worker     {
141*9880d681SAndroid Build Coastguard Worker         if (iJIT_DLL_is_missing)
142*9880d681SAndroid Build Coastguard Worker             return 0;
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker         /* load the Function from the DLL */
145*9880d681SAndroid Build Coastguard Worker         if (!loadiJIT_Funcs())
146*9880d681SAndroid Build Coastguard Worker             return 0;
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker         /* Call Graph initialization. */
149*9880d681SAndroid Build Coastguard Worker     }
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker     /* If the event is method entry/exit, check that in the current mode
152*9880d681SAndroid Build Coastguard Worker      * VTune is allowed to receive it
153*9880d681SAndroid Build Coastguard Worker      */
154*9880d681SAndroid Build Coastguard Worker     if ((event_type == iJVM_EVENT_TYPE_ENTER_NIDS ||
155*9880d681SAndroid Build Coastguard Worker          event_type == iJVM_EVENT_TYPE_LEAVE_NIDS) &&
156*9880d681SAndroid Build Coastguard Worker         (executionMode != iJIT_CALLGRAPH_ON))
157*9880d681SAndroid Build Coastguard Worker     {
158*9880d681SAndroid Build Coastguard Worker         return 0;
159*9880d681SAndroid Build Coastguard Worker     }
160*9880d681SAndroid Build Coastguard Worker     /* This section is performed when method enter event occurs.
161*9880d681SAndroid Build Coastguard Worker      * It updates the virtual stack, or creates it if this is the first
162*9880d681SAndroid Build Coastguard Worker      * method entry in the thread. The stack pointer is decreased.
163*9880d681SAndroid Build Coastguard Worker      */
164*9880d681SAndroid Build Coastguard Worker     if (event_type == iJVM_EVENT_TYPE_ENTER_NIDS)
165*9880d681SAndroid Build Coastguard Worker     {
166*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
167*9880d681SAndroid Build Coastguard Worker         pThreadStack threadStack =
168*9880d681SAndroid Build Coastguard Worker             (pThreadStack)TlsGetValue (threadLocalStorageHandle);
169*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
170*9880d681SAndroid Build Coastguard Worker         pThreadStack threadStack =
171*9880d681SAndroid Build Coastguard Worker             (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
172*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker         /* check for use of reserved method IDs */
175*9880d681SAndroid Build Coastguard Worker         if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
176*9880d681SAndroid Build Coastguard Worker             return 0;
177*9880d681SAndroid Build Coastguard Worker 
178*9880d681SAndroid Build Coastguard Worker         if (!threadStack)
179*9880d681SAndroid Build Coastguard Worker         {
180*9880d681SAndroid Build Coastguard Worker             /* initialize the stack. */
181*9880d681SAndroid Build Coastguard Worker             threadStack = (pThreadStack) calloc (sizeof(ThreadStack), 1);
182*9880d681SAndroid Build Coastguard Worker             threadStack->TopStack = INIT_TOP_Stack;
183*9880d681SAndroid Build Coastguard Worker             threadStack->CurrentStack = INIT_TOP_Stack;
184*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
185*9880d681SAndroid Build Coastguard Worker             TlsSetValue(threadLocalStorageHandle,(void*)threadStack);
186*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
187*9880d681SAndroid Build Coastguard Worker             pthread_setspecific(threadLocalStorageHandle,(void*)threadStack);
188*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
189*9880d681SAndroid Build Coastguard Worker         }
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker         /* decrease the stack. */
192*9880d681SAndroid Build Coastguard Worker         ((piJIT_Method_NIDS) EventSpecificData)->stack_id =
193*9880d681SAndroid Build Coastguard Worker             (threadStack->CurrentStack)--;
194*9880d681SAndroid Build Coastguard Worker     }
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker     /* This section is performed when method leave event occurs
197*9880d681SAndroid Build Coastguard Worker      * It updates the virtual stack.
198*9880d681SAndroid Build Coastguard Worker      *    Increases the stack pointer.
199*9880d681SAndroid Build Coastguard Worker      *    If the stack pointer reached the top (left the global function)
200*9880d681SAndroid Build Coastguard Worker      *        increase the pointer and the top pointer.
201*9880d681SAndroid Build Coastguard Worker      */
202*9880d681SAndroid Build Coastguard Worker     if (event_type == iJVM_EVENT_TYPE_LEAVE_NIDS)
203*9880d681SAndroid Build Coastguard Worker     {
204*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
205*9880d681SAndroid Build Coastguard Worker         pThreadStack threadStack =
206*9880d681SAndroid Build Coastguard Worker            (pThreadStack)TlsGetValue (threadLocalStorageHandle);
207*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
208*9880d681SAndroid Build Coastguard Worker         pThreadStack threadStack =
209*9880d681SAndroid Build Coastguard Worker             (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
210*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker         /* check for use of reserved method IDs */
213*9880d681SAndroid Build Coastguard Worker         if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
214*9880d681SAndroid Build Coastguard Worker             return 0;
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker         if (!threadStack)
217*9880d681SAndroid Build Coastguard Worker         {
218*9880d681SAndroid Build Coastguard Worker             /* Error: first report in this thread is method exit */
219*9880d681SAndroid Build Coastguard Worker             exit (1);
220*9880d681SAndroid Build Coastguard Worker         }
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker         ((piJIT_Method_NIDS) EventSpecificData)->stack_id =
223*9880d681SAndroid Build Coastguard Worker             ++(threadStack->CurrentStack) + 1;
224*9880d681SAndroid Build Coastguard Worker 
225*9880d681SAndroid Build Coastguard Worker         if (((piJIT_Method_NIDS) EventSpecificData)->stack_id
226*9880d681SAndroid Build Coastguard Worker                > threadStack->TopStack)
227*9880d681SAndroid Build Coastguard Worker             ((piJIT_Method_NIDS) EventSpecificData)->stack_id =
228*9880d681SAndroid Build Coastguard Worker                 (unsigned int)-1;
229*9880d681SAndroid Build Coastguard Worker     }
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker     if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED)
232*9880d681SAndroid Build Coastguard Worker     {
233*9880d681SAndroid Build Coastguard Worker         /* check for use of reserved method IDs */
234*9880d681SAndroid Build Coastguard Worker         if ( ((piJIT_Method_Load) EventSpecificData)->method_id <= 999 )
235*9880d681SAndroid Build Coastguard Worker             return 0;
236*9880d681SAndroid Build Coastguard Worker     }
237*9880d681SAndroid Build Coastguard Worker 
238*9880d681SAndroid Build Coastguard Worker     ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
239*9880d681SAndroid Build Coastguard Worker 
240*9880d681SAndroid Build Coastguard Worker     return ReturnValue;
241*9880d681SAndroid Build Coastguard Worker }
242*9880d681SAndroid Build Coastguard Worker 
243*9880d681SAndroid Build Coastguard Worker /* The new mode call back routine */
244*9880d681SAndroid Build Coastguard Worker ITT_EXTERN_C void JITAPI
iJIT_RegisterCallbackEx(void * userdata,iJIT_ModeChangedEx NewModeCallBackFuncEx)245*9880d681SAndroid Build Coastguard Worker iJIT_RegisterCallbackEx(void *userdata, iJIT_ModeChangedEx
246*9880d681SAndroid Build Coastguard Worker                         NewModeCallBackFuncEx)
247*9880d681SAndroid Build Coastguard Worker {
248*9880d681SAndroid Build Coastguard Worker     /* is it already missing... or the load of functions from the DLL failed */
249*9880d681SAndroid Build Coastguard Worker     if (iJIT_DLL_is_missing || !loadiJIT_Funcs())
250*9880d681SAndroid Build Coastguard Worker     {
251*9880d681SAndroid Build Coastguard Worker         /* then do not bother with notifications */
252*9880d681SAndroid Build Coastguard Worker         NewModeCallBackFuncEx(userdata, iJIT_NO_NOTIFICATIONS);
253*9880d681SAndroid Build Coastguard Worker         /* Error: could not load JIT functions. */
254*9880d681SAndroid Build Coastguard Worker         return;
255*9880d681SAndroid Build Coastguard Worker     }
256*9880d681SAndroid Build Coastguard Worker     /* nothing to do with the callback */
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker 
259*9880d681SAndroid Build Coastguard Worker /*
260*9880d681SAndroid Build Coastguard Worker  * This function allows the user to query in which mode, if at all,
261*9880d681SAndroid Build Coastguard Worker  *VTune is running
262*9880d681SAndroid Build Coastguard Worker  */
iJIT_IsProfilingActive()263*9880d681SAndroid Build Coastguard Worker ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
264*9880d681SAndroid Build Coastguard Worker {
265*9880d681SAndroid Build Coastguard Worker     if (!iJIT_DLL_is_missing)
266*9880d681SAndroid Build Coastguard Worker     {
267*9880d681SAndroid Build Coastguard Worker         loadiJIT_Funcs();
268*9880d681SAndroid Build Coastguard Worker     }
269*9880d681SAndroid Build Coastguard Worker 
270*9880d681SAndroid Build Coastguard Worker     return executionMode;
271*9880d681SAndroid Build Coastguard Worker }
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker /* this function loads the collector dll (BistroJavaCollector)
274*9880d681SAndroid Build Coastguard Worker  * and the relevant functions.
275*9880d681SAndroid Build Coastguard Worker  * on success: all functions load,     iJIT_DLL_is_missing = 0, return value = 1
276*9880d681SAndroid Build Coastguard Worker  * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
277*9880d681SAndroid Build Coastguard Worker  */
loadiJIT_Funcs()278*9880d681SAndroid Build Coastguard Worker static int loadiJIT_Funcs()
279*9880d681SAndroid Build Coastguard Worker {
280*9880d681SAndroid Build Coastguard Worker     static int bDllWasLoaded = 0;
281*9880d681SAndroid Build Coastguard Worker     char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
282*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
283*9880d681SAndroid Build Coastguard Worker     DWORD dNameLength = 0;
284*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
285*9880d681SAndroid Build Coastguard Worker 
286*9880d681SAndroid Build Coastguard Worker     if(bDllWasLoaded)
287*9880d681SAndroid Build Coastguard Worker     {
288*9880d681SAndroid Build Coastguard Worker         /* dll was already loaded, no need to do it for the second time */
289*9880d681SAndroid Build Coastguard Worker         return 1;
290*9880d681SAndroid Build Coastguard Worker     }
291*9880d681SAndroid Build Coastguard Worker 
292*9880d681SAndroid Build Coastguard Worker     /* Assumes that the DLL will not be found */
293*9880d681SAndroid Build Coastguard Worker     iJIT_DLL_is_missing = 1;
294*9880d681SAndroid Build Coastguard Worker     FUNC_NotifyEvent = NULL;
295*9880d681SAndroid Build Coastguard Worker 
296*9880d681SAndroid Build Coastguard Worker     if (m_libHandle)
297*9880d681SAndroid Build Coastguard Worker     {
298*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
299*9880d681SAndroid Build Coastguard Worker         FreeLibrary(m_libHandle);
300*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
301*9880d681SAndroid Build Coastguard Worker         dlclose(m_libHandle);
302*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
303*9880d681SAndroid Build Coastguard Worker         m_libHandle = NULL;
304*9880d681SAndroid Build Coastguard Worker     }
305*9880d681SAndroid Build Coastguard Worker 
306*9880d681SAndroid Build Coastguard Worker     /* Try to get the dll name from the environment */
307*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
308*9880d681SAndroid Build Coastguard Worker     dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
309*9880d681SAndroid Build Coastguard Worker     if (dNameLength)
310*9880d681SAndroid Build Coastguard Worker     {
311*9880d681SAndroid Build Coastguard Worker         DWORD envret = 0;
312*9880d681SAndroid Build Coastguard Worker         dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
313*9880d681SAndroid Build Coastguard Worker         envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
314*9880d681SAndroid Build Coastguard Worker                                          dllName, dNameLength);
315*9880d681SAndroid Build Coastguard Worker         if (envret)
316*9880d681SAndroid Build Coastguard Worker         {
317*9880d681SAndroid Build Coastguard Worker             /* Try to load the dll from the PATH... */
318*9880d681SAndroid Build Coastguard Worker             m_libHandle = LoadLibraryExA(dllName,
319*9880d681SAndroid Build Coastguard Worker                                          NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
320*9880d681SAndroid Build Coastguard Worker         }
321*9880d681SAndroid Build Coastguard Worker         free(dllName);
322*9880d681SAndroid Build Coastguard Worker     } else {
323*9880d681SAndroid Build Coastguard Worker         /* Try to use old VS_PROFILER variable */
324*9880d681SAndroid Build Coastguard Worker         dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
325*9880d681SAndroid Build Coastguard Worker         if (dNameLength)
326*9880d681SAndroid Build Coastguard Worker         {
327*9880d681SAndroid Build Coastguard Worker             DWORD envret = 0;
328*9880d681SAndroid Build Coastguard Worker             dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
329*9880d681SAndroid Build Coastguard Worker             envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
330*9880d681SAndroid Build Coastguard Worker                                              dllName, dNameLength);
331*9880d681SAndroid Build Coastguard Worker             if (envret)
332*9880d681SAndroid Build Coastguard Worker             {
333*9880d681SAndroid Build Coastguard Worker                 /* Try to load the dll from the PATH... */
334*9880d681SAndroid Build Coastguard Worker                 m_libHandle = LoadLibraryA(dllName);
335*9880d681SAndroid Build Coastguard Worker             }
336*9880d681SAndroid Build Coastguard Worker             free(dllName);
337*9880d681SAndroid Build Coastguard Worker         }
338*9880d681SAndroid Build Coastguard Worker     }
339*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
340*9880d681SAndroid Build Coastguard Worker     dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
341*9880d681SAndroid Build Coastguard Worker     if (!dllName)
342*9880d681SAndroid Build Coastguard Worker         dllName = getenv(DLL_ENVIRONMENT_VAR);
343*9880d681SAndroid Build Coastguard Worker #ifdef ANDROID
344*9880d681SAndroid Build Coastguard Worker     if (!dllName)
345*9880d681SAndroid Build Coastguard Worker         dllName = ANDROID_JIT_AGENT_PATH;
346*9880d681SAndroid Build Coastguard Worker #endif
347*9880d681SAndroid Build Coastguard Worker     if (dllName)
348*9880d681SAndroid Build Coastguard Worker     {
349*9880d681SAndroid Build Coastguard Worker         /* Try to load the dll from the PATH... */
350*9880d681SAndroid Build Coastguard Worker         m_libHandle = dlopen(dllName, RTLD_LAZY);
351*9880d681SAndroid Build Coastguard Worker     }
352*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
353*9880d681SAndroid Build Coastguard Worker 
354*9880d681SAndroid Build Coastguard Worker     if (!m_libHandle)
355*9880d681SAndroid Build Coastguard Worker     {
356*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
357*9880d681SAndroid Build Coastguard Worker         m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
358*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
359*9880d681SAndroid Build Coastguard Worker         m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
360*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
361*9880d681SAndroid Build Coastguard Worker     }
362*9880d681SAndroid Build Coastguard Worker 
363*9880d681SAndroid Build Coastguard Worker     /* if the dll wasn't loaded - exit. */
364*9880d681SAndroid Build Coastguard Worker     if (!m_libHandle)
365*9880d681SAndroid Build Coastguard Worker     {
366*9880d681SAndroid Build Coastguard Worker         iJIT_DLL_is_missing = 1; /* don't try to initialize
367*9880d681SAndroid Build Coastguard Worker                                   * JIT agent the second time
368*9880d681SAndroid Build Coastguard Worker                                   */
369*9880d681SAndroid Build Coastguard Worker         return 0;
370*9880d681SAndroid Build Coastguard Worker     }
371*9880d681SAndroid Build Coastguard Worker 
372*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
373*9880d681SAndroid Build Coastguard Worker     FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
374*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
375*9880d681SAndroid Build Coastguard Worker     FUNC_NotifyEvent = (TPNotify)(intptr_t)dlsym(m_libHandle, "NotifyEvent");
376*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
377*9880d681SAndroid Build Coastguard Worker     if (!FUNC_NotifyEvent)
378*9880d681SAndroid Build Coastguard Worker     {
379*9880d681SAndroid Build Coastguard Worker         FUNC_Initialize = NULL;
380*9880d681SAndroid Build Coastguard Worker         return 0;
381*9880d681SAndroid Build Coastguard Worker     }
382*9880d681SAndroid Build Coastguard Worker 
383*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
384*9880d681SAndroid Build Coastguard Worker     FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
385*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
386*9880d681SAndroid Build Coastguard Worker     FUNC_Initialize = (TPInitialize)(intptr_t)dlsym(m_libHandle, "Initialize");
387*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
388*9880d681SAndroid Build Coastguard Worker     if (!FUNC_Initialize)
389*9880d681SAndroid Build Coastguard Worker     {
390*9880d681SAndroid Build Coastguard Worker         FUNC_NotifyEvent = NULL;
391*9880d681SAndroid Build Coastguard Worker         return 0;
392*9880d681SAndroid Build Coastguard Worker     }
393*9880d681SAndroid Build Coastguard Worker 
394*9880d681SAndroid Build Coastguard Worker     executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
395*9880d681SAndroid Build Coastguard Worker 
396*9880d681SAndroid Build Coastguard Worker     bDllWasLoaded = 1;
397*9880d681SAndroid Build Coastguard Worker     iJIT_DLL_is_missing = 0; /* DLL is ok. */
398*9880d681SAndroid Build Coastguard Worker 
399*9880d681SAndroid Build Coastguard Worker     /*
400*9880d681SAndroid Build Coastguard Worker      * Call Graph mode: init the thread local storage
401*9880d681SAndroid Build Coastguard Worker      * (need to store the virtual stack there).
402*9880d681SAndroid Build Coastguard Worker      */
403*9880d681SAndroid Build Coastguard Worker     if ( executionMode == iJIT_CALLGRAPH_ON )
404*9880d681SAndroid Build Coastguard Worker     {
405*9880d681SAndroid Build Coastguard Worker         /* Allocate a thread local storage slot for the thread "stack" */
406*9880d681SAndroid Build Coastguard Worker         if (!threadLocalStorageHandle)
407*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
408*9880d681SAndroid Build Coastguard Worker             threadLocalStorageHandle = TlsAlloc();
409*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
410*9880d681SAndroid Build Coastguard Worker         pthread_key_create(&threadLocalStorageHandle, NULL);
411*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
412*9880d681SAndroid Build Coastguard Worker     }
413*9880d681SAndroid Build Coastguard Worker 
414*9880d681SAndroid Build Coastguard Worker     return 1;
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker 
417*9880d681SAndroid Build Coastguard Worker /*
418*9880d681SAndroid Build Coastguard Worker  * This function should be called by the user whenever a thread ends,
419*9880d681SAndroid Build Coastguard Worker  * to free the thread "virtual stack" storage
420*9880d681SAndroid Build Coastguard Worker  */
FinalizeThread()421*9880d681SAndroid Build Coastguard Worker ITT_EXTERN_C void JITAPI FinalizeThread()
422*9880d681SAndroid Build Coastguard Worker {
423*9880d681SAndroid Build Coastguard Worker     if (threadLocalStorageHandle)
424*9880d681SAndroid Build Coastguard Worker     {
425*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
426*9880d681SAndroid Build Coastguard Worker         pThreadStack threadStack =
427*9880d681SAndroid Build Coastguard Worker             (pThreadStack)TlsGetValue (threadLocalStorageHandle);
428*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
429*9880d681SAndroid Build Coastguard Worker         pThreadStack threadStack =
430*9880d681SAndroid Build Coastguard Worker             (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
431*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
432*9880d681SAndroid Build Coastguard Worker         if (threadStack)
433*9880d681SAndroid Build Coastguard Worker         {
434*9880d681SAndroid Build Coastguard Worker             free (threadStack);
435*9880d681SAndroid Build Coastguard Worker             threadStack = NULL;
436*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
437*9880d681SAndroid Build Coastguard Worker             TlsSetValue (threadLocalStorageHandle, threadStack);
438*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
439*9880d681SAndroid Build Coastguard Worker             pthread_setspecific(threadLocalStorageHandle, threadStack);
440*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
441*9880d681SAndroid Build Coastguard Worker         }
442*9880d681SAndroid Build Coastguard Worker     }
443*9880d681SAndroid Build Coastguard Worker }
444*9880d681SAndroid Build Coastguard Worker 
445*9880d681SAndroid Build Coastguard Worker /*
446*9880d681SAndroid Build Coastguard Worker  * This function should be called by the user when the process ends,
447*9880d681SAndroid Build Coastguard Worker  * to free the local storage index
448*9880d681SAndroid Build Coastguard Worker */
FinalizeProcess()449*9880d681SAndroid Build Coastguard Worker ITT_EXTERN_C void JITAPI FinalizeProcess()
450*9880d681SAndroid Build Coastguard Worker {
451*9880d681SAndroid Build Coastguard Worker     if (m_libHandle)
452*9880d681SAndroid Build Coastguard Worker     {
453*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
454*9880d681SAndroid Build Coastguard Worker         FreeLibrary(m_libHandle);
455*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
456*9880d681SAndroid Build Coastguard Worker         dlclose(m_libHandle);
457*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
458*9880d681SAndroid Build Coastguard Worker         m_libHandle = NULL;
459*9880d681SAndroid Build Coastguard Worker     }
460*9880d681SAndroid Build Coastguard Worker 
461*9880d681SAndroid Build Coastguard Worker     if (threadLocalStorageHandle)
462*9880d681SAndroid Build Coastguard Worker #if ITT_PLATFORM==ITT_PLATFORM_WIN
463*9880d681SAndroid Build Coastguard Worker         TlsFree (threadLocalStorageHandle);
464*9880d681SAndroid Build Coastguard Worker #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
465*9880d681SAndroid Build Coastguard Worker     pthread_key_delete(threadLocalStorageHandle);
466*9880d681SAndroid Build Coastguard Worker #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
467*9880d681SAndroid Build Coastguard Worker }
468*9880d681SAndroid Build Coastguard Worker 
469*9880d681SAndroid Build Coastguard Worker /*
470*9880d681SAndroid Build Coastguard Worker  * This function should be called by the user for any method once.
471*9880d681SAndroid Build Coastguard Worker  * The function will return a unique method ID, the user should maintain
472*9880d681SAndroid Build Coastguard Worker  * the ID for each method
473*9880d681SAndroid Build Coastguard Worker  */
iJIT_GetNewMethodID()474*9880d681SAndroid Build Coastguard Worker ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
475*9880d681SAndroid Build Coastguard Worker {
476*9880d681SAndroid Build Coastguard Worker     static unsigned int methodID = 0x100000;
477*9880d681SAndroid Build Coastguard Worker 
478*9880d681SAndroid Build Coastguard Worker     if (methodID == 0)
479*9880d681SAndroid Build Coastguard Worker         return 0;  /* ERROR : this is not a valid value */
480*9880d681SAndroid Build Coastguard Worker 
481*9880d681SAndroid Build Coastguard Worker     return methodID++;
482*9880d681SAndroid Build Coastguard Worker }
483