jitprofiling.c (10516B)
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 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 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 */ 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 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 }