Removing dependency on third party library for Intel JIT event support.

Patch committed on behalf of Kirill Uhanov

llvm-svn: 164831
This commit is contained in:
Andrew Kaylor 2012-09-28 17:35:20 +00:00
parent bfbf4015c4
commit 6b7788b0c5
15 changed files with 1285 additions and 376 deletions

View File

@ -177,23 +177,7 @@ option(LLVM_USE_INTEL_JITEVENTS
if( LLVM_USE_INTEL_JITEVENTS )
# Verify we are on a supported platform
if( CMAKE_SYSTEM_NAME MATCHES "Windows" OR CMAKE_SYSTEM_NAME MATCHES "Linux" )
# Directory where Intel Parallel Amplifier XE 2011 is installed.
if ( WIN32 )
set(LLVM_INTEL_JITEVENTS_DIR $ENV{VTUNE_AMPLIFIER_XE_2011_DIR})
else ( WIN32 )
set(LLVM_INTEL_JITEVENTS_DIR "/opt/intel/vtune_amplifier_xe_2011")
endif ( WIN32 )
# Set include and library search paths for Intel JIT Events API
set(LLVM_INTEL_JITEVENTS_INCDIR "${LLVM_INTEL_JITEVENTS_DIR}/include")
if ( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set(LLVM_INTEL_JITEVENTS_LIBDIR "${LLVM_INTEL_JITEVENTS_DIR}/lib64")
else ( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set(LLVM_INTEL_JITEVENTS_LIBDIR "${LLVM_INTEL_JITEVENTS_DIR}/lib32")
endif ( CMAKE_SIZEOF_VOID_P EQUAL 8 )
else()
if( NOT CMAKE_SYSTEM_NAME MATCHES "Windows" AND NOT CMAKE_SYSTEM_NAME MATCHES "Linux" )
message(FATAL_ERROR
"Intel JIT API support is available on Linux and Windows only.")
endif()

View File

@ -1290,46 +1290,23 @@ AC_DEFINE_UNQUOTED([LLVM_USE_OPROFILE],$USE_OPROFILE,
dnl Enable support for Intel JIT Events API.
AC_ARG_WITH(intel-jitevents,
AS_HELP_STRING([--with-intel-jitevents=<vtune-amplifier-dir>],
[Specify location of run-time support library for Intel JIT API (default=/opt/intel/vtune_amplifier_xe_2011)]),
AS_HELP_STRING([--with-intel-jitevents Notify Intel JIT profiling API of generated code]),
[
case "$withval" in
yes) AC_SUBST(USE_INTEL_JITEVENTS,[1]);;
no) AC_SUBST(USE_INTEL_JITEVENTS,[0]);;
*) AC_MSG_ERROR([Invalid setting for --with-intel-jitevents. Use "yes" or "no"]);;
esac
case $llvm_cv_os_type in
Linux|Win32|Cygwin|MingW) ;;
*)
AC_MSG_ERROR([
Intel JIT API support is available on Linux and Windows only."]) ;;
*) AC_MSG_ERROR([Intel JIT API support is available on Linux and Windows only.]);;
esac
AC_SUBST(USE_INTEL_JITEVENTS, [1])
case "$llvm_cv_target_arch" in
x86) llvm_intel_jitevents_archdir="lib32";;
x86_64) llvm_intel_jitevents_archdir="lib64";;
*) echo "Target architecture $llvm_cv_target_arch does not support Intel JIT Events API"
exit -1;;
x86|x86_64) ;;
*) AC_MSG_ERROR([Target architecture $llvm_cv_target_arch does not support Intel JIT Events API.]);;
esac
INTEL_JITEVENTS_INCDIR="/opt/intel/vtune_amplifier_xe_2011/include"
INTEL_JITEVENTS_LIBDIR="/opt/intel/vtune_amplifier_xe_2011/$llvm_intel_jitevents_archdir"
case "$withval" in
/* | [[A-Za-z]]:[[\\/]]*) INTEL_JITEVENTS_INCDIR=$withval/include
INTEL_JITEVENTS_LIBDIR=$withval/$llvm_intel_jitevents_archdir ;;
*) ;;
esac
AC_SUBST(INTEL_JITEVENTS_INCDIR)
AC_SUBST(INTEL_JITEVENTS_LIBDIR)
LIBS="$LIBS -L${INTEL_JITEVENTS_LIBDIR}"
CPPFLAGS="$CPPFLAGS -I$INTEL_JITEVENTS_INCDIR"
AC_SEARCH_LIBS(iJIT_IsProfilingActive, jitprofiling, [], [
echo "Error! Cannot find libjitprofiling.a. Please check path specified in flag --with-intel-jitevents"
exit -1
])
AC_CHECK_HEADER([jitprofiling.h], [], [
echo "Error! Cannot find jitprofiling.h. Please check path specified in flag --with-intel-jitevents"
exit -1
])
],
[
AC_SUBST(USE_INTEL_JITEVENTS, [0])

326
configure vendored
View File

@ -766,8 +766,6 @@ COVERED_SWITCH_DEFAULT
USE_UDIS86
USE_OPROFILE
USE_INTEL_JITEVENTS
INTEL_JITEVENTS_INCDIR
INTEL_JITEVENTS_LIBDIR
XML2CONFIG
LIBXML2_LIBS
LIBXML2_INC
@ -1462,10 +1460,8 @@ Optional Packages:
--with-udis86=<path> Use udis86 external x86 disassembler library
--with-oprofile=<prefix>
Tell OProfile >= 0.9.4 how to symbolize JIT output
--with-intel-jitevents=<vtune-amplifier-dir>
Specify location of run-time support library for
Intel JIT API
(default=/opt/intel/vtune_amplifier_xe_2011)
--with-intel-jitevents Notify Intel JIT profiling API of generated code
Some influential environment variables:
CC C compiler command
@ -10316,7 +10312,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10319 "configure"
#line 10315 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -13576,307 +13572,29 @@ _ACEOF
# Check whether --with-intel-jitevents was given.
if test "${with_intel_jitevents+set}" = set; then
withval=$with_intel_jitevents;
case "$withval" in
yes) USE_INTEL_JITEVENTS=1
;;
no) USE_INTEL_JITEVENTS=0
;;
*) { { echo "$as_me:$LINENO: error: Invalid setting for --with-intel-jitevents. Use \"yes\" or \"no\"" >&5
echo "$as_me: error: Invalid setting for --with-intel-jitevents. Use \"yes\" or \"no\"" >&2;}
{ (exit 1); exit 1; }; };;
esac
case $llvm_cv_os_type in
Linux|Win32|Cygwin|MingW) ;;
*)
{ { echo "$as_me:$LINENO: error:
Intel JIT API support is available on Linux and Windows only.\"" >&5
echo "$as_me: error:
Intel JIT API support is available on Linux and Windows only.\"" >&2;}
{ (exit 1); exit 1; }; } ;;
*) { { echo "$as_me:$LINENO: error: Intel JIT API support is available on Linux and Windows only." >&5
echo "$as_me: error: Intel JIT API support is available on Linux and Windows only." >&2;}
{ (exit 1); exit 1; }; };;
esac
USE_INTEL_JITEVENTS=1
case "$llvm_cv_target_arch" in
x86) llvm_intel_jitevents_archdir="lib32";;
x86_64) llvm_intel_jitevents_archdir="lib64";;
*) echo "Target architecture $llvm_cv_target_arch does not support Intel JIT Events API"
exit -1;;
x86|x86_64) ;;
*) { { echo "$as_me:$LINENO: error: Target architecture $llvm_cv_target_arch does not support Intel JIT Events API." >&5
echo "$as_me: error: Target architecture $llvm_cv_target_arch does not support Intel JIT Events API." >&2;}
{ (exit 1); exit 1; }; };;
esac
INTEL_JITEVENTS_INCDIR="/opt/intel/vtune_amplifier_xe_2011/include"
INTEL_JITEVENTS_LIBDIR="/opt/intel/vtune_amplifier_xe_2011/$llvm_intel_jitevents_archdir"
case "$withval" in
/* | [A-Za-z]:[\\/]*) INTEL_JITEVENTS_INCDIR=$withval/include
INTEL_JITEVENTS_LIBDIR=$withval/$llvm_intel_jitevents_archdir ;;
*) ;;
esac
LIBS="$LIBS -L${INTEL_JITEVENTS_LIBDIR}"
CPPFLAGS="$CPPFLAGS -I$INTEL_JITEVENTS_INCDIR"
{ echo "$as_me:$LINENO: checking for library containing iJIT_IsProfilingActive" >&5
echo $ECHO_N "checking for library containing iJIT_IsProfilingActive... $ECHO_C" >&6; }
if test "${ac_cv_search_iJIT_IsProfilingActive+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_func_search_save_LIBS=$LIBS
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char iJIT_IsProfilingActive ();
int
main ()
{
return iJIT_IsProfilingActive ();
;
return 0;
}
_ACEOF
for ac_lib in '' jitprofiling; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_search_iJIT_IsProfilingActive=$ac_res
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if test "${ac_cv_search_iJIT_IsProfilingActive+set}" = set; then
break
fi
done
if test "${ac_cv_search_iJIT_IsProfilingActive+set}" = set; then
:
else
ac_cv_search_iJIT_IsProfilingActive=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_search_iJIT_IsProfilingActive" >&5
echo "${ECHO_T}$ac_cv_search_iJIT_IsProfilingActive" >&6; }
ac_res=$ac_cv_search_iJIT_IsProfilingActive
if test "$ac_res" != no; then
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
echo "Error! Cannot find libjitprofiling.a. Please check path specified in flag --with-intel-jitevents"
exit -1
fi
if test "${ac_cv_header_jitprofiling_h+set}" = set; then
{ echo "$as_me:$LINENO: checking for jitprofiling.h" >&5
echo $ECHO_N "checking for jitprofiling.h... $ECHO_C" >&6; }
if test "${ac_cv_header_jitprofiling_h+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
{ echo "$as_me:$LINENO: result: $ac_cv_header_jitprofiling_h" >&5
echo "${ECHO_T}$ac_cv_header_jitprofiling_h" >&6; }
else
# Is the header compilable?
{ echo "$as_me:$LINENO: checking jitprofiling.h usability" >&5
echo $ECHO_N "checking jitprofiling.h usability... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <jitprofiling.h>
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6; }
# Is the header present?
{ echo "$as_me:$LINENO: checking jitprofiling.h presence" >&5
echo $ECHO_N "checking jitprofiling.h presence... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <jitprofiling.h>
_ACEOF
if { (ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6; }
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: jitprofiling.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: jitprofiling.h: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: present but cannot be compiled" >&5
echo "$as_me: WARNING: jitprofiling.h: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: jitprofiling.h: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: see the Autoconf documentation" >&5
echo "$as_me: WARNING: jitprofiling.h: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: jitprofiling.h: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: jitprofiling.h: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: jitprofiling.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: jitprofiling.h: in the future, the compiler will take precedence" >&2;}
( cat <<\_ASBOX
## ------------------------------------ ##
## Report this to http://llvm.org/bugs/ ##
## ------------------------------------ ##
_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for jitprofiling.h" >&5
echo $ECHO_N "checking for jitprofiling.h... $ECHO_C" >&6; }
if test "${ac_cv_header_jitprofiling_h+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_header_jitprofiling_h=$ac_header_preproc
fi
{ echo "$as_me:$LINENO: result: $ac_cv_header_jitprofiling_h" >&5
echo "${ECHO_T}$ac_cv_header_jitprofiling_h" >&6; }
fi
if test $ac_cv_header_jitprofiling_h = yes; then
:
else
echo "Error! Cannot find jitprofiling.h. Please check path specified in flag --with-intel-jitevents"
exit -1
fi
else
@ -22308,8 +22026,6 @@ COVERED_SWITCH_DEFAULT!$COVERED_SWITCH_DEFAULT$ac_delim
USE_UDIS86!$USE_UDIS86$ac_delim
USE_OPROFILE!$USE_OPROFILE$ac_delim
USE_INTEL_JITEVENTS!$USE_INTEL_JITEVENTS$ac_delim
INTEL_JITEVENTS_INCDIR!$INTEL_JITEVENTS_INCDIR$ac_delim
INTEL_JITEVENTS_LIBDIR!$INTEL_JITEVENTS_LIBDIR$ac_delim
XML2CONFIG!$XML2CONFIG$ac_delim
LIBXML2_LIBS!$LIBXML2_LIBS$ac_delim
LIBXML2_INC!$LIBXML2_INC$ac_delim
@ -22338,7 +22054,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 95; then
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@ -273,11 +273,6 @@ LLVM-specific variables
**LLVM_USE_INTEL_JITEVENTS**:BOOL
Enable building support for Intel JIT Events API. Defaults to OFF
**LLVM_INTEL_JITEVENTS_DIR**:PATH
Path to installation of Intel(R) VTune(TM) Amplifier XE 2011, used to locate
the ``jitprofiling`` library. Default = ``%VTUNE_AMPLIFIER_XE_2011_DIR%``
(Windows) | ``/opt/intel/vtune_amplifier_xe_2011`` (Linux)
Executing the test suite
========================

View File

@ -1,11 +1,6 @@
include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. )
set(system_libs
${system_libs}
jitprofiling
)
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMIntelJITEvents
IntelJITEventListener.cpp
jitprofiling.c
)

View File

@ -22,12 +22,12 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/ExecutionEngine/IntelJITEventsWrapper.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/ValueHandle.h"
#include "EventListenerCommon.h"
#include "IntelJITEventsWrapper.h"
using namespace llvm;
using namespace llvm::jitprofiling;

View File

@ -18,7 +18,7 @@
#ifndef INTEL_JIT_EVENTS_WRAPPER_H
#define INTEL_JIT_EVENTS_WRAPPER_H
#include <jitprofiling.h>
#include "jitprofiling.h"
namespace llvm {

View File

@ -11,7 +11,8 @@ LIBRARYNAME = LLVMIntelJITEvents
include $(LEVEL)/Makefile.config
SOURCES := IntelJITEventListener.cpp
CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR) -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
SOURCES := IntelJITEventListener.cpp \
jitprofiling.c
CPPFLAGS += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LLVM_SRC_ROOT)/Makefile.rules

View File

@ -0,0 +1,449 @@
/*===-- ittnotify_config.h - JIT Profiling API internal config-----*- C -*-===*
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*===----------------------------------------------------------------------===*
*
* This file provides Intel(R) Performance Analyzer JIT (Just-In-Time)
* Profiling API internal config.
*
*===----------------------------------------------------------------------===*/
#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_ */

View File

@ -0,0 +1,63 @@
//===-- ittnotify_types.h - Intel(R) Performance Analyzer JIT (Just-In-Time) Profiling API internal types. ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#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_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_none, NULL } \
}
#endif /* _ITTNOTIFY_TYPES_H_ */

View File

@ -0,0 +1,476 @@
/*===-- jitprofiling.c - JIT (Just-In-Time) Profiling API----------*- C -*-===*
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*===----------------------------------------------------------------------===*
*
* This file provides Intel(R) Performance Analyzer JIT (Just-In-Time)
* Profiling API implementation.
*
*===----------------------------------------------------------------------===*/
#include "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 "jitprofiling.h"
static const char rcsid[] = "\n@(#) $Revision: 243501 $\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);
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;
}
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++;
}

View File

@ -0,0 +1,254 @@
/*===-- jitprofiling.h - JIT Profiling API-------------------------*- C -*-===*
*
* The LLVM Compiler Infrastructure
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*===----------------------------------------------------------------------===*
*
* This file provides Intel(R) Performance Analyzer JIT (Just-In-Time)
* Profiling API declaration.
*
*===----------------------------------------------------------------------===*/
#ifndef __JITPROFILING_H__
#define __JITPROFILING_H__
/*
* Various constants used by functions
*/
/* event notification */
typedef enum iJIT_jvm_event
{
/* shutdown */
/*
* Program exiting EventSpecificData NA
*/
iJVM_EVENT_TYPE_SHUTDOWN = 2,
/* JIT profiling */
/*
* issued after method code jitted into memory but before code is executed
* EventSpecificData is an iJIT_Method_Load
*/
iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED=13,
/* issued before unload. Method code will no longer be executed, but code
* and info are still in memory. The VTune profiler may capture method
* code only at this point EventSpecificData is iJIT_Method_Id
*/
iJVM_EVENT_TYPE_METHOD_UNLOAD_START,
/* Method Profiling */
/* method name, Id and stack is supplied
* issued when a method is about to be entered EventSpecificData is
* iJIT_Method_NIDS
*/
iJVM_EVENT_TYPE_ENTER_NIDS = 19,
/* method name, Id and stack is supplied
* issued when a method is about to be left EventSpecificData is
* iJIT_Method_NIDS
*/
iJVM_EVENT_TYPE_LEAVE_NIDS
} iJIT_JVM_EVENT;
typedef enum _iJIT_ModeFlags
{
/* No need to Notify VTune, since VTune is not running */
iJIT_NO_NOTIFICATIONS = 0x0000,
/* when turned on the jit must call
* iJIT_NotifyEvent
* (
* iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
* )
* for all the method already jitted
*/
iJIT_BE_NOTIFY_ON_LOAD = 0x0001,
/* when turned on the jit must call
* iJIT_NotifyEvent
* (
* iJVM_EVENT_TYPE_METHOD_UNLOAD_FINISHED,
* ) for all the method that are unloaded
*/
iJIT_BE_NOTIFY_ON_UNLOAD = 0x0002,
/* when turned on the jit must instrument all
* the currently jited code with calls on
* method entries
*/
iJIT_BE_NOTIFY_ON_METHOD_ENTRY = 0x0004,
/* when turned on the jit must instrument all
* the currently jited code with calls
* on method exit
*/
iJIT_BE_NOTIFY_ON_METHOD_EXIT = 0x0008
} iJIT_ModeFlags;
/* Flags used by iJIT_IsProfilingActive() */
typedef enum _iJIT_IsProfilingActiveFlags
{
/* No profiler is running. Currently not used */
iJIT_NOTHING_RUNNING = 0x0000,
/* Sampling is running. This is the default value
* returned by iJIT_IsProfilingActive()
*/
iJIT_SAMPLING_ON = 0x0001,
/* Call Graph is running */
iJIT_CALLGRAPH_ON = 0x0002
} iJIT_IsProfilingActiveFlags;
/* Enumerator for the environment of methods*/
typedef enum _iJDEnvironmentType
{
iJDE_JittingAPI = 2
} iJDEnvironmentType;
/**********************************
* Data structures for the events *
**********************************/
/* structure for the events:
* iJVM_EVENT_TYPE_METHOD_UNLOAD_START
*/
typedef struct _iJIT_Method_Id
{
/* Id of the method (same as the one passed in
* the iJIT_Method_Load struct
*/
unsigned int method_id;
} *piJIT_Method_Id, iJIT_Method_Id;
/* structure for the events:
* iJVM_EVENT_TYPE_ENTER_NIDS,
* iJVM_EVENT_TYPE_LEAVE_NIDS,
* iJVM_EVENT_TYPE_EXCEPTION_OCCURRED_NIDS
*/
typedef struct _iJIT_Method_NIDS
{
/* unique method ID */
unsigned int method_id;
/* NOTE: no need to fill this field, it's filled by VTune */
unsigned int stack_id;
/* method name (just the method, without the class) */
char* method_name;
} *piJIT_Method_NIDS, iJIT_Method_NIDS;
/* structures for the events:
* iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED
*/
typedef struct _LineNumberInfo
{
/* x86 Offset from the begining of the method*/
unsigned int Offset;
/* source line number from the begining of the source file */
unsigned int LineNumber;
} *pLineNumberInfo, LineNumberInfo;
typedef struct _iJIT_Method_Load
{
/* unique method ID - can be any unique value, (except 0 - 999) */
unsigned int method_id;
/* method name (can be with or without the class and signature, in any case
* the class name will be added to it)
*/
char* method_name;
/* virtual address of that method - This determines the method range for the
* iJVM_EVENT_TYPE_ENTER/LEAVE_METHOD_ADDR events
*/
void* method_load_address;
/* Size in memory - Must be exact */
unsigned int method_size;
/* Line Table size in number of entries - Zero if none */
unsigned int line_number_size;
/* Pointer to the begining of the line numbers info array */
pLineNumberInfo line_number_table;
/* unique class ID */
unsigned int class_id;
/* class file name */
char* class_file_name;
/* source file name */
char* source_file_name;
/* bits supplied by the user for saving in the JIT file */
void* user_data;
/* the size of the user data buffer */
unsigned int user_data_size;
/* NOTE: no need to fill this field, it's filled by VTune */
iJDEnvironmentType env;
} *piJIT_Method_Load, iJIT_Method_Load;
/* API Functions */
#ifdef __cplusplus
extern "C" {
#endif
#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
/* called when the settings are changed with new settings */
typedef void (*iJIT_ModeChangedEx)(void *UserData, iJIT_ModeFlags Flags);
int JITAPI iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData);
/* The new mode call back routine */
void JITAPI iJIT_RegisterCallbackEx(void *userdata,
iJIT_ModeChangedEx NewModeCallBackFuncEx);
iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive(void);
void JITAPI FinalizeThread(void);
void JITAPI FinalizeProcess(void);
unsigned int JITAPI iJIT_GetNewMethodID(void);
#ifdef __cplusplus
}
#endif
#endif /* __JITPROFILING_H__ */

View File

@ -1,6 +1,4 @@
link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser selectiondag)
if( LLVM_USE_OPROFILE )

View File

@ -14,8 +14,6 @@ set(LLVM_OPTIONAL_SOURCES
)
if( LLVM_USE_INTEL_JITEVENTS )
include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} )
link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
set(ProfileTestSources
IntelJITEventListenerTest.cpp
)

View File

@ -11,7 +11,10 @@
using namespace llvm;
#include "llvm/ExecutionEngine/IntelJITEventsWrapper.h"
// Because we want to keep the implementation details of the Intel API used to
// communicate with Amplifier out of the public header files, the header below
// is included from the source tree instead.
#include "../../../lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h"
#include <map>
#include <list>