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