js/src/vtune/jitprofiling.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/vtune/jitprofiling.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,528 @@
     1.4 +/*
     1.5 +  This file is provided under a dual BSD/GPLv2 license.  When using or
     1.6 +  redistributing this file, you may do so under either license.
     1.7 +
     1.8 +  GPL LICENSE SUMMARY
     1.9 +
    1.10 +  Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
    1.11 +
    1.12 +  This program is free software; you can redistribute it and/or modify
    1.13 +  it under the terms of version 2 of the GNU General Public License as
    1.14 +  published by the Free Software Foundation.
    1.15 +
    1.16 +  This program is distributed in the hope that it will be useful, but
    1.17 +  WITHOUT ANY WARRANTY; without even the implied warranty of
    1.18 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.19 +  General Public License for more details.
    1.20 +
    1.21 +  You should have received a copy of the GNU General Public License
    1.22 +  along with this program; if not, write to the Free Software
    1.23 +  Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
    1.24 +  The full GNU General Public License is included in this distribution
    1.25 +  in the file called LICENSE.GPL.
    1.26 +
    1.27 +  Contact Information:
    1.28 +  http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
    1.29 +
    1.30 +  BSD LICENSE
    1.31 +
    1.32 +  Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
    1.33 +  All rights reserved.
    1.34 +
    1.35 +  Redistribution and use in source and binary forms, with or without
    1.36 +  modification, are permitted provided that the following conditions
    1.37 +  are met:
    1.38 +
    1.39 +    * Redistributions of source code must retain the above copyright
    1.40 +      notice, this list of conditions and the following disclaimer.
    1.41 +    * Redistributions in binary form must reproduce the above copyright
    1.42 +      notice, this list of conditions and the following disclaimer in
    1.43 +      the documentation and/or other materials provided with the
    1.44 +      distribution.
    1.45 +    * Neither the name of Intel Corporation nor the names of its
    1.46 +      contributors may be used to endorse or promote products derived
    1.47 +      from this software without specific prior written permission.
    1.48 +
    1.49 +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.50 +  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.51 +  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.52 +  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.53 +  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.54 +  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.55 +  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.56 +  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.57 +  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.58 +  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.59 +  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.60 +*/
    1.61 +#include "vtune/ittnotify_config.h"
    1.62 +
    1.63 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
    1.64 +#include <windows.h>
    1.65 +#pragma optimize("", off)
    1.66 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
    1.67 +#include <pthread.h>
    1.68 +#include <dlfcn.h>
    1.69 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
    1.70 +#include <malloc.h>
    1.71 +#include <stdlib.h>
    1.72 +
    1.73 +#include "vtune/jitprofiling.h"
    1.74 +
    1.75 +static const char rcsid[] = "\n@(#) $Revision: 294150 $\n";
    1.76 +
    1.77 +#define DLL_ENVIRONMENT_VAR             "VS_PROFILER"
    1.78 +
    1.79 +#ifndef NEW_DLL_ENVIRONMENT_VAR
    1.80 +#if ITT_ARCH==ITT_ARCH_IA32
    1.81 +#define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER32"
    1.82 +#else
    1.83 +#define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER64"
    1.84 +#endif
    1.85 +#endif /* NEW_DLL_ENVIRONMENT_VAR */
    1.86 +
    1.87 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
    1.88 +#define DEFAULT_DLLNAME                 "JitPI.dll"
    1.89 +HINSTANCE m_libHandle = NULL;
    1.90 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
    1.91 +#define DEFAULT_DLLNAME                 "libJitPI.so"
    1.92 +void* m_libHandle = NULL;
    1.93 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
    1.94 +
    1.95 +/* default location of JIT profiling agent on Android */
    1.96 +#define ANDROID_JIT_AGENT_PATH  "/data/intel/libittnotify.so"
    1.97 +
    1.98 +/* the function pointers */
    1.99 +typedef unsigned int(*TPInitialize)(void);
   1.100 +static TPInitialize FUNC_Initialize=NULL;
   1.101 +
   1.102 +typedef unsigned int(*TPNotify)(unsigned int, void*);
   1.103 +static TPNotify FUNC_NotifyEvent=NULL;
   1.104 +
   1.105 +static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
   1.106 +
   1.107 +/* end collector dll part. */
   1.108 +
   1.109 +/* loadiJIT_Funcs() : this function is called just in the beginning 
   1.110 + *  and is responsible to load the functions from BistroJavaCollector.dll
   1.111 + * result:
   1.112 + *  on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
   1.113 + *  on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
   1.114 + */ 
   1.115 +static int loadiJIT_Funcs(void);
   1.116 +
   1.117 +/* global representing whether the BistroJavaCollector can't be loaded */
   1.118 +static int iJIT_DLL_is_missing = 0;
   1.119 +
   1.120 +/* Virtual stack - the struct is used as a virtual stack for each thread.
   1.121 + * Every thread initializes with a stack of size INIT_TOP_STACK.
   1.122 + * Every method entry decreases from the current stack point,
   1.123 + * and when a thread stack reaches its top of stack (return from the global 
   1.124 + * function), the top of stack and the current stack increase. Notice that 
   1.125 + * when returning from a function the stack pointer is the address of 
   1.126 + * the function return.
   1.127 +*/
   1.128 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.129 +static DWORD threadLocalStorageHandle = 0;
   1.130 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.131 +static pthread_key_t threadLocalStorageHandle = (pthread_key_t)0;
   1.132 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.133 +
   1.134 +#define INIT_TOP_Stack 10000
   1.135 +
   1.136 +typedef struct 
   1.137 +{
   1.138 +    unsigned int TopStack;
   1.139 +    unsigned int CurrentStack;
   1.140 +} ThreadStack, *pThreadStack;
   1.141 +
   1.142 +/* end of virtual stack. */
   1.143 +
   1.144 +/*
   1.145 + * The function for reporting virtual-machine related events to VTune.
   1.146 + * Note: when reporting iJVM_EVENT_TYPE_ENTER_NIDS, there is no need to fill 
   1.147 + * in the stack_id field in the iJIT_Method_NIDS structure, as VTune fills it.
   1.148 + * The return value in iJVM_EVENT_TYPE_ENTER_NIDS && 
   1.149 + * iJVM_EVENT_TYPE_LEAVE_NIDS events will be 0 in case of failure.
   1.150 + * in iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event 
   1.151 + * it will be -1 if EventSpecificData == 0 otherwise it will be 0.
   1.152 +*/
   1.153 +
   1.154 +ITT_EXTERN_C int JITAPI 
   1.155 +iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
   1.156 +{
   1.157 +    int ReturnValue;
   1.158 +
   1.159 +    /*
   1.160 +     * This section is for debugging outside of VTune. 
   1.161 +     * It creates the environment variables that indicates call graph mode.
   1.162 +     * If running outside of VTune remove the remark.
   1.163 +     *
   1.164 +     *
   1.165 +     * static int firstTime = 1;
   1.166 +     * char DoCallGraph[12] = "DoCallGraph";
   1.167 +     * if (firstTime)
   1.168 +     * {
   1.169 +     * firstTime = 0;
   1.170 +     * SetEnvironmentVariable( "BISTRO_COLLECTORS_DO_CALLGRAPH", DoCallGraph);
   1.171 +     * }
   1.172 +     *
   1.173 +     * end of section.
   1.174 +    */
   1.175 +
   1.176 +    /* initialization part - the functions have not been loaded yet. This part
   1.177 +     *        will load the functions, and check if we are in Call Graph mode. 
   1.178 +     *        (for special treatment).
   1.179 +     */
   1.180 +    if (!FUNC_NotifyEvent) 
   1.181 +    {
   1.182 +        if (iJIT_DLL_is_missing) 
   1.183 +            return 0;
   1.184 +
   1.185 +        /* load the Function from the DLL */
   1.186 +        if (!loadiJIT_Funcs()) 
   1.187 +            return 0;
   1.188 +
   1.189 +        /* Call Graph initialization. */
   1.190 +    }
   1.191 +
   1.192 +    /* If the event is method entry/exit, check that in the current mode 
   1.193 +     * VTune is allowed to receive it
   1.194 +     */
   1.195 +    if ((event_type == iJVM_EVENT_TYPE_ENTER_NIDS || 
   1.196 +         event_type == iJVM_EVENT_TYPE_LEAVE_NIDS) &&
   1.197 +        (executionMode != iJIT_CALLGRAPH_ON))
   1.198 +    {
   1.199 +        return 0;
   1.200 +    }
   1.201 +    /* This section is performed when method enter event occurs.
   1.202 +     * It updates the virtual stack, or creates it if this is the first 
   1.203 +     * method entry in the thread. The stack pointer is decreased.
   1.204 +     */
   1.205 +    if (event_type == iJVM_EVENT_TYPE_ENTER_NIDS)
   1.206 +    {
   1.207 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.208 +        pThreadStack threadStack = 
   1.209 +            (pThreadStack)TlsGetValue (threadLocalStorageHandle);
   1.210 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.211 +        pThreadStack threadStack = 
   1.212 +            (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
   1.213 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.214 +
   1.215 +        /* check for use of reserved method IDs */
   1.216 +        if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
   1.217 +            return 0;
   1.218 +
   1.219 +        if (!threadStack)
   1.220 +        {
   1.221 +            /* initialize the stack. */
   1.222 +            threadStack = (pThreadStack) calloc (sizeof(ThreadStack), 1);
   1.223 +            if (!threadStack)
   1.224 +                return 0;
   1.225 +            threadStack->TopStack = INIT_TOP_Stack;
   1.226 +            threadStack->CurrentStack = INIT_TOP_Stack;
   1.227 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.228 +            TlsSetValue(threadLocalStorageHandle,(void*)threadStack);
   1.229 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.230 +            pthread_setspecific(threadLocalStorageHandle,(void*)threadStack);
   1.231 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.232 +        }
   1.233 +
   1.234 +        /* decrease the stack. */
   1.235 +        ((piJIT_Method_NIDS) EventSpecificData)->stack_id = 
   1.236 +            (threadStack->CurrentStack)--;
   1.237 +    }
   1.238 +
   1.239 +    /* This section is performed when method leave event occurs
   1.240 +     * It updates the virtual stack.
   1.241 +     *    Increases the stack pointer.
   1.242 +     *    If the stack pointer reached the top (left the global function)
   1.243 +     *        increase the pointer and the top pointer.
   1.244 +     */
   1.245 +    if (event_type == iJVM_EVENT_TYPE_LEAVE_NIDS)
   1.246 +    {
   1.247 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.248 +        pThreadStack threadStack = 
   1.249 +           (pThreadStack)TlsGetValue (threadLocalStorageHandle);
   1.250 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.251 +        pThreadStack threadStack = 
   1.252 +            (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
   1.253 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.254 +
   1.255 +        /* check for use of reserved method IDs */
   1.256 +        if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
   1.257 +            return 0;
   1.258 +
   1.259 +        if (!threadStack)
   1.260 +        {
   1.261 +            /* Error: first report in this thread is method exit */
   1.262 +            exit (1);
   1.263 +        }
   1.264 +
   1.265 +        ((piJIT_Method_NIDS) EventSpecificData)->stack_id = 
   1.266 +            ++(threadStack->CurrentStack) + 1;
   1.267 +
   1.268 +        if (((piJIT_Method_NIDS) EventSpecificData)->stack_id 
   1.269 +               > threadStack->TopStack)
   1.270 +            ((piJIT_Method_NIDS) EventSpecificData)->stack_id = 
   1.271 +                (unsigned int)-1;
   1.272 +    }
   1.273 +
   1.274 +    if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED)
   1.275 +    {
   1.276 +        /* check for use of reserved method IDs */
   1.277 +        if ( ((piJIT_Method_Load) EventSpecificData)->method_id <= 999 )
   1.278 +            return 0;
   1.279 +    }
   1.280 +    else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
   1.281 +    {
   1.282 +        /* check for use of reserved method IDs */
   1.283 +        if ( ((piJIT_Method_Load_V2) EventSpecificData)->method_id <= 999 )
   1.284 +            return 0;
   1.285 +    }
   1.286 +
   1.287 +    ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
   1.288 +
   1.289 +    return ReturnValue;
   1.290 +}
   1.291 +
   1.292 +/* The new mode call back routine */
   1.293 +ITT_EXTERN_C void JITAPI 
   1.294 +iJIT_RegisterCallbackEx(void *userdata, iJIT_ModeChangedEx 
   1.295 +                        NewModeCallBackFuncEx) 
   1.296 +{
   1.297 +    /* is it already missing... or the load of functions from the DLL failed */
   1.298 +    if (iJIT_DLL_is_missing || !loadiJIT_Funcs())
   1.299 +    {
   1.300 +        /* then do not bother with notifications */
   1.301 +        NewModeCallBackFuncEx(userdata, iJIT_NO_NOTIFICATIONS);  
   1.302 +        /* Error: could not load JIT functions. */
   1.303 +        return;
   1.304 +    }
   1.305 +    /* nothing to do with the callback */
   1.306 +}
   1.307 +
   1.308 +/*
   1.309 + * This function allows the user to query in which mode, if at all, 
   1.310 + *VTune is running
   1.311 + */
   1.312 +ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
   1.313 +{
   1.314 +    if (!iJIT_DLL_is_missing)
   1.315 +    {
   1.316 +        loadiJIT_Funcs();
   1.317 +    }
   1.318 +
   1.319 +    return executionMode;
   1.320 +}
   1.321 +
   1.322 +/* this function loads the collector dll (BistroJavaCollector) 
   1.323 + * and the relevant functions.
   1.324 + * on success: all functions load,     iJIT_DLL_is_missing = 0, return value = 1
   1.325 + * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
   1.326 + */ 
   1.327 +static int loadiJIT_Funcs()
   1.328 +{
   1.329 +    static int bDllWasLoaded = 0;
   1.330 +    char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
   1.331 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.332 +    DWORD dNameLength = 0;
   1.333 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.334 +
   1.335 +    if(bDllWasLoaded)
   1.336 +    {
   1.337 +        /* dll was already loaded, no need to do it for the second time */
   1.338 +        return 1;
   1.339 +    }
   1.340 +
   1.341 +    /* Assumes that the DLL will not be found */
   1.342 +    iJIT_DLL_is_missing = 1;
   1.343 +    FUNC_NotifyEvent = NULL;
   1.344 +
   1.345 +    if (m_libHandle) 
   1.346 +    {
   1.347 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.348 +        FreeLibrary(m_libHandle);
   1.349 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.350 +        dlclose(m_libHandle);
   1.351 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.352 +        m_libHandle = NULL;
   1.353 +    }
   1.354 +
   1.355 +    /* Try to get the dll name from the environment */
   1.356 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.357 +    dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
   1.358 +    if (dNameLength)
   1.359 +    {
   1.360 +        DWORD envret = 0;
   1.361 +        dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
   1.362 +        envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, 
   1.363 +                                         dllName, dNameLength);
   1.364 +        if (envret)
   1.365 +        {
   1.366 +            /* Try to load the dll from the PATH... */
   1.367 +            m_libHandle = LoadLibraryExA(dllName, 
   1.368 +                                         NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
   1.369 +        }
   1.370 +        free(dllName);
   1.371 +    } else {
   1.372 +        /* Try to use old VS_PROFILER variable */
   1.373 +        dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
   1.374 +        if (dNameLength)
   1.375 +        {
   1.376 +            DWORD envret = 0;
   1.377 +            dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
   1.378 +            envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, 
   1.379 +                                             dllName, dNameLength);
   1.380 +            if (envret)
   1.381 +            {
   1.382 +                /* Try to load the dll from the PATH... */
   1.383 +                m_libHandle = LoadLibraryA(dllName);
   1.384 +            }
   1.385 +            free(dllName);
   1.386 +        }
   1.387 +    }
   1.388 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.389 +    dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
   1.390 +    if (!dllName)
   1.391 +        dllName = getenv(DLL_ENVIRONMENT_VAR);
   1.392 +#ifdef ANDROID
   1.393 +    if (!dllName)
   1.394 +        dllName = ANDROID_JIT_AGENT_PATH;
   1.395 +#endif
   1.396 +    if (dllName)
   1.397 +    {
   1.398 +        /* Try to load the dll from the PATH... */
   1.399 +        m_libHandle = dlopen(dllName, RTLD_LAZY);
   1.400 +    }
   1.401 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.402 +
   1.403 +    if (!m_libHandle)
   1.404 +    {
   1.405 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.406 +        m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
   1.407 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.408 +        m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
   1.409 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.410 +    }
   1.411 +
   1.412 +    /* if the dll wasn't loaded - exit. */
   1.413 +    if (!m_libHandle)
   1.414 +    {
   1.415 +        iJIT_DLL_is_missing = 1; /* don't try to initialize 
   1.416 +                                  * JIT agent the second time 
   1.417 +                                  */
   1.418 +        return 0;
   1.419 +    }
   1.420 +
   1.421 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.422 +    FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
   1.423 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.424 +    FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
   1.425 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.426 +    if (!FUNC_NotifyEvent) 
   1.427 +    {
   1.428 +        FUNC_Initialize = NULL;
   1.429 +        return 0;
   1.430 +    }
   1.431 +
   1.432 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.433 +    FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
   1.434 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.435 +    FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
   1.436 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.437 +    if (!FUNC_Initialize) 
   1.438 +    {
   1.439 +        FUNC_NotifyEvent = NULL;
   1.440 +        return 0;
   1.441 +    }
   1.442 +
   1.443 +    executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
   1.444 +
   1.445 +    bDllWasLoaded = 1;
   1.446 +    iJIT_DLL_is_missing = 0; /* DLL is ok. */
   1.447 +
   1.448 +    /*
   1.449 +     * Call Graph mode: init the thread local storage
   1.450 +     * (need to store the virtual stack there).
   1.451 +     */
   1.452 +    if ( executionMode == iJIT_CALLGRAPH_ON )
   1.453 +    {
   1.454 +        /* Allocate a thread local storage slot for the thread "stack" */
   1.455 +        if (!threadLocalStorageHandle)
   1.456 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.457 +            threadLocalStorageHandle = TlsAlloc();
   1.458 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.459 +        pthread_key_create(&threadLocalStorageHandle, NULL);
   1.460 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.461 +    }
   1.462 +
   1.463 +    return 1;
   1.464 +}
   1.465 +
   1.466 +/*
   1.467 + * This function should be called by the user whenever a thread ends, 
   1.468 + * to free the thread "virtual stack" storage
   1.469 + */
   1.470 +ITT_EXTERN_C void JITAPI FinalizeThread()
   1.471 +{
   1.472 +    if (threadLocalStorageHandle)
   1.473 +    {
   1.474 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.475 +        pThreadStack threadStack = 
   1.476 +            (pThreadStack)TlsGetValue (threadLocalStorageHandle);
   1.477 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.478 +        pThreadStack threadStack = 
   1.479 +            (pThreadStack)pthread_getspecific(threadLocalStorageHandle);
   1.480 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.481 +        if (threadStack)
   1.482 +        {
   1.483 +            free (threadStack);
   1.484 +            threadStack = NULL;
   1.485 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.486 +            TlsSetValue (threadLocalStorageHandle, threadStack);
   1.487 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.488 +            pthread_setspecific(threadLocalStorageHandle, threadStack);
   1.489 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.490 +        }
   1.491 +    }
   1.492 +}
   1.493 +
   1.494 +/*
   1.495 + * This function should be called by the user when the process ends, 
   1.496 + * to free the local storage index
   1.497 +*/
   1.498 +ITT_EXTERN_C void JITAPI FinalizeProcess()
   1.499 +{
   1.500 +    if (m_libHandle) 
   1.501 +    {
   1.502 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.503 +        FreeLibrary(m_libHandle);
   1.504 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.505 +        dlclose(m_libHandle);
   1.506 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.507 +        m_libHandle = NULL;
   1.508 +    }
   1.509 +
   1.510 +    if (threadLocalStorageHandle)
   1.511 +#if ITT_PLATFORM==ITT_PLATFORM_WIN
   1.512 +        TlsFree (threadLocalStorageHandle);
   1.513 +#else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.514 +    pthread_key_delete(threadLocalStorageHandle);
   1.515 +#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
   1.516 +}
   1.517 +
   1.518 +/*
   1.519 + * This function should be called by the user for any method once.
   1.520 + * The function will return a unique method ID, the user should maintain 
   1.521 + * the ID for each method
   1.522 + */
   1.523 +ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
   1.524 +{
   1.525 +    static unsigned int methodID = 0x100000;
   1.526 +
   1.527 +    if (methodID == 0)
   1.528 +        return 0;  /* ERROR : this is not a valid value */
   1.529 +
   1.530 +    return methodID++;
   1.531 +}

mercurial