js/src/vtune/jitprofiling.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 This file is provided under a dual BSD/GPLv2 license. When using or
michael@0 3 redistributing this file, you may do so under either license.
michael@0 4
michael@0 5 GPL LICENSE SUMMARY
michael@0 6
michael@0 7 Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
michael@0 8
michael@0 9 This program is free software; you can redistribute it and/or modify
michael@0 10 it under the terms of version 2 of the GNU General Public License as
michael@0 11 published by the Free Software Foundation.
michael@0 12
michael@0 13 This program is distributed in the hope that it will be useful, but
michael@0 14 WITHOUT ANY WARRANTY; without even the implied warranty of
michael@0 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@0 16 General Public License for more details.
michael@0 17
michael@0 18 You should have received a copy of the GNU General Public License
michael@0 19 along with this program; if not, write to the Free Software
michael@0 20 Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
michael@0 21 The full GNU General Public License is included in this distribution
michael@0 22 in the file called LICENSE.GPL.
michael@0 23
michael@0 24 Contact Information:
michael@0 25 http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
michael@0 26
michael@0 27 BSD LICENSE
michael@0 28
michael@0 29 Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
michael@0 30 All rights reserved.
michael@0 31
michael@0 32 Redistribution and use in source and binary forms, with or without
michael@0 33 modification, are permitted provided that the following conditions
michael@0 34 are met:
michael@0 35
michael@0 36 * Redistributions of source code must retain the above copyright
michael@0 37 notice, this list of conditions and the following disclaimer.
michael@0 38 * Redistributions in binary form must reproduce the above copyright
michael@0 39 notice, this list of conditions and the following disclaimer in
michael@0 40 the documentation and/or other materials provided with the
michael@0 41 distribution.
michael@0 42 * Neither the name of Intel Corporation nor the names of its
michael@0 43 contributors may be used to endorse or promote products derived
michael@0 44 from this software without specific prior written permission.
michael@0 45
michael@0 46 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 47 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 48 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 49 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 50 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 51 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 52 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 53 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 54 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 55 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 56 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 57 */
michael@0 58 #include "vtune/ittnotify_config.h"
michael@0 59
michael@0 60 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 61 #include <windows.h>
michael@0 62 #pragma optimize("", off)
michael@0 63 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 64 #include <pthread.h>
michael@0 65 #include <dlfcn.h>
michael@0 66 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 67 #include <malloc.h>
michael@0 68 #include <stdlib.h>
michael@0 69
michael@0 70 #include "vtune/jitprofiling.h"
michael@0 71
michael@0 72 static const char rcsid[] = "\n@(#) $Revision: 294150 $\n";
michael@0 73
michael@0 74 #define DLL_ENVIRONMENT_VAR "VS_PROFILER"
michael@0 75
michael@0 76 #ifndef NEW_DLL_ENVIRONMENT_VAR
michael@0 77 #if ITT_ARCH==ITT_ARCH_IA32
michael@0 78 #define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER32"
michael@0 79 #else
michael@0 80 #define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER64"
michael@0 81 #endif
michael@0 82 #endif /* NEW_DLL_ENVIRONMENT_VAR */
michael@0 83
michael@0 84 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 85 #define DEFAULT_DLLNAME "JitPI.dll"
michael@0 86 HINSTANCE m_libHandle = NULL;
michael@0 87 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 88 #define DEFAULT_DLLNAME "libJitPI.so"
michael@0 89 void* m_libHandle = NULL;
michael@0 90 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 91
michael@0 92 /* default location of JIT profiling agent on Android */
michael@0 93 #define ANDROID_JIT_AGENT_PATH "/data/intel/libittnotify.so"
michael@0 94
michael@0 95 /* the function pointers */
michael@0 96 typedef unsigned int(*TPInitialize)(void);
michael@0 97 static TPInitialize FUNC_Initialize=NULL;
michael@0 98
michael@0 99 typedef unsigned int(*TPNotify)(unsigned int, void*);
michael@0 100 static TPNotify FUNC_NotifyEvent=NULL;
michael@0 101
michael@0 102 static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
michael@0 103
michael@0 104 /* end collector dll part. */
michael@0 105
michael@0 106 /* loadiJIT_Funcs() : this function is called just in the beginning
michael@0 107 * and is responsible to load the functions from BistroJavaCollector.dll
michael@0 108 * result:
michael@0 109 * on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
michael@0 110 * on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
michael@0 111 */
michael@0 112 static int loadiJIT_Funcs(void);
michael@0 113
michael@0 114 /* global representing whether the BistroJavaCollector can't be loaded */
michael@0 115 static int iJIT_DLL_is_missing = 0;
michael@0 116
michael@0 117 /* Virtual stack - the struct is used as a virtual stack for each thread.
michael@0 118 * Every thread initializes with a stack of size INIT_TOP_STACK.
michael@0 119 * Every method entry decreases from the current stack point,
michael@0 120 * and when a thread stack reaches its top of stack (return from the global
michael@0 121 * function), the top of stack and the current stack increase. Notice that
michael@0 122 * when returning from a function the stack pointer is the address of
michael@0 123 * the function return.
michael@0 124 */
michael@0 125 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 126 static DWORD threadLocalStorageHandle = 0;
michael@0 127 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 128 static pthread_key_t threadLocalStorageHandle = (pthread_key_t)0;
michael@0 129 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 130
michael@0 131 #define INIT_TOP_Stack 10000
michael@0 132
michael@0 133 typedef struct
michael@0 134 {
michael@0 135 unsigned int TopStack;
michael@0 136 unsigned int CurrentStack;
michael@0 137 } ThreadStack, *pThreadStack;
michael@0 138
michael@0 139 /* end of virtual stack. */
michael@0 140
michael@0 141 /*
michael@0 142 * The function for reporting virtual-machine related events to VTune.
michael@0 143 * Note: when reporting iJVM_EVENT_TYPE_ENTER_NIDS, there is no need to fill
michael@0 144 * in the stack_id field in the iJIT_Method_NIDS structure, as VTune fills it.
michael@0 145 * The return value in iJVM_EVENT_TYPE_ENTER_NIDS &&
michael@0 146 * iJVM_EVENT_TYPE_LEAVE_NIDS events will be 0 in case of failure.
michael@0 147 * in iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event
michael@0 148 * it will be -1 if EventSpecificData == 0 otherwise it will be 0.
michael@0 149 */
michael@0 150
michael@0 151 ITT_EXTERN_C int JITAPI
michael@0 152 iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
michael@0 153 {
michael@0 154 int ReturnValue;
michael@0 155
michael@0 156 /*
michael@0 157 * This section is for debugging outside of VTune.
michael@0 158 * It creates the environment variables that indicates call graph mode.
michael@0 159 * If running outside of VTune remove the remark.
michael@0 160 *
michael@0 161 *
michael@0 162 * static int firstTime = 1;
michael@0 163 * char DoCallGraph[12] = "DoCallGraph";
michael@0 164 * if (firstTime)
michael@0 165 * {
michael@0 166 * firstTime = 0;
michael@0 167 * SetEnvironmentVariable( "BISTRO_COLLECTORS_DO_CALLGRAPH", DoCallGraph);
michael@0 168 * }
michael@0 169 *
michael@0 170 * end of section.
michael@0 171 */
michael@0 172
michael@0 173 /* initialization part - the functions have not been loaded yet. This part
michael@0 174 * will load the functions, and check if we are in Call Graph mode.
michael@0 175 * (for special treatment).
michael@0 176 */
michael@0 177 if (!FUNC_NotifyEvent)
michael@0 178 {
michael@0 179 if (iJIT_DLL_is_missing)
michael@0 180 return 0;
michael@0 181
michael@0 182 /* load the Function from the DLL */
michael@0 183 if (!loadiJIT_Funcs())
michael@0 184 return 0;
michael@0 185
michael@0 186 /* Call Graph initialization. */
michael@0 187 }
michael@0 188
michael@0 189 /* If the event is method entry/exit, check that in the current mode
michael@0 190 * VTune is allowed to receive it
michael@0 191 */
michael@0 192 if ((event_type == iJVM_EVENT_TYPE_ENTER_NIDS ||
michael@0 193 event_type == iJVM_EVENT_TYPE_LEAVE_NIDS) &&
michael@0 194 (executionMode != iJIT_CALLGRAPH_ON))
michael@0 195 {
michael@0 196 return 0;
michael@0 197 }
michael@0 198 /* This section is performed when method enter event occurs.
michael@0 199 * It updates the virtual stack, or creates it if this is the first
michael@0 200 * method entry in the thread. The stack pointer is decreased.
michael@0 201 */
michael@0 202 if (event_type == iJVM_EVENT_TYPE_ENTER_NIDS)
michael@0 203 {
michael@0 204 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 205 pThreadStack threadStack =
michael@0 206 (pThreadStack)TlsGetValue (threadLocalStorageHandle);
michael@0 207 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 208 pThreadStack threadStack =
michael@0 209 (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
michael@0 210 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 211
michael@0 212 /* check for use of reserved method IDs */
michael@0 213 if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
michael@0 214 return 0;
michael@0 215
michael@0 216 if (!threadStack)
michael@0 217 {
michael@0 218 /* initialize the stack. */
michael@0 219 threadStack = (pThreadStack) calloc (sizeof(ThreadStack), 1);
michael@0 220 if (!threadStack)
michael@0 221 return 0;
michael@0 222 threadStack->TopStack = INIT_TOP_Stack;
michael@0 223 threadStack->CurrentStack = INIT_TOP_Stack;
michael@0 224 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 225 TlsSetValue(threadLocalStorageHandle,(void*)threadStack);
michael@0 226 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 227 pthread_setspecific(threadLocalStorageHandle,(void*)threadStack);
michael@0 228 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 229 }
michael@0 230
michael@0 231 /* decrease the stack. */
michael@0 232 ((piJIT_Method_NIDS) EventSpecificData)->stack_id =
michael@0 233 (threadStack->CurrentStack)--;
michael@0 234 }
michael@0 235
michael@0 236 /* This section is performed when method leave event occurs
michael@0 237 * It updates the virtual stack.
michael@0 238 * Increases the stack pointer.
michael@0 239 * If the stack pointer reached the top (left the global function)
michael@0 240 * increase the pointer and the top pointer.
michael@0 241 */
michael@0 242 if (event_type == iJVM_EVENT_TYPE_LEAVE_NIDS)
michael@0 243 {
michael@0 244 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 245 pThreadStack threadStack =
michael@0 246 (pThreadStack)TlsGetValue (threadLocalStorageHandle);
michael@0 247 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 248 pThreadStack threadStack =
michael@0 249 (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
michael@0 250 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 251
michael@0 252 /* check for use of reserved method IDs */
michael@0 253 if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
michael@0 254 return 0;
michael@0 255
michael@0 256 if (!threadStack)
michael@0 257 {
michael@0 258 /* Error: first report in this thread is method exit */
michael@0 259 exit (1);
michael@0 260 }
michael@0 261
michael@0 262 ((piJIT_Method_NIDS) EventSpecificData)->stack_id =
michael@0 263 ++(threadStack->CurrentStack) + 1;
michael@0 264
michael@0 265 if (((piJIT_Method_NIDS) EventSpecificData)->stack_id
michael@0 266 > threadStack->TopStack)
michael@0 267 ((piJIT_Method_NIDS) EventSpecificData)->stack_id =
michael@0 268 (unsigned int)-1;
michael@0 269 }
michael@0 270
michael@0 271 if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED)
michael@0 272 {
michael@0 273 /* check for use of reserved method IDs */
michael@0 274 if ( ((piJIT_Method_Load) EventSpecificData)->method_id <= 999 )
michael@0 275 return 0;
michael@0 276 }
michael@0 277 else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
michael@0 278 {
michael@0 279 /* check for use of reserved method IDs */
michael@0 280 if ( ((piJIT_Method_Load_V2) EventSpecificData)->method_id <= 999 )
michael@0 281 return 0;
michael@0 282 }
michael@0 283
michael@0 284 ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
michael@0 285
michael@0 286 return ReturnValue;
michael@0 287 }
michael@0 288
michael@0 289 /* The new mode call back routine */
michael@0 290 ITT_EXTERN_C void JITAPI
michael@0 291 iJIT_RegisterCallbackEx(void *userdata, iJIT_ModeChangedEx
michael@0 292 NewModeCallBackFuncEx)
michael@0 293 {
michael@0 294 /* is it already missing... or the load of functions from the DLL failed */
michael@0 295 if (iJIT_DLL_is_missing || !loadiJIT_Funcs())
michael@0 296 {
michael@0 297 /* then do not bother with notifications */
michael@0 298 NewModeCallBackFuncEx(userdata, iJIT_NO_NOTIFICATIONS);
michael@0 299 /* Error: could not load JIT functions. */
michael@0 300 return;
michael@0 301 }
michael@0 302 /* nothing to do with the callback */
michael@0 303 }
michael@0 304
michael@0 305 /*
michael@0 306 * This function allows the user to query in which mode, if at all,
michael@0 307 *VTune is running
michael@0 308 */
michael@0 309 ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
michael@0 310 {
michael@0 311 if (!iJIT_DLL_is_missing)
michael@0 312 {
michael@0 313 loadiJIT_Funcs();
michael@0 314 }
michael@0 315
michael@0 316 return executionMode;
michael@0 317 }
michael@0 318
michael@0 319 /* this function loads the collector dll (BistroJavaCollector)
michael@0 320 * and the relevant functions.
michael@0 321 * on success: all functions load, iJIT_DLL_is_missing = 0, return value = 1
michael@0 322 * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
michael@0 323 */
michael@0 324 static int loadiJIT_Funcs()
michael@0 325 {
michael@0 326 static int bDllWasLoaded = 0;
michael@0 327 char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
michael@0 328 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 329 DWORD dNameLength = 0;
michael@0 330 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 331
michael@0 332 if(bDllWasLoaded)
michael@0 333 {
michael@0 334 /* dll was already loaded, no need to do it for the second time */
michael@0 335 return 1;
michael@0 336 }
michael@0 337
michael@0 338 /* Assumes that the DLL will not be found */
michael@0 339 iJIT_DLL_is_missing = 1;
michael@0 340 FUNC_NotifyEvent = NULL;
michael@0 341
michael@0 342 if (m_libHandle)
michael@0 343 {
michael@0 344 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 345 FreeLibrary(m_libHandle);
michael@0 346 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 347 dlclose(m_libHandle);
michael@0 348 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 349 m_libHandle = NULL;
michael@0 350 }
michael@0 351
michael@0 352 /* Try to get the dll name from the environment */
michael@0 353 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 354 dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
michael@0 355 if (dNameLength)
michael@0 356 {
michael@0 357 DWORD envret = 0;
michael@0 358 dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
michael@0 359 envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
michael@0 360 dllName, dNameLength);
michael@0 361 if (envret)
michael@0 362 {
michael@0 363 /* Try to load the dll from the PATH... */
michael@0 364 m_libHandle = LoadLibraryExA(dllName,
michael@0 365 NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
michael@0 366 }
michael@0 367 free(dllName);
michael@0 368 } else {
michael@0 369 /* Try to use old VS_PROFILER variable */
michael@0 370 dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
michael@0 371 if (dNameLength)
michael@0 372 {
michael@0 373 DWORD envret = 0;
michael@0 374 dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
michael@0 375 envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
michael@0 376 dllName, dNameLength);
michael@0 377 if (envret)
michael@0 378 {
michael@0 379 /* Try to load the dll from the PATH... */
michael@0 380 m_libHandle = LoadLibraryA(dllName);
michael@0 381 }
michael@0 382 free(dllName);
michael@0 383 }
michael@0 384 }
michael@0 385 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 386 dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
michael@0 387 if (!dllName)
michael@0 388 dllName = getenv(DLL_ENVIRONMENT_VAR);
michael@0 389 #ifdef ANDROID
michael@0 390 if (!dllName)
michael@0 391 dllName = ANDROID_JIT_AGENT_PATH;
michael@0 392 #endif
michael@0 393 if (dllName)
michael@0 394 {
michael@0 395 /* Try to load the dll from the PATH... */
michael@0 396 m_libHandle = dlopen(dllName, RTLD_LAZY);
michael@0 397 }
michael@0 398 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 399
michael@0 400 if (!m_libHandle)
michael@0 401 {
michael@0 402 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 403 m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
michael@0 404 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 405 m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
michael@0 406 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 407 }
michael@0 408
michael@0 409 /* if the dll wasn't loaded - exit. */
michael@0 410 if (!m_libHandle)
michael@0 411 {
michael@0 412 iJIT_DLL_is_missing = 1; /* don't try to initialize
michael@0 413 * JIT agent the second time
michael@0 414 */
michael@0 415 return 0;
michael@0 416 }
michael@0 417
michael@0 418 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 419 FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
michael@0 420 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 421 FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
michael@0 422 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 423 if (!FUNC_NotifyEvent)
michael@0 424 {
michael@0 425 FUNC_Initialize = NULL;
michael@0 426 return 0;
michael@0 427 }
michael@0 428
michael@0 429 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 430 FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
michael@0 431 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 432 FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
michael@0 433 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 434 if (!FUNC_Initialize)
michael@0 435 {
michael@0 436 FUNC_NotifyEvent = NULL;
michael@0 437 return 0;
michael@0 438 }
michael@0 439
michael@0 440 executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
michael@0 441
michael@0 442 bDllWasLoaded = 1;
michael@0 443 iJIT_DLL_is_missing = 0; /* DLL is ok. */
michael@0 444
michael@0 445 /*
michael@0 446 * Call Graph mode: init the thread local storage
michael@0 447 * (need to store the virtual stack there).
michael@0 448 */
michael@0 449 if ( executionMode == iJIT_CALLGRAPH_ON )
michael@0 450 {
michael@0 451 /* Allocate a thread local storage slot for the thread "stack" */
michael@0 452 if (!threadLocalStorageHandle)
michael@0 453 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 454 threadLocalStorageHandle = TlsAlloc();
michael@0 455 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 456 pthread_key_create(&threadLocalStorageHandle, NULL);
michael@0 457 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 458 }
michael@0 459
michael@0 460 return 1;
michael@0 461 }
michael@0 462
michael@0 463 /*
michael@0 464 * This function should be called by the user whenever a thread ends,
michael@0 465 * to free the thread "virtual stack" storage
michael@0 466 */
michael@0 467 ITT_EXTERN_C void JITAPI FinalizeThread()
michael@0 468 {
michael@0 469 if (threadLocalStorageHandle)
michael@0 470 {
michael@0 471 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 472 pThreadStack threadStack =
michael@0 473 (pThreadStack)TlsGetValue (threadLocalStorageHandle);
michael@0 474 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 475 pThreadStack threadStack =
michael@0 476 (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
michael@0 477 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 478 if (threadStack)
michael@0 479 {
michael@0 480 free (threadStack);
michael@0 481 threadStack = NULL;
michael@0 482 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 483 TlsSetValue (threadLocalStorageHandle, threadStack);
michael@0 484 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 485 pthread_setspecific(threadLocalStorageHandle, threadStack);
michael@0 486 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 487 }
michael@0 488 }
michael@0 489 }
michael@0 490
michael@0 491 /*
michael@0 492 * This function should be called by the user when the process ends,
michael@0 493 * to free the local storage index
michael@0 494 */
michael@0 495 ITT_EXTERN_C void JITAPI FinalizeProcess()
michael@0 496 {
michael@0 497 if (m_libHandle)
michael@0 498 {
michael@0 499 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 500 FreeLibrary(m_libHandle);
michael@0 501 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 502 dlclose(m_libHandle);
michael@0 503 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 504 m_libHandle = NULL;
michael@0 505 }
michael@0 506
michael@0 507 if (threadLocalStorageHandle)
michael@0 508 #if ITT_PLATFORM==ITT_PLATFORM_WIN
michael@0 509 TlsFree (threadLocalStorageHandle);
michael@0 510 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 511 pthread_key_delete(threadLocalStorageHandle);
michael@0 512 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
michael@0 513 }
michael@0 514
michael@0 515 /*
michael@0 516 * This function should be called by the user for any method once.
michael@0 517 * The function will return a unique method ID, the user should maintain
michael@0 518 * the ID for each method
michael@0 519 */
michael@0 520 ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
michael@0 521 {
michael@0 522 static unsigned int methodID = 0x100000;
michael@0 523
michael@0 524 if (methodID == 0)
michael@0 525 return 0; /* ERROR : this is not a valid value */
michael@0 526
michael@0 527 return methodID++;
michael@0 528 }

mercurial