зеркало из https://github.com/mozilla/gecko-dev.git
Bug 891541 - Part 1/2 - Ship VTune support for AsmJS with Nightly and Aurora. r=glandium
This commit is contained in:
Родитель
5bb1d9fb66
Коммит
18dfb0eeea
|
@ -105,7 +105,7 @@ VPATH += $(srcdir)/assembler/assembler \
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# END enclude sources for the Nitro assembler
|
# END include sources for the Nitro assembler
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
ifdef JS_HAS_CTYPES
|
ifdef JS_HAS_CTYPES
|
||||||
|
@ -367,15 +367,6 @@ else
|
||||||
NSPR_STATIC_PATH = $(DIST)/lib
|
NSPR_STATIC_PATH = $(DIST)/lib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef MOZ_VTUNE
|
|
||||||
ifeq ($(OS_ARCH), WINNT)
|
|
||||||
EXTRA_DSO_LDOPTS += $(VTUNE_LIBRARIES)
|
|
||||||
LIBS += $(VTUNE_LIBRARIES)
|
|
||||||
else
|
|
||||||
SHARED_LIBRARY_LIBS += $(VTUNE_LIBRARIES)
|
|
||||||
endif # WINNT
|
|
||||||
endif # MOZ_VTUNE
|
|
||||||
|
|
||||||
ifdef MOZ_ETW
|
ifdef MOZ_ETW
|
||||||
# This will get the ETW provider resources into the library mozjs.dll
|
# This will get the ETW provider resources into the library mozjs.dll
|
||||||
RESFILE = ETWProvider.res
|
RESFILE = ETWProvider.res
|
||||||
|
|
|
@ -3549,35 +3549,21 @@ MOZ_ARG_ENABLE_BOOL(vtune,
|
||||||
[ --enable-vtune Enable vtune profiling. Implies --enable-profiling.],
|
[ --enable-vtune Enable vtune profiling. Implies --enable-profiling.],
|
||||||
MOZ_VTUNE=1,
|
MOZ_VTUNE=1,
|
||||||
MOZ_VTUNE= )
|
MOZ_VTUNE= )
|
||||||
if test -n "$MOZ_VTUNE"; then
|
|
||||||
if test -z "$VTUNE_AMPLIFIER_XE_2013_DIR"; then
|
|
||||||
echo "Error: VTUNE_AMPLIFIER_XE_2013_DIR undefined."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
VTUNE_DIR=`echo "$VTUNE_AMPLIFIER_XE_2013_DIR" | sed 's,\\\,/,g'`
|
|
||||||
VTUNE_DIR=`echo "$VTUNE_DIR" | sed 's,(,\\\(,g'`
|
|
||||||
VTUNE_DIR=`echo "$VTUNE_DIR" | sed 's,),\\\),g'`
|
|
||||||
VTUNE_DIR=`echo "$VTUNE_DIR" | sed 's, ,\\\ ,g'`
|
|
||||||
|
|
||||||
VTUNE_LIB=lib32
|
|
||||||
if test "x86_64" = "$TARGET_CPU"; then
|
|
||||||
VTUNE_LIB=lib64
|
|
||||||
fi
|
|
||||||
|
|
||||||
VTUNE_LIBRARIES="${VTUNE_DIR}/${VTUNE_LIB}/${LIB_PREFIX}jitprofiling.${LIB_SUFFIX}"
|
|
||||||
AC_SUBST(VTUNE_LIBRARIES)
|
|
||||||
|
|
||||||
CXXFLAGS="$CXXFLAGS -I${VTUNE_DIR}/include"
|
|
||||||
MOZ_PROFILING=1
|
|
||||||
AC_DEFINE(MOZ_VTUNE)
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
dnl Profiling
|
dnl Profiling
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
if test -n "$MOZ_PROFILING"; then
|
if test -n "$MOZ_PROFILING"; then
|
||||||
AC_DEFINE(MOZ_PROFILING)
|
AC_DEFINE(MOZ_PROFILING)
|
||||||
|
|
||||||
|
case "$OS_TARGET" in
|
||||||
|
Linux) MOZ_VTUNE=1 ;;
|
||||||
|
WINNT) MOZ_VTUNE=1 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "$MOZ_VTUNE"; then
|
||||||
|
AC_DEFINE(MOZ_VTUNE)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "mozilla/Move.h"
|
#include "mozilla/Move.h"
|
||||||
|
|
||||||
#ifdef MOZ_VTUNE
|
#ifdef MOZ_VTUNE
|
||||||
# include "jitprofiling.h"
|
# include "vtune/VTuneWrapper.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "jsmath.h"
|
#include "jsmath.h"
|
||||||
|
@ -4710,10 +4710,8 @@ GenerateCode(ModuleCompiler &m, ModuleCompiler::Func &func, MIRGenerator &mir, L
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_VTUNE
|
#ifdef MOZ_VTUNE
|
||||||
if (iJIT_IsProfilingActive() == iJIT_SAMPLING_ON) {
|
if (IsVTuneProfilingActive() && !m.trackProfiledFunction(func, m.masm().size()))
|
||||||
if (!m.trackProfiledFunction(func, m.masm().size()))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JS_ION_PERF
|
#ifdef JS_ION_PERF
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
#include "ion/AsmJSLink.h"
|
#include "ion/AsmJSLink.h"
|
||||||
|
|
||||||
#ifdef MOZ_VTUNE
|
#ifdef MOZ_VTUNE
|
||||||
# include "jitprofiling.h"
|
# include "vtune/VTuneWrapper.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "jscntxt.h"
|
#include "jscntxt.h"
|
||||||
#include "jsmath.h"
|
#include "jsmath.h"
|
||||||
#include "jswrapper.h"
|
#include "jswrapper.h"
|
||||||
|
@ -576,7 +577,7 @@ LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MOZ_VTUNE)
|
#if defined(MOZ_VTUNE)
|
||||||
if (!SendFunctionsToVTune(cx, module))
|
if (IsVTuneProfilingActive() && !SendFunctionsToVTune(cx, module))
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -328,6 +328,11 @@ if CONFIG['JS_HAS_CTYPES']:
|
||||||
'Library.cpp',
|
'Library.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['MOZ_VTUNE']:
|
||||||
|
CSRCS += [
|
||||||
|
'vtune/jitprofiling.c'
|
||||||
|
]
|
||||||
|
|
||||||
if CONFIG['HAVE_LINUX_PERF_EVENT_H']:
|
if CONFIG['HAVE_LINUX_PERF_EVENT_H']:
|
||||||
CPP_SOURCES += [
|
CPP_SOURCES += [
|
||||||
'pm_linux.cpp'
|
'pm_linux.cpp'
|
||||||
|
|
|
@ -52,15 +52,6 @@ SHELL_INSTALL_AUTOLOAD_DEST := $(DIST)/bin
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
ifdef MOZ_VTUNE
|
|
||||||
ifeq ($(OS_ARCH), WINNT)
|
|
||||||
EXTRA_DSO_LDOPTS += $(VTUNE_LIBRARIES)
|
|
||||||
LIBS += $(VTUNE_LIBRARIES)
|
|
||||||
else
|
|
||||||
SHARED_LIBRARY_LIBS += $(VTUNE_LIBRARIES)
|
|
||||||
endif # WINNT
|
|
||||||
endif # MOZ_VTUNE
|
|
||||||
|
|
||||||
# People expect the js shell to wind up in the top-level JS dir.
|
# People expect the js shell to wind up in the top-level JS dir.
|
||||||
libs::
|
libs::
|
||||||
$(INSTALL) $(IFLAGS2) $(PROGRAM) $(DEPTH)
|
$(INSTALL) $(IFLAGS2) $(PROGRAM) $(DEPTH)
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
VTune files imported from VTune Amplifier XE 2013 Rev 11.
|
||||||
|
|
||||||
|
To update these files, copy the following from a VTune install directory:
|
||||||
|
sdk/src/ittnotify/ittnotify_config.h
|
||||||
|
sdk/src/ittnotify/ittnotify_types.h
|
||||||
|
sdk/src/ittnotify/jitprofiling.c
|
||||||
|
include/jitprofiling.h
|
||||||
|
|
||||||
|
If the license has changed, update the "VTune License" section of
|
||||||
|
toolkit/content/license.html
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef vtunewrapper_h
|
||||||
|
#define vtunewrapper_h
|
||||||
|
|
||||||
|
#include "vtune/jitprofiling.h"
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
IsVTuneProfilingActive()
|
||||||
|
{
|
||||||
|
return (iJIT_IsProfilingActive() == iJIT_SAMPLING_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // vtunewrapper_h
|
|
@ -0,0 +1,493 @@
|
||||||
|
/*
|
||||||
|
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||||
|
redistributing this file, you may do so under either license.
|
||||||
|
|
||||||
|
GPL LICENSE SUMMARY
|
||||||
|
|
||||||
|
Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of version 2 of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
The full GNU General Public License is included in this distribution
|
||||||
|
in the file called LICENSE.GPL.
|
||||||
|
|
||||||
|
Contact Information:
|
||||||
|
http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
|
||||||
|
|
||||||
|
BSD LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _ITTNOTIFY_CONFIG_H_
|
||||||
|
#define _ITTNOTIFY_CONFIG_H_
|
||||||
|
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
#ifndef ITT_OS_WIN
|
||||||
|
# define ITT_OS_WIN 1
|
||||||
|
#endif /* ITT_OS_WIN */
|
||||||
|
|
||||||
|
#ifndef ITT_OS_LINUX
|
||||||
|
# define ITT_OS_LINUX 2
|
||||||
|
#endif /* ITT_OS_LINUX */
|
||||||
|
|
||||||
|
#ifndef ITT_OS_MAC
|
||||||
|
# define ITT_OS_MAC 3
|
||||||
|
#endif /* ITT_OS_MAC */
|
||||||
|
|
||||||
|
#ifndef ITT_OS
|
||||||
|
# if defined WIN32 || defined _WIN32
|
||||||
|
# define ITT_OS ITT_OS_WIN
|
||||||
|
# elif defined( __APPLE__ ) && defined( __MACH__ )
|
||||||
|
# define ITT_OS ITT_OS_MAC
|
||||||
|
# else
|
||||||
|
# define ITT_OS ITT_OS_LINUX
|
||||||
|
# endif
|
||||||
|
#endif /* ITT_OS */
|
||||||
|
|
||||||
|
#ifndef ITT_PLATFORM_WIN
|
||||||
|
# define ITT_PLATFORM_WIN 1
|
||||||
|
#endif /* ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
#ifndef ITT_PLATFORM_POSIX
|
||||||
|
# define ITT_PLATFORM_POSIX 2
|
||||||
|
#endif /* ITT_PLATFORM_POSIX */
|
||||||
|
|
||||||
|
#ifndef ITT_PLATFORM
|
||||||
|
# if ITT_OS==ITT_OS_WIN
|
||||||
|
# define ITT_PLATFORM ITT_PLATFORM_WIN
|
||||||
|
# else
|
||||||
|
# define ITT_PLATFORM ITT_PLATFORM_POSIX
|
||||||
|
# endif /* _WIN32 */
|
||||||
|
#endif /* ITT_PLATFORM */
|
||||||
|
|
||||||
|
#if defined(_UNICODE) && !defined(UNICODE)
|
||||||
|
#define UNICODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
#include <tchar.h>
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
#include <stdint.h>
|
||||||
|
#if defined(UNICODE) || defined(_UNICODE)
|
||||||
|
#include <wchar.h>
|
||||||
|
#endif /* UNICODE || _UNICODE */
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
#ifndef CDECL
|
||||||
|
# if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
# define CDECL __cdecl
|
||||||
|
# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||||
|
# define CDECL /* not actual on x86_64 platform */
|
||||||
|
# else /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||||
|
# define CDECL __attribute__ ((cdecl))
|
||||||
|
# endif /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||||
|
# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
#endif /* CDECL */
|
||||||
|
|
||||||
|
#ifndef STDCALL
|
||||||
|
# if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
# define STDCALL __stdcall
|
||||||
|
# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||||
|
# define STDCALL /* not supported on x86_64 platform */
|
||||||
|
# else /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||||
|
# define STDCALL __attribute__ ((stdcall))
|
||||||
|
# endif /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||||
|
# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
#endif /* STDCALL */
|
||||||
|
|
||||||
|
#define ITTAPI CDECL
|
||||||
|
#define LIBITTAPI CDECL
|
||||||
|
|
||||||
|
/* TODO: Temporary for compatibility! */
|
||||||
|
#define ITTAPI_CALL CDECL
|
||||||
|
#define LIBITTAPI_CALL CDECL
|
||||||
|
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
/* use __forceinline (VC++ specific) */
|
||||||
|
#define ITT_INLINE __forceinline
|
||||||
|
#define ITT_INLINE_ATTRIBUTE /* nothing */
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
/*
|
||||||
|
* Generally, functions are not inlined unless optimization is specified.
|
||||||
|
* For functions declared inline, this attribute inlines the function even
|
||||||
|
* if no optimization level was specified.
|
||||||
|
*/
|
||||||
|
#ifdef __STRICT_ANSI__
|
||||||
|
#define ITT_INLINE static
|
||||||
|
#else /* __STRICT_ANSI__ */
|
||||||
|
#define ITT_INLINE static inline
|
||||||
|
#endif /* __STRICT_ANSI__ */
|
||||||
|
#define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline))
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
#ifndef ITT_ARCH_IA32
|
||||||
|
# define ITT_ARCH_IA32 1
|
||||||
|
#endif /* ITT_ARCH_IA32 */
|
||||||
|
|
||||||
|
#ifndef ITT_ARCH_IA32E
|
||||||
|
# define ITT_ARCH_IA32E 2
|
||||||
|
#endif /* ITT_ARCH_IA32E */
|
||||||
|
|
||||||
|
#ifndef ITT_ARCH_IA64
|
||||||
|
# define ITT_ARCH_IA64 3
|
||||||
|
#endif /* ITT_ARCH_IA64 */
|
||||||
|
|
||||||
|
#ifndef ITT_ARCH
|
||||||
|
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||||
|
# define ITT_ARCH ITT_ARCH_IA32E
|
||||||
|
# elif defined _M_IA64 || defined __ia64
|
||||||
|
# define ITT_ARCH ITT_ARCH_IA64
|
||||||
|
# else
|
||||||
|
# define ITT_ARCH ITT_ARCH_IA32
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define ITT_EXTERN_C extern "C"
|
||||||
|
#else
|
||||||
|
# define ITT_EXTERN_C /* nothing */
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#define ITT_TO_STR_AUX(x) #x
|
||||||
|
#define ITT_TO_STR(x) ITT_TO_STR_AUX(x)
|
||||||
|
|
||||||
|
#define __ITT_BUILD_ASSERT(expr, suffix) do { \
|
||||||
|
static char __itt_build_check_##suffix[(expr) ? 1 : -1]; \
|
||||||
|
__itt_build_check_##suffix[0] = 0; \
|
||||||
|
} while(0)
|
||||||
|
#define _ITT_BUILD_ASSERT(expr, suffix) __ITT_BUILD_ASSERT((expr), suffix)
|
||||||
|
#define ITT_BUILD_ASSERT(expr) _ITT_BUILD_ASSERT((expr), __LINE__)
|
||||||
|
|
||||||
|
#define ITT_MAGIC { 0xED, 0xAB, 0xAB, 0xEC, 0x0D, 0xEE, 0xDA, 0x30 }
|
||||||
|
|
||||||
|
/* Replace with snapshot date YYYYMMDD for promotion build. */
|
||||||
|
#define API_VERSION_BUILD 20111111
|
||||||
|
|
||||||
|
#ifndef API_VERSION_NUM
|
||||||
|
#define API_VERSION_NUM 0.0.0
|
||||||
|
#endif /* API_VERSION_NUM */
|
||||||
|
|
||||||
|
#define API_VERSION "ITT-API-Version " ITT_TO_STR(API_VERSION_NUM) \
|
||||||
|
" (" ITT_TO_STR(API_VERSION_BUILD) ")"
|
||||||
|
|
||||||
|
/* OS communication functions */
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
#include <windows.h>
|
||||||
|
typedef HMODULE lib_t;
|
||||||
|
typedef DWORD TIDT;
|
||||||
|
typedef CRITICAL_SECTION mutex_t;
|
||||||
|
#define MUTEX_INITIALIZER { 0 }
|
||||||
|
#define strong_alias(name, aliasname) /* empty for Windows */
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#if defined(UNICODE) || defined(_UNICODE)
|
||||||
|
#include <wchar.h>
|
||||||
|
#endif /* UNICODE */
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE 1 /* need for PTHREAD_MUTEX_RECURSIVE */
|
||||||
|
#endif /* _GNU_SOURCE */
|
||||||
|
#include <pthread.h>
|
||||||
|
typedef void* lib_t;
|
||||||
|
typedef pthread_t TIDT;
|
||||||
|
typedef pthread_mutex_t mutex_t;
|
||||||
|
#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||||
|
#define _strong_alias(name, aliasname) \
|
||||||
|
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
|
||||||
|
#define strong_alias(name, aliasname) _strong_alias(name, aliasname)
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
#define __itt_get_proc(lib, name) GetProcAddress(lib, name)
|
||||||
|
#define __itt_mutex_init(mutex) InitializeCriticalSection(mutex)
|
||||||
|
#define __itt_mutex_lock(mutex) EnterCriticalSection(mutex)
|
||||||
|
#define __itt_mutex_unlock(mutex) LeaveCriticalSection(mutex)
|
||||||
|
#define __itt_load_lib(name) LoadLibraryA(name)
|
||||||
|
#define __itt_unload_lib(handle) FreeLibrary(handle)
|
||||||
|
#define __itt_system_error() (int)GetLastError()
|
||||||
|
#define __itt_fstrcmp(s1, s2) lstrcmpA(s1, s2)
|
||||||
|
#define __itt_fstrlen(s) lstrlenA(s)
|
||||||
|
#define __itt_fstrcpyn(s1, s2, l) lstrcpynA(s1, s2, l)
|
||||||
|
#define __itt_fstrdup(s) _strdup(s)
|
||||||
|
#define __itt_thread_id() GetCurrentThreadId()
|
||||||
|
#define __itt_thread_yield() SwitchToThread()
|
||||||
|
#ifndef ITT_SIMPLE_INIT
|
||||||
|
ITT_INLINE long
|
||||||
|
__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
|
||||||
|
ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
|
||||||
|
{
|
||||||
|
return InterlockedIncrement(ptr);
|
||||||
|
}
|
||||||
|
#endif /* ITT_SIMPLE_INIT */
|
||||||
|
#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
|
||||||
|
#define __itt_get_proc(lib, name) dlsym(lib, name)
|
||||||
|
#define __itt_mutex_init(mutex) {\
|
||||||
|
pthread_mutexattr_t mutex_attr; \
|
||||||
|
int error_code = pthread_mutexattr_init(&mutex_attr); \
|
||||||
|
if (error_code) \
|
||||||
|
__itt_report_error(__itt_error_system, "pthread_mutexattr_init", \
|
||||||
|
error_code); \
|
||||||
|
error_code = pthread_mutexattr_settype(&mutex_attr, \
|
||||||
|
PTHREAD_MUTEX_RECURSIVE); \
|
||||||
|
if (error_code) \
|
||||||
|
__itt_report_error(__itt_error_system, "pthread_mutexattr_settype", \
|
||||||
|
error_code); \
|
||||||
|
error_code = pthread_mutex_init(mutex, &mutex_attr); \
|
||||||
|
if (error_code) \
|
||||||
|
__itt_report_error(__itt_error_system, "pthread_mutex_init", \
|
||||||
|
error_code); \
|
||||||
|
error_code = pthread_mutexattr_destroy(&mutex_attr); \
|
||||||
|
if (error_code) \
|
||||||
|
__itt_report_error(__itt_error_system, "pthread_mutexattr_destroy", \
|
||||||
|
error_code); \
|
||||||
|
}
|
||||||
|
#define __itt_mutex_lock(mutex) pthread_mutex_lock(mutex)
|
||||||
|
#define __itt_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
|
||||||
|
#define __itt_load_lib(name) dlopen(name, RTLD_LAZY)
|
||||||
|
#define __itt_unload_lib(handle) dlclose(handle)
|
||||||
|
#define __itt_system_error() errno
|
||||||
|
#define __itt_fstrcmp(s1, s2) strcmp(s1, s2)
|
||||||
|
#define __itt_fstrlen(s) strlen(s)
|
||||||
|
#define __itt_fstrcpyn(s1, s2, l) strncpy(s1, s2, l)
|
||||||
|
#define __itt_fstrdup(s) strdup(s)
|
||||||
|
#define __itt_thread_id() pthread_self()
|
||||||
|
#define __itt_thread_yield() sched_yield()
|
||||||
|
#if ITT_ARCH==ITT_ARCH_IA64
|
||||||
|
#ifdef __INTEL_COMPILER
|
||||||
|
#define __TBB_machine_fetchadd4(addr, val) __fetchadd4_acq((void *)addr, val)
|
||||||
|
#else /* __INTEL_COMPILER */
|
||||||
|
/* TODO: Add Support for not Intel compilers for IA64 */
|
||||||
|
#endif /* __INTEL_COMPILER */
|
||||||
|
#else /* ITT_ARCH!=ITT_ARCH_IA64 */
|
||||||
|
ITT_INLINE long
|
||||||
|
__TBB_machine_fetchadd4(volatile void* ptr, long addend) ITT_INLINE_ATTRIBUTE;
|
||||||
|
ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend)
|
||||||
|
{
|
||||||
|
long result;
|
||||||
|
__asm__ __volatile__("lock\nxadd %0,%1"
|
||||||
|
: "=r"(result),"=m"(*(long*)ptr)
|
||||||
|
: "0"(addend), "m"(*(long*)ptr)
|
||||||
|
: "memory");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* ITT_ARCH==ITT_ARCH_IA64 */
|
||||||
|
#ifndef ITT_SIMPLE_INIT
|
||||||
|
ITT_INLINE long
|
||||||
|
__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
|
||||||
|
ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
|
||||||
|
{
|
||||||
|
return __TBB_machine_fetchadd4(ptr, 1) + 1L;
|
||||||
|
}
|
||||||
|
#endif /* ITT_SIMPLE_INIT */
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
__itt_collection_normal = 0,
|
||||||
|
__itt_collection_paused = 1
|
||||||
|
} __itt_collection_state;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
__itt_thread_normal = 0,
|
||||||
|
__itt_thread_ignored = 1
|
||||||
|
} __itt_thread_state;
|
||||||
|
|
||||||
|
#pragma pack(push, 8)
|
||||||
|
|
||||||
|
typedef struct ___itt_thread_info
|
||||||
|
{
|
||||||
|
const char* nameA; /*!< Copy of original name in ASCII. */
|
||||||
|
#if defined(UNICODE) || defined(_UNICODE)
|
||||||
|
const wchar_t* nameW; /*!< Copy of original name in UNICODE. */
|
||||||
|
#else /* UNICODE || _UNICODE */
|
||||||
|
void* nameW;
|
||||||
|
#endif /* UNICODE || _UNICODE */
|
||||||
|
TIDT tid;
|
||||||
|
__itt_thread_state state; /*!< Thread state (paused or normal) */
|
||||||
|
int extra1; /*!< Reserved to the runtime */
|
||||||
|
void* extra2; /*!< Reserved to the runtime */
|
||||||
|
struct ___itt_thread_info* next;
|
||||||
|
} __itt_thread_info;
|
||||||
|
|
||||||
|
#include "ittnotify_types.h" /* For __itt_group_id definition */
|
||||||
|
|
||||||
|
typedef struct ___itt_api_info_20101001
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
void** func_ptr;
|
||||||
|
void* init_func;
|
||||||
|
__itt_group_id group;
|
||||||
|
} __itt_api_info_20101001;
|
||||||
|
|
||||||
|
typedef struct ___itt_api_info
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
void** func_ptr;
|
||||||
|
void* init_func;
|
||||||
|
void* null_func;
|
||||||
|
__itt_group_id group;
|
||||||
|
} __itt_api_info;
|
||||||
|
|
||||||
|
struct ___itt_domain;
|
||||||
|
struct ___itt_string_handle;
|
||||||
|
|
||||||
|
typedef struct ___itt_global
|
||||||
|
{
|
||||||
|
unsigned char magic[8];
|
||||||
|
unsigned long version_major;
|
||||||
|
unsigned long version_minor;
|
||||||
|
unsigned long version_build;
|
||||||
|
volatile long api_initialized;
|
||||||
|
volatile long mutex_initialized;
|
||||||
|
volatile long atomic_counter;
|
||||||
|
mutex_t mutex;
|
||||||
|
lib_t lib;
|
||||||
|
void* error_handler;
|
||||||
|
const char** dll_path_ptr;
|
||||||
|
__itt_api_info* api_list_ptr;
|
||||||
|
struct ___itt_global* next;
|
||||||
|
/* Joinable structures below */
|
||||||
|
__itt_thread_info* thread_list;
|
||||||
|
struct ___itt_domain* domain_list;
|
||||||
|
struct ___itt_string_handle* string_list;
|
||||||
|
__itt_collection_state state;
|
||||||
|
} __itt_global;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#define NEW_THREAD_INFO_W(gptr,h,h_tail,t,s,n) { \
|
||||||
|
h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
|
||||||
|
if (h != NULL) { \
|
||||||
|
h->tid = t; \
|
||||||
|
h->nameA = NULL; \
|
||||||
|
h->nameW = n ? _wcsdup(n) : NULL; \
|
||||||
|
h->state = s; \
|
||||||
|
h->extra1 = 0; /* reserved */ \
|
||||||
|
h->extra2 = NULL; /* reserved */ \
|
||||||
|
h->next = NULL; \
|
||||||
|
if (h_tail == NULL) \
|
||||||
|
(gptr)->thread_list = h; \
|
||||||
|
else \
|
||||||
|
h_tail->next = h; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NEW_THREAD_INFO_A(gptr,h,h_tail,t,s,n) { \
|
||||||
|
h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
|
||||||
|
if (h != NULL) { \
|
||||||
|
h->tid = t; \
|
||||||
|
h->nameA = n ? __itt_fstrdup(n) : NULL; \
|
||||||
|
h->nameW = NULL; \
|
||||||
|
h->state = s; \
|
||||||
|
h->extra1 = 0; /* reserved */ \
|
||||||
|
h->extra2 = NULL; /* reserved */ \
|
||||||
|
h->next = NULL; \
|
||||||
|
if (h_tail == NULL) \
|
||||||
|
(gptr)->thread_list = h; \
|
||||||
|
else \
|
||||||
|
h_tail->next = h; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NEW_DOMAIN_W(gptr,h,h_tail,name) { \
|
||||||
|
h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
|
||||||
|
if (h != NULL) { \
|
||||||
|
h->flags = 0; /* domain is disabled by default */ \
|
||||||
|
h->nameA = NULL; \
|
||||||
|
h->nameW = name ? _wcsdup(name) : NULL; \
|
||||||
|
h->extra1 = 0; /* reserved */ \
|
||||||
|
h->extra2 = NULL; /* reserved */ \
|
||||||
|
h->next = NULL; \
|
||||||
|
if (h_tail == NULL) \
|
||||||
|
(gptr)->domain_list = h; \
|
||||||
|
else \
|
||||||
|
h_tail->next = h; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NEW_DOMAIN_A(gptr,h,h_tail,name) { \
|
||||||
|
h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
|
||||||
|
if (h != NULL) { \
|
||||||
|
h->flags = 0; /* domain is disabled by default */ \
|
||||||
|
h->nameA = name ? __itt_fstrdup(name) : NULL; \
|
||||||
|
h->nameW = NULL; \
|
||||||
|
h->extra1 = 0; /* reserved */ \
|
||||||
|
h->extra2 = NULL; /* reserved */ \
|
||||||
|
h->next = NULL; \
|
||||||
|
if (h_tail == NULL) \
|
||||||
|
(gptr)->domain_list = h; \
|
||||||
|
else \
|
||||||
|
h_tail->next = h; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NEW_STRING_HANDLE_W(gptr,h,h_tail,name) { \
|
||||||
|
h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
|
||||||
|
if (h != NULL) { \
|
||||||
|
h->strA = NULL; \
|
||||||
|
h->strW = name ? _wcsdup(name) : NULL; \
|
||||||
|
h->extra1 = 0; /* reserved */ \
|
||||||
|
h->extra2 = NULL; /* reserved */ \
|
||||||
|
h->next = NULL; \
|
||||||
|
if (h_tail == NULL) \
|
||||||
|
(gptr)->string_list = h; \
|
||||||
|
else \
|
||||||
|
h_tail->next = h; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NEW_STRING_HANDLE_A(gptr,h,h_tail,name) { \
|
||||||
|
h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
|
||||||
|
if (h != NULL) { \
|
||||||
|
h->strA = name ? __itt_fstrdup(name) : NULL; \
|
||||||
|
h->strW = NULL; \
|
||||||
|
h->extra1 = 0; /* reserved */ \
|
||||||
|
h->extra2 = NULL; /* reserved */ \
|
||||||
|
h->next = NULL; \
|
||||||
|
if (h_tail == NULL) \
|
||||||
|
(gptr)->string_list = h; \
|
||||||
|
else \
|
||||||
|
h_tail->next = h; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ITTNOTIFY_CONFIG_H_ */
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||||
|
redistributing this file, you may do so under either license.
|
||||||
|
|
||||||
|
GPL LICENSE SUMMARY
|
||||||
|
|
||||||
|
Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of version 2 of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
The full GNU General Public License is included in this distribution
|
||||||
|
in the file called LICENSE.GPL.
|
||||||
|
|
||||||
|
Contact Information:
|
||||||
|
http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
|
||||||
|
|
||||||
|
BSD LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _ITTNOTIFY_TYPES_H_
|
||||||
|
#define _ITTNOTIFY_TYPES_H_
|
||||||
|
|
||||||
|
typedef enum ___itt_group_id
|
||||||
|
{
|
||||||
|
__itt_group_none = 0,
|
||||||
|
__itt_group_legacy = 1<<0,
|
||||||
|
__itt_group_control = 1<<1,
|
||||||
|
__itt_group_thread = 1<<2,
|
||||||
|
__itt_group_mark = 1<<3,
|
||||||
|
__itt_group_sync = 1<<4,
|
||||||
|
__itt_group_fsync = 1<<5,
|
||||||
|
__itt_group_jit = 1<<6,
|
||||||
|
__itt_group_model = 1<<7,
|
||||||
|
__itt_group_splitter_min = 1<<7,
|
||||||
|
__itt_group_counter = 1<<8,
|
||||||
|
__itt_group_frame = 1<<9,
|
||||||
|
__itt_group_stitch = 1<<10,
|
||||||
|
__itt_group_heap = 1<<11,
|
||||||
|
__itt_group_splitter_max = 1<<12,
|
||||||
|
__itt_group_structure = 1<<12,
|
||||||
|
__itt_group_suppress = 1<<13,
|
||||||
|
__itt_group_arrays = 1<<14,
|
||||||
|
__itt_group_all = -1
|
||||||
|
} __itt_group_id;
|
||||||
|
|
||||||
|
#pragma pack(push, 8)
|
||||||
|
|
||||||
|
typedef struct ___itt_group_list
|
||||||
|
{
|
||||||
|
__itt_group_id id;
|
||||||
|
const char* name;
|
||||||
|
} __itt_group_list;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#define ITT_GROUP_LIST(varname) \
|
||||||
|
static __itt_group_list varname[] = { \
|
||||||
|
{ __itt_group_all, "all" }, \
|
||||||
|
{ __itt_group_control, "control" }, \
|
||||||
|
{ __itt_group_thread, "thread" }, \
|
||||||
|
{ __itt_group_mark, "mark" }, \
|
||||||
|
{ __itt_group_sync, "sync" }, \
|
||||||
|
{ __itt_group_fsync, "fsync" }, \
|
||||||
|
{ __itt_group_jit, "jit" }, \
|
||||||
|
{ __itt_group_model, "model" }, \
|
||||||
|
{ __itt_group_counter, "counter" }, \
|
||||||
|
{ __itt_group_frame, "frame" }, \
|
||||||
|
{ __itt_group_stitch, "stitch" }, \
|
||||||
|
{ __itt_group_heap, "heap" }, \
|
||||||
|
{ __itt_group_structure, "structure" }, \
|
||||||
|
{ __itt_group_suppress, "suppress" }, \
|
||||||
|
{ __itt_group_arrays, "arrays" }, \
|
||||||
|
{ __itt_group_none, NULL } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ITTNOTIFY_TYPES_H_ */
|
|
@ -0,0 +1,528 @@
|
||||||
|
/*
|
||||||
|
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||||
|
redistributing this file, you may do so under either license.
|
||||||
|
|
||||||
|
GPL LICENSE SUMMARY
|
||||||
|
|
||||||
|
Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of version 2 of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
The full GNU General Public License is included in this distribution
|
||||||
|
in the file called LICENSE.GPL.
|
||||||
|
|
||||||
|
Contact Information:
|
||||||
|
http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
|
||||||
|
|
||||||
|
BSD LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2005-2012 Intel Corporation. All rights reserved.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "vtune/ittnotify_config.h"
|
||||||
|
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
#include <windows.h>
|
||||||
|
#pragma optimize("", off)
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "vtune/jitprofiling.h"
|
||||||
|
|
||||||
|
static const char rcsid[] = "\n@(#) $Revision: 294150 $\n";
|
||||||
|
|
||||||
|
#define DLL_ENVIRONMENT_VAR "VS_PROFILER"
|
||||||
|
|
||||||
|
#ifndef NEW_DLL_ENVIRONMENT_VAR
|
||||||
|
#if ITT_ARCH==ITT_ARCH_IA32
|
||||||
|
#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER32"
|
||||||
|
#else
|
||||||
|
#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER64"
|
||||||
|
#endif
|
||||||
|
#endif /* NEW_DLL_ENVIRONMENT_VAR */
|
||||||
|
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
#define DEFAULT_DLLNAME "JitPI.dll"
|
||||||
|
HINSTANCE m_libHandle = NULL;
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
#define DEFAULT_DLLNAME "libJitPI.so"
|
||||||
|
void* m_libHandle = NULL;
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
/* default location of JIT profiling agent on Android */
|
||||||
|
#define ANDROID_JIT_AGENT_PATH "/data/intel/libittnotify.so"
|
||||||
|
|
||||||
|
/* the function pointers */
|
||||||
|
typedef unsigned int(*TPInitialize)(void);
|
||||||
|
static TPInitialize FUNC_Initialize=NULL;
|
||||||
|
|
||||||
|
typedef unsigned int(*TPNotify)(unsigned int, void*);
|
||||||
|
static TPNotify FUNC_NotifyEvent=NULL;
|
||||||
|
|
||||||
|
static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
|
||||||
|
|
||||||
|
/* end collector dll part. */
|
||||||
|
|
||||||
|
/* loadiJIT_Funcs() : this function is called just in the beginning
|
||||||
|
* and is responsible to load the functions from BistroJavaCollector.dll
|
||||||
|
* result:
|
||||||
|
* on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
|
||||||
|
* on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
|
||||||
|
*/
|
||||||
|
static int loadiJIT_Funcs(void);
|
||||||
|
|
||||||
|
/* global representing whether the BistroJavaCollector can't be loaded */
|
||||||
|
static int iJIT_DLL_is_missing = 0;
|
||||||
|
|
||||||
|
/* Virtual stack - the struct is used as a virtual stack for each thread.
|
||||||
|
* Every thread initializes with a stack of size INIT_TOP_STACK.
|
||||||
|
* Every method entry decreases from the current stack point,
|
||||||
|
* and when a thread stack reaches its top of stack (return from the global
|
||||||
|
* function), the top of stack and the current stack increase. Notice that
|
||||||
|
* when returning from a function the stack pointer is the address of
|
||||||
|
* the function return.
|
||||||
|
*/
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
static DWORD threadLocalStorageHandle = 0;
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
static pthread_key_t threadLocalStorageHandle = (pthread_key_t)0;
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
#define INIT_TOP_Stack 10000
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int TopStack;
|
||||||
|
unsigned int CurrentStack;
|
||||||
|
} ThreadStack, *pThreadStack;
|
||||||
|
|
||||||
|
/* end of virtual stack. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The function for reporting virtual-machine related events to VTune.
|
||||||
|
* Note: when reporting iJVM_EVENT_TYPE_ENTER_NIDS, there is no need to fill
|
||||||
|
* in the stack_id field in the iJIT_Method_NIDS structure, as VTune fills it.
|
||||||
|
* The return value in iJVM_EVENT_TYPE_ENTER_NIDS &&
|
||||||
|
* iJVM_EVENT_TYPE_LEAVE_NIDS events will be 0 in case of failure.
|
||||||
|
* in iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event
|
||||||
|
* it will be -1 if EventSpecificData == 0 otherwise it will be 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ITT_EXTERN_C int JITAPI
|
||||||
|
iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
|
||||||
|
{
|
||||||
|
int ReturnValue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This section is for debugging outside of VTune.
|
||||||
|
* It creates the environment variables that indicates call graph mode.
|
||||||
|
* If running outside of VTune remove the remark.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* static int firstTime = 1;
|
||||||
|
* char DoCallGraph[12] = "DoCallGraph";
|
||||||
|
* if (firstTime)
|
||||||
|
* {
|
||||||
|
* firstTime = 0;
|
||||||
|
* SetEnvironmentVariable( "BISTRO_COLLECTORS_DO_CALLGRAPH", DoCallGraph);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* end of section.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* initialization part - the functions have not been loaded yet. This part
|
||||||
|
* will load the functions, and check if we are in Call Graph mode.
|
||||||
|
* (for special treatment).
|
||||||
|
*/
|
||||||
|
if (!FUNC_NotifyEvent)
|
||||||
|
{
|
||||||
|
if (iJIT_DLL_is_missing)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* load the Function from the DLL */
|
||||||
|
if (!loadiJIT_Funcs())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Call Graph initialization. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the event is method entry/exit, check that in the current mode
|
||||||
|
* VTune is allowed to receive it
|
||||||
|
*/
|
||||||
|
if ((event_type == iJVM_EVENT_TYPE_ENTER_NIDS ||
|
||||||
|
event_type == iJVM_EVENT_TYPE_LEAVE_NIDS) &&
|
||||||
|
(executionMode != iJIT_CALLGRAPH_ON))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* This section is performed when method enter event occurs.
|
||||||
|
* It updates the virtual stack, or creates it if this is the first
|
||||||
|
* method entry in the thread. The stack pointer is decreased.
|
||||||
|
*/
|
||||||
|
if (event_type == iJVM_EVENT_TYPE_ENTER_NIDS)
|
||||||
|
{
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
pThreadStack threadStack =
|
||||||
|
(pThreadStack)TlsGetValue (threadLocalStorageHandle);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
pThreadStack threadStack =
|
||||||
|
(pThreadStack)pthread_getspecific(threadLocalStorageHandle);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
/* check for use of reserved method IDs */
|
||||||
|
if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!threadStack)
|
||||||
|
{
|
||||||
|
/* initialize the stack. */
|
||||||
|
threadStack = (pThreadStack) calloc (sizeof(ThreadStack), 1);
|
||||||
|
if (!threadStack)
|
||||||
|
return 0;
|
||||||
|
threadStack->TopStack = INIT_TOP_Stack;
|
||||||
|
threadStack->CurrentStack = INIT_TOP_Stack;
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
TlsSetValue(threadLocalStorageHandle,(void*)threadStack);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
pthread_setspecific(threadLocalStorageHandle,(void*)threadStack);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* decrease the stack. */
|
||||||
|
((piJIT_Method_NIDS) EventSpecificData)->stack_id =
|
||||||
|
(threadStack->CurrentStack)--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This section is performed when method leave event occurs
|
||||||
|
* It updates the virtual stack.
|
||||||
|
* Increases the stack pointer.
|
||||||
|
* If the stack pointer reached the top (left the global function)
|
||||||
|
* increase the pointer and the top pointer.
|
||||||
|
*/
|
||||||
|
if (event_type == iJVM_EVENT_TYPE_LEAVE_NIDS)
|
||||||
|
{
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
pThreadStack threadStack =
|
||||||
|
(pThreadStack)TlsGetValue (threadLocalStorageHandle);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
pThreadStack threadStack =
|
||||||
|
(pThreadStack)pthread_getspecific(threadLocalStorageHandle);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
/* check for use of reserved method IDs */
|
||||||
|
if ( ((piJIT_Method_NIDS) EventSpecificData)->method_id <= 999 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!threadStack)
|
||||||
|
{
|
||||||
|
/* Error: first report in this thread is method exit */
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
((piJIT_Method_NIDS) EventSpecificData)->stack_id =
|
||||||
|
++(threadStack->CurrentStack) + 1;
|
||||||
|
|
||||||
|
if (((piJIT_Method_NIDS) EventSpecificData)->stack_id
|
||||||
|
> threadStack->TopStack)
|
||||||
|
((piJIT_Method_NIDS) EventSpecificData)->stack_id =
|
||||||
|
(unsigned int)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED)
|
||||||
|
{
|
||||||
|
/* check for use of reserved method IDs */
|
||||||
|
if ( ((piJIT_Method_Load) EventSpecificData)->method_id <= 999 )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
|
||||||
|
{
|
||||||
|
/* check for use of reserved method IDs */
|
||||||
|
if ( ((piJIT_Method_Load_V2) EventSpecificData)->method_id <= 999 )
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
|
||||||
|
|
||||||
|
return ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The new mode call back routine */
|
||||||
|
ITT_EXTERN_C void JITAPI
|
||||||
|
iJIT_RegisterCallbackEx(void *userdata, iJIT_ModeChangedEx
|
||||||
|
NewModeCallBackFuncEx)
|
||||||
|
{
|
||||||
|
/* is it already missing... or the load of functions from the DLL failed */
|
||||||
|
if (iJIT_DLL_is_missing || !loadiJIT_Funcs())
|
||||||
|
{
|
||||||
|
/* then do not bother with notifications */
|
||||||
|
NewModeCallBackFuncEx(userdata, iJIT_NO_NOTIFICATIONS);
|
||||||
|
/* Error: could not load JIT functions. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* nothing to do with the callback */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function allows the user to query in which mode, if at all,
|
||||||
|
*VTune is running
|
||||||
|
*/
|
||||||
|
ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
|
||||||
|
{
|
||||||
|
if (!iJIT_DLL_is_missing)
|
||||||
|
{
|
||||||
|
loadiJIT_Funcs();
|
||||||
|
}
|
||||||
|
|
||||||
|
return executionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this function loads the collector dll (BistroJavaCollector)
|
||||||
|
* and the relevant functions.
|
||||||
|
* on success: all functions load, iJIT_DLL_is_missing = 0, return value = 1
|
||||||
|
* on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
|
||||||
|
*/
|
||||||
|
static int loadiJIT_Funcs()
|
||||||
|
{
|
||||||
|
static int bDllWasLoaded = 0;
|
||||||
|
char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
DWORD dNameLength = 0;
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
if(bDllWasLoaded)
|
||||||
|
{
|
||||||
|
/* dll was already loaded, no need to do it for the second time */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assumes that the DLL will not be found */
|
||||||
|
iJIT_DLL_is_missing = 1;
|
||||||
|
FUNC_NotifyEvent = NULL;
|
||||||
|
|
||||||
|
if (m_libHandle)
|
||||||
|
{
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
FreeLibrary(m_libHandle);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
dlclose(m_libHandle);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
m_libHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to get the dll name from the environment */
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
|
||||||
|
if (dNameLength)
|
||||||
|
{
|
||||||
|
DWORD envret = 0;
|
||||||
|
dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
|
||||||
|
envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
|
||||||
|
dllName, dNameLength);
|
||||||
|
if (envret)
|
||||||
|
{
|
||||||
|
/* Try to load the dll from the PATH... */
|
||||||
|
m_libHandle = LoadLibraryExA(dllName,
|
||||||
|
NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
|
}
|
||||||
|
free(dllName);
|
||||||
|
} else {
|
||||||
|
/* Try to use old VS_PROFILER variable */
|
||||||
|
dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
|
||||||
|
if (dNameLength)
|
||||||
|
{
|
||||||
|
DWORD envret = 0;
|
||||||
|
dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
|
||||||
|
envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
|
||||||
|
dllName, dNameLength);
|
||||||
|
if (envret)
|
||||||
|
{
|
||||||
|
/* Try to load the dll from the PATH... */
|
||||||
|
m_libHandle = LoadLibraryA(dllName);
|
||||||
|
}
|
||||||
|
free(dllName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
|
||||||
|
if (!dllName)
|
||||||
|
dllName = getenv(DLL_ENVIRONMENT_VAR);
|
||||||
|
#ifdef ANDROID
|
||||||
|
if (!dllName)
|
||||||
|
dllName = ANDROID_JIT_AGENT_PATH;
|
||||||
|
#endif
|
||||||
|
if (dllName)
|
||||||
|
{
|
||||||
|
/* Try to load the dll from the PATH... */
|
||||||
|
m_libHandle = dlopen(dllName, RTLD_LAZY);
|
||||||
|
}
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
|
||||||
|
if (!m_libHandle)
|
||||||
|
{
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the dll wasn't loaded - exit. */
|
||||||
|
if (!m_libHandle)
|
||||||
|
{
|
||||||
|
iJIT_DLL_is_missing = 1; /* don't try to initialize
|
||||||
|
* JIT agent the second time
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
if (!FUNC_NotifyEvent)
|
||||||
|
{
|
||||||
|
FUNC_Initialize = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
if (!FUNC_Initialize)
|
||||||
|
{
|
||||||
|
FUNC_NotifyEvent = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
|
||||||
|
|
||||||
|
bDllWasLoaded = 1;
|
||||||
|
iJIT_DLL_is_missing = 0; /* DLL is ok. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call Graph mode: init the thread local storage
|
||||||
|
* (need to store the virtual stack there).
|
||||||
|
*/
|
||||||
|
if ( executionMode == iJIT_CALLGRAPH_ON )
|
||||||
|
{
|
||||||
|
/* Allocate a thread local storage slot for the thread "stack" */
|
||||||
|
if (!threadLocalStorageHandle)
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
threadLocalStorageHandle = TlsAlloc();
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
pthread_key_create(&threadLocalStorageHandle, NULL);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function should be called by the user whenever a thread ends,
|
||||||
|
* to free the thread "virtual stack" storage
|
||||||
|
*/
|
||||||
|
ITT_EXTERN_C void JITAPI FinalizeThread()
|
||||||
|
{
|
||||||
|
if (threadLocalStorageHandle)
|
||||||
|
{
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
pThreadStack threadStack =
|
||||||
|
(pThreadStack)TlsGetValue (threadLocalStorageHandle);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
pThreadStack threadStack =
|
||||||
|
(pThreadStack)pthread_getspecific(threadLocalStorageHandle);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
if (threadStack)
|
||||||
|
{
|
||||||
|
free (threadStack);
|
||||||
|
threadStack = NULL;
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
TlsSetValue (threadLocalStorageHandle, threadStack);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
pthread_setspecific(threadLocalStorageHandle, threadStack);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function should be called by the user when the process ends,
|
||||||
|
* to free the local storage index
|
||||||
|
*/
|
||||||
|
ITT_EXTERN_C void JITAPI FinalizeProcess()
|
||||||
|
{
|
||||||
|
if (m_libHandle)
|
||||||
|
{
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
FreeLibrary(m_libHandle);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
dlclose(m_libHandle);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
m_libHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threadLocalStorageHandle)
|
||||||
|
#if ITT_PLATFORM==ITT_PLATFORM_WIN
|
||||||
|
TlsFree (threadLocalStorageHandle);
|
||||||
|
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
pthread_key_delete(threadLocalStorageHandle);
|
||||||
|
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function should be called by the user for any method once.
|
||||||
|
* The function will return a unique method ID, the user should maintain
|
||||||
|
* the ID for each method
|
||||||
|
*/
|
||||||
|
ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
|
||||||
|
{
|
||||||
|
static unsigned int methodID = 0x100000;
|
||||||
|
|
||||||
|
if (methodID == 0)
|
||||||
|
return 0; /* ERROR : this is not a valid value */
|
||||||
|
|
||||||
|
return methodID++;
|
||||||
|
}
|
|
@ -0,0 +1,610 @@
|
||||||
|
/*
|
||||||
|
This file is provided under a dual BSD/GPLv2 license. When using or
|
||||||
|
redistributing this file, you may do so under either license.
|
||||||
|
|
||||||
|
GPL LICENSE SUMMARY
|
||||||
|
|
||||||
|
Copyright (c) 2005-2013 Intel Corporation. All rights reserved.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of version 2 of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
The full GNU General Public License is included in this distribution
|
||||||
|
in the file called LICENSE.GPL.
|
||||||
|
|
||||||
|
Contact Information:
|
||||||
|
http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
|
||||||
|
|
||||||
|
BSD LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2005-2013 Intel Corporation. All rights reserved.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Intel Corporation nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __JITPROFILING_H__
|
||||||
|
#define __JITPROFILING_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief JIT Profiling APIs
|
||||||
|
*
|
||||||
|
* The JIT Profiling API is used to report information about just-in-time
|
||||||
|
* generated code that can be used by performance tools. The user inserts
|
||||||
|
* calls in the code generator to report information before JIT-compiled
|
||||||
|
* code goes to execution. This information is collected at runtime and used
|
||||||
|
* by tools like Intel(R) VTune(TM) Amplifier to display performance metrics
|
||||||
|
* associated with JIT-compiled code.
|
||||||
|
*
|
||||||
|
* These APIs can be used to\n
|
||||||
|
* **Profile trace-based and method-based JIT-compiled
|
||||||
|
* code**. Some examples of environments that you can profile with this APIs:
|
||||||
|
* dynamic JIT compilation of JavaScript code traces, OpenCL JIT execution,
|
||||||
|
* Java/.NET managed execution environments, and custom ISV JIT engines.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* #include <jitprofiling.h>
|
||||||
|
*
|
||||||
|
* if (iJIT_IsProfilingActive != iJIT_SAMPLING_ON) {
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* iJIT_Method_Load jmethod = {0};
|
||||||
|
* jmethod.method_id = iJIT_GetNewMethodID();
|
||||||
|
* jmethod.method_name = "method_name";
|
||||||
|
* jmethod.class_file_name = "class_name";
|
||||||
|
* jmethod.source_file_name = "source_file_name";
|
||||||
|
* jmethod.method_load_address = code_addr;
|
||||||
|
* jmethod.method_size = code_size;
|
||||||
|
*
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_SHUTDOWN, NULL);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* * Expected behaviour:
|
||||||
|
* * If any iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event overwrites
|
||||||
|
* already reported method, then such a method becomes invalid and its
|
||||||
|
* memory region is treated as unloaded. VTune Amplifier displays the metrics
|
||||||
|
* collected by the method until it is overwritten.
|
||||||
|
* * If supplied line number information contains multiple source lines for
|
||||||
|
* the same assembly instruction (code location), then VTune Amplifier picks up
|
||||||
|
* the first line number.
|
||||||
|
* * Dynamically generated code can be associated with a module name.
|
||||||
|
* Use the iJIT_Method_Load_V2 structure.\n
|
||||||
|
* Clarification of some cases:\n
|
||||||
|
* * If you register a function with the same method ID multiple times
|
||||||
|
* specifying different module names, then the VTune Amplifier picks up
|
||||||
|
* the module name registered first. If you want to distinguish the same
|
||||||
|
* function between different JIT engines, supply different method IDs for
|
||||||
|
* each function. Other symbolic information (for example, source file)
|
||||||
|
* can be identical.
|
||||||
|
*
|
||||||
|
* **Analyze split functions** (multiple joint or disjoint code regions
|
||||||
|
* belonging to the same function) **including re-JIT**
|
||||||
|
* with potential overlapping of code regions in time, which is common in
|
||||||
|
* resource-limited environments.
|
||||||
|
* @code
|
||||||
|
* #include <jitprofiling.h>
|
||||||
|
*
|
||||||
|
* unsigned int method_id = iJIT_GetNewMethodID();
|
||||||
|
*
|
||||||
|
* iJIT_Method_Load a = {0};
|
||||||
|
* a.method_id = method_id;
|
||||||
|
* a.method_load_address = acode_addr;
|
||||||
|
* a.method_size = acode_size;
|
||||||
|
*
|
||||||
|
* iJIT_Method_Load b = {0};
|
||||||
|
* b.method_id = method_id;
|
||||||
|
* b.method_load_address = baddr_second;
|
||||||
|
* b.method_size = bsize_second;
|
||||||
|
*
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a);
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&b);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* * Expected behaviour:
|
||||||
|
* * If a iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event overwrites
|
||||||
|
* already reported method, then such a method becomes invalid and
|
||||||
|
* its memory region is treated as unloaded.
|
||||||
|
* * All code regions reported with the same method ID are considered as
|
||||||
|
* belonging to the same method. Symbolic information (method name,
|
||||||
|
* source file name) will be taken from the first notification, all
|
||||||
|
* subsequent notifications with the same method ID will be processed
|
||||||
|
* only for line number table information. So, the VTune Amplifier will map
|
||||||
|
* samples to a source line using the line number table from the current
|
||||||
|
* notification while taking source file name from the very first one.\n
|
||||||
|
* Clarification of some cases:\n
|
||||||
|
* * If you register a second code region with a different source file
|
||||||
|
* name and the same method ID, then this information will be saved and
|
||||||
|
* will not be considered as an extension of the first code region, but
|
||||||
|
* VTune Amplifier will use source file of the first code region and map
|
||||||
|
* performance metrics incorrectly.
|
||||||
|
* * If you register a second code region with the same source file as
|
||||||
|
* for the first region and the same method ID, then source file will be
|
||||||
|
* discarded but VTune Amplifier will map metrics to the source file correctly.
|
||||||
|
* * If you register a second code region with a null source file and
|
||||||
|
* the same method ID, then provided line number info will be associated
|
||||||
|
* with the source file of the first code region.
|
||||||
|
*
|
||||||
|
* **Explore inline functions** including multi-level hierarchy of
|
||||||
|
* nested inlines to see how performance metrics are distributed through them.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* #include <jitprofiling.h>
|
||||||
|
*
|
||||||
|
* // method_id parent_id
|
||||||
|
* // [-- c --] 3000 2000
|
||||||
|
* // [---- d -----] 2001 1000
|
||||||
|
* // [---- b ----] 2000 1000
|
||||||
|
* // [------------ a ----------------] 1000 n/a
|
||||||
|
*
|
||||||
|
* iJIT_Method_Load a = {0};
|
||||||
|
* a.method_id = 1000;
|
||||||
|
*
|
||||||
|
* iJIT_Method_Inline_Load b = {0};
|
||||||
|
* b.method_id = 2000;
|
||||||
|
* b.parent_method_id = 1000;
|
||||||
|
*
|
||||||
|
* iJIT_Method_Inline_Load c = {0};
|
||||||
|
* c.method_id = 3000;
|
||||||
|
* c.parent_method_id = 2000;
|
||||||
|
*
|
||||||
|
* iJIT_Method_Inline_Load d = {0};
|
||||||
|
* d.method_id = 2001;
|
||||||
|
* d.parent_method_id = 1000;
|
||||||
|
*
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a);
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&b);
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&c);
|
||||||
|
* iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&d);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* * Requirements:
|
||||||
|
* * Each inline (iJIT_Method_Inline_Load) method should be associated
|
||||||
|
* with two method IDs: one for itself, one for its immediate parent.
|
||||||
|
* * Address regions of inline methods of the same parent method cannot
|
||||||
|
* overlap each other.
|
||||||
|
* * Execution of the parent method must not be started until it and all
|
||||||
|
* its inlines are reported.
|
||||||
|
* * Expected behaviour:
|
||||||
|
* * In case of nested inlines an order of
|
||||||
|
* iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED events is not important.
|
||||||
|
* * If any event overwrites either inline method or top parent method,
|
||||||
|
* then the parent including inlines becomes invalid and its memory
|
||||||
|
* region is treated as unloaded.
|
||||||
|
*
|
||||||
|
* **Life time of allocated data**\n
|
||||||
|
* The client sends an event notification to the agent with event-specific
|
||||||
|
* data, which is a structure. The pointers in the structure refers to memory
|
||||||
|
* allocated by the client, which responsible for releasing it. The pointers are
|
||||||
|
* used by the iJIT_NotifyEvent method to copy client's data in a trace file
|
||||||
|
* and they are not used after the iJIT_NotifyEvent method returns.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup jitapi JIT Profiling
|
||||||
|
* @ingroup internal
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum iJIT_jvm_event
|
||||||
|
* @brief Enumerator for the types of notifications
|
||||||
|
*/
|
||||||
|
typedef enum iJIT_jvm_event
|
||||||
|
{
|
||||||
|
iJVM_EVENT_TYPE_SHUTDOWN = 2, /**< Send to shutdown the agent.
|
||||||
|
* Use NULL for event data. */
|
||||||
|
|
||||||
|
iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED = 13, /**< Send when a dynamic code is
|
||||||
|
* JIT compiled and loaded into
|
||||||
|
* memory by the JIT engine but
|
||||||
|
* before the code is executed.
|
||||||
|
* Use iJIT_Method_Load as event
|
||||||
|
* data. */
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
iJVM_EVENT_TYPE_METHOD_UNLOAD_START, /**< Send when a compiled dynamic
|
||||||
|
* code is being unloaded from memory.
|
||||||
|
* Use iJIT_Method_Load as event data.*/
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
//TODO: add a note that line info assumes from method load
|
||||||
|
iJVM_EVENT_TYPE_METHOD_UPDATE, /**< Send to provide a new content for
|
||||||
|
* an early reported dynamic code.
|
||||||
|
* The previous content will be invalidate
|
||||||
|
* starting from time of the notification.
|
||||||
|
* Use iJIT_Method_Load as event data but
|
||||||
|
* required fields are following:
|
||||||
|
* - method_id identify the code to update.
|
||||||
|
* - method_load_address specify start address
|
||||||
|
* within identified code range
|
||||||
|
* where update should be started.
|
||||||
|
* - method_size specify length of updated code
|
||||||
|
* range. */
|
||||||
|
|
||||||
|
iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, /**< Send when an inline dynamic
|
||||||
|
* code is JIT compiled and loaded
|
||||||
|
* into memory by the JIT engine
|
||||||
|
* but before the parent code region
|
||||||
|
* is started executing.
|
||||||
|
* Use iJIT_Method_Inline_Load as event data.*/
|
||||||
|
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
/* Legacy stuff. Do not use it. */
|
||||||
|
iJVM_EVENT_TYPE_ENTER_NIDS = 19,
|
||||||
|
iJVM_EVENT_TYPE_LEAVE_NIDS,
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2 /**< Send when a dynamic code is
|
||||||
|
* JIT compiled and loaded into
|
||||||
|
* memory by the JIT engine but
|
||||||
|
* before the code is executed.
|
||||||
|
* Use iJIT_Method_Load_V2 as event
|
||||||
|
* data. */
|
||||||
|
} iJIT_JVM_EVENT;
|
||||||
|
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
/* Legacy stuff. Do not use it. */
|
||||||
|
typedef enum _iJIT_ModeFlags
|
||||||
|
{
|
||||||
|
iJIT_NO_NOTIFICATIONS = 0x0000,
|
||||||
|
iJIT_BE_NOTIFY_ON_LOAD = 0x0001,
|
||||||
|
iJIT_BE_NOTIFY_ON_UNLOAD = 0x0002,
|
||||||
|
iJIT_BE_NOTIFY_ON_METHOD_ENTRY = 0x0004,
|
||||||
|
iJIT_BE_NOTIFY_ON_METHOD_EXIT = 0x0008
|
||||||
|
|
||||||
|
} iJIT_ModeFlags;
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum _iJIT_IsProfilingActiveFlags
|
||||||
|
* @brief Enumerator for the agent's mode
|
||||||
|
*/
|
||||||
|
typedef enum _iJIT_IsProfilingActiveFlags
|
||||||
|
{
|
||||||
|
iJIT_NOTHING_RUNNING = 0x0000, /**< The agent is not running.
|
||||||
|
* iJIT_NotifyEvent calls will
|
||||||
|
* not be processed. */
|
||||||
|
iJIT_SAMPLING_ON = 0x0001, /**< The agent is running and
|
||||||
|
* ready to process notifications. */
|
||||||
|
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
/* Legacy. Call Graph is running */
|
||||||
|
iJIT_CALLGRAPH_ON = 0x0002
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
} iJIT_IsProfilingActiveFlags;
|
||||||
|
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
/* Legacy stuff. Do not use it. */
|
||||||
|
typedef enum _iJDEnvironmentType
|
||||||
|
{
|
||||||
|
iJDE_JittingAPI = 2
|
||||||
|
|
||||||
|
} iJDEnvironmentType;
|
||||||
|
|
||||||
|
typedef struct _iJIT_Method_Id
|
||||||
|
{
|
||||||
|
unsigned int method_id;
|
||||||
|
|
||||||
|
} *piJIT_Method_Id, iJIT_Method_Id;
|
||||||
|
|
||||||
|
typedef struct _iJIT_Method_NIDS
|
||||||
|
{
|
||||||
|
unsigned int method_id; /**< Unique method ID */
|
||||||
|
unsigned int stack_id; /**< NOTE: no need to fill this field,
|
||||||
|
* it's filled by VTune Amplifier */
|
||||||
|
char* method_name; /**< Method name (just the method, without the class) */
|
||||||
|
|
||||||
|
} *piJIT_Method_NIDS, iJIT_Method_NIDS;
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
typedef enum _iJIT_CodeType
|
||||||
|
{
|
||||||
|
iJIT_CT_UNKNOWN = 0,
|
||||||
|
iJIT_CT_CODE, // executable code
|
||||||
|
iJIT_CT_DATA, // this kind of “update” will be excluded from the function’s body.
|
||||||
|
iJIT_CT_EOF
|
||||||
|
} iJIT_CodeType;
|
||||||
|
|
||||||
|
typedef struct _iJIT_Method_Update
|
||||||
|
{
|
||||||
|
unsigned int method_id;
|
||||||
|
void* load_address;
|
||||||
|
unsigned int size;
|
||||||
|
iJIT_CodeType type;
|
||||||
|
|
||||||
|
} *piJIT_Method_Update, iJIT_Method_Update;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @details Describes a single entry in the line number information of
|
||||||
|
* a code region that gives information about how the reported code region
|
||||||
|
* is mapped to source file.
|
||||||
|
* Intel(R) VTune(TM) Amplifier uses line number information to attribute
|
||||||
|
* the samples (virtual address) to a line number. \n
|
||||||
|
* It is acceptable to report different code addresses for the same source line:
|
||||||
|
* @code
|
||||||
|
* Offset LineNumber
|
||||||
|
* 1 2
|
||||||
|
* 12 4
|
||||||
|
* 15 2
|
||||||
|
* 18 1
|
||||||
|
* 21 30
|
||||||
|
*
|
||||||
|
* VTune(TM) Amplifier XE contsructs the following table using the client data
|
||||||
|
*
|
||||||
|
* Code subrange Line number
|
||||||
|
* 0-1 2
|
||||||
|
* 1-12 4
|
||||||
|
* 12-15 2
|
||||||
|
* 15-18 1
|
||||||
|
* 18-21 30
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
typedef struct _LineNumberInfo
|
||||||
|
{
|
||||||
|
unsigned int Offset; /**< Offset from the begining of the code region. */
|
||||||
|
unsigned int LineNumber; /**< Matching source line number offset (from beginning of source file). */
|
||||||
|
|
||||||
|
} *pLineNumberInfo, LineNumberInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of a JIT-compiled method
|
||||||
|
*/
|
||||||
|
typedef struct _iJIT_Method_Load
|
||||||
|
{
|
||||||
|
unsigned int method_id; /**< Unique method ID.
|
||||||
|
* Method ID cannot be smaller than 999.
|
||||||
|
* Either you use the API function
|
||||||
|
* iJIT_GetNewMethodID to get a valid and unique
|
||||||
|
* method ID, or you take care of ID uniqueness
|
||||||
|
* and correct range by yourself.\n
|
||||||
|
* You must use the same method ID for all code
|
||||||
|
* regions of the same method, otherwise different
|
||||||
|
* method IDs mean different methods. */
|
||||||
|
|
||||||
|
char* method_name; /** The name of the method. It can be optionally
|
||||||
|
* prefixed with its class name and appended with
|
||||||
|
* its complete signature. Can't be NULL. */
|
||||||
|
|
||||||
|
void* method_load_address; /** The start virtual address of the method code
|
||||||
|
* region. If NULL that data provided with
|
||||||
|
* event are not accepted. */
|
||||||
|
|
||||||
|
unsigned int method_size; /** The code size of the method in memory.
|
||||||
|
* If 0, then data provided with the event are not
|
||||||
|
* accepted. */
|
||||||
|
|
||||||
|
unsigned int line_number_size; /** The number of entries in the line number
|
||||||
|
* table.0 if none. */
|
||||||
|
|
||||||
|
pLineNumberInfo line_number_table; /** Pointer to the line numbers info
|
||||||
|
* array. Can be NULL if
|
||||||
|
* line_number_size is 0. See
|
||||||
|
* LineNumberInfo Structure for a
|
||||||
|
* description of a single entry in
|
||||||
|
* the line number info array */
|
||||||
|
|
||||||
|
unsigned int class_id; /** This field is obsolete. */
|
||||||
|
|
||||||
|
char* class_file_name; /** Class name. Can be NULL.*/
|
||||||
|
|
||||||
|
char* source_file_name; /** Source file name. Can be NULL.*/
|
||||||
|
|
||||||
|
void* user_data; /** This field is obsolete. */
|
||||||
|
|
||||||
|
unsigned int user_data_size; /** This field is obsolete. */
|
||||||
|
|
||||||
|
iJDEnvironmentType env; /** This field is obsolete. */
|
||||||
|
|
||||||
|
} *piJIT_Method_Load, iJIT_Method_Load;
|
||||||
|
|
||||||
|
#pragma pack(push, 8)
|
||||||
|
/**
|
||||||
|
* Description of a JIT-compiled method
|
||||||
|
*
|
||||||
|
* When you use the iJIT_Method_Load_V2 structure to describe
|
||||||
|
* the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2
|
||||||
|
* as an event type to report it.
|
||||||
|
*/
|
||||||
|
typedef struct _iJIT_Method_Load_V2
|
||||||
|
{
|
||||||
|
unsigned int method_id; /**< Unique method ID.
|
||||||
|
* Method ID cannot be smaller than 999.
|
||||||
|
* Either you use the API function
|
||||||
|
* iJIT_GetNewMethodID to get a valid and unique
|
||||||
|
* method ID, or you take care of ID uniqueness
|
||||||
|
* and correct range by yourself.\n
|
||||||
|
* You must use the same method ID for all code
|
||||||
|
* regions of the same method, otherwise different
|
||||||
|
* method IDs mean different methods. */
|
||||||
|
|
||||||
|
char* method_name; /** The name of the method. It can be optionally
|
||||||
|
* prefixed with its class name and appended with
|
||||||
|
* its complete signature. Can't be NULL. */
|
||||||
|
|
||||||
|
void* method_load_address; /** The start virtual address of the method code
|
||||||
|
* region. If NULL that data provided with
|
||||||
|
* event are not accepted. */
|
||||||
|
|
||||||
|
unsigned int method_size; /** The code size of the method in memory.
|
||||||
|
* If 0, then data provided with the event are not
|
||||||
|
* accepted. */
|
||||||
|
|
||||||
|
unsigned int line_number_size; /** The number of entries in the line number
|
||||||
|
* table.0 if none. */
|
||||||
|
|
||||||
|
pLineNumberInfo line_number_table; /** Pointer to the line numbers info
|
||||||
|
* array. Can be NULL if
|
||||||
|
* line_number_size is 0. See
|
||||||
|
* LineNumberInfo Structure for a
|
||||||
|
* description of a single entry in
|
||||||
|
* the line number info array */
|
||||||
|
|
||||||
|
char* class_file_name; /** Class name. Can be NULL.*/
|
||||||
|
|
||||||
|
char* source_file_name; /** Source file name. Can be NULL.*/
|
||||||
|
|
||||||
|
char* module_name; /** Module name. Can be NULL.
|
||||||
|
The module name can be useful for distinguishing among
|
||||||
|
different JIT engines. Intel VTune Amplifier will display
|
||||||
|
reported methods split by specified modules */
|
||||||
|
|
||||||
|
} *piJIT_Method_Load_V2, iJIT_Method_Load_V2;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of an inline JIT-compiled method
|
||||||
|
*/
|
||||||
|
typedef struct _iJIT_Method_Inline_Load
|
||||||
|
{
|
||||||
|
unsigned int method_id; /**< Unique method ID.
|
||||||
|
* Method ID cannot be smaller than 999.
|
||||||
|
* Either you use the API function
|
||||||
|
* iJIT_GetNewMethodID to get a valid and unique
|
||||||
|
* method ID, or you take care of ID uniqueness
|
||||||
|
* and correct range by yourself. */
|
||||||
|
|
||||||
|
unsigned int parent_method_id; /** Unique immediate parent's method ID.
|
||||||
|
* Method ID may not be smaller than 999.
|
||||||
|
* Either you use the API function
|
||||||
|
* iJIT_GetNewMethodID to get a valid and unique
|
||||||
|
* method ID, or you take care of ID uniqueness
|
||||||
|
* and correct range by yourself. */
|
||||||
|
|
||||||
|
char* method_name; /** The name of the method. It can be optionally
|
||||||
|
* prefixed with its class name and appended with
|
||||||
|
* its complete signature. Can't be NULL. */
|
||||||
|
|
||||||
|
void* method_load_address; /** The virtual address on which the method
|
||||||
|
* is inlined. If NULL, then data provided with
|
||||||
|
* the event are not accepted. */
|
||||||
|
|
||||||
|
unsigned int method_size; /** The code size of the method in memory.
|
||||||
|
* If 0 that data provided with event are not
|
||||||
|
* accepted. */
|
||||||
|
|
||||||
|
unsigned int line_number_size; /** The number of entries in the line number
|
||||||
|
* table. 0 if none. */
|
||||||
|
|
||||||
|
pLineNumberInfo line_number_table; /** Pointer to the line numbers info
|
||||||
|
* array. Can be NULL if
|
||||||
|
* line_number_size is 0. See
|
||||||
|
* LineNumberInfo Structure for a
|
||||||
|
* description of a single entry in
|
||||||
|
* the line number info array */
|
||||||
|
|
||||||
|
char* class_file_name; /** Class name. Can be NULL.*/
|
||||||
|
|
||||||
|
char* source_file_name; /** Source file name. Can be NULL.*/
|
||||||
|
|
||||||
|
} *piJIT_Method_Inline_Load, iJIT_Method_Inline_Load;
|
||||||
|
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#ifndef CDECL
|
||||||
|
# if defined WIN32 || defined _WIN32
|
||||||
|
# define CDECL __cdecl
|
||||||
|
# else /* defined WIN32 || defined _WIN32 */
|
||||||
|
# if defined _M_X64 || defined _M_AMD64 || defined __x86_64__
|
||||||
|
# define CDECL /* not actual on x86_64 platform */
|
||||||
|
# else /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||||
|
# define CDECL __attribute__ ((cdecl))
|
||||||
|
# endif /* _M_X64 || _M_AMD64 || __x86_64__ */
|
||||||
|
# endif /* defined WIN32 || defined _WIN32 */
|
||||||
|
#endif /* CDECL */
|
||||||
|
|
||||||
|
#define JITAPI CDECL
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates a new unique method ID.
|
||||||
|
*
|
||||||
|
* You must use this API to obtain unique and valid method IDs for methods or
|
||||||
|
* traces reported to the agent if you don't have you own mechanism to generate
|
||||||
|
* unique method IDs.
|
||||||
|
*
|
||||||
|
* @return a new unique method ID. When out of unique method IDs, this API
|
||||||
|
* returns 0, which is not an accepted value.
|
||||||
|
*/
|
||||||
|
unsigned int JITAPI iJIT_GetNewMethodID(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the current mode of the agent.
|
||||||
|
*
|
||||||
|
* @return iJIT_SAMPLING_ON, indicating that agent is running, or
|
||||||
|
* iJIT_NOTHING_RUNNING if no agent is running.
|
||||||
|
*/
|
||||||
|
iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reports infomation about JIT-compiled code to the agent.
|
||||||
|
*
|
||||||
|
* The reported information is used to attribute samples obtained from any
|
||||||
|
* Intel(R) VTune(TM) Amplifier collector. This API needs to be called
|
||||||
|
* after JIT compilation and before the first entry into the JIT compiled
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* @param[in] event_type - type of the data sent to the agent
|
||||||
|
* @param[in] EventSpecificData - pointer to event-specific data
|
||||||
|
*
|
||||||
|
* @returns 1 on success, otherwise 0.
|
||||||
|
*/
|
||||||
|
int JITAPI iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData);
|
||||||
|
|
||||||
|
/** @cond exclude_from_documentation */
|
||||||
|
/*
|
||||||
|
* Do not use these legacy APIs, which are here for backward compatibility
|
||||||
|
* with Intel(R) VTune(TM) Performance Analyzer.
|
||||||
|
*/
|
||||||
|
typedef void (*iJIT_ModeChangedEx)(void *UserData, iJIT_ModeFlags Flags);
|
||||||
|
void JITAPI iJIT_RegisterCallbackEx(void *userdata,
|
||||||
|
iJIT_ModeChangedEx NewModeCallBackFuncEx);
|
||||||
|
void JITAPI FinalizeThread(void);
|
||||||
|
void JITAPI FinalizeProcess(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
/** @} jitapi group */
|
||||||
|
|
||||||
|
#endif /* __JITPROFILING_H__ */
|
Загрузка…
Ссылка в новой задаче