jitprofiling.cpp 8.3 KB

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