1 /* <copyright>
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6
7 Copyright (c) 2005-2014 Intel Corporation. All rights reserved.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of version 2 of the GNU General Public License as
11 published by the Free Software Foundation.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 The full GNU General Public License is included in this distribution
22 in the file called LICENSE.GPL.
23
24 Contact Information:
25 http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
26
27 BSD LICENSE
28
29 Copyright (c) 2005-2014 Intel Corporation. All rights reserved.
30 All rights reserved.
31
32 Redistribution and use in source and binary forms, with or without
33 modification, are permitted provided that the following conditions
34 are met:
35
36 * Redistributions of source code must retain the above copyright
37 notice, this list of conditions and the following disclaimer.
38 * Redistributions in binary form must reproduce the above copyright
39 notice, this list of conditions and the following disclaimer in
40 the documentation and/or other materials provided with the
41 distribution.
42 * Neither the name of Intel Corporation nor the names of its
43 contributors may be used to endorse or promote products derived
44 from this software without specific prior written permission.
45
46 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
49 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
50 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
52 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 </copyright> */
58
59 #include "vtune/ittnotify_config.h"
60
61 #if ITT_PLATFORM==ITT_PLATFORM_WIN
62 #include <windows.h>
63 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
64 #if ITT_PLATFORM != ITT_PLATFORM_MAC && ITT_PLATFORM != ITT_PLATFORM_FREEBSD
65 #include <malloc.h>
66 #endif
67 #include <stdlib.h>
68
69 #include "vtune/jitprofiling.h"
70
71 static const char rcsid[] = "\n@(#) $Revision: 471937 $\n";
72
73 #define DLL_ENVIRONMENT_VAR "VS_PROFILER"
74
75 #ifndef NEW_DLL_ENVIRONMENT_VAR
76 #if ITT_ARCH==ITT_ARCH_IA32
77 #define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER32"
78 #else
79 #define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER64"
80 #endif
81 #endif /* NEW_DLL_ENVIRONMENT_VAR */
82
83 #if ITT_PLATFORM==ITT_PLATFORM_WIN
84 #define DEFAULT_DLLNAME "JitPI.dll"
85 HINSTANCE m_libHandle = NULL;
86 #elif ITT_PLATFORM==ITT_PLATFORM_MAC
87 #define DEFAULT_DLLNAME "libJitPI.dylib"
88 void* m_libHandle = NULL;
89 #else
90 #define DEFAULT_DLLNAME "libJitPI.so"
91 void* m_libHandle = NULL;
92 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
93
94 /* default location of JIT profiling agent on Android */
95 #define ANDROID_JIT_AGENT_PATH "/data/intel/libittnotify.so"
96
97 /* the function pointers */
98 typedef unsigned int(JITAPI *TPInitialize)(void);
99 static TPInitialize FUNC_Initialize=NULL;
100
101 typedef unsigned int(JITAPI *TPNotify)(unsigned int, void*);
102 static TPNotify FUNC_NotifyEvent=NULL;
103
104 static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
105
106 /* end collector dll part. */
107
108 /* loadiJIT_Funcs() : this function is called just in the beginning
109 * and is responsible to load the functions from BistroJavaCollector.dll
110 * result:
111 * on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
112 * on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
113 */
114 int loadiJIT_Funcs(void);
115
116 /* global representing whether the collector can't be loaded */
117 static int iJIT_DLL_is_missing = 0;
118
119 ITT_EXTERN_C int JITAPI
iJIT_NotifyEvent(iJIT_JVM_EVENT event_type,void * EventSpecificData)120 iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
121 {
122 int ReturnValue = 0;
123
124 /* initialization part - the collector has not been loaded yet. */
125 if (!FUNC_NotifyEvent)
126 {
127 if (iJIT_DLL_is_missing)
128 return 0;
129
130 if (!loadiJIT_Funcs())
131 return 0;
132 }
133
134 if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED ||
135 event_type == iJVM_EVENT_TYPE_METHOD_UPDATE)
136 {
137 if (((piJIT_Method_Load)EventSpecificData)->method_id == 0)
138 return 0;
139 }
140 else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
141 {
142 if (((piJIT_Method_Load_V2)EventSpecificData)->method_id == 0)
143 return 0;
144 }
145 else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3)
146 {
147 if (((piJIT_Method_Load_V3)EventSpecificData)->method_id == 0)
148 return 0;
149 }
150 else if (event_type == iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED)
151 {
152 if (((piJIT_Method_Inline_Load)EventSpecificData)->method_id == 0 ||
153 ((piJIT_Method_Inline_Load)EventSpecificData)->parent_method_id == 0)
154 return 0;
155 }
156
157 ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
158
159 return ReturnValue;
160 }
161
iJIT_IsProfilingActive()162 ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
163 {
164 if (!iJIT_DLL_is_missing)
165 {
166 loadiJIT_Funcs();
167 }
168
169 return executionMode;
170 }
171
172 /* This function loads the collector dll and the relevant functions.
173 * on success: all functions load, iJIT_DLL_is_missing = 0, return value = 1
174 * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
175 */
loadiJIT_Funcs()176 int loadiJIT_Funcs()
177 {
178 static int bDllWasLoaded = 0;
179 char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
180 #if ITT_PLATFORM==ITT_PLATFORM_WIN
181 DWORD dNameLength = 0;
182 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
183
184 if(bDllWasLoaded)
185 {
186 /* dll was already loaded, no need to do it for the second time */
187 return 1;
188 }
189
190 /* Assumes that the DLL will not be found */
191 iJIT_DLL_is_missing = 1;
192 FUNC_NotifyEvent = NULL;
193
194 if (m_libHandle)
195 {
196 #if ITT_PLATFORM==ITT_PLATFORM_WIN
197 FreeLibrary(m_libHandle);
198 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
199 dlclose(m_libHandle);
200 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
201 m_libHandle = NULL;
202 }
203
204 /* Try to get the dll name from the environment */
205 #if ITT_PLATFORM==ITT_PLATFORM_WIN
206 dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
207 if (dNameLength)
208 {
209 DWORD envret = 0;
210 dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
211 if(dllName != NULL)
212 {
213 envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
214 dllName, dNameLength);
215 if (envret)
216 {
217 /* Try to load the dll from the PATH... */
218 m_libHandle = LoadLibraryExA(dllName,
219 NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
220 }
221 free(dllName);
222 }
223 } else {
224 /* Try to use old VS_PROFILER variable */
225 dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
226 if (dNameLength)
227 {
228 DWORD envret = 0;
229 dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
230 if(dllName != NULL)
231 {
232 envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
233 dllName, dNameLength);
234 if (envret)
235 {
236 /* Try to load the dll from the PATH... */
237 m_libHandle = LoadLibraryA(dllName);
238 }
239 free(dllName);
240 }
241 }
242 }
243 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
244 dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
245 if (!dllName)
246 dllName = getenv(DLL_ENVIRONMENT_VAR);
247 #if defined(__ANDROID__) || defined(ANDROID)
248 if (!dllName)
249 dllName = ANDROID_JIT_AGENT_PATH;
250 #endif
251 if (dllName)
252 {
253 /* Try to load the dll from the PATH... */
254 m_libHandle = dlopen(dllName, RTLD_LAZY);
255 }
256 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
257
258 if (!m_libHandle)
259 {
260 #if ITT_PLATFORM==ITT_PLATFORM_WIN
261 m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
262 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
263 m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
264 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
265 }
266
267 /* if the dll wasn't loaded - exit. */
268 if (!m_libHandle)
269 {
270 iJIT_DLL_is_missing = 1; /* don't try to initialize
271 * JIT agent the second time
272 */
273 return 0;
274 }
275
276 #if ITT_PLATFORM==ITT_PLATFORM_WIN
277 FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
278 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
279 FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
280 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
281 if (!FUNC_NotifyEvent)
282 {
283 FUNC_Initialize = NULL;
284 return 0;
285 }
286
287 #if ITT_PLATFORM==ITT_PLATFORM_WIN
288 FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
289 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
290 FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
291 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
292 if (!FUNC_Initialize)
293 {
294 FUNC_NotifyEvent = NULL;
295 return 0;
296 }
297
298 executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
299
300 bDllWasLoaded = 1;
301 iJIT_DLL_is_missing = 0; /* DLL is ok. */
302
303 return 1;
304 }
305
iJIT_GetNewMethodID()306 ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
307 {
308 static unsigned int methodID = 1;
309
310 if (methodID == 0)
311 return 0; /* ERROR : this is not a valid value */
312
313 return methodID++;
314 }
315