• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   Copyright (C) 2005-2019 Intel Corporation
3 
4   SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
5 */
6 
7 #include "ittnotify_config.h"
8 
9 #if ITT_PLATFORM==ITT_PLATFORM_WIN
10 #include <windows.h>
11 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
12 #if ITT_PLATFORM != ITT_PLATFORM_MAC && ITT_PLATFORM != ITT_PLATFORM_FREEBSD
13 #include <malloc.h>
14 #endif
15 #include <stdlib.h>
16 
17 #include "jitprofiling.h"
18 
19 static const char rcsid[] = "\n@(#) $Revision$\n";
20 
21 #define DLL_ENVIRONMENT_VAR             "VS_PROFILER"
22 
23 #ifndef NEW_DLL_ENVIRONMENT_VAR
24 #if ITT_ARCH==ITT_ARCH_IA32
25 #define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER32"
26 #else
27 #define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER64"
28 #endif
29 #endif /* NEW_DLL_ENVIRONMENT_VAR */
30 
31 #if ITT_PLATFORM==ITT_PLATFORM_WIN
32 #define DEFAULT_DLLNAME                 "JitPI.dll"
33 HINSTANCE m_libHandle = NULL;
34 #elif ITT_PLATFORM==ITT_PLATFORM_MAC
35 #define DEFAULT_DLLNAME                 "libJitPI.dylib"
36 void* m_libHandle = NULL;
37 #else
38 #define DEFAULT_DLLNAME                 "libJitPI.so"
39 void* m_libHandle = NULL;
40 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
41 
42 /* default location of JIT profiling agent on Android */
43 #define ANDROID_JIT_AGENT_PATH  "/data/intel/libittnotify.so"
44 
45 /* the function pointers */
46 typedef unsigned int(JITAPI *TPInitialize)(void);
47 static TPInitialize FUNC_Initialize=NULL;
48 
49 typedef unsigned int(JITAPI *TPNotify)(unsigned int, void*);
50 static TPNotify FUNC_NotifyEvent=NULL;
51 
52 static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
53 
54 /* end collector dll part. */
55 
56 /* loadiJIT_Funcs() : this function is called just in the beginning
57  * and is responsible to load the functions from BistroJavaCollector.dll
58  * result:
59  *  on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
60  *  on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
61  */
62 static int loadiJIT_Funcs(void);
63 
64 /* global representing whether the collector can't be loaded */
65 static int iJIT_DLL_is_missing = 0;
66 
67 ITT_EXTERN_C int JITAPI
iJIT_NotifyEvent(iJIT_JVM_EVENT event_type,void * EventSpecificData)68 iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
69 {
70     int ReturnValue = 0;
71 
72     /* initialization part - the collector has not been loaded yet. */
73     if (!FUNC_NotifyEvent)
74     {
75         if (iJIT_DLL_is_missing)
76             return 0;
77 
78         if (!loadiJIT_Funcs())
79             return 0;
80     }
81 
82     if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED ||
83         event_type == iJVM_EVENT_TYPE_METHOD_UPDATE)
84     {
85         if (((piJIT_Method_Load)EventSpecificData)->method_id == 0)
86             return 0;
87     }
88     else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
89     {
90         if (((piJIT_Method_Load_V2)EventSpecificData)->method_id == 0)
91             return 0;
92     }
93     else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3)
94     {
95         if (((piJIT_Method_Load_V3)EventSpecificData)->method_id == 0)
96             return 0;
97     }
98     else if (event_type == iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED)
99     {
100         if (((piJIT_Method_Inline_Load)EventSpecificData)->method_id == 0 ||
101             ((piJIT_Method_Inline_Load)EventSpecificData)->parent_method_id == 0)
102             return 0;
103     }
104 
105     ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
106 
107     return ReturnValue;
108 }
109 
iJIT_IsProfilingActive()110 ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
111 {
112     if (!iJIT_DLL_is_missing)
113     {
114         loadiJIT_Funcs();
115     }
116 
117     return executionMode;
118 }
119 
120 /* This function loads the collector dll and the relevant functions.
121  * on success: all functions load,     iJIT_DLL_is_missing = 0, return value = 1
122  * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
123  */
loadiJIT_Funcs()124 static int loadiJIT_Funcs()
125 {
126     static int bDllWasLoaded = 0;
127     char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
128 #if ITT_PLATFORM==ITT_PLATFORM_WIN
129     DWORD dNameLength = 0;
130 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
131 
132     if(bDllWasLoaded)
133     {
134         /* dll was already loaded, no need to do it for the second time */
135         return 1;
136     }
137 
138     /* Assumes that the DLL will not be found */
139     iJIT_DLL_is_missing = 1;
140     FUNC_NotifyEvent = NULL;
141 
142     if (m_libHandle)
143     {
144 #if ITT_PLATFORM==ITT_PLATFORM_WIN
145         FreeLibrary(m_libHandle);
146 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
147         dlclose(m_libHandle);
148 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
149         m_libHandle = NULL;
150     }
151 
152     /* Try to get the dll name from the environment */
153 #if ITT_PLATFORM==ITT_PLATFORM_WIN
154     dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
155     if (dNameLength)
156     {
157         DWORD envret = 0;
158         dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
159         if(dllName != NULL)
160         {
161             envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
162                                              dllName, dNameLength);
163             if (envret)
164             {
165                 /* Try to load the dll from the PATH... */
166                 m_libHandle = LoadLibraryExA(dllName,
167                                              NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
168             }
169             free(dllName);
170         }
171     } else {
172         /* Try to use old VS_PROFILER variable */
173         dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
174         if (dNameLength)
175         {
176             DWORD envret = 0;
177             dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
178             if(dllName != NULL)
179             {
180                 envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
181                                                  dllName, dNameLength);
182                 if (envret)
183                 {
184                     /* Try to load the dll from the PATH... */
185                     m_libHandle = LoadLibraryA(dllName);
186                 }
187                 free(dllName);
188             }
189         }
190     }
191 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
192     dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
193     if (!dllName)
194         dllName = getenv(DLL_ENVIRONMENT_VAR);
195 #if defined(__ANDROID__) || defined(ANDROID)
196     if (!dllName)
197         dllName = ANDROID_JIT_AGENT_PATH;
198 #endif
199     if (dllName)
200     {
201         /* Try to load the dll from the PATH... */
202         if (DL_SYMBOLS)
203         {
204             m_libHandle = dlopen(dllName, RTLD_LAZY);
205         }
206     }
207 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
208 
209     if (!m_libHandle)
210     {
211 #if ITT_PLATFORM==ITT_PLATFORM_WIN
212         m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
213 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
214         if (DL_SYMBOLS)
215         {
216             m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
217         }
218 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
219     }
220 
221     /* if the dll wasn't loaded - exit. */
222     if (!m_libHandle)
223     {
224         iJIT_DLL_is_missing = 1; /* don't try to initialize
225                                   * JIT agent the second time
226                                   */
227         return 0;
228     }
229 
230 #if ITT_PLATFORM==ITT_PLATFORM_WIN
231     FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
232 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
233     FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
234 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
235     if (!FUNC_NotifyEvent)
236     {
237         FUNC_Initialize = NULL;
238         return 0;
239     }
240 
241 #if ITT_PLATFORM==ITT_PLATFORM_WIN
242     FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
243 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
244     FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
245 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
246     if (!FUNC_Initialize)
247     {
248         FUNC_NotifyEvent = NULL;
249         return 0;
250     }
251 
252     executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
253 
254     bDllWasLoaded = 1;
255     iJIT_DLL_is_missing = 0; /* DLL is ok. */
256 
257     return 1;
258 }
259 
iJIT_GetNewMethodID()260 ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
261 {
262     static unsigned int methodID = 1;
263 
264     if (methodID == 0)
265         return 0;  /* ERROR : this is not a valid value */
266 
267     return methodID++;
268 }
269