diff -Nru google-perftools-2.1/aclocal.m4 google-perftools-2.2.1/aclocal.m4
--- google-perftools-2.1/aclocal.m4 2013-07-30 11:12:28.000000000 +0200
+++ google-perftools-2.2.1/aclocal.m4 2014-06-22 00:52:48.000000000 +0200
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.13.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
@@ -32,10 +32,10 @@
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.13'
+[am__api_version='1.14'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.13.3], [],
+m4_if([$1], [1.14.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -51,7 +51,7 @@
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.13.3])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
@@ -418,6 +418,12 @@
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@@ -526,6 +532,48 @@
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard:
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: .
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
@@ -534,7 +582,6 @@
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
@@ -596,6 +643,42 @@
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
@@ -646,38 +729,6 @@
rm -f confinc confmf
])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_CC_C_O
-# --------------
-# Like AC_PROG_CC_C_O, but changed for automake.
-AC_DEFUN([AM_PROG_CC_C_O],
-[AC_REQUIRE([AC_PROG_CC_C_O])dnl
-AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([compile])dnl
-# FIXME: we rely on the cache variable name because
-# there is no other way.
-set dummy $CC
-am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-dnl Make sure AC_PROG_CC is never called again, or it will override our
-dnl setting of CC.
-m4_define([AC_PROG_CC],
- [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
-])
-
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997-2013 Free Software Foundation, Inc.
@@ -748,6 +799,70 @@
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
diff -Nru google-perftools-2.1/config.guess google-perftools-2.2.1/config.guess
--- google-perftools-2.1/config.guess 2013-07-30 11:12:29.000000000 +0200
+++ google-perftools-2.2.1/config.guess 2014-06-22 00:52:50.000000000 +0200
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2013 Free Software Foundation, Inc.
+# Copyright 1992-2014 Free Software Foundation, Inc.
-timestamp='2013-05-16'
+timestamp='2014-03-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@
LIBC=gnu
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
;;
esac
@@ -826,7 +826,7 @@
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
- i*:MSYS*:*)
+ *:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
@@ -969,10 +969,10 @@
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
- or1k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
exit ;;
- or32:Linux:*:*)
+ or32:Linux:*:* | or1k*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
@@ -995,6 +995,12 @@
ppc:Linux:*:*)
echo powerpc-unknown-linux-${LIBC}
exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
@@ -1254,16 +1260,26 @@
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- case $UNAME_PROCESSOR in
- i386) UNAME_PROCESSOR=x86_64 ;;
- powerpc) UNAME_PROCESSOR=powerpc64 ;;
- esac
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
@@ -1355,154 +1371,6 @@
exit ;;
esac
-eval $set_cc_for_build
-cat >$dummy.c <
-# include
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
cat >&2 <.
#
@@ -590,8 +590,8 @@
# Identity of this package.
PACKAGE_NAME='gperftools'
PACKAGE_TARNAME='gperftools'
-PACKAGE_VERSION='2.1'
-PACKAGE_STRING='gperftools 2.1'
+PACKAGE_VERSION='2.2.1'
+PACKAGE_STRING='gperftools 2.2.1'
PACKAGE_BUGREPORT='google-perftools@googlegroups.com'
PACKAGE_URL=''
@@ -653,6 +653,8 @@
OSX_TRUE
MINGW_FALSE
MINGW_TRUE
+HAVE_PTHREAD_DESPITE_ASKING_FOR_FALSE
+HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE
PTHREAD_CFLAGS
PTHREAD_LIBS
PTHREAD_CC
@@ -725,6 +727,9 @@
TC_VERSION_PATCH
TC_VERSION_MINOR
TC_VERSION_MAJOR
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
AM_BACKSLASH
AM_DEFAULT_VERBOSITY
AM_DEFAULT_V
@@ -804,11 +809,13 @@
ac_user_opts='
enable_option_checking
enable_silent_rules
+enable_maintainer_mode
enable_cpu_profiler
enable_heap_profiler
enable_heap_checker
enable_debugalloc
enable_minimal
+enable_stacktrace_via_backtrace
enable_dependency_tracking
enable_shared
enable_static
@@ -1372,7 +1379,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures gperftools 2.1 to adapt to many kinds of systems.
+\`configure' configures gperftools 2.2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1442,7 +1449,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of gperftools 2.1:";;
+ short | recursive ) echo "Configuration of gperftools 2.2.1:";;
esac
cat <<\_ACEOF
@@ -1452,12 +1459,18 @@
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-silent-rules less verbose build output (undo: "make V=1")
--disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
--disable-cpu-profiler do not build the cpu profiler
--disable-heap-profiler do not build the heap profiler
--disable-heap-checker do not build the heap checker
--disable-debugalloc do not build versions of libs with debugalloc
--enable-minimal build only tcmalloc-minimal (and maybe
tcmalloc-minimal-debug)
+ --enable-stacktrace-via-backtrace
+ enable use of backtrace() for stacktrace capturing
+ (may deadlock)
--enable-dependency-tracking
do not reject slow dependency extractors
--disable-dependency-tracking
@@ -1558,7 +1571,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-gperftools configure 2.1
+gperftools configure 2.2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2148,7 +2161,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by gperftools $as_me 2.1, which was
+It was created by gperftools $as_me 2.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2501,8 +2514,8 @@
# Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B)
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-TCMALLOC_SO_VERSION=5:2:1
-PROFILER_SO_VERSION=3:2:3
+TCMALLOC_SO_VERSION=6:2:2
+PROFILER_SO_VERSION=4:1:4
@@ -2611,7 +2624,7 @@
case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
-am__api_version='1.13'
+am__api_version='1.14'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -3097,7 +3110,7 @@
# Define the identity of the package.
PACKAGE='gperftools'
- VERSION='2.1'
+ VERSION='2.2.1'
cat >>confdefs.h <<_ACEOF
@@ -3148,9 +3161,75 @@
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard:
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: .
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
ac_config_headers="$ac_config_headers src/config.h"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
# Export the version information (for tc_version and friends)
TC_VERSION_MAJOR=`expr "$PACKAGE_VERSION" : '\([0-9]*\)'`
TC_VERSION_MINOR=`expr "$PACKAGE_VERSION" : '[0-9]*\.\([0-9]*\)'`
@@ -3219,6 +3298,11 @@
enable_heap_profiler=no
enable_heap_checker=no
fi
+# Check whether --enable-stacktrace-via-backtrace was given.
+if test "${enable_stacktrace_via_backtrace+set}" = set; then :
+ enableval=$enable_stacktrace_via_backtrace; enable_backtrace=yes
+fi
+
# Checks for programs.
@@ -4459,6 +4543,65 @@
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
depcc="$CC" am_compiler_list=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -4732,131 +4875,6 @@
GCC_FALSE=
fi
# let the Makefile know if we're gcc
-if test "x$CC" != xcc; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
-$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
-$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
-fi
-set dummy $CC; ac_cc=`$as_echo "$2" |
- sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-# Make sure it works both with $CC and with simple cc.
-# We do the test twice because some compilers refuse to overwrite an
-# existing .o file with -o, though they will create one.
-ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
-rm -f conftest2.*
-if { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } &&
- test -f conftest2.$ac_objext && { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; };
-then
- eval ac_cv_prog_cc_${ac_cc}_c_o=yes
- if test "x$CC" != xcc; then
- # Test first that cc exists at all.
- if { ac_try='cc -c conftest.$ac_ext >&5'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
- rm -f conftest2.*
- if { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } &&
- test -f conftest2.$ac_objext && { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; };
- then
- # cc works too.
- :
- else
- # cc exists but doesn't like -o.
- eval ac_cv_prog_cc_${ac_cc}_c_o=no
- fi
- fi
- fi
-else
- eval ac_cv_prog_cc_${ac_cc}_c_o=no
-fi
-rm -f core conftest*
-
-fi
-if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
-
-fi
-
-# FIXME: we rely on the cache variable name because
-# there is no other way.
-set dummy $CC
-am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
- # Losing compiler, so override with the script.
- # FIXME: It is wrong to rewrite CC.
- # But if we don't then we get into trouble of one sort or another.
- # A longer-term fix would be to have automake use am__CC in this case,
- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
- CC="$am_aux_dir/compile $CC"
-fi
-
# shrug: autogen.sh suddenly needs this for some reason
# Check if we have an objcopy installed that supports -W
@@ -7331,7 +7349,7 @@
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -7356,7 +7374,10 @@
;;
esac
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -7375,7 +7396,10 @@
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -16505,6 +16529,7 @@
pc_fields="$pc_fields uc_mcontext.gregs[REG_EIP]" # Linux (i386)
pc_fields="$pc_fields uc_mcontext.gregs[REG_RIP]" # Linux (x86_64)
pc_fields="$pc_fields uc_mcontext.sc_ip" # Linux (ia64)
+ pc_fields="$pc_fields uc_mcontext.pc" # Linux (mips)
pc_fields="$pc_fields uc_mcontext.uc_regs->gregs[PT_NIP]" # Linux (ppc)
pc_fields="$pc_fields uc_mcontext.gregs[R15]" # Linux (arm old [untested])
pc_fields="$pc_fields uc_mcontext.arm_pc" # Linux (arm arch 5)
@@ -16668,7 +16693,7 @@
fi
-# We want to link in libunwind if it exists
+# We want to link in libunwind or libexecinfo if it exists
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for backtrace in -lunwind" >&5
$as_echo_n "checking for backtrace in -lunwind... " >&6; }
if ${ac_cv_lib_unwind_backtrace+:} false; then :
@@ -16708,9 +16733,50 @@
if test "x$ac_cv_lib_unwind_backtrace" = xyes; then :
UNWIND_LIBS=-lunwind
else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for backtrace in -lexecinfo" >&5
+$as_echo_n "checking for backtrace in -lexecinfo... " >&6; }
+if ${ac_cv_lib_execinfo_backtrace+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lexecinfo $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* 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 backtrace ();
+int
+main ()
+{
+return backtrace ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_execinfo_backtrace=yes
+else
+ ac_cv_lib_execinfo_backtrace=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_execinfo_backtrace" >&5
+$as_echo "$ac_cv_lib_execinfo_backtrace" >&6; }
+if test "x$ac_cv_lib_execinfo_backtrace" = xyes; then :
+ UNWIND_LIBS=-lexecinfo
+else
UNWIND_LIBS=
fi
+fi
+
# On x86_64, instead of libunwind, we can choose to compile with frame-pointers.
@@ -16730,6 +16796,8 @@
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x86 without frame pointers" >&5
+$as_echo_n "checking for x86 without frame pointers... " >&6; }
# Some x86_64 systems do not insert frame pointers by default.
# We want to see if the current system is one of those.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -16770,7 +16838,11 @@
:
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if test "$is_x86_64" = yes && ! grep 'mov.*rsp.*rbp' fp.s >/dev/null 2>&1; then
+x86_no_fp_by_default=no
+if test "$is_x86_64" = yes && ! grep 'mov.*rsp.*rbp' fp.s >/dev/null 2>&1; then :
+ x86_no_fp_by_default=yes
+fi
+ if test "$x86_no_fp_by_default" = yes; then
X86_64_AND_NO_FP_BY_DEFAULT_TRUE=
X86_64_AND_NO_FP_BY_DEFAULT_FALSE='#'
else
@@ -16780,6 +16852,9 @@
rm fp.s
CFLAGS="$OLD_CFLAGS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $x86_no_fp_by_default" >&5
+$as_echo "$x86_no_fp_by_default" >&6; }
+
# We need to know if we're i386 so we can turn on -mmms, which is not
# on by default for i386 (it is for x86_64).
@@ -17022,15 +17097,19 @@
# And mingw also does compile __thread but resultant code actually
# fails to work correctly at least in some not so ancient version:
# http://mingw-users.1079350.n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-amp-thread-specifier-not-working-td3440749.html
+#
+# Also it was reported that earlier gcc versions for mips compile
+# __thread but it doesn't really work
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __thread" >&5
$as_echo_n "checking for __thread... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ < 2))
+#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ < 2))
#error gcc has this bug: http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html
-#endif
-#if defined(__MINGW32__)
-#error mingw doesn't really support tls
+#elif defined(__MINGW32__)
+#error mingw doesnt really support tls
+#elif defined(__APPLE__)
+#error OSX __thread support is known to call malloc which makes it unsafe to use from malloc replacement
#endif
int
@@ -17774,6 +17853,62 @@
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthread symbols are available in C++ without including pthread.h" >&5
+$as_echo_n "checking whether pthread symbols are available in C++ without including pthread.h... " >&6; }
+acx_pthread_despite_asking_for=no
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include
+ #include
+
+int
+main ()
+{
+
+ pthread_t th; pthread_join(th, 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+ acx_pthread_despite_asking_for=yes
+
+$as_echo "#define HAVE_PTHREAD_DESPITE_ASKING_FOR 1" >>confdefs.h
+
+ $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_despite_asking_for" >&5
+$as_echo "$acx_pthread_despite_asking_for" >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ if test x"$acx_pthread_despite_asking_for" = xyes; then
+ HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE=
+ HAVE_PTHREAD_DESPITE_ASKING_FOR_FALSE='#'
+else
+ HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE='#'
+ HAVE_PTHREAD_DESPITE_ASKING_FOR_FALSE=
+fi
+
+
# Find out what namespace 'normal' STL code lives in
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler implements namespaces" >&5
$as_echo_n "checking whether the compiler implements namespaces... " >&6; }
@@ -17959,6 +18094,20 @@
;;
esac
+if test "x$enable_backtrace" = xyes; then
+ ac_fn_c_check_decl "$LINENO" "backtrace" "ac_cv_have_decl_backtrace" "#include
+"
+if test "x$ac_cv_have_decl_backtrace" = xyes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_BACKTRACE $ac_have_decl
+_ACEOF
+
+fi
# For windows, this has a non-trivial value (__declspec(export)), but any
# system that uses configure wants this to be the empty string.
@@ -18196,6 +18345,10 @@
am__EXEEXT_FALSE=
fi
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
as_fn_error $? "conditional \"AMDEP\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -18236,6 +18389,10 @@
as_fn_error $? "conditional \"HAVE_W_NO_UNUSED_RESULT\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE}" && test -z "${HAVE_PTHREAD_DESPITE_ASKING_FOR_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_PTHREAD_DESPITE_ASKING_FOR\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${MINGW_TRUE}" && test -z "${MINGW_FALSE}"; then
as_fn_error $? "conditional \"MINGW\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -18665,7 +18822,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by gperftools $as_me 2.1, which was
+This file was extended by gperftools $as_me 2.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -18731,7 +18888,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-gperftools config.status 2.1
+gperftools config.status 2.2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -20764,3 +20921,15 @@
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
+
+if test "$x86_no_fp_by_default" = yes && test "x$enable_frame_pointers" != xyes && test "x$UNWIND_LIBS" = x && test "x$enable_minimal" != xyes; then :
+ if test "x$enable_backtrace" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No frame pointers and no libunwind. Expect backtrace capturing and unittests to fail" >&5
+$as_echo "$as_me: WARNING: No frame pointers and no libunwind. Expect backtrace capturing and unittests to fail" >&2;}
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "No frame pointers and no libunwind. The compilation will fail
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+fi
diff -Nru google-perftools-2.1/configure.ac google-perftools-2.2.1/configure.ac
--- google-perftools-2.1/configure.ac 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/configure.ac 2014-06-22 00:52:34.000000000 +0200
@@ -2,13 +2,13 @@
## In general, the safest way to proceed is to run ./autogen.sh
# make sure we're interpreted by some minimal autoconf
-AC_PREREQ([2.68])
+AC_PREREQ([2.59])
-AC_INIT([gperftools],[2.1],[google-perftools@googlegroups.com])
+AC_INIT([gperftools],[2.2.1],[google-perftools@googlegroups.com])
# Update this value for every release! (A:B:C will map to foo.so.(A-C).C.B)
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-TCMALLOC_SO_VERSION=5:2:1
-PROFILER_SO_VERSION=3:2:3
+TCMALLOC_SO_VERSION=6:2:2
+PROFILER_SO_VERSION=4:1:4
AC_SUBST(TCMALLOC_SO_VERSION)
AC_SUBST(PROFILER_SO_VERSION)
@@ -21,6 +21,8 @@
AM_INIT_AUTOMAKE([dist-zip])
AC_CONFIG_HEADERS([src/config.h])
+AM_MAINTAINER_MODE()
+
# Export the version information (for tc_version and friends)
TC_VERSION_MAJOR=`expr "$PACKAGE_VERSION" : '\([[0-9]]*\)'`
TC_VERSION_MINOR=`expr "$PACKAGE_VERSION" : '[[0-9]]*\.\([[0-9]]*\)'`
@@ -79,6 +81,11 @@
enable_heap_profiler=no
enable_heap_checker=no
fi
+AC_ARG_ENABLE([stacktrace-via-backtrace],
+ [AS_HELP_STRING([--enable-stacktrace-via-backtrace],
+ [enable use of backtrace() for stacktrace capturing (may deadlock)])],
+ [enable_backtrace=yes],
+ [])
# Checks for programs.
@@ -99,7 +106,7 @@
[gpt_cv_objcopy_weaken=no])
AM_CONDITIONAL(HAVE_OBJCOPY_WEAKEN, test $gpt_cv_objcopy_weaken = yes)
-LT_INIT([])
+AC_PROG_LIBTOOL
AC_C_INLINE
AX_C___ATTRIBUTE__
@@ -204,8 +211,9 @@
# Some tests test the behavior of .so files, and only make sense for dynamic.
AM_CONDITIONAL(ENABLE_STATIC, test "$enable_static" = yes)
-# We want to link in libunwind if it exists
-AC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind, UNWIND_LIBS=)
+# We want to link in libunwind or libexecinfo if it exists
+AC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind,
+ [AC_CHECK_LIB(execinfo, backtrace, UNWIND_LIBS=-lexecinfo, UNWIND_LIBS=)])
AC_SUBST(UNWIND_LIBS)
# On x86_64, instead of libunwind, we can choose to compile with frame-pointers.
@@ -215,6 +223,7 @@
, enable_frame_pointers=no)
AM_CONDITIONAL(ENABLE_FRAME_POINTERS, test "$enable_frame_pointers" = yes)
+AC_MSG_CHECKING([for x86 without frame pointers])
# Some x86_64 systems do not insert frame pointers by default.
# We want to see if the current system is one of those.
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],
@@ -225,10 +234,14 @@
# We do our own determination of success/failure in the grep, below.
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int f(int x) {return x;}], [return f(0);])],
[:], [:])
+x86_no_fp_by_default=no
+AS_IF([test "$is_x86_64" = yes && ! grep 'mov.*rsp.*rbp' fp.s >/dev/null 2>&1], [x86_no_fp_by_default=yes])
AM_CONDITIONAL(X86_64_AND_NO_FP_BY_DEFAULT,
- test "$is_x86_64" = yes && ! grep 'mov.*rsp.*rbp' fp.s >/dev/null 2>&1)
+ test "$x86_no_fp_by_default" = yes)
rm fp.s
CFLAGS="$OLD_CFLAGS"
+AC_MSG_RESULT([$x86_no_fp_by_default])
+
# We need to know if we're i386 so we can turn on -mmms, which is not
# on by default for i386 (it is for x86_64).
@@ -299,12 +312,16 @@
# And mingw also does compile __thread but resultant code actually
# fails to work correctly at least in some not so ancient version:
# http://mingw-users.1079350.n2.nabble.com/gcc-4-4-multi-threaded-exception-handling-amp-thread-specifier-not-working-td3440749.html
+#
+# Also it was reported that earlier gcc versions for mips compile
+# __thread but it doesn't really work
AC_MSG_CHECKING([for __thread])
-AC_LINK_IFELSE([AC_LANG_PROGRAM([#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ < 2))
+AC_LINK_IFELSE([AC_LANG_PROGRAM([#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) || (__GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ < 2))
#error gcc has this bug: http://gcc.gnu.org/ml/gcc-bugs/2006-09/msg02275.html
-#endif
-#if defined(__MINGW32__)
-#error mingw doesn't really support tls
+#elif defined(__MINGW32__)
+#error mingw doesnt really support tls
+#elif defined(__APPLE__)
+#error OSX __thread support is known to call malloc which makes it unsafe to use from malloc replacement
#endif
], [static __thread int p = 0])],
[AC_DEFINE(HAVE_TLS, 1,
@@ -345,6 +362,26 @@
# In fact, a lot of the code in this directory depends on pthreads
ACX_PTHREAD
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+AC_MSG_CHECKING([whether pthread symbols are available in C++ without including pthread.h])
+acx_pthread_despite_asking_for=no
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([
+ #include
+ #include
+ ],[
+ pthread_t th; pthread_join(th, 0);
+ ])],[
+ acx_pthread_despite_asking_for=yes
+ AC_DEFINE(HAVE_PTHREAD_DESPITE_ASKING_FOR, 1, [defined to 1 if pthread symbols are exposed even without include pthread.h])
+ AC_DEFINE(HAVE_PTHREAD, 1, [])
+ ])
+AC_MSG_RESULT([$acx_pthread_despite_asking_for])
+AC_LANG_RESTORE
+
+AM_CONDITIONAL(HAVE_PTHREAD_DESPITE_ASKING_FOR, test x"$acx_pthread_despite_asking_for" = xyes)
+
# Find out what namespace 'normal' STL code lives in
AC_CXX_STL_NAMESPACE
@@ -362,6 +399,9 @@
;;
esac
+if test "x$enable_backtrace" = xyes; then
+ AC_CHECK_DECLS([backtrace], [], [], [#include ])
+fi
# For windows, this has a non-trivial value (__declspec(export)), but any
# system that uses configure wants this to be the empty string.
@@ -436,3 +476,8 @@
AC_CONFIG_FILES([Makefile
src/gperftools/tcmalloc.h src/windows/gperftools/tcmalloc.h])
AC_OUTPUT
+
+AS_IF([test "$x86_no_fp_by_default" = yes && test "x$enable_frame_pointers" != xyes && test "x$UNWIND_LIBS" = x && test "x$enable_minimal" != xyes],
+ [AS_IF([test "x$enable_backtrace" = xyes],
+ [AC_MSG_WARN([No frame pointers and no libunwind. Expect backtrace capturing and unittests to fail])],
+ [AC_MSG_FAILURE([No frame pointers and no libunwind. The compilation will fail])])])
diff -Nru google-perftools-2.1/debian/changelog google-perftools-2.2.1/debian/changelog
--- google-perftools-2.1/debian/changelog 2014-09-08 00:10:10.000000000 +0200
+++ google-perftools-2.2.1/debian/changelog 2014-09-08 00:10:11.000000000 +0200
@@ -1,3 +1,12 @@
+google-perftools (2.2.1-0.1) unstable; urgency=medium
+
+ * Non-maintainer upload
+ * New upstream release. (Closes: #757149)
+ * Updated watch file
+ * Added ppc64el, arm64 architectures (Closes: #737677)
+
+ -- Hilko Bengen Sun, 07 Sep 2014 21:22:29 +0200
+
google-perftools (2.1-2) unstable; urgency=low
* Now builds with automake 1.11. (Closes: #724381)
diff -Nru google-perftools-2.1/debian/control google-perftools-2.2.1/debian/control
--- google-perftools-2.1/debian/control 2014-09-08 00:10:10.000000000 +0200
+++ google-perftools-2.2.1/debian/control 2014-09-08 00:10:11.000000000 +0200
@@ -11,7 +11,7 @@
Package: libgoogle-perftools-dev
Section: libdevel
-Architecture: i386 amd64 powerpc armel armhf
+Architecture: i386 amd64 powerpc ppc64el arm64 armel armhf
Depends: ${misc:Depends}, libgoogle-perftools4 (= ${binary:Version}), libtcmalloc-minimal4 (= ${binary:Version}), libunwind8-dev [amd64]
Description: libraries for CPU and heap analysis, plus an efficient thread-caching malloc
The gperftools, previously called google-perftools, package contains some
@@ -22,7 +22,7 @@
Package: libtcmalloc-minimal4
Section: libs
-Architecture: i386 amd64 powerpc armel armhf
+Architecture: i386 amd64 powerpc ppc64el arm64 armel armhf
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: efficient thread-caching malloc
The gperftools, previously called google-perftools, package contains some
@@ -32,7 +32,7 @@
Package: libtcmalloc-minimal4-dbg
Section: debug
Priority: extra
-Architecture: i386 amd64 powerpc armel armhf
+Architecture: i386 amd64 powerpc ppc64el arm64 armel armhf
Depends: ${misc:Depends}, libtcmalloc-minimal4 (= ${binary:Version})
Description: efficient thread-caching malloc
Contains debugging symbols for libtcmalloc-minimal4.
@@ -43,7 +43,7 @@
Package: libgoogle-perftools4
Section: libs
-Architecture: i386 amd64 powerpc armel armhf
+Architecture: i386 amd64 powerpc ppc64el arm64 armel armhf
Depends: libtcmalloc-minimal4 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
Conflicts: libgoogle-perftools0
Description: libraries for CPU and heap analysis, plus an efficient thread-caching malloc
@@ -55,7 +55,7 @@
Package: libgoogle-perftools4-dbg
Section: debug
Priority: extra
-Architecture: i386 amd64 powerpc armel armhf
+Architecture: i386 amd64 powerpc ppc64el arm64 armel armhf
Depends: ${misc:Depends}, libgoogle-perftools4 (= ${binary:Version})
Description: libraries for CPU and heap analysis, plus an efficient thread-caching malloc
Contains debugging symbols for libgoogle-perftools4.
diff -Nru google-perftools-2.1/debian/watch google-perftools-2.2.1/debian/watch
--- google-perftools-2.1/debian/watch 2014-09-08 00:10:10.000000000 +0200
+++ google-perftools-2.2.1/debian/watch 2014-09-08 00:10:11.000000000 +0200
@@ -1,7 +1,2 @@
-# Example watch control file for uscan
-# Rename this file to "watch" and then you can run the "uscan" command
-# to check for upstream updates and more.
-# Site Directory Pattern Version Script
-# http://prdownloads.sourceforge.net/goog-perftools/
version=3
-http://code.google.com/p/gperftools/downloads/list?can=1 .*/gperftools-(\d[\d\.]*)\.tar\.gz
+https://code.google.com/p/gperftools/ https://.*/gperftools-(\d[\d\.]*)\.tar\.gz
diff -Nru google-perftools-2.1/doc/pprof.see_also google-perftools-2.2.1/doc/pprof.see_also
--- google-perftools-2.1/doc/pprof.see_also 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/doc/pprof.see_also 2013-05-25 23:42:55.000000000 +0200
@@ -0,0 +1,11 @@
+[see also]
+Further documentation for
+.B pprof
+is maintained as a web page called
+.B cpu_profiler.html
+and is likely installed at one of the following locations:
+.IP
+.B /usr/share/gperftools/cpu_profiler.html
+.br
+.B /usr/local/share/gperftools/cpu_profiler.html
+.PP
diff -Nru google-perftools-2.1/doc/tcmalloc.html google-perftools-2.2.1/doc/tcmalloc.html
--- google-perftools-2.1/doc/tcmalloc.html 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/doc/tcmalloc.html 2013-09-09 17:03:30.000000000 +0200
@@ -86,9 +86,9 @@
back from a thread-local cache into the central data structures.
-TCMalloc treats objects with size <= 32K ("small" objects)
+
TCMalloc treats objects with size <= 256K ("small" objects)
differently from larger objects. Large objects are allocated directly
-from the central heap using a page-level allocator (a page is a 4K
+from the central heap using a page-level allocator (a page is a 8K
aligned region of memory). I.e., a large object is always
page-aligned and occupies an integral number of pages.
@@ -99,8 +99,8 @@
-Each small object size maps to one of approximately 60 allocatable
-size-classes. For example, all allocations in the range 833 to 1024
+
Each small object size maps to one of approximately 88 allocatable
+size-classes. For example, all allocations in the range 961 to 1024
bytes are rounded up to 1024. The size-classes are spaced so that
small sizes are separated by 8 bytes, larger sizes by 16 bytes, even
larger sizes by 32 bytes, and so forth. The maximal spacing is
@@ -198,12 +198,12 @@
-A large object size (> 32K) is rounded up to a page size (4K)
+
A large object size (> 256K) is rounded up to a page size (8K)
and is handled by a central page heap. The central page heap is again
-an array of free lists. For i < 256, the
+an array of free lists. For i < 128, the
kth entry is a free list of runs that consist of
-k pages. The 256th entry is a free list of
-runs that have length >= 256 pages:
+k pages. The 128th entry is a free list of
+runs that have length >= 128 pages:
An allocation for k pages is satisfied by looking in
@@ -238,9 +238,9 @@
In a 32-bit address space, the central array is represented by a a
2-level radix tree where the root contains 32 entries and each leaf
-contains 2^15 entries (a 32-bit address spave has 2^20 4K pages, and
-the first level of tree divides the 2^20 pages by 2^5). This leads to
-a starting memory usage of 128KB of space (2^15*4 bytes) for the
+contains 2^14 entries (a 32-bit address space has 2^19 8K pages, and
+the first level of tree divides the 2^19 pages by 2^5). This leads to
+a starting memory usage of 64KB of space (2^14*4 bytes) for the
central array, which seems acceptable.
On 64-bit machines, we use a 3-level radix tree.
diff -Nru google-perftools-2.1/gperftools.sln google-perftools-2.2.1/gperftools.sln
--- google-perftools-2.1/gperftools.sln 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/gperftools.sln 2013-09-22 03:14:21.000000000 +0200
@@ -100,6 +100,11 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "system-alloc_unittest", "vsprojects\system-alloc_unittest\system-alloc_unittest.vcproj", "{387F753A-0312-4A7B-A1D6-B2795E832E96}"
+ ProjectSection(ProjectDependencies) = postProject
+ {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F} = {55E2B3AE-3CA1-4DB6-97F7-0A044D6F446F}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -190,6 +195,10 @@
{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Debug.Build.0 = Debug|Win32
{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release.ActiveCfg = Release|Win32
{3A559C75-FD26-4300-B86B-165FD43EE1CE}.Release.Build.0 = Release|Win32
+ {387F753A-0312-4A7B-A1D6-B2795E832E96}.Debug.ActiveCfg = Debug|Win32
+ {387F753A-0312-4A7B-A1D6-B2795E832E96}.Debug.Build.0 = Debug|Win32
+ {387F753A-0312-4A7B-A1D6-B2795E832E96}.Release.ActiveCfg = Release|Win32
+ {387F753A-0312-4A7B-A1D6-B2795E832E96}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
diff -Nru google-perftools-2.1/libtool google-perftools-2.2.1/libtool
--- google-perftools-2.1/libtool 2013-07-30 11:12:45.000000000 +0200
+++ google-perftools-2.2.1/libtool 2014-06-22 00:53:07.000000000 +0200
@@ -1,8 +1,8 @@
#! /bin/sh
# libtool - Provide generalized library-building support services.
-# Generated automatically by config.status (gperftools) 2.1
-# Libtool was configured on host chi:
+# Generated automatically by config.status (gperftools) 2.2.1
+# Libtool was configured on host beta.altoros.corp:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
#
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
@@ -272,10 +272,10 @@
hardcode_into_libs=yes
# Compile-time system search path for libraries.
-sys_lib_search_path_spec="/usr/lib/gcc/x86_64-linux-gnu/4.8 /usr/lib/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib "
+sys_lib_search_path_spec="/usr/lib/gcc/i586-linux-gnu/4.9 /usr/lib/i386-linux-gnu /usr/lib /lib/i386-linux-gnu /lib "
# Run-time system search path for libraries.
-sys_lib_dlsearch_path_spec="/lib /usr/lib /lib/i386-linux-gnu /usr/lib/i386-linux-gnu /lib/i486-linux-gnu /usr/lib/i486-linux-gnu /usr/local/lib /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu /lib32 /usr/lib32 /libx32 /usr/libx32 "
+sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/local/lib /usr/lib/i386-linux-gnu/libfakeroot /lib/i386-linux-gnu /usr/lib/i386-linux-gnu /lib/i486-linux-gnu /usr/lib/i486-linux-gnu /usr/local/lib /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu /lib64 /usr/lib64 /libx32 /usr/libx32 "
# Whether dlopen is supported.
dlopen_support=unknown
@@ -292,7 +292,7 @@
# The linker used to build libraries.
-LD="/usr/bin/ld -m elf_x86_64"
+LD="/usr/bin/ld -m elf_i386"
# How to create reloadable object files.
reload_flag=" -r"
@@ -513,7 +513,7 @@
# compiler: $LTCC
# compiler flags: $LTCFLAGS
# linker: $LD (gnu? $with_gnu_ld)
-# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.3
+# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.7
# automake: $automake_version
# autoconf: $autoconf_version
#
@@ -523,7 +523,7 @@
PROGRAM=libtool
PACKAGE=libtool
-VERSION="2.4.2 Debian-2.4.2-1.3"
+VERSION="2.4.2 Debian-2.4.2-1.7"
TIMESTAMP=""
package_revision=1.3337
@@ -10099,7 +10099,7 @@
# ### BEGIN LIBTOOL TAG CONFIG: CXX
# The linker used to build libraries.
-LD="/usr/bin/ld -m elf_x86_64"
+LD="/usr/bin/ld -m elf_i386"
# How to create reloadable object files.
reload_flag=" -r"
@@ -10230,17 +10230,17 @@
hardcode_action=immediate
# The directories searched by this compiler when creating a shared library.
-compiler_lib_search_dirs="/usr/lib/gcc/x86_64-linux-gnu/4.8 /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /usr/lib/gcc/x86_64-linux-gnu/4.8/../../.."
+compiler_lib_search_dirs="/usr/lib/gcc/i586-linux-gnu/4.9 /usr/lib/gcc/i586-linux-gnu/4.9/../../../i386-linux-gnu /usr/lib/gcc/i586-linux-gnu/4.9/../../../../lib /lib/i386-linux-gnu /lib/../lib /usr/lib/i386-linux-gnu /usr/lib/../lib /usr/lib/gcc/i586-linux-gnu/4.9/../../.."
# Dependencies to place before and after the objects being linked to
# create a shared library.
-predep_objects="/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbeginS.o"
-postdep_objects="/usr/lib/gcc/x86_64-linux-gnu/4.8/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o"
+predep_objects="/usr/lib/gcc/i586-linux-gnu/4.9/../../../i386-linux-gnu/crti.o /usr/lib/gcc/i586-linux-gnu/4.9/crtbeginS.o"
+postdep_objects="/usr/lib/gcc/i586-linux-gnu/4.9/crtendS.o /usr/lib/gcc/i586-linux-gnu/4.9/../../../i386-linux-gnu/crtn.o"
predeps=""
postdeps="-lstdc++ -lm -lgcc_s -lc -lgcc_s"
# The library search path used internally by the compiler when linking
# a shared library.
-compiler_lib_search_path="-L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.."
+compiler_lib_search_path="-L/usr/lib/gcc/i586-linux-gnu/4.9 -L/usr/lib/gcc/i586-linux-gnu/4.9/../../../i386-linux-gnu -L/usr/lib/gcc/i586-linux-gnu/4.9/../../../../lib -L/lib/i386-linux-gnu -L/lib/../lib -L/usr/lib/i386-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/i586-linux-gnu/4.9/../../.."
# ### END LIBTOOL TAG CONFIG: CXX
diff -Nru google-perftools-2.1/ltmain.sh google-perftools-2.2.1/ltmain.sh
--- google-perftools-2.1/ltmain.sh 2013-07-30 11:12:25.000000000 +0200
+++ google-perftools-2.2.1/ltmain.sh 2014-06-22 00:52:45.000000000 +0200
@@ -70,7 +70,7 @@
# compiler: $LTCC
# compiler flags: $LTCFLAGS
# linker: $LD (gnu? $with_gnu_ld)
-# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.3
+# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.7
# automake: $automake_version
# autoconf: $autoconf_version
#
@@ -80,7 +80,7 @@
PROGRAM=libtool
PACKAGE=libtool
-VERSION="2.4.2 Debian-2.4.2-1.3"
+VERSION="2.4.2 Debian-2.4.2-1.7"
TIMESTAMP=""
package_revision=1.3337
diff -Nru google-perftools-2.1/m4/libtool.m4 google-perftools-2.2.1/m4/libtool.m4
--- google-perftools-2.1/m4/libtool.m4 2013-07-30 11:12:25.000000000 +0200
+++ google-perftools-2.2.1/m4/libtool.m4 2014-06-22 00:52:45.000000000 +0200
@@ -1312,7 +1312,7 @@
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -1333,7 +1333,10 @@
;;
esac
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -1352,7 +1355,10 @@
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
diff -Nru google-perftools-2.1/m4/pc_from_ucontext.m4 google-perftools-2.2.1/m4/pc_from_ucontext.m4
--- google-perftools-2.1/m4/pc_from_ucontext.m4 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/m4/pc_from_ucontext.m4 2013-09-09 17:03:30.000000000 +0200
@@ -25,6 +25,7 @@
pc_fields="$pc_fields uc_mcontext.gregs[[REG_EIP]]" # Linux (i386)
pc_fields="$pc_fields uc_mcontext.gregs[[REG_RIP]]" # Linux (x86_64)
pc_fields="$pc_fields uc_mcontext.sc_ip" # Linux (ia64)
+ pc_fields="$pc_fields uc_mcontext.pc" # Linux (mips)
pc_fields="$pc_fields uc_mcontext.uc_regs->gregs[[PT_NIP]]" # Linux (ppc)
pc_fields="$pc_fields uc_mcontext.gregs[[R15]]" # Linux (arm old [untested])
pc_fields="$pc_fields uc_mcontext.arm_pc" # Linux (arm arch 5)
diff -Nru google-perftools-2.1/Makefile.am google-perftools-2.2.1/Makefile.am
--- google-perftools-2.1/Makefile.am 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/Makefile.am 2014-06-22 00:34:32.000000000 +0200
@@ -17,6 +17,8 @@
# This is mostly based on configure options
AM_CXXFLAGS =
+NO_BUILTIN_CXXFLAGS =
+
# These are good warnings to turn on by default. We also tell gcc
# that malloc, free, realloc, mmap, etc. are not builtins (these flags
# are supported since gcc 3.1.1). gcc doesn't think most of them are
@@ -30,6 +32,8 @@
-fno-builtin-memalign -fno-builtin-posix_memalign \
-fno-builtin-valloc -fno-builtin-pvalloc
+NO_BUILTIN_CXXFLAGS += -fno-builtin
+
# On i386, -mmmx is needed for the mmx-based instructions in
# atomicops-internal-x86.h. Also as of gcc 4.6, -fomit-frame-pointer
# is the default. Since we must always have frame pointers for I386
@@ -188,6 +192,7 @@
$(LOGGING_INCLUDES)
SYSINFO_INCLUDES = src/base/sysinfo.h \
+ src/getenv_safe.h \
src/base/logging.h \
src/base/commandlineflags.h \
src/base/cycleclock.h \
@@ -214,6 +219,7 @@
noinst_LTLIBRARIES += libwindows.la
libwindows_la_SOURCES = $(WINDOWS_INCLUDES) \
src/windows/port.cc \
+ src/windows/system-alloc.cc \
src/windows/ia32_modrm_map.cc \
src/windows/ia32_opcode_map.cc \
src/windows/mini_disassembler.cc \
@@ -233,7 +239,9 @@
src/base/atomicops-internals-linuxppc.h \
src/base/atomicops-internals-arm-generic.h \
src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
src/base/atomicops-internals-windows.h \
+ src/base/atomicops-internals-gcc.h \
src/base/atomicops-internals-x86.h
noinst_LTLIBRARIES += libspinlock.la
libspinlock_la_SOURCES = src/base/spinlock.cc \
@@ -262,7 +270,11 @@
# patch_functions.cc #includes tcmalloc.cc, so no need to link it in.
TCMALLOC_CC =
# windows has its own system for threads and system memory allocation.
+if HAVE_PTHREAD_DESPITE_ASKING_FOR
+MAYBE_THREADS_CC = src/maybe_threads.cc
+else
MAYBE_THREADS_CC =
+endif
SYSTEM_ALLOC_CC =
else !MINGW
# spinlock is the only code that uses atomicops.
@@ -334,13 +346,16 @@
if WITH_STACK_TRACE
### The header files we use. We divide into categories based on directory
-S_STACKTRACE_INCLUDES = src/stacktrace_config.h \
+S_STACKTRACE_INCLUDES = src/stacktrace_impl_setup-inl.h \
src/stacktrace_generic-inl.h \
src/stacktrace_libunwind-inl.h \
src/stacktrace_arm-inl.h \
src/stacktrace_powerpc-inl.h \
+ src/stacktrace_powerpc-darwin-inl.h \
+ src/stacktrace_powerpc-linux-inl.h \
src/stacktrace_x86-inl.h \
src/stacktrace_win32-inl.h \
+ src/stacktrace_instrument-inl.h \
src/base/elf_mem_image.h \
src/base/vdso_support.h
@@ -521,7 +536,7 @@
tcmalloc_minimal_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
src/tests/testutil.h src/tests/testutil.cc \
$(TCMALLOC_UNITTEST_INCLUDES)
-tcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_minimal_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
# We want libtcmalloc last on the link line, but due to a bug in
# libtool involving convenience libs, they need to come last on the
@@ -536,13 +551,13 @@
TESTS += tcmalloc_minimal_large_unittest
WINDOWS_PROJECTS += vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcproj
tcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
-tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_minimal_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
tcmalloc_minimal_large_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
TESTS += tcmalloc_minimal_large_heap_fragmentation_unittest
tcmalloc_minimal_large_heap_fragmentation_unittest_SOURCES = src/tests/large_heap_fragmentation_unittest.cc
-tcmalloc_minimal_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_minimal_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_minimal_large_heap_fragmentation_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
tcmalloc_minimal_large_heap_fragmentation_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@@ -582,11 +597,12 @@
addressmap_unittest_CXXFLAGS = -g $(AM_CXXFLAGS)
addressmap_unittest_LDADD = liblogging.la
+WINDOWS_PROJECTS += vsprojects/system-alloc_unittest/system-alloc_unittest.vcproj
if !MINGW
TESTS += system_alloc_unittest
system_alloc_unittest_SOURCES = src/config_for_unittests.h \
src/tests/system-alloc_unittest.cc
-system_alloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+system_alloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
system_alloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
system_alloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
endif !MINGW
@@ -601,7 +617,7 @@
TESTS += frag_unittest
WINDOWS_PROJECTS += vsprojects/frag_unittest/frag_unittest.vcproj
frag_unittest_SOURCES = src/tests/frag_unittest.cc src/config_for_unittests.h
-frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
frag_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
frag_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@@ -610,7 +626,7 @@
markidle_unittest_SOURCES = src/tests/markidle_unittest.cc \
src/config_for_unittests.h \
src/tests/testutil.h src/tests/testutil.cc
-markidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+markidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
markidle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
markidle_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@@ -660,7 +676,7 @@
malloc_extension_c_test_CFLAGS += -ansi
endif GCC
malloc_extension_c_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-malloc_extension_c_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
+malloc_extension_c_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS) -lstdc++
endif !ENABLE_STATIC
endif !MINGW
@@ -671,7 +687,7 @@
src/tcmalloc.h \
src/config_for_unittests.h \
src/tests/testutil.h src/tests/testutil.cc
-memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
memalign_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
memalign_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
endif !OSX
@@ -694,7 +710,7 @@
src/config_for_unittests.h \
src/base/logging.h \
src/pagemap.h
-pagemap_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+pagemap_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
pagemap_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
pagemap_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@@ -703,7 +719,7 @@
realloc_unittest_SOURCES = src/tests/realloc_unittest.cc \
src/config_for_unittests.h \
src/base/logging.h
-realloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+realloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
realloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
realloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@@ -720,7 +736,7 @@
thread_dealloc_unittest_SOURCES = src/tests/thread_dealloc_unittest.cc \
src/config_for_unittests.h \
src/tests/testutil.h src/tests/testutil.cc
-thread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+thread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
thread_dealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
thread_dealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@@ -827,7 +843,7 @@
# This is the sub-program used by debugallocation_test.sh
noinst_PROGRAMS += debugallocation_test
debugallocation_test_SOURCES = src/tests/debugallocation_test.cc
-debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
debugallocation_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
debugallocation_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
endif WITH_STACK_TRACE
@@ -851,7 +867,8 @@
src/base/stl_allocator.h \
src/base/sysinfo.h \
src/base/thread_lister.h \
- src/heap-profile-table.h
+ src/heap-profile-table.h \
+ src/heap-profile-stats.h
SG_TCMALLOC_INCLUDES = src/gperftools/heap-profiler.h \
src/gperftools/heap-checker.h
TCMALLOC_INCLUDES = $(S_TCMALLOC_INCLUDES) $(SG_TCMALLOC_MINIMAL_INCLUDES) \
@@ -920,7 +937,7 @@
src/tcmalloc.h \
src/tests/testutil.h src/tests/testutil.cc \
$(TCMALLOC_UNITTEST_INCLUDES)
-tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
# We want libtcmalloc last on the link line, but due to a bug in
# libtool involving convenience libs, they need to come last on the
@@ -941,7 +958,7 @@
tcmalloc_both_unittest_srcs = src/tests/tcmalloc_unittest.cc \
src/tests/testutil.h src/tests/testutil.cc \
$(TCMALLOC_UNITTEST_INCLUDES)
-tcmalloc_both_unittest_cflags = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_both_unittest_cflags = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_both_unittest_lflags = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
if WITH_CPU_PROFILER
# We want libtcmalloc last on the link line, but due to a bug in
@@ -967,13 +984,13 @@
TESTS += tcmalloc_large_unittest
tcmalloc_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
-tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
tcmalloc_large_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
TESTS += tcmalloc_large_heap_fragmentation_unittest
tcmalloc_large_heap_fragmentation_unittest_SOURCES = src/tests/large_heap_fragmentation_unittest.cc
-tcmalloc_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_large_heap_fragmentation_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
tcmalloc_large_heap_fragmentation_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
@@ -1038,7 +1055,7 @@
src/gperftools/heap-profiler.h
heap_profiler_unittest_SOURCES = src/tests/heap-profiler_unittest.cc \
$(HEAP_PROFILER_UNITTEST_INCLUDES)
-heap_profiler_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+heap_profiler_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
heap_profiler_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
heap_profiler_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
@@ -1080,7 +1097,7 @@
$(LOGGING_INCLUDES)
heap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \
$(HEAP_CHECKER_UNITTEST_INCLUDES)
-heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
heap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
# We want libtcmalloc last on the link line, but due to a bug in
# libtool involving convenience libs, they need to come last on the
@@ -1406,5 +1423,6 @@
$(SCRIPTS) libtool \
src/windows/get_mangled_names.cc src/windows/override_functions.cc \
src/windows/config.h src/windows/gperftools/tcmalloc.h \
+ doc/pprof.see_also src/windows/TODO \
$(WINDOWS_PROJECTS) \
src/solaris/libstdc++.la
diff -Nru google-perftools-2.1/Makefile.in google-perftools-2.2.1/Makefile.in
--- google-perftools-2.1/Makefile.in 2013-07-30 11:12:29.000000000 +0200
+++ google-perftools-2.2.1/Makefile.in 2014-06-22 00:52:50.000000000 +0200
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -100,27 +100,28 @@
@GCC_TRUE@ -fno-builtin-memalign -fno-builtin-posix_memalign \
@GCC_TRUE@ -fno-builtin-valloc -fno-builtin-pvalloc
+@GCC_TRUE@am__append_3 = -fno-builtin
# On i386, -mmmx is needed for the mmx-based instructions in
# atomicops-internal-x86.h. Also as of gcc 4.6, -fomit-frame-pointer
# is the default. Since we must always have frame pointers for I386
# in order to generate backtraces we now specify -fno-omit-frame-pointer
# by default.
-@GCC_TRUE@@I386_TRUE@am__append_3 = -mmmx -fno-omit-frame-pointer
-@HAVE_W_NO_UNUSED_RESULT_TRUE@am__append_4 = -Wno-unused-result
+@GCC_TRUE@@I386_TRUE@am__append_4 = -mmmx -fno-omit-frame-pointer
+@HAVE_W_NO_UNUSED_RESULT_TRUE@am__append_5 = -Wno-unused-result
# These are x86-specific, having to do with frame-pointers. In
# particular, some x86_64 systems do not insert frame pointers by
# default (all i386 systems that I know of, do. I don't know about
# non-x86 chips). We need to tell perftools what to do about that.
-@ENABLE_FRAME_POINTERS_TRUE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@am__append_5 = -fno-omit-frame-pointer
-@ENABLE_FRAME_POINTERS_FALSE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@am__append_6 = -DNO_FRAME_POINTER
-@MINGW_TRUE@am__append_7 = -Wl,-u__tcmalloc
+@ENABLE_FRAME_POINTERS_TRUE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@am__append_6 = -fno-omit-frame-pointer
+@ENABLE_FRAME_POINTERS_FALSE@@X86_64_AND_NO_FP_BY_DEFAULT_TRUE@am__append_7 = -DNO_FRAME_POINTER
+@MINGW_TRUE@am__append_8 = -Wl,-u__tcmalloc
TESTS = low_level_alloc_unittest$(EXEEXT) atomicops_unittest$(EXEEXT) \
$(am__EXEEXT_9) tcmalloc_minimal_unittest$(EXEEXT) \
tcmalloc_minimal_large_unittest$(EXEEXT) \
tcmalloc_minimal_large_heap_fragmentation_unittest$(EXEEXT) \
- $(am__append_17) addressmap_unittest$(EXEEXT) $(am__EXEEXT_10) \
+ $(am__append_18) addressmap_unittest$(EXEEXT) $(am__EXEEXT_10) \
packed_cache_test$(EXEEXT) frag_unittest$(EXEEXT) \
markidle_unittest$(EXEEXT) \
current_allocated_bytes_test$(EXEEXT) \
@@ -129,38 +130,38 @@
pagemap_unittest$(EXEEXT) realloc_unittest$(EXEEXT) \
stack_trace_table_test$(EXEEXT) \
thread_dealloc_unittest$(EXEEXT) $(am__EXEEXT_13) \
- $(am__EXEEXT_14) $(am__EXEEXT_15) $(am__append_29) \
- $(am__append_39) $(am__EXEEXT_16) $(am__EXEEXT_17) \
- $(am__EXEEXT_18) $(am__append_49) $(am__EXEEXT_19) \
- $(am__append_58) $(am__append_60) $(am__EXEEXT_20) \
+ $(am__EXEEXT_14) $(am__EXEEXT_15) $(am__append_30) \
+ $(am__append_40) $(am__EXEEXT_16) $(am__EXEEXT_17) \
+ $(am__EXEEXT_18) $(am__append_50) $(am__EXEEXT_19) \
+ $(am__append_59) $(am__append_61) $(am__EXEEXT_20) \
$(am__EXEEXT_21)
noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
$(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \
$(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_22)
bin_PROGRAMS =
-@MINGW_TRUE@am__append_8 = libwindows.la libspinlock.la
+@MINGW_TRUE@am__append_9 = libwindows.la libspinlock.la
# We also need to tell mingw that sysinfo.cc needs shlwapi.lib.
# (We do this via a #pragma for msvc, but need to do it here for mingw).
-@MINGW_TRUE@am__append_9 = -lshlwapi
-@MINGW_FALSE@am__append_10 = libspinlock.la
-@WITH_STACK_TRACE_TRUE@am__append_11 = $(SG_STACKTRACE_INCLUDES)
+@MINGW_TRUE@am__append_10 = -lshlwapi
+@MINGW_FALSE@am__append_11 = libspinlock.la
+@WITH_STACK_TRACE_TRUE@am__append_12 = $(SG_STACKTRACE_INCLUDES)
### Making the library
-@WITH_STACK_TRACE_TRUE@am__append_12 = libstacktrace.la
+@WITH_STACK_TRACE_TRUE@am__append_13 = libstacktrace.la
### Unittests
-@WITH_STACK_TRACE_TRUE@am__append_13 = stacktrace_unittest
+@WITH_STACK_TRACE_TRUE@am__append_14 = stacktrace_unittest
### Documentation
-@WITH_STACK_TRACE_TRUE@am__append_14 = doc/pprof_remote_servers.html
+@WITH_STACK_TRACE_TRUE@am__append_15 = doc/pprof_remote_servers.html
# Let unittests find pprof if they need to run it
-@WITH_STACK_TRACE_TRUE@am__append_15 = PPROF_PATH=$(top_srcdir)/src/pprof
+@WITH_STACK_TRACE_TRUE@am__append_16 = PPROF_PATH=$(top_srcdir)/src/pprof
# On MSVC, we need our own versions of addr2line and nm to work with pprof.
# This is a slight abuse of WINDOWS_PROJECTS, but not much
-@WITH_STACK_TRACE_TRUE@am__append_16 = \
+@WITH_STACK_TRACE_TRUE@am__append_17 = \
@WITH_STACK_TRACE_TRUE@ vsprojects/nm-pdb/nm-pdb.vcproj \
@WITH_STACK_TRACE_TRUE@ vsprojects/addr2line-pdb/addr2line-pdb.vcproj \
@WITH_STACK_TRACE_TRUE@ src/windows/nm-pdb.c \
@@ -172,41 +173,41 @@
# libraries anyway (so can't be LD_PRELOADed) -- in fact, anybody who
# chooses not to build shared libraries won't be able to run this test.
# TODO(csilvers): figure out how to nix ".exe" or otherwise work under mingw
-@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_17 = maybe_threads_unittest.sh$(EXEEXT)
-@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_18 = $(maybe_threads_unittest_sh_SOURCES)
-@MINGW_TRUE@am__append_19 = src/windows/port.h src/windows/port.cc
-@MINGW_FALSE@am__append_20 = system_alloc_unittest
+@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_18 = maybe_threads_unittest.sh$(EXEEXT)
+@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_19 = $(maybe_threads_unittest_sh_SOURCES)
+@MINGW_TRUE@am__append_20 = src/windows/port.h src/windows/port.cc
+@MINGW_FALSE@am__append_21 = system_alloc_unittest
# This doesn't work with static linkage, because libtcmalloc.a isn't
# happy with C linkage (it misses the stdc++ library). Likewise with
# mingw, which links foo.a even though it doesn't set ENABLE_STATIC.
# TODO(csilvers): set enable_static=true in configure.ac:36?
-@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_21 = malloc_extension_c_test
+@ENABLE_STATIC_FALSE@@MINGW_FALSE@am__append_22 = malloc_extension_c_test
# -ansi here is just to help ensure the code is bog-standard C.
-@ENABLE_STATIC_FALSE@@GCC_TRUE@@MINGW_FALSE@am__append_22 = -ansi
-@MINGW_FALSE@@OSX_FALSE@am__append_23 = memalign_unittest
+@ENABLE_STATIC_FALSE@@GCC_TRUE@@MINGW_FALSE@am__append_23 = -ansi
+@MINGW_FALSE@@OSX_FALSE@am__append_24 = memalign_unittest
### ------- tcmalloc_minimal_debug (thread-caching malloc with debugallocation)
# Like tcmalloc.cc, debugallocation.cc needs exceptions to fulfill its
# API. Luckily, we can reuse everything else from tcmalloc_minimal.
-@WITH_DEBUGALLOC_TRUE@am__append_24 = libtcmalloc_minimal_debug.la
@WITH_DEBUGALLOC_TRUE@am__append_25 = libtcmalloc_minimal_debug.la
+@WITH_DEBUGALLOC_TRUE@am__append_26 = libtcmalloc_minimal_debug.la
### Unittests
-@WITH_DEBUGALLOC_TRUE@am__append_26 = tcmalloc_minimal_debug_unittest \
+@WITH_DEBUGALLOC_TRUE@am__append_27 = tcmalloc_minimal_debug_unittest \
@WITH_DEBUGALLOC_TRUE@ malloc_extension_debug_test
-@MINGW_FALSE@@OSX_FALSE@@WITH_DEBUGALLOC_TRUE@am__append_27 = memalign_debug_unittest
-@WITH_DEBUGALLOC_TRUE@am__append_28 = realloc_debug_unittest
+@MINGW_FALSE@@OSX_FALSE@@WITH_DEBUGALLOC_TRUE@am__append_28 = memalign_debug_unittest
+@WITH_DEBUGALLOC_TRUE@am__append_29 = realloc_debug_unittest
# debugallocation_test checks that we print a proper stacktrace when
# debug-allocs fail, so we can't run it if we don't have stacktrace info.
-@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@am__append_29 = debugallocation_test.sh$(EXEEXT)
-@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@am__append_30 = $(debugallocation_test_sh_SOURCES)
+@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@am__append_30 = debugallocation_test.sh$(EXEEXT)
+@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@am__append_31 = $(debugallocation_test_sh_SOURCES)
# This is the sub-program used by debugallocation_test.sh
-@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@am__append_31 = debugallocation_test
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_32 = $(SG_TCMALLOC_INCLUDES)
+@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@am__append_32 = debugallocation_test
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_33 = $(SG_TCMALLOC_INCLUDES)
### Making the library
@@ -214,24 +215,24 @@
# for all files in this library -- except tcmalloc.cc which needs them
# to fulfill its API. Automake doesn't allow per-file CXXFLAGS, so we need
# to separate into two libraries.
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_33 = libtcmalloc_internal.la
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_34 = libtcmalloc.la
-@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_35 = $(HEAP_CHECKER_SOURCES)
-@WITH_HEAP_CHECKER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_36 = -DNO_HEAP_CHECK
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_34 = libtcmalloc_internal.la
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_35 = libtcmalloc.la
+@WITH_HEAP_CHECKER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_36 = $(HEAP_CHECKER_SOURCES)
@WITH_HEAP_CHECKER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_37 = -DNO_HEAP_CHECK
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_38 = libtcmalloc.la
+@WITH_HEAP_CHECKER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_38 = -DNO_HEAP_CHECK
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_39 = libtcmalloc.la
### Unittests
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_39 = tcmalloc_unittest.sh$(EXEEXT)
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_40 = $(tcmalloc_unittest_sh_SOURCES) \
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_40 = tcmalloc_unittest.sh$(EXEEXT)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_41 = $(tcmalloc_unittest_sh_SOURCES) \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(sampling_test_sh_SOURCES)
# This is the sub-program used by sampling_test.sh
# The -g is so pprof can get symbol information.
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_41 = tcmalloc_unittest \
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_42 = tcmalloc_unittest \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ sampling_test
-@OSX_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_42 = tcmalloc_both_unittest
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_43 = \
+@OSX_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_43 = tcmalloc_both_unittest
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_44 = \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ tcmalloc_large_unittest \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ tcmalloc_large_heap_fragmentation_unittest \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ raw_printer_test \
@@ -242,74 +243,74 @@
# on, which it's not by default. Use the "standard" value of 2^19.
# These unittests often need to run binaries. They're in the current dir
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_44 = TCMALLOC_SAMPLE_PARAMETER=524288 \
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_45 = TCMALLOC_SAMPLE_PARAMETER=524288 \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ BINDIR=. \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ TMPDIR=/tmp/perftools
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_45 = vsprojects/sampler_test/sampler_test.vcproj
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_46 = vsprojects/sampler_test/sampler_test.vcproj
# Tests the compatibility include-headers in google/. Requires a function
# defined in the heap-profiler, which is why the test lives here.
-@WITH_HEAP_PROFILER_TRUE@am__append_46 = \
+@WITH_HEAP_PROFILER_TRUE@am__append_47 = \
@WITH_HEAP_PROFILER_TRUE@ heap-profiler_unittest.sh$(EXEEXT) \
@WITH_HEAP_PROFILER_TRUE@ simple_compat_test
-@WITH_HEAP_PROFILER_TRUE@am__append_47 = $(heap_profiler_unittest_sh_SOURCES)
+@WITH_HEAP_PROFILER_TRUE@am__append_48 = $(heap_profiler_unittest_sh_SOURCES)
# These are sub-programs used by heap-profiler_unittest.sh
-@WITH_HEAP_PROFILER_TRUE@am__append_48 = heap-profiler_unittest
-@WITH_HEAP_CHECKER_TRUE@am__append_49 = \
+@WITH_HEAP_PROFILER_TRUE@am__append_49 = heap-profiler_unittest
+@WITH_HEAP_CHECKER_TRUE@am__append_50 = \
@WITH_HEAP_CHECKER_TRUE@ heap-checker_unittest.sh$(EXEEXT) \
@WITH_HEAP_CHECKER_TRUE@ heap-checker-death_unittest.sh$(EXEEXT)
-@WITH_HEAP_CHECKER_TRUE@am__append_50 = \
+@WITH_HEAP_CHECKER_TRUE@am__append_51 = \
@WITH_HEAP_CHECKER_TRUE@ $(heap_checker_unittest_sh_SOURCES) \
@WITH_HEAP_CHECKER_TRUE@ $(top_srcdir)/$(heap_checker_death_unittest_sh_SOURCES)
# These are sub-programs used by heap-checker_unittest.sh
-@WITH_HEAP_CHECKER_TRUE@am__append_51 = heap-checker_unittest
+@WITH_HEAP_CHECKER_TRUE@am__append_52 = heap-checker_unittest
### Documentation (above and beyond tcmalloc_minimal documentation)
-@WITH_HEAP_PROFILER_TRUE@am__append_52 = doc/heapprofile.html doc/heap-example1.png
-@WITH_HEAP_CHECKER_TRUE@am__append_53 = doc/heap_checker.html
+@WITH_HEAP_PROFILER_TRUE@am__append_53 = doc/heapprofile.html doc/heap-example1.png
+@WITH_HEAP_CHECKER_TRUE@am__append_54 = doc/heap_checker.html
### ------- tcmalloc with debugallocation
-@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_54 = libtcmalloc_debug.la
@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_55 = libtcmalloc_debug.la
+@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_56 = libtcmalloc_debug.la
### Unittests
-@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_56 = tcmalloc_debug_unittest \
+@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_57 = tcmalloc_debug_unittest \
@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ sampler_debug_test \
@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ sampling_debug_test.sh$(EXEEXT)
# This is the sub-program using by sampling_debug_test.sh
# The -g is so pprof can get symbol information.
-@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_57 = sampling_debug_test
-@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__append_58 = heap-profiler_debug_unittest.sh$(EXEEXT)
+@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_58 = sampling_debug_test
+@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__append_59 = heap-profiler_debug_unittest.sh$(EXEEXT)
# These are sub-programs used by heap-profiler_debug_unittest.sh
-@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__append_59 = heap-profiler_debug_unittest
-@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__append_60 = heap-checker_debug_unittest.sh$(EXEEXT)
+@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_PROFILER_TRUE@am__append_60 = heap-profiler_debug_unittest
+@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__append_61 = heap-checker_debug_unittest.sh$(EXEEXT)
# These are sub-programs used by heap-checker_debug_unittest.sh
-@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__append_61 = heap-checker_debug_unittest
-@WITH_CPU_PROFILER_TRUE@am__append_62 = $(SG_CPU_PROFILER_INCLUDES)
+@WITH_DEBUGALLOC_TRUE@@WITH_HEAP_CHECKER_TRUE@am__append_62 = heap-checker_debug_unittest
+@WITH_CPU_PROFILER_TRUE@am__append_63 = $(SG_CPU_PROFILER_INCLUDES)
### Making the library
-@WITH_CPU_PROFILER_TRUE@am__append_63 = libprofiler.la
+@WITH_CPU_PROFILER_TRUE@am__append_64 = libprofiler.la
### Unittests
-@WITH_CPU_PROFILER_TRUE@am__append_64 = getpc_test \
+@WITH_CPU_PROFILER_TRUE@am__append_65 = getpc_test \
@WITH_CPU_PROFILER_TRUE@ profiledata_unittest \
@WITH_CPU_PROFILER_TRUE@ profile_handler_unittest \
@WITH_CPU_PROFILER_TRUE@ profiler_unittest.sh$(EXEEXT)
-@WITH_CPU_PROFILER_TRUE@am__append_65 = $(profiler_unittest_sh_SOURCES)
+@WITH_CPU_PROFILER_TRUE@am__append_66 = $(profiler_unittest_sh_SOURCES)
# These are sub-programs used by profiler_unittest.sh
-@WITH_CPU_PROFILER_TRUE@am__append_66 = profiler1_unittest profiler2_unittest profiler3_unittest \
+@WITH_CPU_PROFILER_TRUE@am__append_67 = profiler1_unittest profiler2_unittest profiler3_unittest \
@WITH_CPU_PROFILER_TRUE@ profiler4_unittest
@WITH_CPU_PROFILER_FALSE@profiler2_unittest_DEPENDENCIES =
### Documentation
-@WITH_CPU_PROFILER_TRUE@am__append_67 = doc/cpuprofile.html \
+@WITH_CPU_PROFILER_TRUE@am__append_68 = doc/cpuprofile.html \
@WITH_CPU_PROFILER_TRUE@ doc/cpuprofile-fileformat.html \
@WITH_CPU_PROFILER_TRUE@ doc/pprof-test-big.gif \
@WITH_CPU_PROFILER_TRUE@ doc/pprof-test.gif \
@@ -324,9 +325,9 @@
# works fine for .so files, it does not for .a files. The easiest way
# around this -- and I've tried a bunch of the hard ways -- is to just
# to create another set of libraries that has both functionality in it.
-@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_68 = libtcmalloc_and_profiler.la
-@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_69 = tcmalloc_and_profiler_unittest
-@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_70 = libtcmalloc_and_profiler.la
+@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_69 = libtcmalloc_and_profiler.la
+@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_70 = tcmalloc_and_profiler_unittest
+@WITH_CPU_PROFILER_TRUE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@am__append_71 = libtcmalloc_and_profiler.la
subdir = .
DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
@@ -419,6 +420,8 @@
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h \
src/base/dynamic_annotations.h src/third_party/valgrind.h \
src/gperftools/profiler.h src/gperftools/stacktrace.h
@WITH_CPU_PROFILER_TRUE@am__objects_2 = $(am__objects_1) \
@@ -448,7 +451,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h
@MINGW_FALSE@am_libspinlock_la_OBJECTS = spinlock.lo \
@MINGW_FALSE@ spinlock_internal.lo atomicops-internals-x86.lo \
@MINGW_FALSE@ $(am__objects_1)
@@ -462,11 +467,14 @@
@WITH_STACK_TRACE_TRUE@ $(am__DEPENDENCIES_1) $(LIBSPINLOCK)
am__libstacktrace_la_SOURCES_DIST = src/stacktrace.cc \
src/base/elf_mem_image.cc src/base/vdso_support.cc \
- src/stacktrace_config.h src/stacktrace_generic-inl.h \
+ src/stacktrace_impl_setup-inl.h src/stacktrace_generic-inl.h \
src/stacktrace_libunwind-inl.h src/stacktrace_arm-inl.h \
- src/stacktrace_powerpc-inl.h src/stacktrace_x86-inl.h \
- src/stacktrace_win32-inl.h src/base/elf_mem_image.h \
- src/base/vdso_support.h src/gperftools/stacktrace.h
+ src/stacktrace_powerpc-inl.h \
+ src/stacktrace_powerpc-darwin-inl.h \
+ src/stacktrace_powerpc-linux-inl.h src/stacktrace_x86-inl.h \
+ src/stacktrace_win32-inl.h src/stacktrace_instrument-inl.h \
+ src/base/elf_mem_image.h src/base/vdso_support.h \
+ src/gperftools/stacktrace.h
@WITH_STACK_TRACE_TRUE@am__objects_4 = $(am__objects_1) \
@WITH_STACK_TRACE_TRUE@ $(am__objects_1)
@WITH_STACK_TRACE_TRUE@am_libstacktrace_la_OBJECTS = stacktrace.lo \
@@ -497,7 +505,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/tcmalloc_guard.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/tcmalloc_guard.h \
src/base/commandlineflags.h src/base/basictypes.h \
src/pagemap.h src/sampler.h src/central_freelist.h \
src/linked_list.h src/libc_override.h \
@@ -514,7 +524,8 @@
src/base/linux_syscall_support.h src/base/linuxthreads.h \
src/base/stl_allocator.h src/base/sysinfo.h \
src/base/thread_lister.h src/heap-profile-table.h \
- src/gperftools/malloc_hook.h src/gperftools/malloc_hook_c.h \
+ src/heap-profile-stats.h src/gperftools/malloc_hook.h \
+ src/gperftools/malloc_hook_c.h \
src/gperftools/malloc_extension.h \
src/gperftools/malloc_extension_c.h \
src/gperftools/heap-profiler.h src/gperftools/heap-checker.h \
@@ -561,7 +572,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/tcmalloc_guard.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/tcmalloc_guard.h \
src/base/commandlineflags.h src/base/basictypes.h \
src/pagemap.h src/sampler.h src/central_freelist.h \
src/linked_list.h src/libc_override.h \
@@ -578,7 +591,8 @@
src/base/linux_syscall_support.h src/base/linuxthreads.h \
src/base/stl_allocator.h src/base/sysinfo.h \
src/base/thread_lister.h src/heap-profile-table.h \
- src/gperftools/malloc_hook.h src/gperftools/malloc_hook_c.h \
+ src/heap-profile-stats.h src/gperftools/malloc_hook.h \
+ src/gperftools/malloc_hook_c.h \
src/gperftools/malloc_extension.h \
src/gperftools/malloc_extension_c.h \
src/gperftools/heap-profiler.h src/gperftools/heap-checker.h \
@@ -627,7 +641,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/tcmalloc_guard.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/tcmalloc_guard.h \
src/base/commandlineflags.h src/base/basictypes.h \
src/pagemap.h src/sampler.h src/central_freelist.h \
src/linked_list.h src/libc_override.h \
@@ -644,7 +660,8 @@
src/base/linux_syscall_support.h src/base/linuxthreads.h \
src/base/stl_allocator.h src/base/sysinfo.h \
src/base/thread_lister.h src/heap-profile-table.h \
- src/gperftools/malloc_hook.h src/gperftools/malloc_hook_c.h \
+ src/heap-profile-stats.h src/gperftools/malloc_hook.h \
+ src/gperftools/malloc_hook_c.h \
src/gperftools/malloc_extension.h \
src/gperftools/malloc_extension_c.h \
src/gperftools/heap-profiler.h src/gperftools/heap-checker.h \
@@ -683,7 +700,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/tcmalloc_guard.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/tcmalloc_guard.h \
src/base/commandlineflags.h src/base/basictypes.h \
src/pagemap.h src/sampler.h src/central_freelist.h \
src/linked_list.h src/libc_override.h \
@@ -703,11 +722,13 @@
src/base/googleinit.h src/base/linux_syscall_support.h \
src/base/linuxthreads.h src/base/stl_allocator.h \
src/base/sysinfo.h src/base/thread_lister.h \
- src/heap-profile-table.h src/gperftools/heap-profiler.h \
- src/gperftools/heap-checker.h src/base/low_level_alloc.cc \
- src/heap-profile-table.cc src/heap-profiler.cc \
- src/raw_printer.cc src/memory_region_map.cc
+ src/heap-profile-table.h src/heap-profile-stats.h \
+ src/gperftools/heap-profiler.h src/gperftools/heap-checker.h \
+ src/base/low_level_alloc.cc src/heap-profile-table.cc \
+ src/heap-profiler.cc src/raw_printer.cc \
+ src/memory_region_map.cc
@MINGW_FALSE@am__objects_17 = libtcmalloc_internal_la-system-alloc.lo
+@HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE@@MINGW_TRUE@am__objects_18 = libtcmalloc_internal_la-maybe_threads.lo
@MINGW_FALSE@am__objects_18 = \
@MINGW_FALSE@ libtcmalloc_internal_la-maybe_threads.lo
am__objects_19 = $(am__objects_6) $(am__objects_1) $(am__objects_1)
@@ -754,7 +775,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/tcmalloc_guard.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/tcmalloc_guard.h \
src/base/commandlineflags.h src/base/basictypes.h \
src/pagemap.h src/sampler.h src/central_freelist.h \
src/linked_list.h src/libc_override.h \
@@ -793,7 +816,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/tcmalloc_guard.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/tcmalloc_guard.h \
src/base/commandlineflags.h src/base/basictypes.h \
src/pagemap.h src/sampler.h src/central_freelist.h \
src/linked_list.h src/libc_override.h \
@@ -837,7 +862,9 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/tcmalloc_guard.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/tcmalloc_guard.h \
src/base/commandlineflags.h src/base/basictypes.h \
src/pagemap.h src/sampler.h src/central_freelist.h \
src/linked_list.h src/libc_override.h \
@@ -854,6 +881,7 @@
src/gperftools/stacktrace.h
@MINGW_FALSE@am__objects_22 = \
@MINGW_FALSE@ libtcmalloc_minimal_internal_la-system-alloc.lo
+@HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE@@MINGW_TRUE@am__objects_23 = libtcmalloc_minimal_internal_la-maybe_threads.lo
@MINGW_FALSE@am__objects_23 = \
@MINGW_FALSE@ libtcmalloc_minimal_internal_la-maybe_threads.lo
am_libtcmalloc_minimal_internal_la_OBJECTS = \
@@ -883,14 +911,16 @@
src/windows/mingw.h src/windows/mini_disassembler.h \
src/windows/mini_disassembler_types.h \
src/windows/preamble_patcher.h src/windows/port.cc \
- src/windows/ia32_modrm_map.cc src/windows/ia32_opcode_map.cc \
+ src/windows/system-alloc.cc src/windows/ia32_modrm_map.cc \
+ src/windows/ia32_opcode_map.cc \
src/windows/mini_disassembler.cc \
src/windows/patch_functions.cc src/windows/preamble_patcher.cc \
src/windows/preamble_patcher_with_stub.cc
@MINGW_TRUE@am_libwindows_la_OBJECTS = $(am__objects_1) port.lo \
-@MINGW_TRUE@ ia32_modrm_map.lo ia32_opcode_map.lo \
-@MINGW_TRUE@ mini_disassembler.lo patch_functions.lo \
-@MINGW_TRUE@ preamble_patcher.lo preamble_patcher_with_stub.lo
+@MINGW_TRUE@ system-alloc.lo ia32_modrm_map.lo \
+@MINGW_TRUE@ ia32_opcode_map.lo mini_disassembler.lo \
+@MINGW_TRUE@ patch_functions.lo preamble_patcher.lo \
+@MINGW_TRUE@ preamble_patcher_with_stub.lo
libwindows_la_OBJECTS = $(am_libwindows_la_OBJECTS)
@MINGW_TRUE@am_libwindows_la_rpath =
@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@am__EXEEXT_1 = debugallocation_test$(EXEEXT)
@@ -936,7 +966,7 @@
tcmalloc_minimal_unittest$(EXEEXT) \
tcmalloc_minimal_large_unittest$(EXEEXT) \
tcmalloc_minimal_large_heap_fragmentation_unittest$(EXEEXT) \
- $(am__append_17) addressmap_unittest$(EXEEXT) $(am__EXEEXT_10) \
+ $(am__append_18) addressmap_unittest$(EXEEXT) $(am__EXEEXT_10) \
packed_cache_test$(EXEEXT) frag_unittest$(EXEEXT) \
markidle_unittest$(EXEEXT) \
current_allocated_bytes_test$(EXEEXT) \
@@ -945,10 +975,10 @@
pagemap_unittest$(EXEEXT) realloc_unittest$(EXEEXT) \
stack_trace_table_test$(EXEEXT) \
thread_dealloc_unittest$(EXEEXT) $(am__EXEEXT_13) \
- $(am__EXEEXT_14) $(am__EXEEXT_15) $(am__append_29) \
- $(am__append_39) $(am__EXEEXT_16) $(am__EXEEXT_17) \
- $(am__EXEEXT_18) $(am__append_49) $(am__EXEEXT_19) \
- $(am__append_58) $(am__append_60) $(am__EXEEXT_20) \
+ $(am__EXEEXT_14) $(am__EXEEXT_15) $(am__append_30) \
+ $(am__append_40) $(am__EXEEXT_16) $(am__EXEEXT_17) \
+ $(am__EXEEXT_18) $(am__append_50) $(am__EXEEXT_19) \
+ $(am__append_59) $(am__append_61) $(am__EXEEXT_20) \
$(am__EXEEXT_21)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
am__addressmap_unittest_SOURCES_DIST = \
@@ -1115,9 +1145,12 @@
src/base/spinlock_posix-inl.h \
src/base/synchronization_profiling.h \
src/base/atomicops-internals-arm-generic.h \
- src/base/atomicops-internals-arm-v6plus.h src/base/logging.h \
+ src/base/atomicops-internals-arm-v6plus.h \
+ src/base/atomicops-internals-mips.h \
+ src/base/atomicops-internals-gcc.h src/base/logging.h \
src/base/commandlineflags.h src/base/dynamic_annotations.h \
src/third_party/valgrind.h
+@HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE@@MINGW_TRUE@am__objects_28 = low_level_alloc_unittest-maybe_threads.$(OBJEXT)
@MINGW_FALSE@am__objects_28 = \
@MINGW_FALSE@ low_level_alloc_unittest-maybe_threads.$(OBJEXT)
am__objects_29 = $(am__objects_1) $(am__objects_1)
@@ -1450,10 +1483,12 @@
$(stack_trace_table_test_LDFLAGS) $(LDFLAGS) -o $@
am__stacktrace_unittest_SOURCES_DIST = \
src/tests/stacktrace_unittest.cc src/config_for_unittests.h \
- src/base/commandlineflags.h src/stacktrace_config.h \
+ src/base/commandlineflags.h src/stacktrace_impl_setup-inl.h \
src/stacktrace_generic-inl.h src/stacktrace_libunwind-inl.h \
src/stacktrace_arm-inl.h src/stacktrace_powerpc-inl.h \
- src/stacktrace_x86-inl.h src/stacktrace_win32-inl.h \
+ src/stacktrace_powerpc-darwin-inl.h \
+ src/stacktrace_powerpc-linux-inl.h src/stacktrace_x86-inl.h \
+ src/stacktrace_win32-inl.h src/stacktrace_instrument-inl.h \
src/base/elf_mem_image.h src/base/vdso_support.h \
src/gperftools/stacktrace.h src/base/logging.h \
src/base/basictypes.h src/base/dynamic_annotations.h \
@@ -2113,6 +2148,7 @@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
@@ -2210,8 +2246,9 @@
AM_CPPFLAGS = -I$(top_srcdir)/src $(am__append_1)
# This is mostly based on configure options
-AM_CXXFLAGS = $(am__append_2) $(am__append_3) $(am__append_4) \
- $(am__append_5) $(am__append_6)
+AM_CXXFLAGS = $(am__append_2) $(am__append_4) $(am__append_5) \
+ $(am__append_6) $(am__append_7)
+NO_BUILTIN_CXXFLAGS = $(am__append_3)
# The -no-undefined flag allows libtool to generate shared libraries for
# Cygwin and MinGW. LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
@@ -2230,7 +2267,7 @@
# accomplishes its tasks via patching, leaving no work for the linker
# to identify, so the linker will ignore libtcmalloc by default unless
# we explicitly create a dependency via -u.
-TCMALLOC_FLAGS = $(am__append_7)
+TCMALLOC_FLAGS = $(am__append_8)
@HAVE_OBJCOPY_WEAKEN_FALSE@WEAKEN = :
# If we have objcopy, make malloc/free/etc weak symbols. That way folks
@@ -2248,15 +2285,15 @@
@HAVE_OBJCOPY_WEAKEN_TRUE@ -W __Znwm -W __ZnwmRKSt9nothrow_t -W __Znam -W __ZnamRKSt9nothrow_t \
@HAVE_OBJCOPY_WEAKEN_TRUE@ -W __ZdlPv -W __ZdaPv
-LIBS_TO_WEAKEN = libtcmalloc_minimal.la $(am__append_25) \
- $(am__append_38) $(am__append_55) $(am__append_70)
+LIBS_TO_WEAKEN = libtcmalloc_minimal.la $(am__append_26) \
+ $(am__append_39) $(am__append_56) $(am__append_71)
perftoolsincludedir = $(includedir)/gperftools
# The .h files you want to install (that is, .h files that people
# who install this package can include in their own applications.)
# We'll add to this later, on a library-by-library basis
-perftoolsinclude_HEADERS = $(am__append_11) \
- $(SG_TCMALLOC_MINIMAL_INCLUDES) $(am__append_32) \
- $(am__append_62)
+perftoolsinclude_HEADERS = $(am__append_12) \
+ $(SG_TCMALLOC_MINIMAL_INCLUDES) $(am__append_33) \
+ $(am__append_63)
# tcmalloc.h is a special case, because it's a .h.in file
nodist_perftoolsinclude_HEADERS = src/gperftools/tcmalloc.h
noinst_HEADERS = src/gperftools/tcmalloc.h.in
@@ -2289,7 +2326,7 @@
# end of the world.
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
README_windows.txt TODO doc/index.html doc/designstyle.css \
- $(am__append_14) doc/tcmalloc.html doc/overview.gif \
+ $(am__append_15) doc/tcmalloc.html doc/overview.gif \
doc/pageheap.gif doc/spanmap.gif doc/threadheap.gif \
doc/t-test1.times.txt \
doc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png \
@@ -2314,13 +2351,13 @@
doc/tcmalloc-opspersec.vs.size.5.threads.png \
doc/tcmalloc-opspersec.vs.size.8.threads.png doc/overview.dot \
doc/pageheap.dot doc/spanmap.dot doc/threadheap.dot \
- $(am__append_52) $(am__append_53) $(am__append_67)
+ $(am__append_53) $(am__append_54) $(am__append_68)
# The libraries (.so's) you want to install
# We'll add to this later, on a library-by-library basis
-lib_LTLIBRARIES = libtcmalloc_minimal.la $(am__append_24) \
- $(am__append_34) $(am__append_54) $(am__append_63) \
- $(am__append_68)
+lib_LTLIBRARIES = libtcmalloc_minimal.la $(am__append_25) \
+ $(am__append_35) $(am__append_55) $(am__append_64) \
+ $(am__append_69)
# This is for 'convenience libraries' -- basically just a container for sources
### Making the library
@@ -2329,9 +2366,9 @@
# for all files in this library -- except tcmalloc.cc which needs them
# to fulfill its API. Automake doesn't allow per-file CXXFLAGS, so we need
# to separate into two libraries.
-noinst_LTLIBRARIES = liblogging.la libsysinfo.la $(am__append_8) \
- $(am__append_10) $(am__append_12) \
- libtcmalloc_minimal_internal.la $(am__append_33)
+noinst_LTLIBRARIES = liblogging.la libsysinfo.la $(am__append_9) \
+ $(am__append_11) $(am__append_13) \
+ libtcmalloc_minimal_internal.la $(am__append_34)
# Add this whether or not we're under MinGW, to keep the tarball complete.
# Because we've commented out the test, above, we have to explicitly add
@@ -2341,12 +2378,13 @@
src/windows/preamble_patcher_test.cc src/windows/shortproc.asm \
src/windows/auto_testing_hook.h \
vsprojects/low_level_alloc_unittest/low_level_alloc_unittest.vcproj \
- $(am__append_16) \
+ $(am__append_17) \
vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj \
vsprojects/tcmalloc_minimal_unittest/tcmalloc_minimal_unittest.vcproj \
vsprojects/tmu-static/tmu-static.vcproj \
vsprojects/tcmalloc_minimal_large/tcmalloc_minimal_large_unittest.vcproj \
vsprojects/addressmap_unittest/addressmap_unittest.vcproj \
+ vsprojects/system-alloc_unittest/system-alloc_unittest.vcproj \
vsprojects/packed-cache_test/packed-cache_test.vcproj \
vsprojects/frag_unittest/frag_unittest.vcproj \
vsprojects/markidle_unittest/markidle_unittest.vcproj \
@@ -2358,14 +2396,14 @@
vsprojects/realloc_unittest/realloc_unittest.vcproj \
vsprojects/stack_trace_table_test/stack_trace_table_test.vcproj \
vsprojects/thread_dealloc_unittest/thread_dealloc_unittest.vcproj \
- $(am__append_45)
+ $(am__append_46)
# TESTS_ENVIRONMENT sets environment variables for when you run unittest.
# We always get "srcdir" set for free.
# We'll add to this later, on a library-by-library basis.
-TESTS_ENVIRONMENT = $(am__append_15) $(am__append_44)
+TESTS_ENVIRONMENT = $(am__append_16) $(am__append_45)
# All script tests should be added here
-noinst_SCRIPTS = $(am__append_18) $(am__append_30) $(am__append_40) \
- $(am__append_47) $(am__append_50) $(am__append_65)
+noinst_SCRIPTS = $(am__append_19) $(am__append_31) $(am__append_41) \
+ $(am__append_48) $(am__append_51) $(am__append_66)
# This is my own var, used for extra libraries I make that I need installed
EXTRA_INSTALL =
@@ -2384,6 +2422,7 @@
$(LOGGING_INCLUDES)
SYSINFO_INCLUDES = src/base/sysinfo.h \
+ src/getenv_safe.h \
src/base/logging.h \
src/base/commandlineflags.h \
src/base/cycleclock.h \
@@ -2393,7 +2432,7 @@
libsysinfo_la_SOURCES = src/base/sysinfo.cc \
$(SYSINFO_INCLUDES)
-libsysinfo_la_LIBADD = $(NANOSLEEP_LIBS) $(am__append_9)
+libsysinfo_la_LIBADD = $(NANOSLEEP_LIBS) $(am__append_10)
# For MinGW, we use also have to use libwindows Luckily, we need the
# windows.a library in exactly the same place we need spinlock.a
@@ -2410,6 +2449,7 @@
@MINGW_TRUE@libwindows_la_SOURCES = $(WINDOWS_INCLUDES) \
@MINGW_TRUE@ src/windows/port.cc \
+@MINGW_TRUE@ src/windows/system-alloc.cc \
@MINGW_TRUE@ src/windows/ia32_modrm_map.cc \
@MINGW_TRUE@ src/windows/ia32_opcode_map.cc \
@MINGW_TRUE@ src/windows/mini_disassembler.cc \
@@ -2438,7 +2478,9 @@
@MINGW_TRUE@ src/base/atomicops-internals-linuxppc.h \
@MINGW_TRUE@ src/base/atomicops-internals-arm-generic.h \
@MINGW_TRUE@ src/base/atomicops-internals-arm-v6plus.h \
+@MINGW_TRUE@ src/base/atomicops-internals-mips.h \
@MINGW_TRUE@ src/base/atomicops-internals-windows.h \
+@MINGW_TRUE@ src/base/atomicops-internals-gcc.h \
@MINGW_TRUE@ src/base/atomicops-internals-x86.h
@MINGW_FALSE@libspinlock_la_SOURCES = src/base/spinlock.cc \
@@ -2461,9 +2503,10 @@
# patch_functions.cc #includes tcmalloc.cc, so no need to link it in.
@MINGW_TRUE@TCMALLOC_CC =
-@MINGW_FALSE@MAYBE_THREADS_CC = src/maybe_threads.cc
+@HAVE_PTHREAD_DESPITE_ASKING_FOR_FALSE@@MINGW_TRUE@MAYBE_THREADS_CC =
# windows has its own system for threads and system memory allocation.
-@MINGW_TRUE@MAYBE_THREADS_CC =
+@HAVE_PTHREAD_DESPITE_ASKING_FOR_TRUE@@MINGW_TRUE@MAYBE_THREADS_CC = src/maybe_threads.cc
+@MINGW_FALSE@MAYBE_THREADS_CC = src/maybe_threads.cc
@MINGW_FALSE@SYSTEM_ALLOC_CC = src/system-alloc.cc
@MINGW_TRUE@SYSTEM_ALLOC_CC =
@MINGW_FALSE@libspinlock_la_LIBADD = $(NANOSLEEP_LIBS)
@@ -2501,13 +2544,16 @@
### ------- stack trace
### The header files we use. We divide into categories based on directory
-@WITH_STACK_TRACE_TRUE@S_STACKTRACE_INCLUDES = src/stacktrace_config.h \
+@WITH_STACK_TRACE_TRUE@S_STACKTRACE_INCLUDES = src/stacktrace_impl_setup-inl.h \
@WITH_STACK_TRACE_TRUE@ src/stacktrace_generic-inl.h \
@WITH_STACK_TRACE_TRUE@ src/stacktrace_libunwind-inl.h \
@WITH_STACK_TRACE_TRUE@ src/stacktrace_arm-inl.h \
@WITH_STACK_TRACE_TRUE@ src/stacktrace_powerpc-inl.h \
+@WITH_STACK_TRACE_TRUE@ src/stacktrace_powerpc-darwin-inl.h \
+@WITH_STACK_TRACE_TRUE@ src/stacktrace_powerpc-linux-inl.h \
@WITH_STACK_TRACE_TRUE@ src/stacktrace_x86-inl.h \
@WITH_STACK_TRACE_TRUE@ src/stacktrace_win32-inl.h \
+@WITH_STACK_TRACE_TRUE@ src/stacktrace_instrument-inl.h \
@WITH_STACK_TRACE_TRUE@ src/base/elf_mem_image.h \
@WITH_STACK_TRACE_TRUE@ src/base/vdso_support.h
@@ -2624,7 +2670,7 @@
src/tests/testutil.h src/tests/testutil.cc \
$(TCMALLOC_UNITTEST_INCLUDES)
-tcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_minimal_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
# We want libtcmalloc last on the link line, but due to a bug in
# libtool involving convenience libs, they need to come last on the
@@ -2637,11 +2683,11 @@
liblogging.la $(PTHREAD_LIBS)
tcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
-tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_minimal_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
tcmalloc_minimal_large_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
tcmalloc_minimal_large_heap_fragmentation_unittest_SOURCES = src/tests/large_heap_fragmentation_unittest.cc
-tcmalloc_minimal_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+tcmalloc_minimal_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
tcmalloc_minimal_large_heap_fragmentation_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
tcmalloc_minimal_large_heap_fragmentation_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@ENABLE_STATIC_FALSE@@MINGW_FALSE@maybe_threads_unittest_sh_SOURCES = src/tests/maybe_threads_unittest.sh
@@ -2650,13 +2696,13 @@
$(LOGGING_INCLUDES)
addressmap_unittest_SOURCES = src/tests/addressmap_unittest.cc \
- $(ADDRESSMAP_UNITTEST_INCLUDES) $(am__append_19)
+ $(ADDRESSMAP_UNITTEST_INCLUDES) $(am__append_20)
addressmap_unittest_CXXFLAGS = -g $(AM_CXXFLAGS)
addressmap_unittest_LDADD = liblogging.la
@MINGW_FALSE@system_alloc_unittest_SOURCES = src/config_for_unittests.h \
@MINGW_FALSE@ src/tests/system-alloc_unittest.cc
-@MINGW_FALSE@system_alloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@MINGW_FALSE@system_alloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@MINGW_FALSE@system_alloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
@MINGW_FALSE@system_alloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
packed_cache_test_SOURCES = src/tests/packed-cache_test.cc
@@ -2664,14 +2710,14 @@
packed_cache_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
packed_cache_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
frag_unittest_SOURCES = src/tests/frag_unittest.cc src/config_for_unittests.h
-frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
frag_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
frag_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
markidle_unittest_SOURCES = src/tests/markidle_unittest.cc \
src/config_for_unittests.h \
src/tests/testutil.h src/tests/testutil.cc
-markidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+markidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
markidle_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
markidle_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
current_allocated_bytes_test_SOURCES = src/tests/current_allocated_bytes_test.cc \
@@ -2705,15 +2751,15 @@
@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_CFLAGS = \
@ENABLE_STATIC_FALSE@@MINGW_FALSE@ $(PTHREAD_CFLAGS) \
@ENABLE_STATIC_FALSE@@MINGW_FALSE@ $(AM_CFLAGS) \
-@ENABLE_STATIC_FALSE@@MINGW_FALSE@ $(am__append_22)
+@ENABLE_STATIC_FALSE@@MINGW_FALSE@ $(am__append_23)
@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
-@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
+@ENABLE_STATIC_FALSE@@MINGW_FALSE@malloc_extension_c_test_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS) -lstdc++
@MINGW_FALSE@@OSX_FALSE@memalign_unittest_SOURCES = src/tests/memalign_unittest.cc \
@MINGW_FALSE@@OSX_FALSE@ src/tcmalloc.h \
@MINGW_FALSE@@OSX_FALSE@ src/config_for_unittests.h \
@MINGW_FALSE@@OSX_FALSE@ src/tests/testutil.h src/tests/testutil.cc
-@MINGW_FALSE@@OSX_FALSE@memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@MINGW_FALSE@@OSX_FALSE@memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@MINGW_FALSE@@OSX_FALSE@memalign_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
@MINGW_FALSE@@OSX_FALSE@memalign_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
page_heap_test_SOURCES = src/tests/page_heap_test.cc \
@@ -2730,14 +2776,14 @@
src/base/logging.h \
src/pagemap.h
-pagemap_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+pagemap_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
pagemap_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
pagemap_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
realloc_unittest_SOURCES = src/tests/realloc_unittest.cc \
src/config_for_unittests.h \
src/base/logging.h
-realloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+realloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
realloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
realloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
stack_trace_table_test_SOURCES = src/tests/stack_trace_table_test.cc \
@@ -2750,7 +2796,7 @@
src/config_for_unittests.h \
src/tests/testutil.h src/tests/testutil.cc
-thread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+thread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
thread_dealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
thread_dealloc_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS)
@WITH_DEBUGALLOC_TRUE@libtcmalloc_minimal_debug_la_SOURCES = src/debugallocation.cc \
@@ -2784,7 +2830,7 @@
@WITH_DEBUGALLOC_TRUE@realloc_debug_unittest_LDADD = libtcmalloc_minimal_debug.la $(PTHREAD_LIBS)
@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@debugallocation_test_sh_SOURCES = src/tests/debugallocation_test.sh
@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@debugallocation_test_SOURCES = src/tests/debugallocation_test.cc
-@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@debugallocation_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@debugallocation_test_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
@WITH_DEBUGALLOC_TRUE@@WITH_STACK_TRACE_TRUE@debugallocation_test_LDADD = libtcmalloc_debug.la $(PTHREAD_LIBS)
@@ -2802,7 +2848,8 @@
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/base/stl_allocator.h \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/base/sysinfo.h \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/base/thread_lister.h \
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/heap-profile-table.h
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/heap-profile-table.h \
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/heap-profile-stats.h
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@SG_TCMALLOC_INCLUDES = src/gperftools/heap-profiler.h \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/gperftools/heap-checker.h
@@ -2822,17 +2869,17 @@
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(PTHREAD_CFLAGS) -DNDEBUG \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(AM_CXXFLAGS) \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(NO_EXCEPTIONS) \
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(am__append_36)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(am__append_37)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_internal_la_LDFLAGS = $(PTHREAD_CFLAGS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_internal_la_LIBADD = libstacktrace.la $(PTHREAD_LIBS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_SOURCES = \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(TCMALLOC_CC) \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(TCMALLOC_INCLUDES) \
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(am__append_35)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(am__append_36)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_CXXFLAGS = \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(PTHREAD_CFLAGS) -DNDEBUG \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(AM_CXXFLAGS) \
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(am__append_37)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(am__append_38)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@libtcmalloc_la_LIBADD = libtcmalloc_internal.la $(PTHREAD_LIBS)
@WITH_HEAP_CHECKER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@HEAP_CHECKER_SOURCES =
@@ -2856,7 +2903,7 @@
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/tests/testutil.h src/tests/testutil.cc \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(TCMALLOC_UNITTEST_INCLUDES)
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
# We want libtcmalloc last on the link line, but due to a bug in
# libtool involving convenience libs, they need to come last on the
@@ -2878,7 +2925,7 @@
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ src/tests/testutil.h src/tests/testutil.cc \
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ $(TCMALLOC_UNITTEST_INCLUDES)
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_cflags = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_cflags = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_lflags = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_ladd = $(LIBTCMALLOC) $(LIBTCMALLOC_MINIMAL) \
@WITH_CPU_PROFILER_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@ liblogging.la $(PTHREAD_LIBS)
@@ -2898,11 +2945,11 @@
@OSX_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_LDFLAGS = $(tcmalloc_both_unittest_lflags)
@OSX_FALSE@@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_both_unittest_LDADD = $(tcmalloc_both_unittest_ladd)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_heap_fragmentation_unittest_SOURCES = src/tests/large_heap_fragmentation_unittest.cc
-@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_heap_fragmentation_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@tcmalloc_large_heap_fragmentation_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
@WITH_HEAP_PROFILER_OR_CHECKER_TRUE@raw_printer_test_SOURCES = src/tests/raw_printer_test.cc
@@ -2933,7 +2980,7 @@
@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_SOURCES = src/tests/heap-profiler_unittest.cc \
@WITH_HEAP_PROFILER_TRUE@ $(HEAP_PROFILER_UNITTEST_INCLUDES)
-@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
@WITH_HEAP_PROFILER_TRUE@heap_profiler_unittest_LDADD = $(LIBTCMALLOC) $(PTHREAD_LIBS)
@WITH_HEAP_PROFILER_TRUE@simple_compat_test_SOURCES = src/tests/simple_compat_test.cc \
@@ -2953,7 +3000,7 @@
@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \
@WITH_HEAP_CHECKER_TRUE@ $(HEAP_CHECKER_UNITTEST_INCLUDES)
-@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS)
+@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
@WITH_HEAP_CHECKER_TRUE@heap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
# We want libtcmalloc last on the link line, but due to a bug in
# libtool involving convenience libs, they need to come last on the
@@ -3109,6 +3156,7 @@
$(SCRIPTS) libtool \
src/windows/get_mangled_names.cc src/windows/override_functions.cc \
src/windows/config.h src/windows/gperftools/tcmalloc.h \
+ doc/pprof.see_also src/windows/TODO \
$(WINDOWS_PROJECTS) \
src/solaris/libstdc++.la
@@ -3118,7 +3166,7 @@
.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
am--refresh: Makefile
@:
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -3145,20 +3193,20 @@
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
-$(top_srcdir)/configure: $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
src/config.h: src/stamp-h1
- @if test ! -f $@; then rm -f src/stamp-h1; else :; fi
- @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1; else :; fi
+ @test -f $@ || rm -f src/stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1
src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status
@rm -f src/stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status src/config.h
-$(top_srcdir)/src/config.h.in: $(am__configure_deps)
+$(top_srcdir)/src/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f src/stamp-h1
touch $@
@@ -3733,6 +3781,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system-alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system_alloc_unittest-system-alloc_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_and_profiler_unittest-tcmalloc_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_and_profiler_unittest-testutil.Po@am__quote@
@@ -3760,14 +3809,14 @@
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -4273,6 +4322,13 @@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o port.lo `test -f 'src/windows/port.cc' || echo '$(srcdir)/'`src/windows/port.cc
+system-alloc.lo: src/windows/system-alloc.cc
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT system-alloc.lo -MD -MP -MF $(DEPDIR)/system-alloc.Tpo -c -o system-alloc.lo `test -f 'src/windows/system-alloc.cc' || echo '$(srcdir)/'`src/windows/system-alloc.cc
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/system-alloc.Tpo $(DEPDIR)/system-alloc.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/windows/system-alloc.cc' object='system-alloc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o system-alloc.lo `test -f 'src/windows/system-alloc.cc' || echo '$(srcdir)/'`src/windows/system-alloc.cc
+
ia32_modrm_map.lo: src/windows/ia32_modrm_map.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ia32_modrm_map.lo -MD -MP -MF $(DEPDIR)/ia32_modrm_map.Tpo -c -o ia32_modrm_map.lo `test -f 'src/windows/ia32_modrm_map.cc' || echo '$(srcdir)/'`src/windows/ia32_modrm_map.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ia32_modrm_map.Tpo $(DEPDIR)/ia32_modrm_map.Plo
@@ -6020,10 +6076,16 @@
$(am__post_remove_distdir)
dist-tarZ: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@@ -6064,9 +6126,10 @@
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ && ../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
diff -Nru google-perftools-2.1/missing google-perftools-2.2.1/missing
--- google-perftools-2.1/missing 2013-07-30 11:12:29.000000000 +0200
+++ google-perftools-2.2.1/missing 2014-06-22 00:52:50.000000000 +0200
@@ -1,7 +1,7 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
-scriptversion=2012-06-26.16; # UTC
+scriptversion=2013-10-28.13; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard , 1996.
@@ -160,7 +160,7 @@
;;
autom4te*)
echo "You might have modified some maintainer files that require"
- echo "the 'automa4te' program to be rebuilt."
+ echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
diff -Nru google-perftools-2.1/NEWS google-perftools-2.2.1/NEWS
--- google-perftools-2.1/NEWS 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/NEWS 2014-06-22 00:52:29.000000000 +0200
@@ -1,3 +1,104 @@
+== 21 Jun 2014 ==
+
+gperftools 2.2.1 is out!
+
+Here's list of fixes:
+
+* issue-626 was closed. Which fixes initialization statically linked
+ tcmalloc.
+
+* issue 628 was closed. It adds missing header file into source
+ tarball. This fixes for compilation on PPC Linux.
+
+== 3 May 2014 ==
+
+gperftools 2.2 is out!
+
+Here are notable changes since 2.2rc:
+
+* issue 620 (crash on windows when c runtime dll is reloaded) was
+ fixed
+
+== 19 Apr 2014 ==
+
+gperftools 2.2rc is out!
+
+Here are notable changes since 2.1:
+
+* a number of fixes for a number compilers and platforms. Notably
+ Visual Studio 2013, recent mingw with c++ threads and some OSX
+ fixes.
+
+* we now have mips and mips64 support! (courtesy of Jovan Zelincevic,
+ Jean Lee, user xiaoyur347 and others)
+
+* we now have aarch64 (aka arm64) support! (contributed by Riku
+ Voipio)
+
+* there's now support for ppc64-le (by Raphael Moreira Zinsly and
+ Adhemerval Zanella)
+
+* there's now some support of uclibc (contributed by user xiaoyur347)
+
+* google/ headers will now give you deprecation warning. They are
+ deprecated since 2.0
+
+* there's now new api: tc_malloc_skip_new_handler (ported from chromium
+ fork)
+
+* issue-557: added support for dumping heap profile via signal (by
+ Jean Lee)
+
+* issue-567: Petr Hosek contributed SysAllocator support for windows
+
+* Joonsoo Kim contributed several speedups for central freelist code
+
+* TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES environment variable now works
+
+* configure scripts are now using AM_MAINTAINER_MODE. It'll only
+ affect folks who modify source from .tar.gz and want automake to
+ automatically rebuild Makefile-s. See automake documentation for
+ that.
+
+* issue-586: detect main executable even if PIE is active (based on
+ patch by user themastermind1). Notably, it fixes profiler use with
+ ruby.
+
+* there is now support for switching backtrace capturing method at
+ runtime (via TCMALLOC_STACKTRACE_METHOD and
+ TCMALLOC_STACKTRACE_METHOD_VERBOSE environment variables)
+
+* there is new backtrace capturing method using -finstrument-functions
+ prologues contributed by user xiaoyur347
+
+* few cases of crashes/deadlocks in profiler were addressed. See
+ (famous) issue-66, issue-547 and issue-579.
+
+* issue-464 (memory corruption in debugalloc's realloc after
+ memallign) is now fixed
+
+* tcmalloc is now able to release memory back to OS on windows
+ (issue-489). The code was ported from chromium fork (by a number of
+ authors).
+
+* Together with issue-489 we ported chromium's "aggressive decommit"
+ mode. In this mode (settable via malloc extension and via
+ environment variable TCMALLOC_AGGRESSIVE_DECOMMIT), free pages are
+ returned back to OS immediately.
+
+* MallocExtension::instance() is now faster (based on patch by
+ Adhemerval Zanella)
+
+* issue-610 (hangs on windows in multibyte locales) is now fixed
+
+The following people helped with ideas or patches (based on git log,
+some contributions purely in bugtracker might be missing): Andrew
+C. Morrow, yurivict, Wang YanQing, Thomas Klausner,
+davide.italiano@10gen.com, Dai MIKURUBE, Joon-Sung Um, Jovan
+Zelincevic, Jean Lee, Petr Hosek, Ben Avison, drussel, Joonsoo Kim,
+Hannes Weisbach, xiaoyur347, Riku Voipio, Adhemerval Zanella, Raphael
+Moreira Zinsly
+
== 30 July 2013 ==
gperftools 2.1 is out!
diff -Nru google-perftools-2.1/src/addressmap-inl.h google-perftools-2.2.1/src/addressmap-inl.h
--- google-perftools-2.1/src/addressmap-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/addressmap-inl.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/atomicops.h google-perftools-2.2.1/src/base/atomicops.h
--- google-perftools-2.1/src/base/atomicops.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
@@ -97,9 +98,13 @@
// ------------------------------------------------------------------------
#include "base/arm_instruction_set_select.h"
-
-// TODO(csilvers): match piii, not just __i386. Also, match k8
-#if defined(__MACH__) && defined(__APPLE__)
+#define GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
+#if defined(TCMALLOC_PREFER_GCC_ATOMICS) && defined(__GNUC__) && GCC_VERSION >= 40700
+#include "base/atomicops-internals-gcc.h"
+#elif defined(__MACH__) && defined(__APPLE__)
#include "base/atomicops-internals-macosx.h"
#elif defined(__GNUC__) && defined(ARMV6)
#include "base/atomicops-internals-arm-v6plus.h"
@@ -111,12 +116,12 @@
#include "base/atomicops-internals-windows.h"
#elif defined(__linux__) && defined(__PPC__)
#include "base/atomicops-internals-linuxppc.h"
+#elif defined(__GNUC__) && defined(__mips__)
+#include "base/atomicops-internals-mips.h"
+#elif defined(__GNUC__) && GCC_VERSION >= 40700
+#include "base/atomicops-internals-gcc.h"
#else
-// Assume x86 for now. If you need to support a new architecture and
-// don't know how to implement atomic ops, you can probably get away
-// with using pthreads, since atomicops is only used by spinlock.h/cc
-//#error You need to implement atomic operations for this architecture
-#include "base/atomicops-internals-x86.h"
+#error You need to implement atomic operations for this architecture
#endif
// Signed type that can hold a pointer and supports the atomic ops below, as
@@ -171,21 +176,6 @@
reinterpret_cast(ptr), new_value);
}
-// Atomically increment *ptr by "increment". Returns the new value of
-// *ptr with the increment applied. This routine implies no memory
-// barriers.
-inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
- AtomicWord increment) {
- return NoBarrier_AtomicIncrement(
- reinterpret_cast(ptr), increment);
-}
-
-inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
- AtomicWord increment) {
- return Barrier_AtomicIncrement(
- reinterpret_cast(ptr), increment);
-}
-
inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
AtomicWord old_value,
AtomicWord new_value) {
@@ -263,9 +253,6 @@
Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
Atomic32 Release_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
-Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment);
Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value);
@@ -286,8 +273,6 @@
Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
Atomic64 Release_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
-Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
diff -Nru google-perftools-2.1/src/base/atomicops-internals-arm-generic.h google-perftools-2.2.1/src/base/atomicops-internals-arm-generic.h
--- google-perftools-2.1/src/base/atomicops-internals-arm-generic.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops-internals-arm-generic.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2003, Google Inc.
// All rights reserved.
//
@@ -32,7 +33,7 @@
//
// This file is an internal atomic implementation, use base/atomicops.h instead.
//
-// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
+// LinuxKernelCmpxchg is from Google Gears.
#ifndef BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
#define BASE_ATOMICOPS_INTERNALS_ARM_GENERIC_H_
@@ -101,26 +102,6 @@
return NoBarrier_AtomicExchange(ptr, new_value);
}
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- for (;;) {
- // Atomic exchange the old value with an incremented one.
- Atomic32 old_value = *ptr;
- Atomic32 new_value = old_value + increment;
- if (pLinuxKernelCmpxchg(old_value, new_value,
- const_cast(ptr)) == 0) {
- // The exchange took place as expected.
- return new_value;
- }
- // Otherwise, *ptr changed mid-loop and we need to retry.
- }
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return Barrier_AtomicIncrement(ptr, increment);
-}
-
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
@@ -200,18 +181,6 @@
return NoBarrier_AtomicExchange(ptr, new_value);
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- NotImplementedFatalError("NoBarrier_AtomicIncrement");
- return 0;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- NotImplementedFatalError("Barrier_AtomicIncrement");
- return 0;
-}
-
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
NotImplementedFatalError("NoBarrier_Store");
}
diff -Nru google-perftools-2.1/src/base/atomicops-internals-arm-v6plus.h google-perftools-2.2.1/src/base/atomicops-internals-arm-v6plus.h
--- google-perftools-2.1/src/base/atomicops-internals-arm-v6plus.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops-internals-arm-v6plus.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
@@ -116,39 +117,6 @@
return NoBarrier_AtomicExchange(ptr, new_value);
}
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 tmp, res;
- __asm__ __volatile__(
- "1:\n"
- "ldrex %1, [%2]\n"
- "add %1, %1, %3\n"
- "strex %0, %1, [%2]\n"
- "teq %0, #0\n"
- "bne 1b"
- : "=&r" (tmp), "=&r"(res)
- : "r" (ptr), "r"(increment)
- : "cc", "memory");
- return res;
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 tmp, res;
- __asm__ __volatile__(
- "1:\n"
- "ldrex %1, [%2]\n"
- "add %1, %1, %3\n"
- "dmb\n"
- "strex %0, %1, [%2]\n"
- "teq %0, #0\n"
- "bne 1b"
- : "=&r" (tmp), "=&r"(res)
- : "r" (ptr), "r"(increment)
- : "cc", "memory");
- return res;
-}
-
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
@@ -251,43 +219,6 @@
return NoBarrier_AtomicExchange(ptr, new_value);
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- int store_failed;
- Atomic64 res;
- __asm__ __volatile__(
- "1:\n"
- "ldrexd %1, [%2]\n"
- "adds %Q1, %Q1, %Q3\n"
- "adc %R1, %R1, %R3\n"
- "strexd %0, %1, [%2]\n"
- "teq %0, #0\n"
- "bne 1b"
- : "=&r" (store_failed), "=&r"(res)
- : "r" (ptr), "r"(increment)
- : "cc", "memory");
- return res;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- int store_failed;
- Atomic64 res;
- __asm__ __volatile__(
- "1:\n"
- "ldrexd %1, [%2]\n"
- "adds %Q1, %Q1, %Q3\n"
- "adc %R1, %R1, %R3\n"
- "dmb\n"
- "strexd %0, %1, [%2]\n"
- "teq %0, #0\n"
- "bne 1b"
- : "=&r" (store_failed), "=&r"(res)
- : "r" (ptr), "r"(increment)
- : "cc", "memory");
- return res;
-}
-
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
int store_failed;
Atomic64 dummy;
@@ -346,18 +277,6 @@
return 0;
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- NotImplementedFatalError("NoBarrier_AtomicIncrement");
- return 0;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- NotImplementedFatalError("Barrier_AtomicIncrement");
- return 0;
-}
-
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
NotImplementedFatalError("NoBarrier_Store");
}
diff -Nru google-perftools-2.1/src/base/atomicops-internals-gcc.h google-perftools-2.2.1/src/base/atomicops-internals-gcc.h
--- google-perftools-2.1/src/base/atomicops-internals-gcc.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/base/atomicops-internals-gcc.h 2014-02-22 21:25:25.000000000 +0100
@@ -0,0 +1,203 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+// Copyright (c) 2014, Linaro
+// 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 Google Inc. 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.
+// ---
+//
+// Author: Riku Voipio, riku.voipio@linaro.org
+//
+// atomic primitives implemented with gcc atomic intrinsics:
+// http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
+//
+
+#ifndef BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
+#define BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
+
+#include
+#include
+#include "base/basictypes.h"
+
+typedef int32_t Atomic32;
+
+namespace base {
+namespace subtle {
+
+typedef int64_t Atomic64;
+
+inline void MemoryBarrier() {
+ __sync_synchronize();
+}
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value = old_value;
+ __atomic_compare_exchange_n(ptr, &prev_value, new_value,
+ 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+ return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ return __atomic_exchange_n(const_cast(ptr), new_value, __ATOMIC_RELAXED);
+}
+
+inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ return __atomic_exchange_n(const_cast(ptr), new_value, __ATOMIC_ACQUIRE);
+}
+
+inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ return __atomic_exchange_n(const_cast(ptr), new_value, __ATOMIC_RELEASE);
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value = old_value;
+ __atomic_compare_exchange_n(ptr, &prev_value, new_value,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
+ return prev_value;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value = old_value;
+ __atomic_compare_exchange_n(ptr, &prev_value, new_value,
+ 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+ return prev_value;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+// 64-bit versions
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev_value = old_value;
+ __atomic_compare_exchange_n(ptr, &prev_value, new_value,
+ 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+ return prev_value;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ return __atomic_exchange_n(const_cast(ptr), new_value, __ATOMIC_RELAXED);
+}
+
+inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ return __atomic_exchange_n(const_cast(ptr), new_value, __ATOMIC_ACQUIRE);
+}
+
+inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ return __atomic_exchange_n(const_cast(ptr), new_value, __ATOMIC_RELEASE);
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev_value = old_value;
+ __atomic_compare_exchange_n(ptr, &prev_value, new_value,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
+ return prev_value;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev_value = old_value;
+ __atomic_compare_exchange_n(ptr, &prev_value, new_value,
+ 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
+ return prev_value;
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+} // namespace base::subtle
+} // namespace base
+
+#endif // BASE_ATOMICOPS_INTERNALS_GCC_GENERIC_H_
diff -Nru google-perftools-2.1/src/base/atomicops-internals-linuxppc.h google-perftools-2.2.1/src/base/atomicops-internals-linuxppc.h
--- google-perftools-2.1/src/base/atomicops-internals-linuxppc.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops-internals-linuxppc.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
@@ -183,16 +184,6 @@
return old_value;
}
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- return OSAtomicAdd32(increment, const_cast(ptr));
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- return OSAtomicAdd32Barrier(increment, const_cast(ptr));
-}
-
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
Atomic32 old_value,
Atomic32 new_value) {
@@ -334,16 +325,6 @@
return old_value;
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
- Atomic64 increment) {
- return OSAtomicAdd64(increment, const_cast(ptr));
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
- Atomic64 increment) {
- return OSAtomicAdd64Barrier(increment, const_cast(ptr));
-}
-
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
Atomic64 old_value,
Atomic64 new_value) {
diff -Nru google-perftools-2.1/src/base/atomicops-internals-macosx.h google-perftools-2.2.1/src/base/atomicops-internals-macosx.h
--- google-perftools-2.1/src/base/atomicops-internals-macosx.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops-internals-macosx.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
@@ -147,16 +148,6 @@
return Acquire_AtomicExchange(ptr, new_value);
}
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- return OSAtomicAdd32(increment, const_cast(ptr));
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- return OSAtomicAdd32Barrier(increment, const_cast(ptr));
-}
-
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
Atomic32 old_value,
Atomic32 new_value) {
@@ -247,16 +238,6 @@
return Acquire_AtomicExchange(ptr, new_value);
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
- Atomic64 increment) {
- return OSAtomicAdd64(increment, const_cast(ptr));
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
- Atomic64 increment) {
- return OSAtomicAdd64Barrier(increment, const_cast(ptr));
-}
-
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
Atomic64 old_value,
Atomic64 new_value) {
diff -Nru google-perftools-2.1/src/base/atomicops-internals-mips.h google-perftools-2.2.1/src/base/atomicops-internals-mips.h
--- google-perftools-2.1/src/base/atomicops-internals-mips.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/base/atomicops-internals-mips.h 2014-02-22 21:25:25.000000000 +0100
@@ -0,0 +1,323 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+/* Copyright (c) 2013, Google Inc.
+ * 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 Google Inc. 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.
+ */
+
+// Author: Jovan Zelincevic
+// based on atomicops-internals by Sanjay Ghemawat
+
+// This file is an internal atomic implementation, use base/atomicops.h instead.
+//
+// This code implements MIPS atomics.
+
+#ifndef BASE_ATOMICOPS_INTERNALS_MIPS_H_
+#define BASE_ATOMICOPS_INTERNALS_MIPS_H_
+
+#if (_MIPS_ISA == _MIPS_ISA_MIPS64)
+#define BASE_HAS_ATOMIC64 1
+#endif
+
+typedef int32_t Atomic32;
+
+namespace base {
+namespace subtle {
+
+// Atomically execute:
+// result = *ptr;
+// if (*ptr == old_value)
+// *ptr = new_value;
+// return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value)
+{
+ Atomic32 prev, tmp;
+ __asm__ volatile(
+ ".set push \n"
+ ".set noreorder \n"
+
+ "1: \n"
+ "ll %0, %5 \n" // prev = *ptr
+ "bne %0, %3, 2f \n" // if (prev != old_value) goto 2
+ " move %2, %4 \n" // tmp = new_value
+ "sc %2, %1 \n" // *ptr = tmp (with atomic check)
+ "beqz %2, 1b \n" // start again on atomic error
+ " nop \n" // delay slot nop
+ "2: \n"
+
+ ".set pop \n"
+ : "=&r" (prev), "=m" (*ptr),
+ "=&r" (tmp)
+ : "Ir" (old_value), "r" (new_value),
+ "m" (*ptr)
+ : "memory"
+ );
+ return prev;
+}
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr. This routine implies no memory barriers.
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value)
+{
+ Atomic32 temp, old;
+ __asm__ volatile(
+ ".set push \n"
+ ".set noreorder \n"
+
+ "1: \n"
+ "ll %1, %2 \n" // old = *ptr
+ "move %0, %3 \n" // temp = new_value
+ "sc %0, %2 \n" // *ptr = temp (with atomic check)
+ "beqz %0, 1b \n" // start again on atomic error
+ " nop \n" // delay slot nop
+
+ ".set pop \n"
+ : "=&r" (temp), "=&r" (old),
+ "=m" (*ptr)
+ : "r" (new_value), "m" (*ptr)
+ : "memory"
+ );
+ return old;
+}
+
+inline void MemoryBarrier()
+{
+ __asm__ volatile("sync" : : : "memory");
+}
+
+// "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation. "Barrier" operations have both "Acquire" and "Release"
+// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value)
+{
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+ return res;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value)
+{
+ MemoryBarrier();
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ return res;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value)
+{
+ *ptr = value;
+}
+
+inline Atomic32 Acquire_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value)
+{
+ Atomic32 old_value = NoBarrier_AtomicExchange(ptr, new_value);
+ MemoryBarrier();
+ return old_value;
+}
+
+inline Atomic32 Release_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value)
+{
+ MemoryBarrier();
+ return NoBarrier_AtomicExchange(ptr, new_value);
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value)
+{
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value)
+{
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr)
+{
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr)
+{
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr)
+{
+ MemoryBarrier();
+ return *ptr;
+}
+
+#if (_MIPS_ISA == _MIPS_ISA_MIPS64) || (_MIPS_SIM == _MIPS_SIM_ABI64)
+
+typedef int64_t Atomic64;
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value)
+{
+ Atomic64 prev, tmp;
+ __asm__ volatile(
+ ".set push \n"
+ ".set noreorder \n"
+
+ "1: \n"
+ "lld %0, %5 \n" // prev = *ptr
+ "bne %0, %3, 2f \n" // if (prev != old_value) goto 2
+ " move %2, %4 \n" // tmp = new_value
+ "scd %2, %1 \n" // *ptr = tmp (with atomic check)
+ "beqz %2, 1b \n" // start again on atomic error
+ " nop \n" // delay slot nop
+ "2: \n"
+
+ ".set pop \n"
+ : "=&r" (prev), "=m" (*ptr),
+ "=&r" (tmp)
+ : "Ir" (old_value), "r" (new_value),
+ "m" (*ptr)
+ : "memory"
+ );
+ return prev;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value)
+{
+ Atomic64 temp, old;
+ __asm__ volatile(
+ ".set push \n"
+ ".set noreorder \n"
+
+ "1: \n"
+ "lld %1, %2 \n" // old = *ptr
+ "move %0, %3 \n" // temp = new_value
+ "scd %0, %2 \n" // *ptr = temp (with atomic check)
+ "beqz %0, 1b \n" // start again on atomic error
+ " nop \n" // delay slot nop
+
+ ".set pop \n"
+ : "=&r" (temp), "=&r" (old),
+ "=m" (*ptr)
+ : "r" (new_value), "m" (*ptr)
+ : "memory"
+ );
+ return old;
+}
+
+inline Atomic64 Acquire_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value)
+{
+ Atomic64 old_value = NoBarrier_AtomicExchange(ptr, new_value);
+ MemoryBarrier();
+ return old_value;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value)
+{
+ Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+ return res;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value)
+{
+ MemoryBarrier();
+ Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ return res;
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value)
+{
+ *ptr = value;
+}
+
+inline Atomic64 Release_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value)
+{
+ MemoryBarrier();
+ return NoBarrier_AtomicExchange(ptr, new_value);
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value)
+{
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value)
+{
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr)
+{
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr)
+{
+ Atomic64 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr)
+{
+ MemoryBarrier();
+ return *ptr;
+}
+
+#endif
+
+} // namespace base::subtle
+} // namespace base
+
+#endif // BASE_ATOMICOPS_INTERNALS_MIPS_H_
diff -Nru google-perftools-2.1/src/base/atomicops-internals-windows.h google-perftools-2.2.1/src/base/atomicops-internals-windows.h
--- google-perftools-2.1/src/base/atomicops-internals-windows.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops-internals-windows.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
@@ -149,18 +150,6 @@
return NoBarrier_AtomicExchange(ptr, new_value);
}
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return FastInterlockedExchangeAdd(
- reinterpret_cast(ptr),
- static_cast(increment)) + increment;
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return Barrier_AtomicIncrement(ptr, increment);
-}
-
} // namespace base::subtle
} // namespace base
@@ -305,18 +294,6 @@
return reinterpret_cast(result);
}
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- return FastInterlockedExchangeAdd64(
- reinterpret_cast(ptr),
- static_cast(increment)) + increment;
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- return Barrier_AtomicIncrement(ptr, increment);
-}
-
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
}
@@ -405,45 +382,6 @@
return 0;
#endif
}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
-#if 0 // Not implemented
- Atomic64 temp = increment;
- __asm__ __volatile__(
- "0:\n\t"
- "movl (%3), %%ebx\n\t" // Move 64-bit increment into
- "movl 4(%3), %%ecx\n\t" // ecx:ebx
- "movl (%2), %%eax\n\t" // Read contents of ptr into
- "movl 4(%2), %%edx\n\t" // edx:eax
- "add %%eax, %%ebx\n\t" // sum => ecx:ebx
- "adc %%edx, %%ecx\n\t" // edx:eax still has old *ptr
- "lock; cmpxchg8b (%2)\n\t"// Attempt cmpxchg; if *ptr
- "jnz 0b\n\t" // is no longer edx:eax, loop
- : "=A"(temp), "+m"(*ptr)
- : "D" (ptr), "S" (&increment)
- : "memory", "%ebx", "%ecx");
- // temp now contains the previous value of *ptr
- return temp + increment;
-#else
- NotImplementedFatalError("NoBarrier_AtomicIncrement");
- return 0;
-#endif
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
-#if 0 // Not implemented
- Atomic64 new_val = NoBarrier_AtomicIncrement(ptr, increment);
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return new_val;
-#else
- NotImplementedFatalError("Barrier_AtomicIncrement");
- return 0;
-#endif
-}
inline void NoBarrier_Store(volatile Atomic64* ptrValue, Atomic64 value)
{
diff -Nru google-perftools-2.1/src/base/atomicops-internals-x86.cc google-perftools-2.2.1/src/base/atomicops-internals-x86.cc
--- google-perftools-2.1/src/base/atomicops-internals-x86.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops-internals-x86.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/atomicops-internals-x86.h google-perftools-2.2.1/src/base/atomicops-internals-x86.h
--- google-perftools-2.1/src/base/atomicops-internals-x86.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/atomicops-internals-x86.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
@@ -104,29 +105,6 @@
return NoBarrier_AtomicExchange(ptr, new_value);
}
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 temp = increment;
- __asm__ __volatile__("lock; xaddl %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now holds the old value of *ptr
- return temp + increment;
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 temp = increment;
- __asm__ __volatile__("lock; xaddl %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now holds the old value of *ptr
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return temp + increment;
-}
-
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
@@ -242,29 +220,6 @@
return NoBarrier_AtomicExchange(ptr, new_value);
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 temp = increment;
- __asm__ __volatile__("lock; xaddq %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now contains the previous value of *ptr
- return temp + increment;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 temp = increment;
- __asm__ __volatile__("lock; xaddq %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now contains the previous value of *ptr
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return temp + increment;
-}
-
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
}
@@ -377,27 +332,6 @@
return NoBarrier_AtomicExchange(ptr, new_val);
}
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 old_val, new_val;
-
- do {
- old_val = *ptr;
- new_val = old_val + increment;
- } while (__sync_val_compare_and_swap(ptr, old_val, new_val) != old_val);
-
- return old_val + increment;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 new_val = NoBarrier_AtomicIncrement(ptr, increment);
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return new_val;
-}
-
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
__asm__ __volatile__("movq %1, %%mm0\n\t" // Use mmx reg for 64-bit atomic
"movq %%mm0, %0\n\t" // moves (ptr could be read-only)
diff -Nru google-perftools-2.1/src/base/basictypes.h google-perftools-2.2.1/src/base/basictypes.h
--- google-perftools-2.1/src/base/basictypes.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/basictypes.h 2014-03-01 20:24:54.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -345,6 +346,11 @@
# elif (defined(__arm__))
# define CACHELINE_ALIGNED __attribute__((aligned(64)))
// some ARMs have shorter cache lines (ARM1176JZF-S is 32 bytes for example) but obviously 64-byte aligned implies 32-byte aligned
+# elif (defined(__mips__))
+# define CACHELINE_ALIGNED __attribute__((aligned(128)))
+# elif (defined(__aarch64__))
+# define CACHELINE_ALIGNED __attribute__((aligned(64)))
+ // implementation specific, Cortex-A53 and 57 should have 64 bytes
# else
# error Could not determine cache line length - unknown architecture
# endif
diff -Nru google-perftools-2.1/src/base/commandlineflags.h google-perftools-2.2.1/src/base/commandlineflags.h
--- google-perftools-2.1/src/base/commandlineflags.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/commandlineflags.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/cycleclock.h google-perftools-2.2.1/src/base/cycleclock.h
--- google-perftools-2.1/src/base/cycleclock.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/cycleclock.h 2014-03-01 20:24:54.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2004, Google Inc.
// All rights reserved.
//
@@ -49,7 +50,7 @@
#include "base/arm_instruction_set_select.h"
// base/sysinfo.h is really big and we don't want to include it unless
// it is necessary.
-#if defined(__arm__) || defined(__mips__)
+#if defined(__arm__) || defined(__mips__) || defined(__aarch64__)
# include "base/sysinfo.h"
#endif
#if defined(__MACH__) && defined(__APPLE__)
@@ -66,7 +67,7 @@
extern "C" uint64 __rdtsc();
#pragma intrinsic(__rdtsc)
#endif
-#if defined(ARMV3) || defined(__mips__)
+#if defined(ARMV3) || defined(__mips__) || defined(__aarch64__)
#include
#endif
@@ -132,8 +133,8 @@
_asm rdtsc
#elif defined(_MSC_VER)
return __rdtsc();
-#elif defined(ARMV3)
-#if defined(ARMV6) // V6 is the earliest arch that has a standard cyclecount
+#elif defined(ARMV3) || defined(__aarch64__)
+#if defined(ARMV7) // V7 is the earliest arch that has a standard cyclecount
uint32 pmccntr;
uint32 pmuseren;
uint32 pmcntenset;
diff -Nru google-perftools-2.1/src/base/dynamic_annotations.c google-perftools-2.2.1/src/base/dynamic_annotations.c
--- google-perftools-2.1/src/base/dynamic_annotations.c 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/dynamic_annotations.c 2014-06-07 22:54:00.000000000 +0200
@@ -40,6 +40,7 @@
#include
#include "base/dynamic_annotations.h"
+#include "getenv_safe.h" // for TCMallocGetenvSafe
#ifdef __GNUC__
/* valgrind.h uses gcc extensions so it won't build with other compilers */
@@ -140,23 +141,11 @@
#ifdef RUNNING_ON_VALGRIND
if (RUNNING_ON_VALGRIND) return 1;
#endif
-#ifdef _MSC_VER
- /* Visual Studio can complain about getenv, so use a windows equivalent. */
- char value[100] = "1"; /* something that is not "0" */
- int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND",
- value, sizeof(value));
- /* value will remain "1" if the called failed for some reason. */
- return (res > 0 && strcmp(value, "0") != 0);
-#else
- /* TODO(csilvers): use GetenvBeforeMain() instead? Will need to
- * change it to be extern "C".
- */
- char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND");
+ const char *running_on_valgrind_str = TCMallocGetenvSafe("RUNNING_ON_VALGRIND");
if (running_on_valgrind_str) {
return strcmp(running_on_valgrind_str, "0") != 0;
}
return 0;
-#endif
}
/* See the comments in dynamic_annotations.h */
diff -Nru google-perftools-2.1/src/base/elfcore.h google-perftools-2.2.1/src/base/elfcore.h
--- google-perftools-2.1/src/base/elfcore.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/elfcore.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2005-2008, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/elf_mem_image.cc google-perftools-2.2.1/src/base/elf_mem_image.cc
--- google-perftools-2.1/src/base/elf_mem_image.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/elf_mem_image.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/elf_mem_image.h google-perftools-2.2.1/src/base/elf_mem_image.h
--- google-perftools-2.1/src/base/elf_mem_image.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/elf_mem_image.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/googleinit.h google-perftools-2.2.1/src/base/googleinit.h
--- google-perftools-2.1/src/base/googleinit.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/googleinit.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/linux_syscall_support.h google-perftools-2.2.1/src/base/linux_syscall_support.h
--- google-perftools-2.1/src/base/linux_syscall_support.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/linux_syscall_support.h 2014-04-13 03:35:40.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2005-2008, Google Inc.
* All rights reserved.
*
@@ -84,7 +85,7 @@
* sys_futex(
* sys_futex1(
* sys_getcpu(
- * sys_getdents(
+ * sys_getdents64(
* sys_getppid(
* sys_gettid(
* sys_lseek(
@@ -116,10 +117,10 @@
* 3) I left these in even though they're not used. They either
* complement the above (write vs read) or are variants (rt_sigaction):
* sys_fstat64
- * sys_getdents64
* sys_llseek
* sys_mmap2
* sys_openat
+ * sys_getdents
* sys_rt_sigaction
* sys_rt_sigprocmask
* sys_sigaddset
@@ -130,11 +131,11 @@
#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
#define SYS_LINUX_SYSCALL_SUPPORT_H
-/* We currently only support x86-32, x86-64, ARM, MIPS, and PPC/PPC64 on Linux.
+/* We currently only support x86-32, x86-64, ARM, MIPS, PPC/PPC64 and Aarch64 on Linux.
* Porting to other related platforms should not be difficult.
*/
#if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
- defined(__mips__) || defined(__PPC__)) && defined(__linux)
+ defined(__mips__) || defined(__PPC__) || defined(__aarch64__)) && defined(__linux)
#ifndef SYS_CPLUSPLUS
#ifdef __cplusplus
@@ -282,7 +283,7 @@
(8*sizeof(unsigned long))];
};
-/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */
+/* include/asm-{arm,generic,i386,mips,x86_64,ppc}/signal.h */
struct kernel_sigaction {
#ifdef __mips__
unsigned long sa_flags;
@@ -373,7 +374,7 @@
};
#endif
-/* include/asm-{arm,i386,mips,x86_64,ppc}/stat.h */
+/* include/asm-{arm,generic,i386,mips,x86_64,ppc}/stat.h */
#if defined(__i386__) || defined(__arm__)
struct kernel_stat {
/* The kernel headers suggest that st_dev and st_rdev should be 32bit
@@ -466,6 +467,29 @@
int st_blocks;
int st_pad4[14];
};
+#elif defined(__aarch64__)
+struct kernel_stat {
+ unsigned long st_dev;
+ unsigned long st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+ unsigned int st_uid;
+ unsigned int st_gid;
+ unsigned long st_rdev;
+ unsigned long __pad1;
+ long st_size;
+ int st_blksize;
+ int __pad2;
+ long st_blocks;
+ long st_atime_;
+ unsigned long st_atime_nsec_;
+ long st_mtime_;
+ unsigned long st_mtime_nsec_;
+ long st_ctime_;
+ unsigned long st_ctime_nsec_;
+ unsigned int __unused4;
+ unsigned int __unused5;
+};
#endif
@@ -675,6 +699,11 @@
#define __NR_getcpu 302
#endif
/* End of powerpc defininitions */
+#elif defined(__aarch64__)
+#ifndef __NR_fstatat
+#define __NR_fstatat 79
+#endif
+/* End of aarch64 defininitions */
#endif
@@ -737,7 +766,8 @@
#endif
#undef LSS_RETURN
- #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__))
+ #if (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || \
+ defined(__aarch64__))
/* Failing system calls return a negative result in the range of
* -1..-4095. These are "errno" values with the sign inverted.
*/
@@ -1780,6 +1810,17 @@
long __ret, __err;
{
#if defined(__PPC64__)
+
+/* Stack frame offsets. */
+#if _CALL_ELF != 2
+#define FRAME_MIN_SIZE 112
+#define FRAME_TOC_SAVE 40
+#else
+#define FRAME_MIN_SIZE 32
+#define FRAME_TOC_SAVE 24
+#endif
+
+
register int (*__fn)(void *) __asm__ ("r3") = fn;
register void *__cstack __asm__ ("r4") = child_stack;
register int __flags __asm__ ("r5") = flags;
@@ -1799,7 +1840,7 @@
/* set up stack frame for child */
"clrrdi %7, %7, 4\n\t"
"li 0, 0\n\t"
- "stdu 0, -112(%7)\n\t"
+ "stdu 0, -%13(%7)\n\t"
/* fn, arg, child_stack are saved acrVoss the syscall */
"mr 28, %6\n\t"
@@ -1825,13 +1866,18 @@
"bne- cr1, 1f\n\t"
/* Do the function call */
- "std 2, 40(1)\n\t"
+ "std 2, %14(1)\n\t"
+#if _CALL_ELF != 2
"ld 0, 0(28)\n\t"
"ld 2, 8(28)\n\t"
"mtctr 0\n\t"
+#else
+ "mr 12, 28\n\t"
+ "mtctr 12\n\t"
+#endif
"mr 3, 27\n\t"
"bctrl\n\t"
- "ld 2, 40(1)\n\t"
+ "ld 2, %14(1)\n\t"
/* Call _exit(r3) */
"li 0, %5\n\t"
@@ -1845,7 +1891,7 @@
"i" (__NR_clone), "i" (__NR_exit),
"r" (__fn), "r" (__cstack), "r" (__flags),
"r" (__arg), "r" (__ptidptr), "r" (__newtls),
- "r" (__ctidptr)
+ "r" (__ctidptr), "i" (FRAME_MIN_SIZE), "i" (FRAME_TOC_SAVE)
: "cr0", "cr1", "memory", "ctr",
"r0", "r29", "r27", "r28");
#else
@@ -1916,6 +1962,128 @@
}
LSS_RETURN(int, __ret, __err);
}
+ #elif defined(__aarch64__)
+ #undef LSS_REG
+ #define LSS_REG(r,a) register long __x##r __asm__("x"#r) = (long)a
+ #undef LSS_BODY
+ #define LSS_BODY(type,name,args...) \
+ register long __res_x0 __asm__("x0"); \
+ long __res; \
+ __asm__ __volatile__ ("mov x8, %1\n" \
+ "svc 0x0\n" \
+ : "=r"(__res_x0) \
+ : "i"(__NR_##name) , ## args \
+ : "memory"); \
+ __res = __res_x0; \
+ LSS_RETURN(type, __res)
+ #undef _syscall0
+ #define _syscall0(type, name) \
+ type LSS_NAME(name)(void) { \
+ LSS_BODY(type, name); \
+ }
+ #undef _syscall1
+ #define _syscall1(type, name, type1, arg1) \
+ type LSS_NAME(name)(type1 arg1) { \
+ LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__x0)); \
+ }
+ #undef _syscall2
+ #define _syscall2(type, name, type1, arg1, type2, arg2) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); \
+ LSS_BODY(type, name, "r"(__x0), "r"(__x1)); \
+ }
+ #undef _syscall3
+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2)); \
+ }
+ #undef _syscall4
+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); \
+ LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3)); \
+ }
+ #undef _syscall5
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); LSS_REG(4, arg5); \
+ LSS_BODY(type, name, "r"(__x0), "r"(__x1), "r"(__x2), "r"(__x3), \
+ "r"(__x4)); \
+ }
+ #undef _syscall6
+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
+ LSS_BODY(type, name, "r"(__x0), "r"(__x1), "x"(__x2), "r"(__x3), \
+ "r"(__x4), "r"(__x5)); \
+ }
+ /* clone function adapted from glibc 2.18 clone.S */
+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
+ int flags, void *arg, int *parent_tidptr,
+ void *newtls, int *child_tidptr) {
+ long __res;
+ {
+ register int (*__fn)(void *) __asm__("x0") = fn;
+ register void *__stack __asm__("x1") = child_stack;
+ register int __flags __asm__("x2") = flags;
+ register void *__arg __asm__("x3") = arg;
+ register int *__ptid __asm__("x4") = parent_tidptr;
+ register void *__tls __asm__("x5") = newtls;
+ register int *__ctid __asm__("x6") = child_tidptr;
+ __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
+ * return -EINVAL;
+ */
+ "cbz x0,1f\n"
+ "cbz x1,1f\n"
+
+ /* Push "arg" and "fn" onto the stack that will be
+ * used by the child.
+ */
+ "stp x0,x3, [x1, #-16]!\n"
+
+ "mov x0,x2\n" /* flags */
+ "mov x2,x4\n" /* ptid */
+ "mov x3,x5\n" /* tls */
+ "mov x4,x6\n" /* ctid */
+ "mov x8,%9\n" /* clone */
+
+ "svc 0x0\n"
+
+ /* if (%r0 != 0)
+ * return %r0;
+ */
+ "cmp x0, #0\n"
+ "bne 2f\n"
+
+ /* In the child, now. Call "fn(arg)".
+ */
+ "ldp x1, x0, [sp], #16\n"
+ "blr x1\n"
+
+ /* Call _exit(%r0).
+ */
+ "mov x8, %10\n"
+ "svc 0x0\n"
+ "1:\n"
+ "mov x8, %1\n"
+ "2:\n"
+ : "=r" (__res)
+ : "i"(-EINVAL),
+ "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
+ "r"(__ptid), "r"(__tls), "r"(__ctid),
+ "i"(__NR_clone), "i"(__NR_exit)
+ : "x30", "memory");
+ }
+ LSS_RETURN(int, __res);
+ }
#endif
#define __NR__exit __NR_exit
#define __NR__gettid __NR_gettid
@@ -1929,11 +2097,16 @@
LSS_INLINE _syscall4(int, futex, int*, a,
int, o, int, v,
struct kernel_timespec*, t)
- LSS_INLINE _syscall3(int, getdents, int, f,
- struct kernel_dirent*, d, int, c)
#ifdef __NR_getdents64
- LSS_INLINE _syscall3(int, getdents64, int, f,
- struct kernel_dirent64*, d, int, c)
+ LSS_INLINE _syscall3(int, getdents64, int, f,
+ struct kernel_dirent64*, d, int, c)
+#define KERNEL_DIRENT kernel_dirent64
+#define GETDENTS sys_getdents64
+#else
+ LSS_INLINE _syscall3(int, getdents, int, f,
+ struct kernel_dirent*, d, int, c)
+#define KERNEL_DIRENT kernel_dirent
+#define GETDENTS sys_getdents
#endif
LSS_INLINE _syscall0(pid_t, getpid)
LSS_INLINE _syscall0(pid_t, getppid)
@@ -1955,8 +2128,6 @@
LSS_INLINE _syscall5(void*, _mremap, void*, o,
size_t, os, size_t, ns,
unsigned long, f, void *, a)
- LSS_INLINE _syscall3(int, open, const char*, p,
- int, f, int, m)
LSS_INLINE _syscall2(int, prctl, int, o,
long, a)
LSS_INLINE _syscall4(long, ptrace, int, r,
@@ -1972,15 +2143,23 @@
LSS_INLINE _syscall0(int, sched_yield)
LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
const stack_t*, o)
- LSS_INLINE _syscall2(int, stat, const char*, f,
- struct kernel_stat*, b)
+ #if defined(__NR_fstatat)
+ LSS_INLINE _syscall4(int, fstatat, int, d, const char *, p,
+ struct kernel_stat*, b, int, flags)
+ LSS_INLINE int LSS_NAME(stat)(const char* p, struct kernel_stat* b) {
+ return LSS_NAME(fstatat)(AT_FDCWD,p,b,0);
+ }
+ #else
+ LSS_INLINE _syscall2(int, stat, const char*, f,
+ struct kernel_stat*, b)
+ #endif
LSS_INLINE _syscall3(ssize_t, write, int, f,
const void *, b, size_t, c)
#if defined(__NR_getcpu)
LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu,
unsigned *, node, void *, unused);
#endif
- #if defined(__x86_64__) || \
+ #if defined(__x86_64__) || defined(__aarch64__) || \
(defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
LSS_INLINE _syscall3(int, socket, int, d,
int, t, int, p)
@@ -2020,18 +2199,43 @@
return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
}
#endif
- #if defined(__x86_64__) || \
- defined(__arm__) || \
- (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32)
+ #if (defined(__aarch64__)) || \
+ (defined(__mips__) && (_MIPS_ISA == _MIPS_ISA_MIPS64))
+ LSS_INLINE _syscall6(void*, mmap, void*, s,
+ size_t, l, int, p,
+ int, f, int, d,
+ __off64_t, o)
+ LSS_INLINE int LSS_NAME(sigaction)(int signum,
+ const struct kernel_sigaction *act,
+ struct kernel_sigaction *oldact) {
+ return LSS_NAME(rt_sigaction)(signum, act, oldact, (KERNEL_NSIG+7)/8);
+
+ }
+ LSS_INLINE int LSS_NAME(sigprocmask)(int how,
+ const struct kernel_sigset_t *set,
+ struct kernel_sigset_t *oldset) {
+ return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8);
+ }
+ #endif
+ #ifdef __NR_wait4
LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
int*, s, int, o,
struct kernel_rusage*, r)
LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){
return LSS_NAME(wait4)(pid, status, options, 0);
}
- #endif
- #if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
+ #else
+ LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
+ int*, s, int, o)
+ #endif
+ #ifdef __NR_openat
LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
+ LSS_INLINE int LSS_NAME(open)(const char* p, int f, int m) {
+ return LSS_NAME(openat)(AT_FDCWD,p,f,m );
+ }
+ #else
+ LSS_INLINE _syscall3(int, open, const char*, p,
+ int, f, int, m)
#endif
LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) {
memset(&set->sig, 0, sizeof(set->sig));
@@ -2202,11 +2406,6 @@
LSS_INLINE _syscall3(int, socket, int, d,
int, t, int, p)
#endif
- #if defined(__i386__) || defined(__PPC__) || \
- (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32)
- LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
- int*, s, int, o)
- #endif
#if defined(__mips__)
/* sys_pipe() on MIPS has non-standard calling conventions, as it returns
* both file handles through CPU registers.
@@ -2229,6 +2428,12 @@
return 0;
}
}
+ #elif defined(__NR_pipe2)
+ LSS_INLINE _syscall2(int, pipe2, int *, p,
+ int, f )
+ LSS_INLINE int LSS_NAME(pipe)( int * p) {
+ return LSS_NAME(pipe2)(p, 0);
+ }
#else
LSS_INLINE _syscall1(int, pipe, int *, p)
#endif
diff -Nru google-perftools-2.1/src/base/linuxthreads.cc google-perftools-2.2.1/src/base/linuxthreads.cc
--- google-perftools-2.1/src/base/linuxthreads.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/linuxthreads.cc 2014-03-01 20:24:54.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
*
@@ -193,9 +194,9 @@
* In order to find the main application from the signal handler, we
* need to store information about it in global variables. This is
* safe, because the main application should be suspended at this
- * time. If the callback ever called ResumeAllProcessThreads(), then
+ * time. If the callback ever called TCMalloc_ResumeAllProcessThreads(), then
* we are running a higher risk, though. So, try to avoid calling
- * abort() after calling ResumeAllProcessThreads.
+ * abort() after calling TCMalloc_ResumeAllProcessThreads.
*/
static volatile int *sig_pids, sig_num_threads, sig_proc, sig_marker;
@@ -214,7 +215,7 @@
sys_ptrace(PTRACE_KILL, sig_pids[sig_num_threads], 0, 0);
}
} else if (sig_num_threads > 0) {
- ResumeAllProcessThreads(sig_num_threads, (int *)sig_pids);
+ TCMalloc_ResumeAllProcessThreads(sig_num_threads, (int *)sig_pids);
}
}
sig_pids = NULL;
@@ -369,10 +370,10 @@
sig_num_threads = num_threads;
sig_pids = pids;
for (;;) {
- struct kernel_dirent *entry;
+ struct KERNEL_DIRENT *entry;
char buf[4096];
- ssize_t nbytes = sys_getdents(proc, (struct kernel_dirent *)buf,
- sizeof(buf));
+ ssize_t nbytes = GETDENTS(proc, (struct KERNEL_DIRENT *)buf,
+ sizeof(buf));
if (nbytes < 0)
goto failure;
else if (nbytes == 0) {
@@ -388,9 +389,9 @@
}
break;
}
- for (entry = (struct kernel_dirent *)buf;
- entry < (struct kernel_dirent *)&buf[nbytes];
- entry = (struct kernel_dirent *)((char *)entry+entry->d_reclen)) {
+ for (entry = (struct KERNEL_DIRENT *)buf;
+ entry < (struct KERNEL_DIRENT *)&buf[nbytes];
+ entry = (struct KERNEL_DIRENT *)((char *)entry+entry->d_reclen)) {
if (entry->d_ino != 0) {
const char *ptr = entry->d_name;
pid_t pid;
@@ -416,7 +417,7 @@
/* Check if the marker is identical to the one we created */
if (sys_stat(fname, &tmp_sb) >= 0 &&
marker_sb.st_ino == tmp_sb.st_ino) {
- long i;
+ long i, j;
/* Found one of our threads, make sure it is no duplicate */
for (i = 0; i < num_threads; i++) {
@@ -452,28 +453,28 @@
sig_num_threads = num_threads;
goto next_entry;
}
- /* Attaching to a process doesn't guarantee it'll stop before
- * ptrace returns; you have to wait on it. Specifying __WCLONE
- * means it will only wait for clone children (i.e. threads,
- * not processes).
- */
- while (sys_waitpid(pid, (int *)0, __WCLONE) < 0) {
+ while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
if (errno != EINTR) {
- /* Assumes ECHILD */
- if (pid == ppid) {
- /* The parent is not a clone */
- found_parent = true;
- break;
- } else {
- sys_ptrace_detach(pid);
- num_threads--;
- sig_num_threads = num_threads;
- goto next_entry;
- }
+ sys_ptrace_detach(pid);
+ num_threads--;
+ sig_num_threads = num_threads;
+ goto next_entry;
}
}
- added_entries++;
+ if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
+ sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i != j) {
+ /* Address spaces are distinct, even though both
+ * processes show the "marker". This is probably
+ * a forked child process rather than a thread.
+ */
+ sys_ptrace_detach(pid);
+ num_threads--;
+ sig_num_threads = num_threads;
+ } else {
+ found_parent |= pid == ppid;
+ added_entries++;
+ }
}
}
}
@@ -496,7 +497,7 @@
* error to the caller.
*/
if (!found_parent) {
- ResumeAllProcessThreads(num_threads, pids);
+ TCMalloc_ResumeAllProcessThreads(num_threads, pids);
sys__exit(3);
}
@@ -508,7 +509,7 @@
args->err = errno;
/* Callback should have resumed threads, but better safe than sorry */
- if (ResumeAllProcessThreads(num_threads, pids)) {
+ if (TCMalloc_ResumeAllProcessThreads(num_threads, pids)) {
/* Callback forgot to resume at least one thread, report error */
args->err = EINVAL;
args->result = -1;
@@ -518,7 +519,7 @@
}
detach_threads:
/* Resume all threads prior to retrying the operation */
- ResumeAllProcessThreads(num_threads, pids);
+ TCMalloc_ResumeAllProcessThreads(num_threads, pids);
sig_pids = NULL;
num_threads = 0;
sig_num_threads = num_threads;
@@ -536,19 +537,19 @@
* address space, the filesystem, and the filehandles with the caller. Most
* notably, it does not share the same pid and ppid; and if it terminates,
* the rest of the application is still there. 'callback' is supposed to do
- * or arrange for ResumeAllProcessThreads. This happens automatically, if
+ * or arrange for TCMalloc_ResumeAllProcessThreads. This happens automatically, if
* the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
* signals are blocked. If the 'callback' decides to unblock them, it must
* ensure that they cannot terminate the application, or that
- * ResumeAllProcessThreads will get called.
+ * TCMalloc_ResumeAllProcessThreads will get called.
* It is an error for the 'callback' to make any library calls that could
* acquire locks. Most notably, this means that most system calls have to
* avoid going through libc. Also, this means that it is not legal to call
* exit() or abort().
* We return -1 on error and the return value of 'callback' on success.
*/
-int ListAllProcessThreads(void *parameter,
- ListAllProcessThreadsCallBack callback, ...) {
+int TCMalloc_ListAllProcessThreads(void *parameter,
+ ListAllProcessThreadsCallBack callback, ...) {
char altstack_mem[ALT_STACKSIZE];
struct ListerParams args;
pid_t clone_pid;
@@ -688,11 +689,11 @@
}
/* This function resumes the list of all linux threads that
- * ListAllProcessThreads pauses before giving to its callback.
+ * TCMalloc_ListAllProcessThreads pauses before giving to its callback.
* The function returns non-zero if at least one thread was
* suspended and has now been resumed.
*/
-int ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
+int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
int detached_at_least_one = 0;
while (num_threads-- > 0) {
detached_at_least_one |= sys_ptrace_detach(thread_pids[num_threads]) >= 0;
diff -Nru google-perftools-2.1/src/base/linuxthreads.h google-perftools-2.2.1/src/base/linuxthreads.h
--- google-perftools-2.1/src/base/linuxthreads.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/linuxthreads.h 2014-03-01 20:24:54.000000000 +0100
@@ -41,7 +41,7 @@
* related platforms should not be difficult.
*/
#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
- defined(__mips__) || defined(__PPC__)) && defined(__linux)
+ defined(__mips__) || defined(__PPC__) || defined(__aarch64__)) && defined(__linux)
/* Define the THREADS symbol to make sure that there is exactly one core dumper
* built into the library.
diff -Nru google-perftools-2.1/src/base/logging.cc google-perftools-2.2.1/src/base/logging.cc
--- google-perftools-2.1/src/base/logging.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/logging.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/logging.h google-perftools-2.2.1/src/base/logging.h
--- google-perftools-2.1/src/base/logging.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/logging.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/low_level_alloc.cc google-perftools-2.2.1/src/base/low_level_alloc.cc
--- google-perftools-2.1/src/base/low_level_alloc.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/low_level_alloc.cc 2014-06-21 21:12:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/low_level_alloc.h google-perftools-2.2.1/src/base/low_level_alloc.h
--- google-perftools-2.1/src/base/low_level_alloc.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/low_level_alloc.h 2014-06-21 21:12:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/simple_mutex.h google-perftools-2.2.1/src/base/simple_mutex.h
--- google-perftools-2.1/src/base/simple_mutex.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/simple_mutex.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/spinlock.cc google-perftools-2.2.1/src/base/spinlock.cc
--- google-perftools-2.1/src/base/spinlock.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/spinlock.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/spinlock.h google-perftools-2.2.1/src/base/spinlock.h
--- google-perftools-2.1/src/base/spinlock.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/spinlock.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/spinlock_internal.cc google-perftools-2.2.1/src/base/spinlock_internal.cc
--- google-perftools-2.1/src/base/spinlock_internal.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/spinlock_internal.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2010, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/spinlock_internal.h google-perftools-2.2.1/src/base/spinlock_internal.h
--- google-perftools-2.1/src/base/spinlock_internal.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/spinlock_internal.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2010, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/spinlock_linux-inl.h google-perftools-2.2.1/src/base/spinlock_linux-inl.h
--- google-perftools-2.1/src/base/spinlock_linux-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/spinlock_linux-inl.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/spinlock_posix-inl.h google-perftools-2.2.1/src/base/spinlock_posix-inl.h
--- google-perftools-2.1/src/base/spinlock_posix-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/spinlock_posix-inl.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/spinlock_win32-inl.h google-perftools-2.2.1/src/base/spinlock_win32-inl.h
--- google-perftools-2.1/src/base/spinlock_win32-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/spinlock_win32-inl.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/stl_allocator.h google-perftools-2.2.1/src/base/stl_allocator.h
--- google-perftools-2.1/src/base/stl_allocator.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/stl_allocator.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/synchronization_profiling.h google-perftools-2.2.1/src/base/synchronization_profiling.h
--- google-perftools-2.1/src/base/synchronization_profiling.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/synchronization_profiling.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2010, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/base/sysinfo.cc google-perftools-2.2.1/src/base/sysinfo.cc
--- google-perftools-2.1/src/base/sysinfo.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/sysinfo.cc 2014-06-07 22:54:00.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
@@ -166,6 +167,12 @@
return NULL; // env var never found
}
+extern "C" {
+ const char* TCMallocGetenvSafe(const char* name) {
+ return GetenvBeforeMain(name);
+ }
+}
+
// This takes as an argument an environment-variable name (like
// CPUPROFILE) whose value is supposed to be a file-path, and sets
// path to that path, and returns true. If the env var doesn't exist,
diff -Nru google-perftools-2.1/src/base/sysinfo.h google-perftools-2.2.1/src/base/sysinfo.h
--- google-perftools-2.1/src/base/sysinfo.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/base/sysinfo.h 2014-04-13 03:05:37.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/base/thread_lister.c google-perftools-2.2.1/src/base/thread_lister.c
--- google-perftools-2.1/src/base/thread_lister.c 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/thread_lister.c 2014-02-22 21:25:25.000000000 +0100
@@ -48,8 +48,8 @@
* or if the multi-threading code has not been ported, yet.
*/
-int ListAllProcessThreads(void *parameter,
- ListAllProcessThreadsCallBack callback, ...) {
+int TCMalloc_ListAllProcessThreads(void *parameter,
+ ListAllProcessThreadsCallBack callback, ...) {
int rc;
va_list ap;
pid_t pid;
@@ -70,7 +70,7 @@
return rc;
}
-int ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
+int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
return 1;
}
diff -Nru google-perftools-2.1/src/base/thread_lister.h google-perftools-2.2.1/src/base/thread_lister.h
--- google-perftools-2.1/src/base/thread_lister.h 2012-02-10 03:45:37.000000000 +0100
+++ google-perftools-2.2.1/src/base/thread_lister.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+/* -*- Mode: c; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
*
@@ -54,26 +55,26 @@
* address space, the filesystem, and the filehandles with the caller. Most
* notably, it does not share the same pid and ppid; and if it terminates,
* the rest of the application is still there. 'callback' is supposed to do
- * or arrange for ResumeAllProcessThreads. This happens automatically, if
+ * or arrange for TCMalloc_ResumeAllProcessThreads. This happens automatically, if
* the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
* signals are blocked. If the 'callback' decides to unblock them, it must
* ensure that they cannot terminate the application, or that
- * ResumeAllProcessThreads will get called.
+ * TCMalloc_ResumeAllProcessThreads will get called.
* It is an error for the 'callback' to make any library calls that could
* acquire locks. Most notably, this means that most system calls have to
* avoid going through libc. Also, this means that it is not legal to call
* exit() or abort().
* We return -1 on error and the return value of 'callback' on success.
*/
-int ListAllProcessThreads(void *parameter,
- ListAllProcessThreadsCallBack callback, ...);
+int TCMalloc_ListAllProcessThreads(void *parameter,
+ ListAllProcessThreadsCallBack callback, ...);
/* This function resumes the list of all linux threads that
- * ListAllProcessThreads pauses before giving to its callback.
- * The function returns non-zero if at least one thread was
+ * TCMalloc_ListAllProcessThreads pauses before giving to its
+ * callback. The function returns non-zero if at least one thread was
* suspended and has now been resumed.
*/
-int ResumeAllProcessThreads(int num_threads, pid_t *thread_pids);
+int TCMalloc_ResumeAllProcessThreads(int num_threads, pid_t *thread_pids);
#ifdef __cplusplus
}
diff -Nru google-perftools-2.1/src/base/vdso_support.cc google-perftools-2.2.1/src/base/vdso_support.cc
--- google-perftools-2.1/src/base/vdso_support.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/vdso_support.cc 2014-04-13 03:35:40.000000000 +0200
@@ -57,7 +57,6 @@
namespace base {
const void *VDSOSupport::vdso_base_ = ElfMemImage::kInvalidBase;
-VDSOSupport::GetCpuFn VDSOSupport::getcpu_fn_ = &InitAndGetCPU;
VDSOSupport::VDSOSupport()
// If vdso_base_ is still set to kInvalidBase, we got here
// before VDSOSupport::Init has been called. Call it now.
@@ -81,14 +80,12 @@
// Valgrind zapping. So we check for Valgrind separately.
if (RunningOnValgrind()) {
vdso_base_ = NULL;
- getcpu_fn_ = &GetCPUViaSyscall;
return NULL;
}
int fd = open("/proc/self/auxv", O_RDONLY);
if (fd == -1) {
// Kernel too old to have a VDSO.
vdso_base_ = NULL;
- getcpu_fn_ = &GetCPUViaSyscall;
return NULL;
}
ElfW(auxv_t) aux;
@@ -106,20 +103,6 @@
vdso_base_ = NULL;
}
}
- GetCpuFn fn = &GetCPUViaSyscall; // default if VDSO not present.
- if (vdso_base_) {
- VDSOSupport vdso;
- SymbolInfo info;
- if (vdso.LookupSymbol("__vdso_getcpu", "LINUX_2.6", STT_FUNC, &info)) {
- // Casting from an int to a pointer is not legal C++. To emphasize
- // this, we use a C-style cast rather than a C++-style cast.
- fn = (GetCpuFn)(info.address);
- }
- }
- // Subtle: this code runs outside of any locks; prevent compiler
- // from assigning to getcpu_fn_ more than once.
- base::subtle::MemoryBarrier();
- getcpu_fn_ = fn;
return vdso_base_;
}
@@ -128,8 +111,6 @@
const void *old_base = vdso_base_;
vdso_base_ = base;
image_.Init(base);
- // Also reset getcpu_fn_, so GetCPU could be tested with simulated VDSO.
- getcpu_fn_ = &InitAndGetCPU;
return old_base;
}
@@ -145,33 +126,6 @@
return image_.LookupSymbolByAddress(address, info_out);
}
-// NOLINT on 'long' because this routine mimics kernel api.
-long VDSOSupport::GetCPUViaSyscall(unsigned *cpu, void *, void *) { // NOLINT
-#if defined(__NR_getcpu)
- return sys_getcpu(cpu, NULL, NULL);
-#else
- // x86_64 never implemented sys_getcpu(), except as a VDSO call.
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-// Use fast __vdso_getcpu if available.
-long VDSOSupport::InitAndGetCPU(unsigned *cpu, void *x, void *y) { // NOLINT
- Init();
- CHECK_NE(getcpu_fn_, &InitAndGetCPU); // << "Init() did not set getcpu_fn_";
- return (*getcpu_fn_)(cpu, x, y);
-}
-
-// This function must be very fast, and may be called from very
-// low level (e.g. tcmalloc). Hence I avoid things like
-// GoogleOnceInit() and ::operator new.
-int GetCPU(void) {
- unsigned cpu;
- int ret_code = (*VDSOSupport::getcpu_fn_)(&cpu, NULL, NULL);
- return ret_code == 0 ? cpu : ret_code;
-}
-
// We need to make sure VDSOSupport::Init() is called before
// the main() runs, since it might do something like setuid or
// chroot. If VDSOSupport
diff -Nru google-perftools-2.1/src/base/vdso_support.h google-perftools-2.2.1/src/base/vdso_support.h
--- google-perftools-2.1/src/base/vdso_support.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/base/vdso_support.h 2014-04-13 03:35:40.000000000 +0200
@@ -122,32 +122,9 @@
// page-aligned.
static const void *vdso_base_;
- // NOLINT on 'long' because these routines mimic kernel api.
- // The 'cache' parameter may be used by some versions of the kernel,
- // and should be NULL or point to a static buffer containing at
- // least two 'long's.
- static long InitAndGetCPU(unsigned *cpu, void *cache, // NOLINT 'long'.
- void *unused);
- static long GetCPUViaSyscall(unsigned *cpu, void *cache, // NOLINT 'long'.
- void *unused);
- typedef long (*GetCpuFn)(unsigned *cpu, void *cache, // NOLINT 'long'.
- void *unused);
-
- // This function pointer may point to InitAndGetCPU,
- // GetCPUViaSyscall, or __vdso_getcpu at different stages of initialization.
- static GetCpuFn getcpu_fn_;
-
- friend int GetCPU(void); // Needs access to getcpu_fn_.
-
DISALLOW_COPY_AND_ASSIGN(VDSOSupport);
};
-// Same as sched_getcpu() on later glibc versions.
-// Return current CPU, using (fast) __vdso_getcpu@LINUX_2.6 if present,
-// otherwise use syscall(SYS_getcpu,...).
-// May return -1 with errno == ENOSYS if the kernel doesn't
-// support SYS_getcpu.
-int GetCPU();
} // namespace base
#endif // HAVE_ELF_MEM_IMAGE
diff -Nru google-perftools-2.1/src/central_freelist.cc google-perftools-2.2.1/src/central_freelist.cc
--- google-perftools-2.1/src/central_freelist.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/central_freelist.cc 2014-06-21 22:55:10.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -257,52 +258,62 @@
}
int result = 0;
- void* head = NULL;
- void* tail = NULL;
+ *start = NULL;
+ *end = NULL;
// TODO: Prefetch multiple TCEntries?
- tail = FetchFromSpansSafe();
- if (tail != NULL) {
- SLL_SetNext(tail, NULL);
- head = tail;
- result = 1;
+ result = FetchFromOneSpansSafe(N, start, end);
+ if (result != 0) {
while (result < N) {
- void *t = FetchFromSpans();
- if (!t) break;
- SLL_Push(&head, t);
- result++;
+ int n;
+ void* head = NULL;
+ void* tail = NULL;
+ n = FetchFromOneSpans(N - result, &head, &tail);
+ if (!n) break;
+ result += n;
+ SLL_PushRange(start, head, tail);
}
}
lock_.Unlock();
- *start = head;
- *end = tail;
return result;
}
-void* CentralFreeList::FetchFromSpansSafe() {
- void *t = FetchFromSpans();
- if (!t) {
+int CentralFreeList::FetchFromOneSpansSafe(int N, void **start, void **end) {
+ int result = FetchFromOneSpans(N, start, end);
+ if (!result) {
Populate();
- t = FetchFromSpans();
+ result = FetchFromOneSpans(N, start, end);
}
- return t;
+ return result;
}
-void* CentralFreeList::FetchFromSpans() {
- if (tcmalloc::DLL_IsEmpty(&nonempty_)) return NULL;
+int CentralFreeList::FetchFromOneSpans(int N, void **start, void **end) {
+ if (tcmalloc::DLL_IsEmpty(&nonempty_)) return 0;
Span* span = nonempty_.next;
ASSERT(span->objects != NULL);
- span->refcount++;
- void* result = span->objects;
- span->objects = *(reinterpret_cast(result));
- if (span->objects == NULL) {
+
+ int result = 0;
+ void *prev, *curr;
+ curr = span->objects;
+ do {
+ prev = curr;
+ curr = *(reinterpret_cast(curr));
+ } while (++result < N && curr != NULL);
+
+ if (curr == NULL) {
// Move to empty list
tcmalloc::DLL_Remove(span);
tcmalloc::DLL_Prepend(&empty_, span);
Event(span, 'E', 0);
}
- counter_--;
+
+ *start = span->objects;
+ *end = prev;
+ span->objects = curr;
+ SLL_SetNext(*end, NULL);
+ span->refcount += result;
+ counter_ -= result;
return result;
}
diff -Nru google-perftools-2.1/src/central_freelist.h google-perftools-2.2.1/src/central_freelist.h
--- google-perftools-2.1/src/central_freelist.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/central_freelist.h 2013-12-06 21:16:47.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -113,13 +114,13 @@
// REQUIRES: lock_ is held
// Remove object from cache and return.
// Return NULL if no free entries in cache.
- void* FetchFromSpans() EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ int FetchFromOneSpans(int N, void **start, void **end) EXCLUSIVE_LOCKS_REQUIRED(lock_);
// REQUIRES: lock_ is held
// Remove object from cache and return. Fetches
// from pageheap if cache is empty. Only returns
// NULL on allocation failure.
- void* FetchFromSpansSafe() EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ int FetchFromOneSpansSafe(int N, void **start, void **end) EXCLUSIVE_LOCKS_REQUIRED(lock_);
// REQUIRES: lock_ is held
// Release a linked list of objects to spans.
diff -Nru google-perftools-2.1/src/common.cc google-perftools-2.2.1/src/common.cc
--- google-perftools-2.1/src/common.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/common.cc 2014-06-07 22:54:00.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -35,6 +36,7 @@
#include "common.h"
#include "system-alloc.h"
#include "base/spinlock.h"
+#include "getenv_safe.h" // TCMallocGetenvSafe
namespace tcmalloc {
@@ -50,7 +52,7 @@
static inline void InitTCMallocTransferNumObjects()
{
if (UNLIKELY(FLAGS_tcmalloc_transfer_num_objects == 0)) {
- const char *envval = getenv("TCMALLOC_TRANSFER_NUM_OBJ");
+ const char *envval = TCMallocGetenvSafe("TCMALLOC_TRANSFER_NUM_OBJ");
FLAGS_tcmalloc_transfer_num_objects = !envval ? kDefaultTransferNumObjecs :
strtol(envval, NULL, 10);
}
@@ -121,7 +123,7 @@
InitTCMallocTransferNumObjects();
// Do some sanity checking on add_amount[]/shift_amount[]/class_array[]
- if (ClassIndex(0) < 0) {
+ if (ClassIndex(0) != 0) {
Log(kCrash, __FILE__, __LINE__,
"Invalid class index for size 0", ClassIndex(0));
}
@@ -187,7 +189,7 @@
}
// Double-check sizes just to be safe
- for (size_t size = 0; size <= kMaxSize; size++) {
+ for (size_t size = 0; size <= kMaxSize;) {
const int sc = SizeClass(size);
if (sc <= 0 || sc >= kNumClasses) {
Log(kCrash, __FILE__, __LINE__,
@@ -202,6 +204,11 @@
Log(kCrash, __FILE__, __LINE__,
"Bad (class, size, requested)", sc, s, size);
}
+ if (size <= kMaxSmallSize) {
+ size += 8;
+ } else {
+ size += 128;
+ }
}
// Initialize the num_objects_to_move array.
diff -Nru google-perftools-2.1/src/common.h google-perftools-2.2.1/src/common.h
--- google-perftools-2.1/src/common.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/common.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/config_for_unittests.h google-perftools-2.2.1/src/config_for_unittests.h
--- google-perftools-2.1/src/config_for_unittests.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/config_for_unittests.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/config.h.in google-perftools-2.2.1/src/config.h.in
--- google-perftools-2.1/src/config.h.in 2013-07-30 11:12:28.000000000 +0200
+++ google-perftools-2.2.1/src/config.h.in 2014-06-22 00:52:49.000000000 +0200
@@ -17,6 +17,10 @@
/* Define to 1 if you have the header file. */
#undef HAVE_CYGWIN_SIGNAL_H
+/* Define to 1 if you have the declaration of `backtrace', and to 0 if you
+ don't. */
+#undef HAVE_DECL_BACKTRACE
+
/* Define to 1 if you have the declaration of `cfree', and to 0 if you don't.
*/
#undef HAVE_DECL_CFREE
@@ -112,6 +116,10 @@
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
+/* defined to 1 if pthread symbols are exposed even without include pthread.h
+ */
+#undef HAVE_PTHREAD_DESPITE_ASKING_FOR
+
/* Define to 1 if you have the header file. */
#undef HAVE_PWD_H
@@ -206,9 +214,6 @@
/* Define to 'volatile' if __malloc_hook is declared volatile */
#undef MALLOC_HOOK_MAYBE_VOLATILE
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
/* Name of package */
#undef PACKAGE
diff -Nru google-perftools-2.1/src/debugallocation.cc google-perftools-2.2.1/src/debugallocation.cc
--- google-perftools-2.1/src/debugallocation.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/debugallocation.cc 2014-04-13 03:35:40.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2000, Google Inc.
// All rights reserved.
//
@@ -75,6 +76,11 @@
#include "malloc_hook-inl.h"
#include "symbolize.h"
+// NOTE: due to #define below, tcmalloc.cc will omit tc_XXX
+// definitions. So that debug implementations can be defined
+// instead. We're going to use do_malloc, do_free and other do_XXX
+// functions that are defined in tcmalloc.cc for actual memory
+// management
#define TCMALLOC_USING_DEBUGALLOCATION
#include "tcmalloc.cc"
@@ -140,16 +146,11 @@
static void TracePrintf(int fd, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
-// The do_* functions are defined in tcmalloc/tcmalloc.cc,
-// which is included before this file
-// when TCMALLOC_FOR_DEBUGALLOCATION is defined
-// TODO(csilvers): get rid of these now that we are tied to tcmalloc.
-#define BASE_MALLOC_NEW do_malloc
-#define BASE_MALLOC do_malloc
-#define BASE_FREE do_free
-#define BASE_MALLOC_STATS do_malloc_stats
-#define BASE_MALLOPT do_mallopt
-#define BASE_MALLINFO do_mallinfo
+// Round "value" up to next "alignment" boundary.
+// Requires that "alignment" be a power of two.
+static intptr_t RoundUp(intptr_t value, intptr_t alignment) {
+ return (value + alignment - 1) & ~(alignment - 1);
+}
// ========================================================================= //
@@ -268,7 +269,7 @@
// setting the environment variable MALLOC_CHECK_ to 1 before you
// start the program (see man malloc).
- // We use either BASE_MALLOC or mmap to make the actual allocation. In
+ // We use either do_malloc or mmap to make the actual allocation. In
// order to remember which one of the two was used for any block, we store an
// appropriate magic word next to the block.
static const int kMagicMalloc = 0xDEADBEEF;
@@ -285,7 +286,7 @@
// should together occupy a multiple of 16 bytes. (At the
// moment, sizeof(size_t) == 4 or 8 depending on piii vs
// k8, and 4 of those sum to 16 or 32 bytes).
- // This, combined with BASE_MALLOC's alignment guarantees,
+ // This, combined with do_malloc's alignment guarantees,
// ensures that SSE types can be stored into the returned
// block, at &size2_.
size_t size1_;
@@ -348,8 +349,17 @@
static size_t real_malloced_size(size_t size) {
return size + sizeof(MallocBlock);
}
+
+ /*
+ * Here we assume size of page is kMinAlign aligned,
+ * so if size is MALLOC_ALIGNMENT aligned too, then we could
+ * guarantee return address is also kMinAlign aligned, because
+ * mmap return address at nearby page boundary on Linux.
+ */
static size_t real_mmapped_size(size_t size) {
- return size + MallocBlock::data_offset();
+ size_t tmp = size + MallocBlock::data_offset();
+ tmp = RoundUp(tmp, kMinAlign);
+ return tmp;
}
size_t real_size() {
@@ -375,8 +385,8 @@
// record us as allocated in the map
alloc_map_lock_.Lock();
if (!alloc_map_) {
- void* p = BASE_MALLOC(sizeof(AllocMap));
- alloc_map_ = new(p) AllocMap(BASE_MALLOC, BASE_FREE);
+ void* p = do_malloc(sizeof(AllocMap));
+ alloc_map_ = new(p) AllocMap(do_malloc, do_free);
}
alloc_map_->Insert(data_addr(), type);
// initialize us
@@ -516,14 +526,10 @@
}
b = (MallocBlock*) (p + (num_pages - 1) * pagesize - sz);
} else {
- b = (MallocBlock*) (type == kMallocType ?
- BASE_MALLOC(real_malloced_size(size)) :
- BASE_MALLOC_NEW(real_malloced_size(size)));
+ b = (MallocBlock*) do_malloc(real_malloced_size(size));
}
#else
- b = (MallocBlock*) (type == kMallocType ?
- BASE_MALLOC(real_malloced_size(size)) :
- BASE_MALLOC_NEW(real_malloced_size(size)));
+ b = (MallocBlock*) do_malloc(real_malloced_size(size);
#endif
// It would be nice to output a diagnostic on allocation failure
@@ -603,7 +609,7 @@
free_queue_lock_.Unlock();
for (int i = 0; i < num_entries; i++) {
CheckForDanglingWrites(entries[i]);
- BASE_FREE(entries[i].block);
+ do_free(entries[i].block);
}
num_entries = 0;
free_queue_lock_.Lock();
@@ -613,7 +619,7 @@
free_queue_lock_.Unlock();
for (int i = 0; i < num_entries; i++) {
CheckForDanglingWrites(entries[i]);
- BASE_FREE(entries[i].block);
+ do_free(entries[i].block);
}
}
@@ -729,14 +735,36 @@
" deallocated; or else a word before the object has been"
" corrupted (memory stomping bug)", p);
}
- // If mb->offset_ is zero (common case), mb is the real header. If
- // mb->offset_ is non-zero, this block was allocated by memalign, and
- // mb->offset_ is the distance backwards to the real header from mb,
- // which is a fake header. The following subtraction works for both zero
- // and non-zero values.
- return reinterpret_cast(
- reinterpret_cast(mb) - mb->offset_);
+ // If mb->offset_ is zero (common case), mb is the real header.
+ // If mb->offset_ is non-zero, this block was allocated by debug
+ // memallign implementation, and mb->offset_ is the distance
+ // backwards to the real header from mb, which is a fake header.
+ if (mb->offset_ == 0) {
+ return mb;
+ }
+
+ MallocBlock *main_block = reinterpret_cast(
+ reinterpret_cast(mb) - mb->offset_);
+
+ if (main_block->offset_ != 0) {
+ RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
+ " Need 0 but got %x",
+ (unsigned)(main_block->offset_));
+ }
+ if (main_block >= p) {
+ RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
+ " Detected main_block address overflow: %x",
+ (unsigned)(mb->offset_));
+ }
+ if (main_block->size2_addr() < p) {
+ RAW_LOG(FATAL, "memory corruption bug: offset_ field is corrupted."
+ " It points below it's own main_block: %x",
+ (unsigned)(mb->offset_));
+ }
+
+ return main_block;
}
+
static const MallocBlock* FromRawPointer(const void* p) {
// const-safe version: we just cast about
return FromRawPointer(const_cast(p));
@@ -1053,11 +1081,36 @@
}
virtual MallocExtension::Ownership GetOwnership(const void* p) {
- if (p) {
- const MallocBlock* mb = MallocBlock::FromRawPointer(p);
- return TCMallocImplementation::GetOwnership(mb);
+ if (!p) {
+ // nobody owns NULL
+ return MallocExtension::kNotOwned;
+ }
+
+ // FIXME: note that correct GetOwnership should not touch memory
+ // that is not owned by tcmalloc. Main implementation is using
+ // pagemap to discover if page in question is owned by us or
+ // not. But pagemap only has marks for first and last page of
+ // spans. Note that if p was returned out of our memalign with
+ // big alignment, then it will point outside of marked pages. Also
+ // note that FromRawPointer call below requires touching memory
+ // before pointer in order to handle memalign-ed chunks
+ // (offset_). This leaves us with two options:
+ //
+ // * do FromRawPointer first and have possibility of crashing if
+ // we're given not owned pointer
+ //
+ // * return incorrect ownership for those large memalign chunks
+ //
+ // I've decided to choose later, which appears to happen rarer and
+ // therefore is arguably a lesser evil
+
+ MallocExtension::Ownership rv = TCMallocImplementation::GetOwnership(p);
+ if (rv != MallocExtension::kOwned) {
+ return rv;
}
- return MallocExtension::kNotOwned; // nobody owns NULL
+
+ const MallocBlock* mb = MallocBlock::FromRawPointer(p);
+ return TCMallocImplementation::GetOwnership(mb);
}
virtual void GetFreeListSizes(vector* v) {
@@ -1075,14 +1128,22 @@
};
-static DebugMallocImplementation debug_malloc_implementation;
+static union {
+ char chars[sizeof(DebugMallocImplementation)];
+ void *ptr;
+} debug_malloc_implementation_space;
REGISTER_MODULE_INITIALIZER(debugallocation, {
+#if (__cplusplus >= 201103L)
+ COMPILE_ASSERT(alignof(debug_malloc_implementation_space) >= alignof(DebugMallocImplementation),
+ debug_malloc_implementation_space_is_not_properly_aligned);
+#endif
// Either we or valgrind will control memory management. We
// register our extension if we're the winner. Otherwise let
// Valgrind use its own malloc (so don't register our extension).
if (!RunningOnValgrind()) {
- MallocExtension::Register(&debug_malloc_implementation);
+ DebugMallocImplementation *impl = new (debug_malloc_implementation_space.chars) DebugMallocImplementation();
+ MallocExtension::Register(impl);
}
});
@@ -1202,8 +1263,18 @@
// return null
if (p == NULL) return NULL;
- memcpy(p->data_addr(), old->data_addr(),
- (old->data_size() < size) ? old->data_size() : size);
+ // if ptr was allocated via memalign, then old->data_size() is not
+ // start of user data. So we must be careful to copy only user-data
+ char *old_begin = (char *)old->data_addr();
+ char *old_end = old_begin + old->data_size();
+
+ ssize_t old_ssize = old_end - (char *)ptr;
+ CHECK_CONDITION(old_ssize >= 0);
+
+ size_t old_size = (size_t)old_ssize;
+ CHECK_CONDITION(old_size <= old->data_size());
+
+ memcpy(p->data_addr(), ptr, (old_size < size) ? old_size : size);
MallocHook::InvokeDeleteHook(ptr);
MallocHook::InvokeNewHook(p->data_addr(), size);
DebugDeallocate(ptr, MallocBlock::kMallocType);
@@ -1266,12 +1337,6 @@
DebugDeallocate(p, MallocBlock::kArrayNewType);
}
-// Round "value" up to next "alignment" boundary.
-// Requires that "alignment" be a power of two.
-static intptr_t RoundUp(intptr_t value, intptr_t alignment) {
- return (value + alignment - 1) & ~(alignment - 1);
-}
-
// This is mostly the same as do_memalign in tcmalloc.cc.
static void *do_debug_memalign(size_t alignment, size_t size) {
// Allocate >= size bytes aligned on "alignment" boundary
@@ -1297,6 +1362,9 @@
// p is now end of fake header (beginning of client area),
// and orig_p is the end of the real header, so offset_
// is their difference.
+ //
+ // Note that other fields of fake_hdr are initialized with
+ // kMagicUninitializedByte
fake_hdr->set_offset(reinterpret_cast(p) - orig_p);
}
return p;
@@ -1402,19 +1470,25 @@
// malloc_stats just falls through to the base implementation.
extern "C" PERFTOOLS_DLL_DECL void tc_malloc_stats(void) __THROW {
- BASE_MALLOC_STATS();
+ do_malloc_stats();
}
extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) __THROW {
- return BASE_MALLOPT(cmd, value);
+ return do_mallopt(cmd, value);
}
#ifdef HAVE_STRUCT_MALLINFO
extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) __THROW {
- return BASE_MALLINFO();
+ return do_mallinfo();
}
#endif
extern "C" PERFTOOLS_DLL_DECL size_t tc_malloc_size(void* ptr) __THROW {
return MallocExtension::instance()->GetAllocatedSize(ptr);
}
+
+extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) __THROW {
+ void* result = DebugAllocate(size, MallocBlock::kMallocType);
+ MallocHook::InvokeNewHook(result, size);
+ return result;
+}
diff -Nru google-perftools-2.1/src/getenv_safe.h google-perftools-2.2.1/src/getenv_safe.h
--- google-perftools-2.1/src/getenv_safe.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/getenv_safe.h 2014-06-07 22:54:00.000000000 +0200
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+ * Copyright (c) 2014, gperftools Contributors
+ * 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 Google Inc. 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 GETENV_SAFE_H
+#define GETENV_SAFE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This getenv function is safe to call before the C runtime is initialized.
+ * On Windows, it utilizes GetEnvironmentVariable() and on unix it uses
+ * /proc/self/environ instead calling getenv(). It's intended to be used in
+ * routines that run before main(), when the state required for getenv() may
+ * not be set up yet. In particular, errno isn't set up until relatively late
+ * (after the pthreads library has a chance to make it threadsafe), and
+ * getenv() doesn't work until then.
+ * On some platforms, this call will utilize the same, static buffer for
+ * repeated GetenvBeforeMain() calls. Callers should not expect pointers from
+ * this routine to be long lived.
+ * Note that on unix, /proc only has the environment at the time the
+ * application was started, so this routine ignores setenv() calls/etc. Also
+ * note it only reads the first 16K of the environment.
+ *
+ * NOTE: this is version of GetenvBeforeMain that's usable from
+ * C. Implementation is in sysinfo.cc
+ */
+const char* TCMallocGetenvSafe(const char* name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -Nru google-perftools-2.1/src/getpc.h google-perftools-2.2.1/src/getpc.h
--- google-perftools-2.1/src/getpc.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/getpc.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/google/heap-checker.h google-perftools-2.2.1/src/google/heap-checker.h
--- google-perftools-2.1/src/google/heap-checker.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/heap-checker.h 2014-04-13 03:35:40.000000000 +0200
@@ -30,4 +30,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/heap-checker.h is deprecated. Use gperftools/heap-checker.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/heap-profiler.h google-perftools-2.2.1/src/google/heap-profiler.h
--- google-perftools-2.1/src/google/heap-profiler.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/heap-profiler.h 2014-04-13 03:35:40.000000000 +0200
@@ -31,4 +31,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/heap-profiler.h is deprecated. Use gperftools/heap-profiler.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/malloc_extension_c.h google-perftools-2.2.1/src/google/malloc_extension_c.h
--- google-perftools-2.1/src/google/malloc_extension_c.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/malloc_extension_c.h 2014-04-13 03:35:40.000000000 +0200
@@ -31,4 +31,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/malloc_extension_c.h is deprecated. Use gperftools/malloc_extension_c.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/malloc_extension.h google-perftools-2.2.1/src/google/malloc_extension.h
--- google-perftools-2.1/src/google/malloc_extension.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/malloc_extension.h 2014-04-13 03:35:40.000000000 +0200
@@ -30,4 +30,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/malloc_extension.h is deprecated. Use gperftools/malloc_extension.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/malloc_hook_c.h google-perftools-2.2.1/src/google/malloc_hook_c.h
--- google-perftools-2.1/src/google/malloc_hook_c.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/malloc_hook_c.h 2014-04-13 03:35:40.000000000 +0200
@@ -31,4 +31,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/malloc_hook_c.h is deprecated. Use gperftools/malloc_hook_c.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/malloc_hook.h google-perftools-2.2.1/src/google/malloc_hook.h
--- google-perftools-2.1/src/google/malloc_hook.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/malloc_hook.h 2014-04-13 03:35:40.000000000 +0200
@@ -30,4 +30,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/malloc_hook.h is deprecated. Use gperftools/malloc_hook.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/profiler.h google-perftools-2.2.1/src/google/profiler.h
--- google-perftools-2.1/src/google/profiler.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/profiler.h 2014-04-13 03:35:40.000000000 +0200
@@ -31,4 +31,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/profiler.h is deprecated. Use gperftools/profiler.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/stacktrace.h google-perftools-2.2.1/src/google/stacktrace.h
--- google-perftools-2.1/src/google/stacktrace.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/stacktrace.h 2014-04-13 03:35:40.000000000 +0200
@@ -30,4 +30,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/stacktrace.h is deprecated. Use gperftools/stacktrace.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/google/tcmalloc.h google-perftools-2.2.1/src/google/tcmalloc.h
--- google-perftools-2.1/src/google/tcmalloc.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/google/tcmalloc.h 2014-04-13 03:35:40.000000000 +0200
@@ -31,4 +31,7 @@
/* The code has moved to gperftools/. Use that include-directory for
* new code.
*/
+#ifdef __GNUC__
+#warning "google/tcmalloc.h is deprecated. Use gperftools/tcmalloc.h instead"
+#endif
#include
diff -Nru google-perftools-2.1/src/gperftools/heap-checker.h google-perftools-2.2.1/src/gperftools/heap-checker.h
--- google-perftools-2.1/src/gperftools/heap-checker.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/gperftools/heap-checker.h 2014-03-29 21:29:12.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -239,9 +240,6 @@
friend void NamedTwoDisabledLeaks();
friend void* RunNamedDisabledLeaks(void*);
friend void TestHeapLeakCheckerNamedDisabling();
- // TODO(csilvers): remove this one, at least
- friend int main(int, char**);
-
// Actually implements IgnoreObject().
static void DoIgnoreObject(const void* ptr);
@@ -256,15 +254,15 @@
// Helper for DoNoLeaks to ignore all objects reachable from all live data
static void IgnoreAllLiveObjectsLocked(const void* self_stack_top);
- // Callback we pass to ListAllProcessThreads (see thread_lister.h)
+ // Callback we pass to TCMalloc_ListAllProcessThreads (see thread_lister.h)
// that is invoked when all threads of our process are found and stopped.
// The call back does the things needed to ignore live data reachable from
// thread stacks and registers for all our threads
// as well as do other global-live-data ignoring
// (via IgnoreNonThreadLiveObjectsLocked)
// during the quiet state of all threads being stopped.
- // For the argument meaning see the comment by ListAllProcessThreads.
- // Here we only use num_threads and thread_pids, that ListAllProcessThreads
+ // For the argument meaning see the comment by TCMalloc_ListAllProcessThreads.
+ // Here we only use num_threads and thread_pids, that TCMalloc_ListAllProcessThreads
// fills for us with the number and pids of all the threads of our process
// it found and attached to.
static int IgnoreLiveThreadsLocked(void* parameter,
diff -Nru google-perftools-2.1/src/gperftools/heap-profiler.h google-perftools-2.2.1/src/gperftools/heap-profiler.h
--- google-perftools-2.1/src/gperftools/heap-profiler.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/gperftools/heap-profiler.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2005, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/gperftools/malloc_extension.h google-perftools-2.2.1/src/gperftools/malloc_extension.h
--- google-perftools-2.1/src/gperftools/malloc_extension.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/gperftools/malloc_extension.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -71,7 +72,7 @@
}
// Interface to a pluggable system allocator.
-class SysAllocator {
+class PERFTOOLS_DLL_DECL SysAllocator {
public:
SysAllocator() {
}
diff -Nru google-perftools-2.1/src/gperftools/malloc_hook.h google-perftools-2.2.1/src/gperftools/malloc_hook.h
--- google-perftools-2.1/src/gperftools/malloc_hook.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/gperftools/malloc_hook.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/gperftools/profiler.h google-perftools-2.2.1/src/gperftools/profiler.h
--- google-perftools-2.1/src/gperftools/profiler.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/gperftools/profiler.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2005, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/gperftools/stacktrace.h google-perftools-2.2.1/src/gperftools/stacktrace.h
--- google-perftools-2.1/src/gperftools/stacktrace.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/gperftools/stacktrace.h 2014-02-09 01:17:55.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/gperftools/tcmalloc.h.in google-perftools-2.2.1/src/gperftools/tcmalloc.h.in
--- google-perftools-2.1/src/gperftools/tcmalloc.h.in 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/gperftools/tcmalloc.h.in 2014-04-13 03:35:40.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2003, Google Inc.
* All rights reserved.
*
@@ -88,6 +89,7 @@
const char** patch) __THROW;
PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) __THROW;
PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW;
PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW;
PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) __THROW;
diff -Nru google-perftools-2.1/src/heap-checker-bcad.cc google-perftools-2.2.1/src/heap-checker-bcad.cc
--- google-perftools-2.1/src/heap-checker-bcad.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/heap-checker-bcad.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/heap-checker.cc google-perftools-2.2.1/src/heap-checker.cc
--- google-perftools-2.1/src/heap-checker.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/heap-checker.cc 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -285,7 +286,7 @@
// Wrapper of LowLevelAlloc for STL_Allocator and direct use.
// We always access this class under held heap_checker_lock,
// this allows us to in particular protect the period when threads are stopped
-// at random spots with ListAllProcessThreads by heap_checker_lock,
+// at random spots with TCMalloc_ListAllProcessThreads by heap_checker_lock,
// w/o worrying about the lock in LowLevelAlloc::Arena.
// We rely on the fact that we use an own arena with an own lock here.
class HeapLeakChecker::Allocator {
@@ -1043,7 +1044,7 @@
THREAD_REGS thread_regs;
#define sys_ptrace(r, p, a, d) syscall(SYS_ptrace, (r), (p), (a), (d))
// We use sys_ptrace to avoid thread locking
- // because this is called from ListAllProcessThreads
+ // because this is called from TCMalloc_ListAllProcessThreads
// when all but this thread are suspended.
if (sys_ptrace(PTRACE_GETREGS, thread_pids[i], NULL, &thread_regs) == 0) {
// Need to use SP to get all the data from the very last stack frame:
@@ -1079,7 +1080,7 @@
// Do all other liveness walking while all threads are stopped:
IgnoreNonThreadLiveObjectsLocked();
// Can now resume the threads:
- ResumeAllProcessThreads(num_threads, thread_pids);
+ TCMalloc_ResumeAllProcessThreads(num_threads, thread_pids);
thread_listing_status = CALLBACK_COMPLETED;
return failures;
}
@@ -1237,7 +1238,7 @@
}
}
-// Callback for ListAllProcessThreads in IgnoreAllLiveObjectsLocked below
+// Callback for TCMalloc_ListAllProcessThreads in IgnoreAllLiveObjectsLocked below
// to test/verify that we have just the one main thread, in which case
// we can do everything in that main thread,
// so that CPU profiler can collect all its samples.
@@ -1248,7 +1249,7 @@
RAW_LOG(WARNING, "Have threads: Won't CPU-profile the bulk of leak "
"checking work happening in IgnoreLiveThreadsLocked!");
}
- ResumeAllProcessThreads(num_threads, thread_pids);
+ TCMalloc_ResumeAllProcessThreads(num_threads, thread_pids);
return num_threads;
}
@@ -1290,16 +1291,17 @@
if (FLAGS_heap_check_ignore_thread_live) {
// In case we are doing CPU profiling we'd like to do all the work
// in the main thread, not in the special thread created by
- // ListAllProcessThreads, so that CPU profiler can collect all its samples.
- // The machinery of ListAllProcessThreads conflicts with the CPU profiler
- // by also relying on signals and ::sigaction.
- // We can do this (run everything in the main thread) safely
- // only if there's just the main thread itself in our process.
- // This variable reflects these two conditions:
+ // TCMalloc_ListAllProcessThreads, so that CPU profiler can
+ // collect all its samples. The machinery of
+ // TCMalloc_ListAllProcessThreads conflicts with the CPU profiler
+ // by also relying on signals and ::sigaction. We can do this
+ // (run everything in the main thread) safely only if there's just
+ // the main thread itself in our process. This variable reflects
+ // these two conditions:
bool want_and_can_run_in_main_thread =
ProfilingIsEnabledForAllThreads() &&
- ListAllProcessThreads(NULL, IsOneThread) == 1;
- // When the normal path of ListAllProcessThreads below is taken,
+ TCMalloc_ListAllProcessThreads(NULL, IsOneThread) == 1;
+ // When the normal path of TCMalloc_ListAllProcessThreads below is taken,
// we fully suspend the threads right here before any liveness checking
// and keep them suspended for the whole time of liveness checking
// inside of the IgnoreLiveThreadsLocked callback.
@@ -1308,7 +1310,7 @@
// graph while we walk it).
int r = want_and_can_run_in_main_thread
? IgnoreLiveThreadsLocked(NULL, 1, &self_thread_pid, dummy_ap)
- : ListAllProcessThreads(NULL, IgnoreLiveThreadsLocked);
+ : TCMalloc_ListAllProcessThreads(NULL, IgnoreLiveThreadsLocked);
need_to_ignore_non_thread_objects = r < 0;
if (r < 0) {
RAW_LOG(WARNING, "Thread finding failed with %d errno=%d", r, errno);
@@ -1651,8 +1653,13 @@
// Save pid of main thread for using in naming dump files
static int32 main_thread_pid = getpid();
#ifdef HAVE_PROGRAM_INVOCATION_NAME
+#ifdef __UCLIBC__
+extern const char* program_invocation_name;
+extern const char* program_invocation_short_name;
+#else
extern char* program_invocation_name;
extern char* program_invocation_short_name;
+#endif
static const char* invocation_name() { return program_invocation_short_name; }
static string invocation_path() { return program_invocation_name; }
#else
@@ -2206,13 +2213,14 @@
RAW_CHECK(MallocHook::AddNewHook(&NewHook), "");
RAW_CHECK(MallocHook::AddDeleteHook(&DeleteHook), "");
constructor_heap_profiling = true;
- MemoryRegionMap::Init(1);
+ MemoryRegionMap::Init(1, /* use_buckets */ false);
// Set up MemoryRegionMap with (at least) one caller stack frame to record
// (important that it's done before HeapProfileTable creation below).
Allocator::Init();
RAW_CHECK(heap_profile == NULL, "");
heap_profile = new(Allocator::Allocate(sizeof(HeapProfileTable)))
- HeapProfileTable(&Allocator::Allocate, &Allocator::Free);
+ HeapProfileTable(&Allocator::Allocate, &Allocator::Free,
+ /* profile_mmap */ false);
RAW_VLOG(10, "Starting tracking the heap");
heap_checker_on = true;
}
diff -Nru google-perftools-2.1/src/heap-profiler.cc google-perftools-2.2.1/src/heap-profiler.cc
--- google-perftools-2.1/src/heap-profiler.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/heap-profiler.cc 2014-04-13 02:18:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -51,6 +52,7 @@
#include
#include
#include
+#include
#include
#include
@@ -190,13 +192,14 @@
RAW_DCHECK(heap_lock.IsHeld(), "");
int bytes_written = 0;
if (is_on) {
- if (FLAGS_mmap_profile) {
- heap_profile->RefreshMMapData();
- }
+ HeapProfileTable::Stats const stats = heap_profile->total();
+ (void)stats; // avoid an unused-variable warning in non-debug mode.
bytes_written = heap_profile->FillOrderedProfile(buf, buflen - 1);
- if (FLAGS_mmap_profile) {
- heap_profile->ClearMMapData();
- }
+ // FillOrderedProfile should not reduce the set of active mmap-ed regions,
+ // hence MemoryRegionMap will let us remove everything we've added above:
+ RAW_DCHECK(stats.Equivalent(heap_profile->total()), "");
+ // if this fails, we somehow removed by FillOrderedProfile
+ // more than we have added.
}
buf[bytes_written] = '\0';
RAW_DCHECK(bytes_written == strlen(buf), "");
@@ -435,7 +438,8 @@
if (FLAGS_mmap_profile) {
// Ask MemoryRegionMap to record all mmap, mremap, and sbrk
// call stack traces of at least size kMaxStackDepth:
- MemoryRegionMap::Init(HeapProfileTable::kMaxStackDepth);
+ MemoryRegionMap::Init(HeapProfileTable::kMaxStackDepth,
+ /* use_buckets */ true);
}
if (FLAGS_mmap_log) {
@@ -455,7 +459,7 @@
reinterpret_cast(ProfilerMalloc(kProfileBufferSize));
heap_profile = new(ProfilerMalloc(sizeof(HeapProfileTable)))
- HeapProfileTable(ProfilerMalloc, ProfilerFree);
+ HeapProfileTable(ProfilerMalloc, ProfilerFree, FLAGS_mmap_profile);
last_dump_alloc = 0;
last_dump_free = 0;
@@ -533,6 +537,20 @@
}
}
+// Signal handler that is registered when a user selectable signal
+// number is defined in the environment variable HEAPPROFILESIGNAL.
+static void HeapProfilerDumpSignal(int signal_number) {
+ (void)signal_number;
+ if (!heap_lock.TryLock()) {
+ return;
+ }
+ if (is_on && !dumping) {
+ DumpProfileLocked("signal");
+ }
+ heap_lock.Unlock();
+}
+
+
//----------------------------------------------------------------------
// Initialization/finalization code
//----------------------------------------------------------------------
@@ -553,6 +571,19 @@
}
#endif
+ char *signal_number_str = getenv("HEAPPROFILESIGNAL");
+ if (signal_number_str != NULL) {
+ long int signal_number = strtol(signal_number_str, NULL, 10);
+ intptr_t old_signal_handler = reinterpret_cast(signal(signal_number, HeapProfilerDumpSignal));
+ if (old_signal_handler == reinterpret_cast(SIG_ERR)) {
+ RAW_LOG(FATAL, "Failed to set signal. Perhaps signal number %s is invalid\n", signal_number_str);
+ } else if (old_signal_handler == 0) {
+ RAW_LOG(INFO,"Using signal %d as heap profiling switch", signal_number);
+ } else {
+ RAW_LOG(FATAL, "Signal %d already in use\n", signal_number);
+ }
+ }
+
HeapProfileTable::CleanupOldProfiles(fname);
HeapProfilerStart(fname);
diff -Nru google-perftools-2.1/src/heap-profile-stats.h google-perftools-2.2.1/src/heap-profile-stats.h
--- google-perftools-2.1/src/heap-profile-stats.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/heap-profile-stats.h 2013-09-22 04:03:49.000000000 +0200
@@ -0,0 +1,78 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+// Copyright (c) 2013, Google Inc.
+// 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 Google Inc. 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.
+
+// This file defines structs to accumulate memory allocation and deallocation
+// counts. These structs are commonly used for malloc (in HeapProfileTable)
+// and mmap (in MemoryRegionMap).
+
+// A bucket is data structure for heap profiling to store a pair of a stack
+// trace and counts of (de)allocation. Buckets are stored in a hash table
+// which is declared as "HeapProfileBucket**".
+//
+// A hash value is computed from a stack trace. Collision in the hash table
+// is resolved by separate chaining with linked lists. The links in the list
+// are implemented with the member "HeapProfileBucket* next".
+//
+// A structure of a hash table HeapProfileBucket** bucket_table would be like:
+// bucket_table[0] => NULL
+// bucket_table[1] => HeapProfileBucket() => HeapProfileBucket() => NULL
+// ...
+// bucket_table[i] => HeapProfileBucket() => NULL
+// ...
+// bucket_table[n] => HeapProfileBucket() => NULL
+
+#ifndef HEAP_PROFILE_STATS_H_
+#define HEAP_PROFILE_STATS_H_
+
+struct HeapProfileStats {
+ // Returns true if the two HeapProfileStats are semantically equal.
+ bool Equivalent(const HeapProfileStats& other) const {
+ return allocs - frees == other.allocs - other.frees &&
+ alloc_size - free_size == other.alloc_size - other.free_size;
+ }
+
+ int32 allocs; // Number of allocation calls.
+ int32 frees; // Number of free calls.
+ int64 alloc_size; // Total size of all allocated objects so far.
+ int64 free_size; // Total size of all freed objects so far.
+};
+
+// Allocation and deallocation statistics per each stack trace.
+struct HeapProfileBucket : public HeapProfileStats {
+ // Longest stack trace we record.
+ static const int kMaxStackDepth = 32;
+
+ uintptr_t hash; // Hash value of the stack trace.
+ int depth; // Depth of stack trace.
+ const void** stack; // Stack trace.
+ HeapProfileBucket* next; // Next entry in hash-table.
+};
+
+#endif // HEAP_PROFILE_STATS_H_
diff -Nru google-perftools-2.1/src/heap-profile-table.cc google-perftools-2.2.1/src/heap-profile-table.cc
--- google-perftools-2.1/src/heap-profile-table.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/heap-profile-table.cc 2013-12-06 21:16:47.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
@@ -99,8 +100,7 @@
//----------------------------------------------------------------------
-// Size for alloc_table_ and mmap_table_.
-static const int kHashTableSize = 179999;
+static const int kHashTableSize = 179999; // Size for bucket_table_.
/*static*/ const int HeapProfileTable::kMaxStackDepth;
//----------------------------------------------------------------------
@@ -122,62 +122,50 @@
//----------------------------------------------------------------------
-HeapProfileTable::HeapProfileTable(Allocator alloc, DeAllocator dealloc)
- : alloc_(alloc), dealloc_(dealloc) {
- // Initialize the overall profile stats.
- memset(&total_, 0, sizeof(total_));
-
- // Make the malloc table.
- const int alloc_table_bytes = kHashTableSize * sizeof(*alloc_table_);
- alloc_table_ = reinterpret_cast(alloc_(alloc_table_bytes));
- memset(alloc_table_, 0, alloc_table_bytes);
- num_alloc_buckets_ = 0;
-
- // Initialize the mmap table.
- mmap_table_ = NULL;
- num_available_mmap_buckets_ = 0;
+HeapProfileTable::HeapProfileTable(Allocator alloc,
+ DeAllocator dealloc,
+ bool profile_mmap)
+ : alloc_(alloc),
+ dealloc_(dealloc),
+ profile_mmap_(profile_mmap),
+ bucket_table_(NULL),
+ num_buckets_(0),
+ address_map_(NULL) {
+ // Make a hash table for buckets.
+ const int table_bytes = kHashTableSize * sizeof(*bucket_table_);
+ bucket_table_ = static_cast(alloc_(table_bytes));
+ memset(bucket_table_, 0, table_bytes);
- // Make malloc and mmap allocation maps.
- alloc_address_map_ =
+ // Make an allocation map.
+ address_map_ =
new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_);
- mmap_address_map_ = NULL;
-}
-HeapProfileTable::~HeapProfileTable() {
- DeallocateBucketTable(alloc_table_);
- alloc_table_ = NULL;
- DeallocateBucketTable(mmap_table_);
- mmap_table_ = NULL;
- DeallocateAllocationMap(alloc_address_map_);
- alloc_address_map_ = NULL;
- DeallocateAllocationMap(mmap_address_map_);
- mmap_address_map_ = NULL;
-}
-
-void HeapProfileTable::DeallocateAllocationMap(AllocationMap* allocation) {
- if (allocation != NULL) {
- alloc_address_map_->~AllocationMap();
- dealloc_(allocation);
- }
+ // Initialize.
+ memset(&total_, 0, sizeof(total_));
+ num_buckets_ = 0;
}
-void HeapProfileTable::DeallocateBucketTable(Bucket** table) {
- if (table != NULL) {
- for (int b = 0; b < kHashTableSize; b++) {
- for (Bucket* x = table[b]; x != 0; /**/) {
- Bucket* b = x;
- x = x->next;
- dealloc_(b->stack);
- dealloc_(b);
- }
+HeapProfileTable::~HeapProfileTable() {
+ // Free the allocation map.
+ address_map_->~AllocationMap();
+ dealloc_(address_map_);
+ address_map_ = NULL;
+
+ // Free the hash table.
+ for (int i = 0; i < kHashTableSize; i++) {
+ for (Bucket* curr = bucket_table_[i]; curr != 0; /**/) {
+ Bucket* bucket = curr;
+ curr = curr->next;
+ dealloc_(bucket->stack);
+ dealloc_(bucket);
}
- dealloc_(table);
}
+ dealloc_(bucket_table_);
+ bucket_table_ = NULL;
}
-HeapProfileTable::Bucket* HeapProfileTable::GetBucket(
- int depth, const void* const key[], Bucket** table,
- int* bucket_count) {
+HeapProfileTable::Bucket* HeapProfileTable::GetBucket(int depth,
+ const void* const key[]) {
// Make hash-value
uintptr_t h = 0;
for (int i = 0; i < depth; i++) {
@@ -190,7 +178,7 @@
// Lookup stack trace in table
unsigned int buck = ((unsigned int) h) % kHashTableSize;
- for (Bucket* b = table[buck]; b != 0; b = b->next) {
+ for (Bucket* b = bucket_table_[buck]; b != 0; b = b->next) {
if ((b->hash == h) &&
(b->depth == depth) &&
equal(key, key + depth, b->stack)) {
@@ -207,11 +195,9 @@
b->hash = h;
b->depth = depth;
b->stack = kcopy;
- b->next = table[buck];
- table[buck] = b;
- if (bucket_count != NULL) {
- ++(*bucket_count);
- }
+ b->next = bucket_table_[buck];
+ bucket_table_[buck] = b;
+ num_buckets_++;
return b;
}
@@ -224,8 +210,7 @@
void HeapProfileTable::RecordAlloc(
const void* ptr, size_t bytes, int stack_depth,
const void* const call_stack[]) {
- Bucket* b = GetBucket(stack_depth, call_stack, alloc_table_,
- &num_alloc_buckets_);
+ Bucket* b = GetBucket(stack_depth, call_stack);
b->allocs++;
b->alloc_size += bytes;
total_.allocs++;
@@ -234,12 +219,12 @@
AllocValue v;
v.set_bucket(b); // also did set_live(false); set_ignore(false)
v.bytes = bytes;
- alloc_address_map_->Insert(ptr, v);
+ address_map_->Insert(ptr, v);
}
void HeapProfileTable::RecordFree(const void* ptr) {
AllocValue v;
- if (alloc_address_map_->FindAndRemove(ptr, &v)) {
+ if (address_map_->FindAndRemove(ptr, &v)) {
Bucket* b = v.bucket();
b->frees++;
b->free_size += v.bytes;
@@ -249,14 +234,14 @@
}
bool HeapProfileTable::FindAlloc(const void* ptr, size_t* object_size) const {
- const AllocValue* alloc_value = alloc_address_map_->Find(ptr);
+ const AllocValue* alloc_value = address_map_->Find(ptr);
if (alloc_value != NULL) *object_size = alloc_value->bytes;
return alloc_value != NULL;
}
bool HeapProfileTable::FindAllocDetails(const void* ptr,
AllocInfo* info) const {
- const AllocValue* alloc_value = alloc_address_map_->Find(ptr);
+ const AllocValue* alloc_value = address_map_->Find(ptr);
if (alloc_value != NULL) {
info->object_size = alloc_value->bytes;
info->call_stack = alloc_value->bucket()->stack;
@@ -270,13 +255,13 @@
const void** object_ptr,
size_t* object_size) const {
const AllocValue* alloc_value =
- alloc_address_map_->FindInside(&AllocValueSize, max_size, ptr, object_ptr);
+ address_map_->FindInside(&AllocValueSize, max_size, ptr, object_ptr);
if (alloc_value != NULL) *object_size = alloc_value->bytes;
return alloc_value != NULL;
}
bool HeapProfileTable::MarkAsLive(const void* ptr) {
- AllocValue* alloc = alloc_address_map_->FindMutable(ptr);
+ AllocValue* alloc = address_map_->FindMutable(ptr);
if (alloc && !alloc->live()) {
alloc->set_live(true);
return true;
@@ -285,7 +270,7 @@
}
void HeapProfileTable::MarkAsIgnored(const void* ptr) {
- AllocValue* alloc = alloc_address_map_->FindMutable(ptr);
+ AllocValue* alloc = address_map_->FindMutable(ptr);
if (alloc) {
alloc->set_ignore(true);
}
@@ -326,81 +311,26 @@
HeapProfileTable::Bucket**
HeapProfileTable::MakeSortedBucketList() const {
- Bucket** list = reinterpret_cast(alloc_(sizeof(Bucket) *
- (num_alloc_buckets_ + num_available_mmap_buckets_)));
+ Bucket** list = static_cast(alloc_(sizeof(Bucket) * num_buckets_));
- RAW_DCHECK(mmap_table_ != NULL || num_available_mmap_buckets_ == 0, "");
-
- int n = 0;
-
- for (int b = 0; b < kHashTableSize; b++) {
- for (Bucket* x = alloc_table_[b]; x != 0; x = x->next) {
- list[n++] = x;
+ int bucket_count = 0;
+ for (int i = 0; i < kHashTableSize; i++) {
+ for (Bucket* curr = bucket_table_[i]; curr != 0; curr = curr->next) {
+ list[bucket_count++] = curr;
}
}
- RAW_DCHECK(n == num_alloc_buckets_, "");
+ RAW_DCHECK(bucket_count == num_buckets_, "");
- if (mmap_table_ != NULL) {
- for (int b = 0; b < kHashTableSize; b++) {
- for (Bucket* x = mmap_table_[b]; x != 0; x = x->next) {
- list[n++] = x;
- }
- }
- }
- RAW_DCHECK(n == num_alloc_buckets_ + num_available_mmap_buckets_, "");
-
- sort(list, list + num_alloc_buckets_ + num_available_mmap_buckets_,
- ByAllocatedSpace);
+ sort(list, list + num_buckets_, ByAllocatedSpace);
return list;
}
-void HeapProfileTable::RefreshMMapData() {
- // Make the table
- static const int mmap_table_bytes = kHashTableSize * sizeof(*mmap_table_);
- if (mmap_table_ == NULL) {
- mmap_table_ = reinterpret_cast(alloc_(mmap_table_bytes));
- memset(mmap_table_, 0, mmap_table_bytes);
- }
- num_available_mmap_buckets_ = 0;
-
- ClearMMapData();
- mmap_address_map_ =
- new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_);
-
- MemoryRegionMap::LockHolder l;
- for (MemoryRegionMap::RegionIterator r =
- MemoryRegionMap::BeginRegionLocked();
- r != MemoryRegionMap::EndRegionLocked(); ++r) {
- Bucket* b =
- GetBucket(r->call_stack_depth, r->call_stack, mmap_table_, NULL);
- if (b->alloc_size == 0) {
- num_available_mmap_buckets_ += 1;
- }
- b->allocs += 1;
- b->alloc_size += r->end_addr - r->start_addr;
-
- AllocValue v;
- v.set_bucket(b);
- v.bytes = r->end_addr - r->start_addr;
- mmap_address_map_->Insert(reinterpret_cast(r->start_addr), v);
- }
-}
-
-void HeapProfileTable::ClearMMapData() {
- if (mmap_address_map_ != NULL) {
- mmap_address_map_->Iterate(ZeroBucketCountsIterator, this);
- mmap_address_map_->~AllocationMap();
- dealloc_(mmap_address_map_);
- mmap_address_map_ = NULL;
- }
-}
-
void HeapProfileTable::IterateOrderedAllocContexts(
AllocContextIterator callback) const {
Bucket** list = MakeSortedBucketList();
AllocContextInfo info;
- for (int i = 0; i < num_alloc_buckets_; ++i) {
+ for (int i = 0; i < num_buckets_; ++i) {
*static_cast(&info) = *static_cast(list[i]);
info.stack_depth = list[i]->depth;
info.call_stack = list[i]->stack;
@@ -432,14 +362,17 @@
memset(&stats, 0, sizeof(stats));
int bucket_length = snprintf(buf, size, "%s", kProfileHeader);
if (bucket_length < 0 || bucket_length >= size) return 0;
- Bucket total_with_mmap(total_);
- if (mmap_table_ != NULL) {
- total_with_mmap.alloc_size += MemoryRegionMap::MapSize();
- total_with_mmap.free_size += MemoryRegionMap::UnmapSize();
- }
- bucket_length = UnparseBucket(total_with_mmap, buf, bucket_length, size,
+ bucket_length = UnparseBucket(total_, buf, bucket_length, size,
" heapprofile", &stats);
- for (int i = 0; i < num_alloc_buckets_; i++) {
+
+ // Dump the mmap list first.
+ if (profile_mmap_) {
+ BufferArgs buffer(buf, bucket_length, size);
+ MemoryRegionMap::IterateBuckets(DumpBucketIterator, &buffer);
+ bucket_length = buffer.buflen;
+ }
+
+ for (int i = 0; i < num_buckets_; i++) {
bucket_length = UnparseBucket(*list[i], buf, bucket_length, size, "",
&stats);
}
@@ -453,6 +386,13 @@
return bucket_length + map_length;
}
+// static
+void HeapProfileTable::DumpBucketIterator(const Bucket* bucket,
+ BufferArgs* args) {
+ args->buflen = UnparseBucket(*bucket, args->buf, args->buflen, args->bufsize,
+ "", NULL);
+}
+
inline
void HeapProfileTable::DumpNonLiveIterator(const void* ptr, AllocValue* v,
const DumpArgs& args) {
@@ -474,17 +414,6 @@
RawWrite(args.fd, buf, len);
}
-inline void HeapProfileTable::ZeroBucketCountsIterator(
- const void* ptr, AllocValue* v, HeapProfileTable* heap_profile) {
- Bucket* b = v->bucket();
- if (b != NULL) {
- b->allocs = 0;
- b->alloc_size = 0;
- b->free_size = 0;
- b->frees = 0;
- }
-}
-
// Callback from NonLiveSnapshot; adds entry to arg->dest
// if not the entry is not live and is not present in arg->base.
void HeapProfileTable::AddIfNonLive(const void* ptr, AllocValue* v,
@@ -549,7 +478,7 @@
HeapProfileTable::Snapshot* HeapProfileTable::TakeSnapshot() {
Snapshot* s = new (alloc_(sizeof(Snapshot))) Snapshot(alloc_, dealloc_);
- alloc_address_map_->Iterate(AddToSnapshot, s);
+ address_map_->Iterate(AddToSnapshot, s);
return s;
}
@@ -574,7 +503,7 @@
AddNonLiveArgs args;
args.dest = s;
args.base = base;
- alloc_address_map_->Iterate(AddIfNonLive, &args);
+ address_map_->Iterate(AddIfNonLive, &args);
RAW_VLOG(2, "NonLiveSnapshot output: %d %d\n",
int(s->total_.allocs - s->total_.frees),
int(s->total_.alloc_size - s->total_.free_size));
diff -Nru google-perftools-2.1/src/heap-profile-table.h google-perftools-2.2.1/src/heap-profile-table.h
--- google-perftools-2.1/src/heap-profile-table.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/heap-profile-table.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
@@ -38,6 +39,7 @@
#include "addressmap-inl.h"
#include "base/basictypes.h"
#include "base/logging.h" // for RawFD
+#include "heap-profile-stats.h"
// Table to maintain a heap profile data inside,
// i.e. the set of currently active heap memory allocations.
@@ -58,18 +60,7 @@
// data types ----------------------------
// Profile stats.
- struct Stats {
- int32 allocs; // Number of allocation calls
- int32 frees; // Number of free calls
- int64 alloc_size; // Total size of all allocated objects so far
- int64 free_size; // Total size of all freed objects so far
-
- // semantic equality
- bool Equivalent(const Stats& x) const {
- return allocs - frees == x.allocs - x.frees &&
- alloc_size - free_size == x.alloc_size - x.free_size;
- }
- };
+ typedef HeapProfileStats Stats;
// Info we can return about an allocation.
struct AllocInfo {
@@ -94,7 +85,7 @@
// interface ---------------------------
- HeapProfileTable(Allocator alloc, DeAllocator dealloc);
+ HeapProfileTable(Allocator alloc, DeAllocator dealloc, bool profile_mmap);
~HeapProfileTable();
// Collect the stack trace for the function that asked to do the
@@ -149,7 +140,7 @@
// Iterate over the allocation profile data calling "callback"
// for every allocation.
void IterateAllocs(AllocIterator callback) const {
- alloc_address_map_->Iterate(MapArgsAllocIterator, callback);
+ address_map_->Iterate(MapArgsAllocIterator, callback);
}
// Allocation context profile data iteration callback
@@ -187,28 +178,13 @@
// Caller must call ReleaseSnapshot() on result when no longer needed.
Snapshot* NonLiveSnapshot(Snapshot* base);
- // Refresh the internal mmap information from MemoryRegionMap. Results of
- // FillOrderedProfile and IterateOrderedAllocContexts will contain mmap'ed
- // memory regions as at calling RefreshMMapData.
- void RefreshMMapData();
-
- // Clear the internal mmap information. Results of FillOrderedProfile and
- // IterateOrderedAllocContexts won't contain mmap'ed memory regions after
- // calling ClearMMapData.
- void ClearMMapData();
-
private:
// data types ----------------------------
// Hash table bucket to hold (de)allocation stats
// for a given allocation call stack trace.
- struct Bucket : public Stats {
- uintptr_t hash; // Hash value of the stack trace
- int depth; // Depth of stack trace
- const void** stack; // Stack trace
- Bucket* next; // Next entry in hash-table
- };
+ typedef HeapProfileBucket Bucket;
// Info stored in the address map
struct AllocValue {
@@ -247,13 +223,30 @@
typedef AddressMap AllocationMap;
+ // Arguments that need to be passed DumpBucketIterator callback below.
+ struct BufferArgs {
+ BufferArgs(char* buf_arg, int buflen_arg, int bufsize_arg)
+ : buf(buf_arg),
+ buflen(buflen_arg),
+ bufsize(bufsize_arg) {
+ }
+
+ char* buf;
+ int buflen;
+ int bufsize;
+
+ DISALLOW_COPY_AND_ASSIGN(BufferArgs);
+ };
+
// Arguments that need to be passed DumpNonLiveIterator callback below.
struct DumpArgs {
+ DumpArgs(RawFD fd_arg, Stats* profile_stats_arg)
+ : fd(fd_arg),
+ profile_stats(profile_stats_arg) {
+ }
+
RawFD fd; // file to write to
Stats* profile_stats; // stats to update (may be NULL)
-
- DumpArgs(RawFD a, Stats* d)
- : fd(a), profile_stats(d) { }
};
// helpers ----------------------------
@@ -274,18 +267,9 @@
const char* extra,
Stats* profile_stats);
- // Deallocate a given allocation map.
- void DeallocateAllocationMap(AllocationMap* allocation);
-
- // Deallocate a given bucket table.
- void DeallocateBucketTable(Bucket** table);
-
- // Get the bucket for the caller stack trace 'key' of depth 'depth' from a
- // bucket hash map 'table' creating the bucket if needed. '*bucket_count'
- // is incremented both when 'bucket_count' is not NULL and when a new
- // bucket object is created.
- Bucket* GetBucket(int depth, const void* const key[], Bucket** table,
- int* bucket_count);
+ // Get the bucket for the caller stack trace 'key' of depth 'depth'
+ // creating the bucket if needed.
+ Bucket* GetBucket(int depth, const void* const key[]);
// Helper for IterateAllocs to do callback signature conversion
// from AllocationMap::Iterate to AllocIterator.
@@ -300,18 +284,17 @@
callback(ptr, info);
}
+ // Helper to dump a bucket.
+ inline static void DumpBucketIterator(const Bucket* bucket,
+ BufferArgs* args);
+
// Helper for DumpNonLiveProfile to do object-granularity
// heap profile dumping. It gets passed to AllocationMap::Iterate.
inline static void DumpNonLiveIterator(const void* ptr, AllocValue* v,
const DumpArgs& args);
- // Helper for filling size variables in buckets by zero.
- inline static void ZeroBucketCountsIterator(
- const void* ptr, AllocValue* v, HeapProfileTable* heap_profile);
-
// Helper for IterateOrderedAllocContexts and FillOrderedProfile.
- // Creates a sorted list of Buckets whose length is num_alloc_buckets_ +
- // num_avaliable_mmap_buckets_.
+ // Creates a sorted list of Buckets whose length is num_buckets_.
// The caller is responsible for deallocating the returned list.
Bucket** MakeSortedBucketList() const;
@@ -344,25 +327,19 @@
// Overall profile stats; we use only the Stats part,
// but make it a Bucket to pass to UnparseBucket.
- // It doesn't contain mmap'ed regions.
Bucket total_;
+ bool profile_mmap_;
+
// Bucket hash table for malloc.
// We hand-craft one instead of using one of the pre-written
// ones because we do not want to use malloc when operating on the table.
// It is only few lines of code, so no big deal.
- Bucket** alloc_table_;
- int num_alloc_buckets_;
-
- // Bucket hash table for mmap.
- // This table is filled with the information from MemoryRegionMap by calling
- // RefreshMMapData.
- Bucket** mmap_table_;
- int num_available_mmap_buckets_;
+ Bucket** bucket_table_;
+ int num_buckets_;
// Map of all currently allocated objects and mapped regions we know about.
- AllocationMap* alloc_address_map_;
- AllocationMap* mmap_address_map_;
+ AllocationMap* address_map_;
DISALLOW_COPY_AND_ASSIGN(HeapProfileTable);
};
diff -Nru google-perftools-2.1/src/internal_logging.cc google-perftools-2.2.1/src/internal_logging.cc
--- google-perftools-2.1/src/internal_logging.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/internal_logging.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/internal_logging.h google-perftools-2.2.1/src/internal_logging.h
--- google-perftools-2.1/src/internal_logging.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/internal_logging.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/libc_override_gcc_and_weak.h google-perftools-2.2.1/src/libc_override_gcc_and_weak.h
--- google-perftools-2.1/src/libc_override_gcc_and_weak.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/libc_override_gcc_and_weak.h 2014-06-21 21:22:58.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
@@ -81,13 +82,20 @@
void* pvalloc(size_t size) __THROW ALIAS(tc_pvalloc);
int posix_memalign(void** r, size_t a, size_t s) __THROW
ALIAS(tc_posix_memalign);
+#ifndef __UCLIBC__
void malloc_stats(void) __THROW ALIAS(tc_malloc_stats);
+#endif
int mallopt(int cmd, int value) __THROW ALIAS(tc_mallopt);
#ifdef HAVE_STRUCT_MALLINFO
struct mallinfo mallinfo(void) __THROW ALIAS(tc_mallinfo);
#endif
size_t malloc_size(void* p) __THROW ALIAS(tc_malloc_size);
+#if defined(__ANDROID__)
+ size_t malloc_usable_size(const void* p) __THROW
+ ALIAS(tc_malloc_size);
+#else
size_t malloc_usable_size(void* p) __THROW ALIAS(tc_malloc_size);
+#endif
} // extern "C"
#undef ALIAS
diff -Nru google-perftools-2.1/src/libc_override_glibc.h google-perftools-2.2.1/src/libc_override_glibc.h
--- google-perftools-2.1/src/libc_override_glibc.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/libc_override_glibc.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/libc_override.h google-perftools-2.2.1/src/libc_override.h
--- google-perftools-2.1/src/libc_override.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/libc_override.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/libc_override_osx.h google-perftools-2.2.1/src/libc_override_osx.h
--- google-perftools-2.1/src/libc_override_osx.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/libc_override_osx.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/libc_override_redefine.h google-perftools-2.2.1/src/libc_override_redefine.h
--- google-perftools-2.1/src/libc_override_redefine.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/libc_override_redefine.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/linked_list.h google-perftools-2.2.1/src/linked_list.h
--- google-perftools-2.1/src/linked_list.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/linked_list.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/malloc_extension.cc google-perftools-2.2.1/src/malloc_extension.cc
--- google-perftools-2.1/src/malloc_extension.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/malloc_extension.cc 2014-03-29 21:41:08.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -50,6 +51,7 @@
#include "gperftools/malloc_extension.h"
#include "gperftools/malloc_extension_c.h"
#include "maybe_threads.h"
+#include "base/googleinit.h"
using STL_NAMESPACE::string;
using STL_NAMESPACE::vector;
@@ -193,23 +195,27 @@
// The current malloc extension object.
-static pthread_once_t module_init = PTHREAD_ONCE_INIT;
-static MallocExtension* current_instance = NULL;
+static MallocExtension* current_instance;
static void InitModule() {
+ if (current_instance != NULL) {
+ return;
+ }
current_instance = new MallocExtension;
#ifndef NO_HEAP_CHECK
HeapLeakChecker::IgnoreObject(current_instance);
#endif
}
+REGISTER_MODULE_INITIALIZER(malloc_extension_init, InitModule())
+
MallocExtension* MallocExtension::instance() {
- perftools_pthread_once(&module_init, InitModule);
+ InitModule();
return current_instance;
}
void MallocExtension::Register(MallocExtension* implementation) {
- perftools_pthread_once(&module_init, InitModule);
+ InitModule();
// When running under valgrind, our custom malloc is replaced with
// valgrind's one and malloc extensions will not work. (Note:
// callers should be responsible for checking that they are the
diff -Nru google-perftools-2.1/src/malloc_hook.cc google-perftools-2.2.1/src/malloc_hook.cc
--- google-perftools-2.1/src/malloc_hook.cc 2013-07-30 08:10:37.000000000 +0200
+++ google-perftools-2.2.1/src/malloc_hook.cc 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -173,18 +174,6 @@
return old_val;
}
-template
-PtrT AtomicPtr::CompareAndSwap(PtrT old_val, PtrT new_val) {
- base::subtle::MemoryBarrier(); // Release semantics.
- PtrT retval = reinterpret_cast(static_cast(
- base::subtle::NoBarrier_CompareAndSwap(
- &data_,
- reinterpret_cast(old_val),
- reinterpret_cast(new_val))));
- base::subtle::MemoryBarrier(); // And acquire semantics.
- return retval;
-}
-
AtomicPtr new_hook_ = { 0 };
AtomicPtr delete_hook_ = { 0 };
AtomicPtr premmap_hook_ = { 0 };
diff -Nru google-perftools-2.1/src/malloc_hook-inl.h google-perftools-2.2.1/src/malloc_hook-inl.h
--- google-perftools-2.1/src/malloc_hook-inl.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/malloc_hook-inl.h 2014-06-21 21:12:00.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -74,14 +75,6 @@
// This is a full-barrier instruction.
PtrT Exchange(PtrT new_val);
- // Atomically executes:
- // result = data_
- // if (data_ == old_val)
- // data_ = new_val;
- // return result;
- // This is a full-barrier instruction.
- PtrT CompareAndSwap(PtrT old_val, PtrT new_val);
-
// Not private so that the class is an aggregate and can be
// initialized by the linker. Don't access this directly.
AtomicWord data_;
diff -Nru google-perftools-2.1/src/malloc_hook_mmap_freebsd.h google-perftools-2.2.1/src/malloc_hook_mmap_freebsd.h
--- google-perftools-2.1/src/malloc_hook_mmap_freebsd.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/malloc_hook_mmap_freebsd.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
@@ -39,6 +40,7 @@
#include
#include
#include
+#include
// Make sure mmap doesn't get #define'd away by
#undef mmap
@@ -73,43 +75,11 @@
}
static inline void* do_sbrk(intptr_t increment) {
- void* curbrk = 0;
+ static void *(*libc_sbrk)(intptr_t);
+ if (libc_sbrk == NULL)
+ libc_sbrk = (void *(*)(intptr_t))dlsym(RTLD_NEXT, "sbrk");
-#if defined(__x86_64__) || defined(__amd64__)
-# ifdef PIC
- __asm__ __volatile__(
- "movq .curbrk@GOTPCREL(%%rip), %%rdx;"
- "movq (%%rdx), %%rax;"
- "movq %%rax, %0;"
- : "=r" (curbrk)
- :: "%rdx", "%rax");
-# else
- __asm__ __volatile__(
- "movq .curbrk(%%rip), %%rax;"
- "movq %%rax, %0;"
- : "=r" (curbrk)
- :: "%rax");
-# endif
-#else
- __asm__ __volatile__(
- "movl .curbrk, %%eax;"
- "movl %%eax, %0;"
- : "=r" (curbrk)
- :: "%eax");
-#endif
-
- if (increment == 0) {
- return curbrk;
- }
-
- char* prevbrk = static_cast(curbrk);
- void* newbrk = prevbrk + increment;
-
- if (brk(newbrk) == -1) {
- return reinterpret_cast(static_cast(-1));
- }
-
- return prevbrk;
+ return libc_sbrk(increment);
}
diff -Nru google-perftools-2.1/src/malloc_hook_mmap_linux.h google-perftools-2.2.1/src/malloc_hook_mmap_linux.h
--- google-perftools-2.1/src/malloc_hook_mmap_linux.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/malloc_hook_mmap_linux.h 2014-03-01 20:24:54.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -51,7 +52,7 @@
// I test for 64-bit first so I don't have to do things like
// '#if (defined(__mips__) && !defined(__MIPS64__))' as a mips32 check.
-#if defined(__x86_64__) || defined(__PPC64__) || (defined(_MIPS_SIM) && _MIPS_SIM == _ABI64)
+#if defined(__x86_64__) || defined(__PPC64__) || defined(__aarch64__) || (defined(_MIPS_SIM) && _MIPS_SIM == _ABI64)
static inline void* do_mmap64(void *start, size_t length,
int prot, int flags,
@@ -201,6 +202,7 @@
return result;
}
+#ifndef __UCLIBC__
// libc's version:
extern "C" void* __sbrk(ptrdiff_t increment);
@@ -211,6 +213,8 @@
return result;
}
+#endif
+
/*static*/void* MallocHook::UnhookedMMap(void *start, size_t length, int prot,
int flags, int fd, off_t offset) {
void* result;
diff -Nru google-perftools-2.1/src/maybe_threads.cc google-perftools-2.2.1/src/maybe_threads.cc
--- google-perftools-2.1/src/maybe_threads.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/maybe_threads.cc 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -71,13 +72,26 @@
static void *perftools_pthread_specific_vals[MAX_PERTHREAD_VALS];
static int next_key;
+// NOTE: it's similar to bitcast defined in basic_types.h with
+// exception of ignoring sizes mismatch
+template
+static T2 memcpy_cast(const T1 &input) {
+ T2 output;
+ size_t s = sizeof(input);
+ if (sizeof(output) < s) {
+ s = sizeof(output);
+ }
+ memcpy(&output, &input, s);
+ return output;
+}
+
int perftools_pthread_key_create(pthread_key_t *key,
void (*destr_function) (void *)) {
if (pthread_key_create) {
return pthread_key_create(key, destr_function);
} else {
assert(next_key < MAX_PERTHREAD_VALS);
- *key = (pthread_key_t)(next_key++);
+ *key = memcpy_cast(next_key++);
return 0;
}
}
@@ -86,7 +100,7 @@
if (pthread_getspecific) {
return pthread_getspecific(key);
} else {
- return perftools_pthread_specific_vals[(int)key];
+ return perftools_pthread_specific_vals[memcpy_cast(key)];
}
}
@@ -94,7 +108,7 @@
if (pthread_setspecific) {
return pthread_setspecific(key, val);
} else {
- perftools_pthread_specific_vals[(int)key] = val;
+ perftools_pthread_specific_vals[memcpy_cast(key)] = val;
return 0;
}
}
diff -Nru google-perftools-2.1/src/maybe_threads.h google-perftools-2.2.1/src/maybe_threads.h
--- google-perftools-2.1/src/maybe_threads.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/maybe_threads.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/memfs_malloc.cc google-perftools-2.2.1/src/memfs_malloc.cc
--- google-perftools-2.1/src/memfs_malloc.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/memfs_malloc.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/memory_region_map.cc google-perftools-2.2.1/src/memory_region_map.cc
--- google-perftools-2.1/src/memory_region_map.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/memory_region_map.cc 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
@@ -84,9 +85,10 @@
// which (sometimes) causes mmap, which calls our hook, and so on.
// We do this as follows: on a recursive call of MemoryRegionMap's
// mmap/sbrk/mremap hook we record the data about the allocation in a
-// static fixed-sized stack (saved_regions), when the recursion unwinds
-// but before returning from the outer hook call we unwind this stack and
-// move the data from saved_regions to its permanent place in the RegionSet,
+// static fixed-sized stack (saved_regions and saved_buckets), when the
+// recursion unwinds but before returning from the outer hook call we unwind
+// this stack and move the data from saved_regions and saved_buckets to its
+// permanent place in the RegionSet and "bucket_table" respectively,
// which can cause more allocations and mmap-s and recursion and unwinding,
// but the whole process ends eventually due to the fact that for the small
// allocations we are doing LowLevelAlloc reuses one mmap call and parcels out
@@ -147,6 +149,13 @@
pthread_t MemoryRegionMap::lock_owner_tid_; // GUARDED_BY(owner_lock_)
int64 MemoryRegionMap::map_size_ = 0;
int64 MemoryRegionMap::unmap_size_ = 0;
+HeapProfileBucket** MemoryRegionMap::bucket_table_ = NULL; // GUARDED_BY(lock_)
+int MemoryRegionMap::num_buckets_ = 0; // GUARDED_BY(lock_)
+int MemoryRegionMap::saved_buckets_count_ = 0; // GUARDED_BY(lock_)
+HeapProfileBucket MemoryRegionMap::saved_buckets_[20]; // GUARDED_BY(lock_)
+
+// GUARDED_BY(lock_)
+const void* MemoryRegionMap::saved_buckets_keys_[20][kMaxStackDepth];
// ========================================================================= //
@@ -182,7 +191,7 @@
// (or rather should we *not* use regions_ to record a hooked mmap).
static bool recursive_insert = false;
-void MemoryRegionMap::Init(int max_stack_depth) {
+void MemoryRegionMap::Init(int max_stack_depth, bool use_buckets) {
RAW_VLOG(10, "MemoryRegionMap Init");
RAW_CHECK(max_stack_depth >= 0, "");
// Make sure we don't overflow the memory in region stacks:
@@ -214,6 +223,15 @@
// Can't instead use HandleSavedRegionsLocked(&DoInsertRegionLocked) before
// recursive_insert = false; as InsertRegionLocked will also construct
// regions_ on demand for us.
+ if (use_buckets) {
+ const int table_bytes = kHashTableSize * sizeof(*bucket_table_);
+ recursive_insert = true;
+ bucket_table_ = static_cast(
+ MyAllocator::Allocate(table_bytes));
+ recursive_insert = false;
+ memset(bucket_table_, 0, table_bytes);
+ num_buckets_ = 0;
+ }
Unlock();
RAW_VLOG(10, "MemoryRegionMap Init done");
}
@@ -228,6 +246,19 @@
RAW_VLOG(10, "MemoryRegionMap Shutdown decrement done");
return true;
}
+ if (bucket_table_ != NULL) {
+ for (int i = 0; i < kHashTableSize; i++) {
+ for (HeapProfileBucket* curr = bucket_table_[i]; curr != 0; /**/) {
+ HeapProfileBucket* bucket = curr;
+ curr = curr->next;
+ MyAllocator::Free(bucket->stack, 0);
+ MyAllocator::Free(bucket, 0);
+ }
+ }
+ MyAllocator::Free(bucket_table_, 0);
+ num_buckets_ = 0;
+ bucket_table_ = NULL;
+ }
RAW_CHECK(MallocHook::RemoveMmapHook(&MmapHook), "");
RAW_CHECK(MallocHook::RemoveMremapHook(&MremapHook), "");
RAW_CHECK(MallocHook::RemoveSbrkHook(&SbrkHook), "");
@@ -245,6 +276,11 @@
return deleted_arena;
}
+bool MemoryRegionMap::IsRecordingLocked() {
+ RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
+ return client_count_ > 0;
+}
+
// Invariants (once libpthread_initialized is true):
// * While lock_ is not held, recursion_count_ is 0 (and
// lock_owner_tid_ is the previous owner, but we don't rely on
@@ -336,6 +372,62 @@
return region != NULL;
}
+HeapProfileBucket* MemoryRegionMap::GetBucket(int depth,
+ const void* const key[]) {
+ RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
+ // Make hash-value
+ uintptr_t hash = 0;
+ for (int i = 0; i < depth; i++) {
+ hash += reinterpret_cast(key[i]);
+ hash += hash << 10;
+ hash ^= hash >> 6;
+ }
+ hash += hash << 3;
+ hash ^= hash >> 11;
+
+ // Lookup stack trace in table
+ unsigned int hash_index = (static_cast(hash)) % kHashTableSize;
+ for (HeapProfileBucket* bucket = bucket_table_[hash_index];
+ bucket != 0;
+ bucket = bucket->next) {
+ if ((bucket->hash == hash) && (bucket->depth == depth) &&
+ std::equal(key, key + depth, bucket->stack)) {
+ return bucket;
+ }
+ }
+
+ // Create new bucket
+ const size_t key_size = sizeof(key[0]) * depth;
+ HeapProfileBucket* bucket;
+ if (recursive_insert) { // recursion: save in saved_buckets_
+ const void** key_copy = saved_buckets_keys_[saved_buckets_count_];
+ std::copy(key, key + depth, key_copy);
+ bucket = &saved_buckets_[saved_buckets_count_];
+ memset(bucket, 0, sizeof(*bucket));
+ ++saved_buckets_count_;
+ bucket->stack = key_copy;
+ bucket->next = NULL;
+ } else {
+ recursive_insert = true;
+ const void** key_copy = static_cast(
+ MyAllocator::Allocate(key_size));
+ recursive_insert = false;
+ std::copy(key, key + depth, key_copy);
+ recursive_insert = true;
+ bucket = static_cast(
+ MyAllocator::Allocate(sizeof(HeapProfileBucket)));
+ recursive_insert = false;
+ memset(bucket, 0, sizeof(*bucket));
+ bucket->stack = key_copy;
+ bucket->next = bucket_table_[hash_index];
+ }
+ bucket->hash = hash;
+ bucket->depth = depth;
+ bucket_table_[hash_index] = bucket;
+ ++num_buckets_;
+ return bucket;
+}
+
MemoryRegionMap::RegionIterator MemoryRegionMap::BeginRegionLocked() {
RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
RAW_CHECK(regions_ != NULL, "");
@@ -404,6 +496,44 @@
}
}
+void MemoryRegionMap::RestoreSavedBucketsLocked() {
+ RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
+ while (saved_buckets_count_ > 0) {
+ HeapProfileBucket bucket = saved_buckets_[--saved_buckets_count_];
+ unsigned int hash_index =
+ static_cast(bucket.hash) % kHashTableSize;
+ bool is_found = false;
+ for (HeapProfileBucket* curr = bucket_table_[hash_index];
+ curr != 0;
+ curr = curr->next) {
+ if ((curr->hash == bucket.hash) && (curr->depth == bucket.depth) &&
+ std::equal(bucket.stack, bucket.stack + bucket.depth, curr->stack)) {
+ curr->allocs += bucket.allocs;
+ curr->alloc_size += bucket.alloc_size;
+ curr->frees += bucket.frees;
+ curr->free_size += bucket.free_size;
+ is_found = true;
+ break;
+ }
+ }
+ if (is_found) continue;
+
+ const size_t key_size = sizeof(bucket.stack[0]) * bucket.depth;
+ const void** key_copy = static_cast(
+ MyAllocator::Allocate(key_size));
+ std::copy(bucket.stack, bucket.stack + bucket.depth, key_copy);
+ HeapProfileBucket* new_bucket = static_cast(
+ MyAllocator::Allocate(sizeof(HeapProfileBucket)));
+ memset(new_bucket, 0, sizeof(*new_bucket));
+ new_bucket->hash = bucket.hash;
+ new_bucket->depth = bucket.depth;
+ new_bucket->stack = key_copy;
+ new_bucket->next = bucket_table_[hash_index];
+ bucket_table_[hash_index] = new_bucket;
+ ++num_buckets_;
+ }
+}
+
inline void MemoryRegionMap::InsertRegionLocked(const Region& region) {
RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
// We can be called recursively, because RegionSet constructor
@@ -452,11 +582,31 @@
Region region;
region.Create(start, size);
// First get the call stack info into the local varible 'region':
- const int depth =
- max_stack_depth_ > 0
- ? MallocHook::GetCallerStackTrace(const_cast(region.call_stack),
- max_stack_depth_, kStripFrames + 1)
- : 0;
+ int depth = 0;
+ // NOTE: libunwind also does mmap and very much likely while holding
+ // it's own lock(s). So some threads may first take libunwind lock,
+ // and then take region map lock (necessary to record mmap done from
+ // inside libunwind). On the other hand other thread(s) may do
+ // normal mmap. Which would call this method to record it. Which
+ // would then proceed with installing that record to region map
+ // while holding region map lock. That may cause mmap from our own
+ // internal allocators, so attempt to unwind in this case may cause
+ // reverse order of taking libuwind and region map locks. Which is
+ // obvious deadlock.
+ //
+ // Thankfully, we can easily detect if we're holding region map lock
+ // and avoid recording backtrace in this (rare and largely
+ // irrelevant) case. By doing this we "declare" that thread needing
+ // both locks must take region map lock last. In other words we do
+ // not allow taking libuwind lock when we already have region map
+ // lock. Note, this is generally impossible when somebody tries to
+ // mix cpu profiling and heap checking/profiling, because cpu
+ // profiler grabs backtraces at arbitrary places. But at least such
+ // combination is rarer and less relevant.
+ if (max_stack_depth_ > 0 && !LockIsHeld()) {
+ depth = MallocHook::GetCallerStackTrace(const_cast(region.call_stack),
+ max_stack_depth_, kStripFrames + 1);
+ }
region.set_call_stack_depth(depth); // record stack info fully
RAW_VLOG(10, "New global region %p..%p from %p",
reinterpret_cast(region.start_addr),
@@ -468,6 +618,16 @@
InsertRegionLocked(region);
// This will (eventually) allocate storage for and copy over the stack data
// from region.call_stack_data_ that is pointed by region.call_stack().
+ if (bucket_table_ != NULL) {
+ HeapProfileBucket* b = GetBucket(depth, region.call_stack);
+ ++b->allocs;
+ b->alloc_size += size;
+ if (!recursive_insert) {
+ recursive_insert = true;
+ RestoreSavedBucketsLocked();
+ recursive_insert = false;
+ }
+ }
Unlock();
}
@@ -486,6 +646,7 @@
Region& r = saved_regions[i];
if (r.start_addr == start_addr && r.end_addr == end_addr) {
// An exact match, so it's safe to remove.
+ RecordRegionRemovalInBucket(r.call_stack_depth, r.call_stack, size);
--saved_regions_count;
--put_pos;
RAW_VLOG(10, ("Insta-Removing saved region %p..%p; "
@@ -530,6 +691,8 @@
RAW_VLOG(12, "Deleting region %p..%p",
reinterpret_cast(region->start_addr),
reinterpret_cast(region->end_addr));
+ RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
+ region->end_addr - region->start_addr);
RegionSet::iterator d = region;
++region;
regions_->erase(d);
@@ -539,6 +702,8 @@
RAW_VLOG(12, "Splitting region %p..%p in two",
reinterpret_cast(region->start_addr),
reinterpret_cast(region->end_addr));
+ RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
+ end_addr - start_addr);
// Make another region for the start portion:
// The new region has to be the start portion because we can't
// just modify region->end_addr as it's the sorting key.
@@ -552,12 +717,16 @@
RAW_VLOG(12, "Start-chopping region %p..%p",
reinterpret_cast(region->start_addr),
reinterpret_cast(region->end_addr));
+ RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
+ end_addr - region->start_addr);
const_cast(*region).set_start_addr(end_addr);
} else if (start_addr > region->start_addr &&
start_addr < region->end_addr) { // cut from end
RAW_VLOG(12, "End-chopping region %p..%p",
reinterpret_cast(region->start_addr),
reinterpret_cast(region->end_addr));
+ RecordRegionRemovalInBucket(region->call_stack_depth, region->call_stack,
+ region->end_addr - start_addr);
// Can't just modify region->end_addr (it's the sorting key):
Region r = *region;
r.set_end_addr(start_addr);
@@ -580,6 +749,16 @@
Unlock();
}
+void MemoryRegionMap::RecordRegionRemovalInBucket(int depth,
+ const void* const stack[],
+ size_t size) {
+ RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
+ if (bucket_table_ == NULL) return;
+ HeapProfileBucket* b = GetBucket(depth, stack);
+ ++b->frees;
+ b->free_size += size;
+}
+
void MemoryRegionMap::MmapHook(const void* result,
const void* start, size_t size,
int prot, int flags,
@@ -618,8 +797,6 @@
}
}
-extern "C" void* __sbrk(ptrdiff_t increment); // defined in libc
-
void MemoryRegionMap::SbrkHook(const void* result, ptrdiff_t increment) {
RAW_VLOG(10, "Sbrk = 0x%" PRIxPTR " of %" PRIdS "", (uintptr_t)result, increment);
if (result != reinterpret_cast(-1)) {
diff -Nru google-perftools-2.1/src/memory_region_map.h google-perftools-2.2.1/src/memory_region_map.h
--- google-perftools-2.1/src/memory_region_map.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/memory_region_map.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
@@ -45,6 +46,7 @@
#include "base/spinlock.h"
#include "base/thread_annotations.h"
#include "base/low_level_alloc.h"
+#include "heap-profile-stats.h"
// TODO(maxim): add a unittest:
// execute a bunch of mmaps and compare memory map what strace logs
@@ -72,6 +74,10 @@
// don't take the address of it!
static const int kMaxStackDepth = 32;
+ // Size of the hash table of buckets. A structure of the bucket table is
+ // described in heap-profile-stats.h.
+ static const int kHashTableSize = 179999;
+
public:
// interface ================================================================
@@ -87,11 +93,14 @@
// are automatically shrunk to "max_stack_depth" when they are recorded.
// Init() can be called more than once w/o harm, largest max_stack_depth
// will be the effective one.
+ // When "use_buckets" is true, then counts of mmap and munmap sizes will be
+ // recorded with each stack trace. If Init() is called more than once, then
+ // counting will be effective after any call contained "use_buckets" of true.
// It will install mmap, munmap, mremap, sbrk hooks
// and initialize arena_ and our hook and locks, hence one can use
// MemoryRegionMap::Lock()/Unlock() to manage the locks.
// Uses Lock/Unlock inside.
- static void Init(int max_stack_depth);
+ static void Init(int max_stack_depth, bool use_buckets);
// Try to shutdown this module undoing what Init() did.
// Returns true iff could do full shutdown (or it was not attempted).
@@ -99,6 +108,10 @@
// the number of Init() calls.
static bool Shutdown();
+ // Return true if MemoryRegionMap is initialized and recording, i.e. when
+ // then number of Init() calls are more than the number of Shutdown() calls.
+ static bool IsRecordingLocked();
+
// Locks to protect our internal data structures.
// These also protect use of arena_ if our Init() has been done.
// The lock is recursive.
@@ -214,6 +227,18 @@
// Returns success. Uses Lock/Unlock inside.
static bool FindAndMarkStackRegion(uintptr_t stack_top, Region* result);
+ // Iterate over the buckets which store mmap and munmap counts per stack
+ // trace. It calls "callback" for each bucket, and passes "arg" to it.
+ template
+ static void IterateBuckets(void (*callback)(const HeapProfileBucket*, Type),
+ Type arg);
+
+ // Get the bucket whose caller stack trace is "key". The stack trace is
+ // used to a depth of "depth" at most. The requested bucket is created if
+ // needed.
+ // The bucket table is described in heap-profile-stats.h.
+ static HeapProfileBucket* GetBucket(int depth, const void* const key[]);
+
private: // our internal types ==============================================
// Region comparator for sorting with STL
@@ -276,11 +301,11 @@
// To be accessed *only* when Lock() is held.
// Hence we protect the non-recursive lock used inside of arena_
// with our recursive Lock(). This lets a user prevent deadlocks
- // when threads are stopped by ListAllProcessThreads at random spots
+ // when threads are stopped by TCMalloc_ListAllProcessThreads at random spots
// simply by acquiring our recursive Lock() before that.
static RegionSet* regions_;
- // Lock to protect regions_ variable and the data behind.
+ // Lock to protect regions_ and buckets_ variables and the data behind.
static SpinLock lock_;
// Lock to protect the recursive lock itself.
static SpinLock owner_lock_;
@@ -295,6 +320,30 @@
// Total size of all unmapped pages so far
static int64 unmap_size_;
+ // Bucket hash table which is described in heap-profile-stats.h.
+ static HeapProfileBucket** bucket_table_ GUARDED_BY(lock_);
+ static int num_buckets_ GUARDED_BY(lock_);
+
+ // The following members are local to MemoryRegionMap::GetBucket()
+ // and MemoryRegionMap::HandleSavedBucketsLocked()
+ // and are file-level to ensure that they are initialized at load time.
+ //
+ // These are used as temporary storage to break the infinite cycle of mmap
+ // calling our hook which (sometimes) causes mmap. It must be a static
+ // fixed-size array. The size 20 is just an expected value for safety.
+ // The details are described in memory_region_map.cc.
+
+ // Number of unprocessed bucket inserts.
+ static int saved_buckets_count_ GUARDED_BY(lock_);
+
+ // Unprocessed inserts (must be big enough to hold all mmaps that can be
+ // caused by a GetBucket call).
+ // Bucket has no constructor, so that c-tor execution does not interfere
+ // with the any-time use of the static memory behind saved_buckets.
+ static HeapProfileBucket saved_buckets_[20] GUARDED_BY(lock_);
+
+ static const void* saved_buckets_keys_[20][kMaxStackDepth] GUARDED_BY(lock_);
+
// helpers ==================================================================
// Helper for FindRegion and FindAndMarkStackRegion:
@@ -308,6 +357,11 @@
// by calling insert_func on them.
inline static void HandleSavedRegionsLocked(
void (*insert_func)(const Region& region));
+
+ // Restore buckets saved in a tmp static array by GetBucket to the bucket
+ // table where all buckets eventually should be.
+ static void RestoreSavedBucketsLocked();
+
// Wrapper around DoInsertRegionLocked
// that handles the case of recursive allocator calls.
inline static void InsertRegionLocked(const Region& region);
@@ -319,6 +373,13 @@
// (called from our munmap/mremap/sbrk hooks).
static void RecordRegionRemoval(const void* start, size_t size);
+ // Record deletion of a memory region of size "size" in a bucket whose
+ // caller stack trace is "key". The stack trace is used to a depth of
+ // "depth" at most.
+ static void RecordRegionRemovalInBucket(int depth,
+ const void* const key[],
+ size_t size);
+
// Hooks for MallocHook
static void MmapHook(const void* result,
const void* start, size_t size,
@@ -337,4 +398,16 @@
DISALLOW_COPY_AND_ASSIGN(MemoryRegionMap);
};
+template
+void MemoryRegionMap::IterateBuckets(
+ void (*callback)(const HeapProfileBucket*, Type), Type callback_arg) {
+ for (int index = 0; index < kHashTableSize; index++) {
+ for (HeapProfileBucket* bucket = bucket_table_[index];
+ bucket != NULL;
+ bucket = bucket->next) {
+ callback(bucket, callback_arg);
+ }
+ }
+}
+
#endif // BASE_MEMORY_REGION_MAP_H_
diff -Nru google-perftools-2.1/src/packed-cache-inl.h google-perftools-2.2.1/src/packed-cache-inl.h
--- google-perftools-2.1/src/packed-cache-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/packed-cache-inl.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/page_heap_allocator.h google-perftools-2.2.1/src/page_heap_allocator.h
--- google-perftools-2.1/src/page_heap_allocator.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/page_heap_allocator.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/page_heap.cc google-perftools-2.2.1/src/page_heap.cc
--- google-perftools-2.1/src/page_heap.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/page_heap.cc 2014-06-22 00:34:32.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -65,7 +66,8 @@
pagemap_cache_(0),
scavenge_counter_(0),
// Start scavenging at kMaxPages list
- release_index_(kMaxPages) {
+ release_index_(kMaxPages),
+ aggressive_decommit_(false) {
COMPILE_ASSERT(kNumClasses <= (1 << PageMapCache::kValuebits), valuebits);
DLL_Init(&large_.normal);
DLL_Init(&large_.returned);
@@ -152,6 +154,7 @@
// Grow the heap and try again.
if (!GrowHeap(n)) {
+ ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
ASSERT(Check());
return NULL;
}
@@ -234,6 +237,22 @@
return leftover;
}
+void PageHeap::CommitSpan(Span* span) {
+ TCMalloc_SystemCommit(reinterpret_cast(span->start << kPageShift),
+ static_cast(span->length << kPageShift));
+ stats_.committed_bytes += span->length << kPageShift;
+}
+
+bool PageHeap::DecommitSpan(Span* span) {
+ bool rv = TCMalloc_SystemRelease(reinterpret_cast(span->start << kPageShift),
+ static_cast(span->length << kPageShift));
+ if (rv) {
+ stats_.committed_bytes -= span->length << kPageShift;
+ }
+
+ return rv;
+}
+
Span* PageHeap::Carve(Span* span, Length n) {
ASSERT(n > 0);
ASSERT(span->location != Span::IN_USE);
@@ -249,11 +268,31 @@
leftover->location = old_location;
Event(leftover, 'S', extra);
RecordSpan(leftover);
+
+ // The previous span of |leftover| was just splitted -- no need to
+ // coalesce them. The next span of |leftover| was not previously coalesced
+ // with |span|, i.e. is NULL or has got location other than |old_location|.
+#ifndef NDEBUG
+ const PageID p = leftover->start;
+ const Length len = leftover->length;
+ Span* next = GetDescriptor(p+len);
+ ASSERT (next == NULL ||
+ next->location == Span::IN_USE ||
+ next->location != leftover->location);
+#endif
+
PrependToFreeList(leftover); // Skip coalescing - no candidates possible
span->length = n;
pagemap_.set(span->start + n - 1, span);
}
ASSERT(Check());
+ if (old_location == Span::ON_RETURNED_FREELIST) {
+ // We need to recommit this address space.
+ CommitSpan(span);
+ }
+ ASSERT(span->location == Span::IN_USE);
+ ASSERT(span->length == n);
+ ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
return span;
}
@@ -270,9 +309,17 @@
Event(span, 'D', span->length);
MergeIntoFreeList(span); // Coalesces if possible
IncrementalScavenge(n);
+ ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
ASSERT(Check());
}
+bool PageHeap::MayMergeSpans(Span *span, Span *other) {
+ if (aggressive_decommit_) {
+ return other->location != Span::IN_USE;
+ }
+ return span->location == other->location;
+}
+
void PageHeap::MergeIntoFreeList(Span* span) {
ASSERT(span->location != Span::IN_USE);
@@ -281,15 +328,44 @@
// entries for the pieces we are merging together because we only
// care about the pagemap entries for the boundaries.
//
- // Note that only similar spans are merged together. For example,
- // we do not coalesce "returned" spans with "normal" spans.
+ // Note: depending on aggressive_decommit_ mode we allow only
+ // similar spans to be coalesced.
+ //
+ // The following applies if aggressive_decommit_ is enabled:
+ //
+ // Note that the adjacent spans we merge into "span" may come out of a
+ // "normal" (committed) list, and cleanly merge with our IN_USE span, which
+ // is implicitly committed. If the adjacents spans are on the "returned"
+ // (decommitted) list, then we must get both spans into the same state before
+ // or after we coalesce them. The current code always decomits. This is
+ // achieved by blindly decommitting the entire coalesced region, which may
+ // include any combination of committed and decommitted spans, at the end of
+ // the method.
+
+ // TODO(jar): "Always decommit" causes some extra calls to commit when we are
+ // called in GrowHeap() during an allocation :-/. We need to eval the cost of
+ // that oscillation, and possibly do something to reduce it.
+
+ // TODO(jar): We need a better strategy for deciding to commit, or decommit,
+ // based on memory usage and free heap sizes.
+
+ uint64_t temp_committed = 0;
+
const PageID p = span->start;
const Length n = span->length;
Span* prev = GetDescriptor(p-1);
- if (prev != NULL && prev->location == span->location) {
+ if (prev != NULL && MayMergeSpans(span, prev)) {
// Merge preceding span into this span
ASSERT(prev->start + prev->length == p);
const Length len = prev->length;
+ if (aggressive_decommit_ && prev->location == Span::ON_RETURNED_FREELIST) {
+ // We're about to put the merge span into the returned freelist and call
+ // DecommitSpan() on it, which will mark the entire span including this
+ // one as released and decrease stats_.committed_bytes by the size of the
+ // merged span. To make the math work out we temporarily increase the
+ // stats_.committed_bytes amount.
+ temp_committed = prev->length << kPageShift;
+ }
RemoveFromFreeList(prev);
DeleteSpan(prev);
span->start -= len;
@@ -298,10 +374,14 @@
Event(span, 'L', len);
}
Span* next = GetDescriptor(p+n);
- if (next != NULL && next->location == span->location) {
+ if (next != NULL && MayMergeSpans(span, next)) {
// Merge next span into this span
ASSERT(next->start == p+n);
const Length len = next->length;
+ if (aggressive_decommit_ && next->location == Span::ON_RETURNED_FREELIST) {
+ // See the comment below 'if (prev->location ...' for explanation.
+ temp_committed += next->length << kPageShift;
+ }
RemoveFromFreeList(next);
DeleteSpan(next);
span->length += len;
@@ -309,6 +389,14 @@
Event(span, 'R', len);
}
+ if (aggressive_decommit_) {
+ if (DecommitSpan(span)) {
+ span->location = Span::ON_RETURNED_FREELIST;
+ stats_.committed_bytes += temp_committed;
+ } else {
+ ASSERT(temp_committed == 0);
+ }
+ }
PrependToFreeList(span);
}
@@ -369,8 +457,7 @@
Span* s = slist->normal.prev;
ASSERT(s->location == Span::ON_NORMAL_FREELIST);
- if (TCMalloc_SystemRelease(reinterpret_cast(s->start << kPageShift),
- static_cast(s->length << kPageShift))) {
+ if (DecommitSpan(s)) {
RemoveFromFreeList(s);
const Length n = s->length;
s->location = Span::ON_RETURNED_FREELIST;
@@ -524,6 +611,7 @@
uint64_t old_system_bytes = stats_.system_bytes;
stats_.system_bytes += (ask << kPageShift);
+ stats_.committed_bytes += (ask << kPageShift);
const PageID p = reinterpret_cast(ptr) >> kPageShift;
ASSERT(p > 0);
@@ -545,6 +633,7 @@
Span* span = NewSpan(p, ask);
RecordSpan(span);
Delete(span);
+ ASSERT(stats_.unmapped_bytes+ stats_.committed_bytes==stats_.system_bytes);
ASSERT(Check());
return true;
} else {
diff -Nru google-perftools-2.1/src/page_heap.h google-perftools-2.2.1/src/page_heap.h
--- google-perftools-2.1/src/page_heap.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/page_heap.h 2014-06-22 00:34:32.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -142,10 +143,12 @@
// Page heap statistics
struct Stats {
- Stats() : system_bytes(0), free_bytes(0), unmapped_bytes(0) {}
+ Stats() : system_bytes(0), free_bytes(0), unmapped_bytes(0), committed_bytes(0) {}
uint64_t system_bytes; // Total bytes allocated from system
uint64_t free_bytes; // Total bytes on normal freelists
uint64_t unmapped_bytes; // Total bytes on returned freelists
+ uint64_t committed_bytes; // Bytes committed, always <= system_bytes_.
+
};
inline Stats stats() const { return stats_; }
@@ -189,6 +192,11 @@
}
void CacheSizeClass(PageID p, size_t cl) const { pagemap_cache_.Put(p, cl); }
+ bool GetAggressiveDecommit(void) {return aggressive_decommit_;}
+ void SetAggressiveDecommit(bool aggressive_decommit) {
+ aggressive_decommit_ = aggressive_decommit;
+ }
+
private:
// Allocates a big block of memory for the pagemap once we reach more than
// 128MB
@@ -263,6 +271,12 @@
// appropriate free list, and adjust stats.
void MergeIntoFreeList(Span* span);
+ // Commit the span.
+ void CommitSpan(Span* span);
+
+ // Decommit the span.
+ bool DecommitSpan(Span* span);
+
// Prepends span to appropriate free list, and adjusts stats.
void PrependToFreeList(Span* span);
@@ -282,11 +296,15 @@
// some unused spans.
bool EnsureLimit(Length n, bool allowRelease = true);
+ bool MayMergeSpans(Span *span, Span *other);
+
// Number of pages to deallocate before doing more scavenging
int64_t scavenge_counter_;
// Index of last free list where we released memory to the OS.
int release_index_;
+
+ bool aggressive_decommit_;
};
} // namespace tcmalloc
diff -Nru google-perftools-2.1/src/pagemap.h google-perftools-2.2.1/src/pagemap.h
--- google-perftools-2.1/src/pagemap.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/pagemap.h 2013-12-06 21:16:47.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -151,9 +152,9 @@
}
void set(Number k, void* v) {
- ASSERT(k >> BITS == 0);
const Number i1 = k >> LEAF_BITS;
const Number i2 = k & (LEAF_LENGTH-1);
+ ASSERT(i1 < ROOT_LENGTH);
root_[i1]->values[i2] = v;
}
diff -Nru google-perftools-2.1/src/pprof google-perftools-2.2.1/src/pprof
--- google-perftools-2.1/src/pprof 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/pprof 2014-04-13 03:35:40.000000000 +0200
@@ -71,6 +71,7 @@
use strict;
use warnings;
use Getopt::Long;
+use Cwd;
my $PPROF_VERSION = "2.0";
@@ -1078,10 +1079,15 @@
# Print profile data in packed binary format (64-bit) to standard out
sub PrintProfileData {
my $profile = shift;
-
+ my $big_endian = pack("L", 1) eq pack("N", 1);
# print header (64-bit style)
# (zero) (header-size) (version) (sample-period) (zero)
- print pack('L*', 0, 0, 3, 0, 0, 0, 1, 0, 0, 0);
+ if ($big_endian) {
+ print pack('L*', 0, 0, 0, 3, 0, 0, 0, 1, 0, 0);
+ }
+ else {
+ print pack('L*', 0, 0, 3, 0, 0, 0, 1, 0, 0, 0);
+ }
foreach my $k (keys(%{$profile})) {
my $count = $profile->{$k};
@@ -1090,8 +1096,14 @@
my $depth = $#addrs + 1;
# int(foo / 2**32) is the only reliable way to get rid of bottom
# 32 bits on both 32- and 64-bit systems.
- print pack('L*', $count & 0xFFFFFFFF, int($count / 2**32));
- print pack('L*', $depth & 0xFFFFFFFF, int($depth / 2**32));
+ if ($big_endian) {
+ print pack('L*', int($count / 2**32), $count & 0xFFFFFFFF);
+ print pack('L*', int($depth / 2**32), $depth & 0xFFFFFFFF);
+ }
+ else {
+ print pack('L*', $count & 0xFFFFFFFF, int($count / 2**32));
+ print pack('L*', $depth & 0xFFFFFFFF, int($depth / 2**32));
+ }
foreach my $full_addr (@addrs) {
my $addr = $full_addr;
@@ -1102,7 +1114,12 @@
}
my $low_addr = substr($addr, -8); # get last 8 hex chars
my $high_addr = substr($addr, -16, 8); # get up to 8 more hex chars
- print pack('L*', hex('0x' . $low_addr), hex('0x' . $high_addr));
+ if ($big_endian) {
+ print pack('L*', hex('0x' . $high_addr), hex('0x' . $low_addr));
+ }
+ else {
+ print pack('L*', hex('0x' . $low_addr), hex('0x' . $high_addr));
+ }
}
}
}
@@ -4326,7 +4343,7 @@
# Split /proc/pid/maps dump into a list of libraries
sub ParseLibraries {
return if $main::use_symbol_page; # We don't need libraries info.
- my $prog = shift;
+ my $prog = Cwd::abs_path(shift);
my $map = shift;
my $pcs = shift;
@@ -4359,6 +4376,16 @@
$finish = HexExtend($2);
$offset = $zero_offset;
$lib = $3;
+ } elsif (($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+)$/i) && ($4 eq $prog)) {
+ # PIEs and address space randomization do not play well with our
+ # default assumption that main executable is at lowest
+ # addresses. So we're detecting main executable in
+ # /proc/self/maps as well.
+ $start = HexExtend($1);
+ $finish = HexExtend($2);
+ $offset = HexExtend($3);
+ $lib = $4;
+ $lib =~ s|\\|/|g; # turn windows-style paths into unix-style paths
} else {
next;
}
@@ -4976,6 +5003,7 @@
sub GetProcedureBoundariesViaNm {
my $escaped_nm_command = shift; # shell-escaped
my $regexp = shift;
+ my $image = shift;
my $symbol_table = {};
open(NM, "$escaped_nm_command |") || error("$escaped_nm_command: $!\n");
@@ -5045,6 +5073,37 @@
$symbol_table->{$routine} = [HexExtend($last_start),
HexExtend($last_start)];
}
+
+ # Verify if addr2line can find the $sep_symbol. If not, we use objdump
+ # to find the address for the $sep_symbol on code section which addr2line
+ # can find.
+ if (defined($sep_address)){
+ my $start_val = $sep_address;
+ my $addr2line = $obj_tool_map{"addr2line"};
+ my $cmd = ShellEscape($addr2line, "-f", "-C", "-e", $image, "-i");
+ open(FINI, "echo $start_val | $cmd |")
+ || error("echo $start_val | $cmd: $!\n");
+ $_ = ;
+ s/\r?\n$//g;
+ my $fini = $_;
+ close(FINI);
+ if ($fini ne $sep_symbol){
+ my $objdump = $obj_tool_map{"objdump"};
+ $cmd = ShellEscape($objdump, "-d", $image);
+ my $grep = ShellEscape("grep", $sep_symbol);
+ my $tail = ShellEscape("tail", "-n", "1");
+ open(FINI, "$cmd | $grep | $tail |")
+ || error("$cmd | $grep | $tail: $!\n");
+ s/\r//g; # turn windows-looking lines into unix-looking lines
+ my $data = ;
+ if (defined($data)){
+ ($start_val, $fini) = split(/ ,$data);
+ }
+ close(FINI);
+ }
+ $sep_address = HexExtend($start_val);
+ }
+
return $symbol_table;
}
@@ -5124,7 +5183,7 @@
}
foreach my $nm_command (@nm_commands) {
- my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp);
+ my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp, $image);
return $symbol_table if (%{$symbol_table});
}
my $symbol_table = {};
diff -Nru google-perftools-2.1/src/profiledata.cc google-perftools-2.2.1/src/profiledata.cc
--- google-perftools-2.1/src/profiledata.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/profiledata.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/profiledata.h google-perftools-2.2.1/src/profiledata.h
--- google-perftools-2.1/src/profiledata.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/profiledata.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/profile-handler.cc google-perftools-2.2.1/src/profile-handler.cc
--- google-perftools-2.1/src/profile-handler.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/profile-handler.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2009, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/profile-handler.h google-perftools-2.2.1/src/profile-handler.h
--- google-perftools-2.1/src/profile-handler.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/profile-handler.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/profiler.cc google-perftools-2.2.1/src/profiler.cc
--- google-perftools-2.1/src/profiler.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/profiler.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -205,9 +206,9 @@
if (signal_number_str != NULL) {
long int signal_number = strtol(signal_number_str, NULL, 10);
if (signal_number >= 1 && signal_number <= 64) {
- void *old_signal_handler = reinterpret_cast(signal(signal_number, CpuProfilerSwitch));
- if (old_signal_handler == NULL) {
- RAW_LOG(INFO,"Using signal %d as cpu profiling switch", signal_number);
+ intptr_t old_signal_handler = reinterpret_cast(signal(signal_number, CpuProfilerSwitch));
+ if (old_signal_handler == 0) {
+ RAW_LOG(INFO,"Using signal %d as cpu profiling switch", signal_number);
} else {
RAW_LOG(FATAL, "Signal %d already in use\n", signal_number);
}
diff -Nru google-perftools-2.1/src/raw_printer.cc google-perftools-2.2.1/src/raw_printer.cc
--- google-perftools-2.1/src/raw_printer.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/raw_printer.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/raw_printer.h google-perftools-2.2.1/src/raw_printer.h
--- google-perftools-2.1/src/raw_printer.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/raw_printer.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/sampler.cc google-perftools-2.2.1/src/sampler.cc
--- google-perftools-2.1/src/sampler.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/sampler.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/sampler.h google-perftools-2.2.1/src/sampler.h
--- google-perftools-2.1/src/sampler.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/sampler.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/span.cc google-perftools-2.2.1/src/span.cc
--- google-perftools-2.1/src/span.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/span.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/span.h google-perftools-2.2.1/src/span.h
--- google-perftools-2.1/src/span.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/span.h 2014-06-22 00:34:32.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/stacktrace_arm-inl.h google-perftools-2.2.1/src/stacktrace_arm-inl.h
--- google-perftools-2.1/src/stacktrace_arm-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace_arm-inl.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
@@ -101,7 +102,7 @@
// int max_depth: the size of the result (and sizes) array(s)
// int skip_count: how many stack pointers to skip before storing in result
// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-int GET_STACK_TRACE_OR_FRAMES {
+static int GET_STACK_TRACE_OR_FRAMES {
#ifdef __GNUC__
void **sp = reinterpret_cast(__builtin_frame_address(0));
#else
@@ -115,6 +116,8 @@
// stored in the stack frame. This works at least for gcc.
StacktraceArmDummyFunction();
+ skip_count++; // skip parent frame due to indirection in stacktrace.cc
+
int n = 0;
while (sp && n < max_depth) {
// The GetStackFrames routine is called when we are in some
diff -Nru google-perftools-2.1/src/stacktrace.cc google-perftools-2.2.1/src/stacktrace.cc
--- google-perftools-2.1/src/stacktrace.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace.cc 2014-04-13 03:35:40.000000000 +0200
@@ -1,10 +1,11 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// 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
@@ -14,7 +15,7 @@
// * Neither the name of Google Inc. 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
@@ -53,49 +54,149 @@
// Some code may do that.
#include
-#include
-#include "stacktrace_config.h"
+#include // for getenv
+#include // for strcmp
+#include // for fprintf
+#include "gperftools/stacktrace.h"
+#include "base/commandlineflags.h"
+#include "base/googleinit.h"
+
+
+// we're using plain struct and not class to avoid any possible issues
+// during initialization. Struct of pointers is easy to init at
+// link-time.
+struct GetStackImplementation {
+ int (*GetStackFramesPtr)(void** result, int* sizes, int max_depth,
+ int skip_count);
+
+ int (*GetStackFramesWithContextPtr)(void** result, int* sizes, int max_depth,
+ int skip_count, const void *uc);
+
+ int (*GetStackTracePtr)(void** result, int max_depth,
+ int skip_count);
+
+ int (*GetStackTraceWithContextPtr)(void** result, int max_depth,
+ int skip_count, const void *uc);
+
+ const char *name;
+};
+
+#if HAVE_DECL_BACKTRACE
+#define STACKTRACE_INL_HEADER "stacktrace_generic-inl.h"
+#define GST_SUFFIX generic
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_generic
+#endif
+
+#if HAVE_LIBUNWIND_H
+#define STACKTRACE_INL_HEADER "stacktrace_libunwind-inl.h"
+#define GST_SUFFIX libunwind
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_libunwind
+#endif // HAVE_LIBUNWIND_H
+
+#if defined(__i386__) || defined(__x86_64__)
+#define STACKTRACE_INL_HEADER "stacktrace_x86-inl.h"
+#define GST_SUFFIX x86
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_x86
+#endif // i386 || x86_64
+
+#if defined(__ppc__) || defined(__PPC__)
+#if defined(__linux__)
+#define STACKTRACE_INL_HEADER "stacktrace_powerpc-linux-inl.h"
+#else
+#define STACKTRACE_INL_HEADER "stacktrace_powerpc-darwin-inl.h"
+#endif
+#define GST_SUFFIX ppc
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_ppc
+#endif
+
+#if defined(__arm__)
+#define STACKTRACE_INL_HEADER "stacktrace_arm-inl.h"
+#define GST_SUFFIX arm
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_arm
+#endif
+
+#ifdef TCMALLOC_ENABLE_INSTRUMENT_STACKTRACE
+#define STACKTRACE_INL_HEADER "stacktrace_instrument-inl.h"
+#define GST_SUFFIX instrument
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_instrument
+#endif
+
+// The Windows case -- probably cygwin and mingw will use one of the
+// x86-includes above, but if not, we can fall back to windows intrinsics.
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
+#define STACKTRACE_INL_HEADER "stacktrace_win32-inl.h"
+#define GST_SUFFIX win32
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_win32
+#endif
-#if defined(STACKTRACE_INL_HEADER)
+static GetStackImplementation *all_impls[] = {
+#ifdef HAVE_GST_generic
+ &impl__generic,
+#endif
+#ifdef HAVE_GST_libunwind
+ &impl__libunwind,
+#endif
+#ifdef HAVE_GST_x86
+ &impl__x86,
+#endif
+#ifdef HAVE_GST_arm
+ &impl__arm,
+#endif
+#ifdef HAVE_GST_ppc
+ &impl__ppc,
+#endif
+#ifdef HAVE_GST_instrument
+ &impl__instrument,
+#endif
+#ifdef HAVE_GST_win32
+ &impl__win32,
+#endif
+ NULL
+};
-#define IS_STACK_FRAMES 0
-#define IS_WITH_CONTEXT 0
-#define GET_STACK_TRACE_OR_FRAMES \
- GetStackTrace(void **result, int max_depth, int skip_count)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 1
-#define IS_WITH_CONTEXT 0
-#define GET_STACK_TRACE_OR_FRAMES \
- GetStackFrames(void **result, int *sizes, int max_depth, int skip_count)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 0
-#define IS_WITH_CONTEXT 1
-#define GET_STACK_TRACE_OR_FRAMES \
- GetStackTraceWithContext(void **result, int max_depth, \
- int skip_count, const void *ucp)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
-
-#define IS_STACK_FRAMES 1
-#define IS_WITH_CONTEXT 1
-#define GET_STACK_TRACE_OR_FRAMES \
- GetStackFramesWithContext(void **result, int *sizes, int max_depth, \
- int skip_count, const void *ucp)
-#include STACKTRACE_INL_HEADER
-#undef IS_STACK_FRAMES
-#undef IS_WITH_CONTEXT
-#undef GET_STACK_TRACE_OR_FRAMES
+// ppc and i386 implementations prefer arch-specific asm implementations.
+// arm's asm implementation is broken
+#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__PPC__)
+#if !defined(NO_FRAME_POINTER)
+#define TCMALLOC_DONT_PREFER_LIBUNWIND
+#endif
+#endif
+#if defined(HAVE_GST_instrument)
+static GetStackImplementation *get_stack_impl = &impl__instrument;
+#elif defined(HAVE_GST_win32)
+static GetStackImplementation *get_stack_impl = &impl__win32;
+#elif defined(HAVE_GST_x86) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND)
+static GetStackImplementation *get_stack_impl = &impl__x86;
+#elif defined(HAVE_GST_ppc) && defined(TCMALLOC_DONT_PREFER_LIBUNWIND)
+static GetStackImplementation *get_stack_impl = &impl__ppc;
+#elif defined(HAVE_GST_libunwind)
+static GetStackImplementation *get_stack_impl = &impl__libunwind;
+#elif defined(HAVE_GST_arm)
+static GetStackImplementation *get_stack_impl = &impl__arm;
+#elif defined(HAVE_GST_generic)
+static GetStackImplementation *get_stack_impl = &impl__generic;
#elif 0
// This is for the benefit of code analysis tools that may have
// trouble with the computed #include above.
@@ -105,6 +206,63 @@
# include "stacktrace_powerpc-inl.h"
# include "stacktrace_win32-inl.h"
# include "stacktrace_arm-inl.h"
+# include "stacktrace_instrument-inl.h"
#else
-# error Cannot calculate stack trace: will need to write for your environment
+#error Cannot calculate stack trace: will need to write for your environment
#endif
+
+static int ATTRIBUTE_NOINLINE frame_forcer(int rv) {
+ return rv;
+}
+
+PERFTOOLS_DLL_DECL int GetStackFrames(void** result, int* sizes, int max_depth,
+ int skip_count) {
+ return frame_forcer(get_stack_impl->GetStackFramesPtr(result, sizes, max_depth, skip_count));
+}
+
+PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** result, int* sizes, int max_depth,
+ int skip_count, const void *uc) {
+ return frame_forcer(get_stack_impl->GetStackFramesWithContextPtr(
+ result, sizes, max_depth,
+ skip_count, uc));
+}
+
+PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
+ int skip_count) {
+ return frame_forcer(get_stack_impl->GetStackTracePtr(result, max_depth, skip_count));
+}
+
+PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,
+ int skip_count, const void *uc) {
+ return frame_forcer(get_stack_impl->GetStackTraceWithContextPtr(
+ result, max_depth, skip_count, uc));
+}
+
+static void init_default_stack_impl_inner(void) {
+ char *val = getenv("TCMALLOC_STACKTRACE_METHOD");
+ if (!val || !*val) {
+ return;
+ }
+ for (GetStackImplementation **p = all_impls; *p; p++) {
+ GetStackImplementation *c = *p;
+ if (strcmp(c->name, val) == 0) {
+ get_stack_impl = c;
+ return;
+ }
+ }
+ fprintf(stderr, "Unknown or unsupported stacktrace method requested: %s. Ignoring it\n", val);
+}
+
+static void init_default_stack_impl(void) {
+ init_default_stack_impl_inner();
+ if (EnvToBool("TCMALLOC_STACKTRACE_METHOD_VERBOSE", false)) {
+ fprintf(stderr, "Chosen stacktrace method is %s\nSupported methods:\n", get_stack_impl->name);
+ for (GetStackImplementation **p = all_impls; *p; p++) {
+ GetStackImplementation *c = *p;
+ fprintf(stderr, "* %s\n", c->name);
+ }
+ fputs("\n", stderr);
+ }
+}
+
+REGISTER_MODULE_INITIALIZER(stacktrace_init_default_stack_impl, init_default_stack_impl());
diff -Nru google-perftools-2.1/src/stacktrace_config.h google-perftools-2.2.1/src/stacktrace_config.h
--- google-perftools-2.1/src/stacktrace_config.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace_config.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,85 +0,0 @@
-// Copyright (c) 2009, Google Inc.
-// 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 Google Inc. 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.
-
-// ---
-// Author: Paul Pluzhnikov
-//
-// Figure out which unwinder to use on a given platform.
-//
-// Defines STACKTRACE_INL_HEADER to the *-inl.h containing
-// actual unwinder implementation.
-//
-// Defines STACKTRACE_SKIP_CONTEXT_ROUTINES if a separate
-// GetStack{Trace,Frames}WithContext should not be provided.
-//
-// This header is "private" to stacktrace.cc and
-// stacktrace_with_context.cc.
-//
-// DO NOT include it into any other files.
-
-#ifndef BASE_STACKTRACE_CONFIG_H_
-#define BASE_STACKTRACE_CONFIG_H_
-
-// First, the i386 and x86_64 case.
-#if (defined(__i386__) || defined(__x86_64__)) && __GNUC__ >= 2
-# if !defined(NO_FRAME_POINTER)
-# define STACKTRACE_INL_HEADER "stacktrace_x86-inl.h"
-# define STACKTRACE_SKIP_CONTEXT_ROUTINES 1
-# elif defined(HAVE_LIBUNWIND_H) // a proxy for having libunwind installed
-# define STACKTRACE_INL_HEADER "stacktrace_libunwind-inl.h"
-# define STACKTRACE_USES_LIBUNWIND 1
-# elif defined(__linux)
-# error Cannnot calculate stack trace: need either libunwind or frame-pointers (see INSTALL file)
-# else
-# error Cannnot calculate stack trace: need libunwind (see INSTALL file)
-# endif
-
-// The PowerPC case
-#elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
-# if !defined(NO_FRAME_POINTER)
-# define STACKTRACE_INL_HEADER "stacktrace_powerpc-inl.h"
-# else
-# define STACKTRACE_INL_HEADER "stacktrace_generic-inl.h"
-# endif
-
-// The ARM case
-#elif defined(__arm__) && __GNUC__ >= 2
-# if !defined(NO_FRAME_POINTER)
-# define STACKTRACE_INL_HEADER "stacktrace_arm-inl.h"
-# else
-# error stacktrace without frame pointer is not supported on ARM
-# endif
-
-// The Windows case -- probably cygwin and mingw will use one of the
-// x86-includes above, but if not, we can fall back to windows intrinsics.
-#elif defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(__MINGW32__)
-# define STACKTRACE_INL_HEADER "stacktrace_win32-inl.h"
-
-#endif // all the cases
-#endif // BASE_STACKTRACE_CONFIG_H_
diff -Nru google-perftools-2.1/src/stacktrace_generic-inl.h google-perftools-2.2.1/src/stacktrace_generic-inl.h
--- google-perftools-2.1/src/stacktrace_generic-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace_generic-inl.h 2014-06-21 21:12:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -59,13 +60,13 @@
// int max_depth: the size of the result (and sizes) array(s)
// int skip_count: how many stack pointers to skip before storing in result
// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-int GET_STACK_TRACE_OR_FRAMES {
+static int GET_STACK_TRACE_OR_FRAMES {
static const int kStackLength = 64;
void * stack[kStackLength];
int size;
size = backtrace(stack, kStackLength);
- skip_count++; // we want to skip the current frame as well
+ skip_count += 2; // we want to skip the current and it's parent frame as well
int result_count = size - skip_count;
if (result_count < 0)
result_count = 0;
diff -Nru google-perftools-2.1/src/stacktrace_impl_setup-inl.h google-perftools-2.2.1/src/stacktrace_impl_setup-inl.h
--- google-perftools-2.1/src/stacktrace_impl_setup-inl.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/stacktrace_impl_setup-inl.h 2014-02-22 21:25:25.000000000 +0100
@@ -0,0 +1,94 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+// NOTE: this is NOT to be #include-d normally. It's internal
+// implementation detail of stacktrace.cc
+//
+
+// Copyright (c) 2014, gperftools Contributors.
+// 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 Google Inc. 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.
+
+// ---
+// Author: Aliaksey Kandratsenka
+//
+// based on stacktrace.cc and stacktrace_config.h by Sanjay Ghemawat
+// and Paul Pluzhnikov from Google Inc
+
+#define SIS_CONCAT2(a, b) a##b
+#define SIS_CONCAT(a, b) SIS_CONCAT2(a,b)
+
+#define SIS_STRINGIFY(a) SIS_STRINGIFY2(a)
+#define SIS_STRINGIFY2(a) #a
+
+#define IS_STACK_FRAMES 0
+#define IS_WITH_CONTEXT 0
+#define GET_STACK_TRACE_OR_FRAMES \
+ SIS_CONCAT(GetStackTrace_, GST_SUFFIX)(void **result, int max_depth, int skip_count)
+#include STACKTRACE_INL_HEADER
+#undef IS_STACK_FRAMES
+#undef IS_WITH_CONTEXT
+#undef GET_STACK_TRACE_OR_FRAMES
+
+#define IS_STACK_FRAMES 1
+#define IS_WITH_CONTEXT 0
+#define GET_STACK_TRACE_OR_FRAMES \
+ SIS_CONCAT(GetStackFrames_, GST_SUFFIX)(void **result, int *sizes, int max_depth, int skip_count)
+#include STACKTRACE_INL_HEADER
+#undef IS_STACK_FRAMES
+#undef IS_WITH_CONTEXT
+#undef GET_STACK_TRACE_OR_FRAMES
+
+#define IS_STACK_FRAMES 0
+#define IS_WITH_CONTEXT 1
+#define GET_STACK_TRACE_OR_FRAMES \
+ SIS_CONCAT(GetStackTraceWithContext_, GST_SUFFIX)(void **result, int max_depth, \
+ int skip_count, const void *ucp)
+#include STACKTRACE_INL_HEADER
+#undef IS_STACK_FRAMES
+#undef IS_WITH_CONTEXT
+#undef GET_STACK_TRACE_OR_FRAMES
+
+#define IS_STACK_FRAMES 1
+#define IS_WITH_CONTEXT 1
+#define GET_STACK_TRACE_OR_FRAMES \
+ SIS_CONCAT(GetStackFramesWithContext_, GST_SUFFIX)(void **result, int *sizes, int max_depth, \
+ int skip_count, const void *ucp)
+#include STACKTRACE_INL_HEADER
+#undef IS_STACK_FRAMES
+#undef IS_WITH_CONTEXT
+#undef GET_STACK_TRACE_OR_FRAMES
+
+static GetStackImplementation SIS_CONCAT(impl__,GST_SUFFIX) = {
+ SIS_CONCAT(GetStackFrames_, GST_SUFFIX),
+ SIS_CONCAT(GetStackFramesWithContext_, GST_SUFFIX),
+ SIS_CONCAT(GetStackTrace_, GST_SUFFIX),
+ SIS_CONCAT(GetStackTraceWithContext_, GST_SUFFIX),
+ SIS_STRINGIFY(GST_SUFFIX)
+};
+
+#undef SIS_CONCAT2
+#undef SIS_CONCAT
diff -Nru google-perftools-2.1/src/stacktrace_instrument-inl.h google-perftools-2.2.1/src/stacktrace_instrument-inl.h
--- google-perftools-2.1/src/stacktrace_instrument-inl.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/stacktrace_instrument-inl.h 2014-02-22 21:25:25.000000000 +0100
@@ -0,0 +1,155 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+// Copyright (c) 2013, Google Inc.
+// 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 Google Inc. 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.
+
+// ---
+// Author: Jean Lee
+// based on gcc Code-Gen-Options "-finstrument-functions" listed in
+// http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html .
+// Should run configure with CXXFLAGS="-finstrument-functions".
+
+// This file is a backtrace implementation for systems :
+// * The glibc implementation of backtrace() may cause a call to malloc,
+// and cause a deadlock in HeapProfiler.
+// * The libunwind implementation prints no backtrace.
+
+// The backtrace arrays are stored in "thread_back_trace" variable.
+// Maybe to use thread local storage is better and should save memorys.
+
+#ifndef BASE_STACKTRACE_INSTRUMENT_INL_H_
+#define BASE_STACKTRACE_INSTRUMENT_INL_H_
+// Note: this file is included into stacktrace.cc more than once.
+// Anything that should only be defined once should be here:
+
+#include
+#include
+#include
+#include
+#include "gperftools/stacktrace.h"
+
+#define gettid() syscall(__NR_gettid)
+#ifndef __x86_64__
+#define MAX_THREAD (32768)
+#else
+#define MAX_THREAD (65536)
+#endif
+#define MAX_DEPTH (30)
+#define ATTRIBUTE_NOINSTRUMENT __attribute__ ((no_instrument_function))
+
+typedef struct {
+ int stack_depth;
+ void* frame[MAX_DEPTH];
+}BACK_TRACE;
+
+static BACK_TRACE thread_back_trace[MAX_THREAD];
+extern "C" {
+void __cyg_profile_func_enter(void *func_address,
+ void *call_site) ATTRIBUTE_NOINSTRUMENT;
+void __cyg_profile_func_enter(void *func_address, void *call_site) {
+ (void)func_address;
+
+ BACK_TRACE* backtrace = thread_back_trace + gettid();
+ int stack_depth = backtrace->stack_depth;
+ backtrace->stack_depth = stack_depth + 1;
+ if ( stack_depth >= MAX_DEPTH ) {
+ return;
+ }
+ backtrace->frame[stack_depth] = call_site;
+}
+
+void __cyg_profile_func_exit(void *func_address,
+ void *call_site) ATTRIBUTE_NOINSTRUMENT;
+void __cyg_profile_func_exit(void *func_address, void *call_site) {
+ (void)func_address;
+ (void)call_site;
+
+ BACK_TRACE* backtrace = thread_back_trace + gettid();
+ int stack_depth = backtrace->stack_depth;
+ backtrace->stack_depth = stack_depth - 1;
+ if ( stack_depth >= MAX_DEPTH ) {
+ return;
+ }
+ backtrace->frame[stack_depth] = 0;
+}
+} // extern "C"
+
+static int cyg_backtrace(void **buffer, int size) {
+ BACK_TRACE* backtrace = thread_back_trace + gettid();
+ int stack_depth = backtrace->stack_depth;
+ if ( stack_depth >= MAX_DEPTH ) {
+ stack_depth = MAX_DEPTH;
+ }
+ int nSize = (size > stack_depth) ? stack_depth : size;
+ for (int i = 0; i < nSize; i++) {
+ buffer[i] = backtrace->frame[nSize - i - 1];
+ }
+
+ return nSize;
+}
+
+#endif // BASE_STACKTRACE_INSTRUMENT_INL_H_
+
+
+// Note: this part of the file is included several times.
+// Do not put globals below.
+
+// The following 4 functions are generated from the code below:
+// GetStack{Trace,Frames}()
+// GetStack{Trace,Frames}WithContext()
+//
+// These functions take the following args:
+// void** result: the stack-trace, as an array
+// int* sizes: the size of each stack frame, as an array
+// (GetStackFrames* only)
+// int max_depth: the size of the result (and sizes) array(s)
+// int skip_count: how many stack pointers to skip before storing in result
+// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
+static int GET_STACK_TRACE_OR_FRAMES {
+ static const int kStackLength = 64;
+ void * stack[kStackLength];
+ int size;
+ memset(stack, 0, sizeof(stack));
+
+ size = cyg_backtrace(stack, kStackLength);
+ skip_count += 2; // we want to skip the current and parent frame as well
+ int result_count = size - skip_count;
+ if (result_count < 0)
+ result_count = 0;
+ if (result_count > max_depth)
+ result_count = max_depth;
+ for (int i = 0; i < result_count; i++)
+ result[i] = stack[i + skip_count];
+
+#if IS_STACK_FRAMES
+ // No implementation for finding out the stack frame sizes yet.
+ memset(sizes, 0, sizeof(*sizes) * result_count);
+#endif
+
+ return result_count;
+}
diff -Nru google-perftools-2.1/src/stacktrace_libunwind-inl.h google-perftools-2.2.1/src/stacktrace_libunwind-inl.h
--- google-perftools-2.1/src/stacktrace_libunwind-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace_libunwind-inl.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -57,6 +58,10 @@
// cases, we return 0 to indicate the situation.
static __thread int recursive;
+#if (defined(__i386__) || defined(__x86_64__)) && defined(__GNU_LIBRARY__)
+#define BASE_STACKTRACE_UNW_CONTEXT_IS_UCONTEXT 1
+#endif
+
#endif // BASE_STACKTRACE_LIBINWIND_INL_H_
// Note: this part of the file is included several times.
@@ -73,7 +78,7 @@
// int max_depth: the size of the result (and sizes) array(s)
// int skip_count: how many stack pointers to skip before storing in result
// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-int GET_STACK_TRACE_OR_FRAMES {
+static int GET_STACK_TRACE_OR_FRAMES {
void *ip;
int n = 0;
unw_cursor_t cursor;
@@ -87,10 +92,27 @@
}
++recursive;
+#if (IS_WITH_CONTEXT && defined(BASE_STACKTRACE_UNW_CONTEXT_IS_UCONTEXT))
+ if (ucp) {
+ uc = *(static_cast(const_cast(ucp)));
+ /* this is a bit weird. profiler.cc calls us with signal's ucontext
+ * yet passing us 2 as skip_count and essentially assuming we won't
+ * use ucontext. */
+ /* In order to fix that I'm going to assume that if ucp is
+ * non-null we're asked to ignore skip_count in case we're
+ * able to use ucp */
+ skip_count = 0;
+ } else {
+ unw_getcontext(&uc);
+ skip_count += 2; // Do not include current and parent frame
+ }
+#else
unw_getcontext(&uc);
+ skip_count += 2; // Do not include current and parent frame
+#endif
+
int ret = unw_init_local(&cursor, &uc);
assert(ret >= 0);
- skip_count++; // Do not include current frame
while (skip_count--) {
if (unw_step(&cursor) <= 0) {
diff -Nru google-perftools-2.1/src/stacktrace_powerpc-darwin-inl.h google-perftools-2.2.1/src/stacktrace_powerpc-darwin-inl.h
--- google-perftools-2.1/src/stacktrace_powerpc-darwin-inl.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/stacktrace_powerpc-darwin-inl.h 2014-04-13 03:35:40.000000000 +0200
@@ -0,0 +1,158 @@
+// Copyright (c) 2007, Google Inc.
+// 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 Google Inc. 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.
+
+// ---
+// Produce stack trace. ABI documentation reference can be found at:
+// * PowerPC32 ABI: https://www.power.org/documentation/
+// power-architecture-32-bit-abi-supplement-1-0-embeddedlinuxunified/
+// * PowerPC64 ABI:
+// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
+
+#ifndef BASE_STACKTRACE_POWERPC_INL_H_
+#define BASE_STACKTRACE_POWERPC_INL_H_
+// Note: this file is included into stacktrace.cc more than once.
+// Anything that should only be defined once should be here:
+
+#include // for uintptr_t
+#include // for NULL
+#include
+
+// Given a pointer to a stack frame, locate and return the calling
+// stackframe, or return NULL if no stackframe can be found. Perform sanity
+// checks (the strictness of which is controlled by the boolean parameter
+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
+template
+static void **NextStackFrame(void **old_sp) {
+ void **new_sp = (void **) *old_sp;
+
+ // Check that the transition from frame pointer old_sp to frame
+ // pointer new_sp isn't clearly bogus
+ if (STRICT_UNWINDING) {
+ // With the stack growing downwards, older stack frame must be
+ // at a greater address that the current one.
+ if (new_sp <= old_sp) return NULL;
+ // Assume stack frames larger than 100,000 bytes are bogus.
+ if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
+ } else {
+ // In the non-strict mode, allow discontiguous stack frames.
+ // (alternate-signal-stacks for example).
+ if (new_sp == old_sp) return NULL;
+ // And allow frames upto about 1MB.
+ if ((new_sp > old_sp)
+ && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
+ }
+ if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
+ return new_sp;
+}
+
+// This ensures that GetStackTrace stes up the Link Register properly.
+void StacktracePowerPCDummyFunction() __attribute__((noinline));
+void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
+#endif // BASE_STACKTRACE_POWERPC_INL_H_
+
+// Note: this part of the file is included several times.
+// Do not put globals below.
+
+// The following 4 functions are generated from the code below:
+// GetStack{Trace,Frames}()
+// GetStack{Trace,Frames}WithContext()
+//
+// These functions take the following args:
+// void** result: the stack-trace, as an array
+// int* sizes: the size of each stack frame, as an array
+// (GetStackFrames* only)
+// int max_depth: the size of the result (and sizes) array(s)
+// int skip_count: how many stack pointers to skip before storing in result
+// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
+int GET_STACK_TRACE_OR_FRAMES {
+ void **sp;
+ // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
+ // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a
+ // different asm syntax. I don't know quite the best way to discriminate
+ // systems using the old as from the new one; I've gone with __APPLE__.
+ // TODO(csilvers): use autoconf instead, to look for 'as --version' == 1 or 2
+ __asm__ volatile ("mr %0,r1" : "=r" (sp));
+
+ // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack
+ // entry that holds the return address of the subroutine call (what
+ // instruction we run after our function finishes). This is the
+ // same as the stack-pointer of our parent routine, which is what we
+ // want here. While the compiler will always(?) set up LR for
+ // subroutine calls, it may not for leaf functions (such as this one).
+ // This routine forces the compiler (at least gcc) to push it anyway.
+ StacktracePowerPCDummyFunction();
+
+#if IS_STACK_FRAMES
+ // Note we do *not* increment skip_count here for the SYSV ABI. If
+ // we did, the list of stack frames wouldn't properly match up with
+ // the list of return addresses. Note this means the top pc entry
+ // is probably bogus for linux/ppc (and other SYSV-ABI systems).
+#else
+ // The LR save area is used by the callee, so the top entry is bogus.
+ skip_count++;
+#endif
+
+ int n = 0;
+ while (sp && n < max_depth) {
+ // The GetStackFrames routine is called when we are in some
+ // informational context (the failure signal handler for example).
+ // Use the non-strict unwinding rules to produce a stack trace
+ // that is as complete as possible (even if it contains a few
+ // bogus entries in some rare cases).
+ void **next_sp = NextStackFrame(sp);
+
+ if (skip_count > 0) {
+ skip_count--;
+ } else {
+ // PowerPC has 3 main ABIs, which say where in the stack the
+ // Link Register is. For DARWIN and AIX (used by apple and
+ // linux ppc64), it's in sp[2]. For SYSV (used by linux ppc),
+ // it's in sp[1].
+#if defined(__PPC64__)
+ // This check is in case the compiler doesn't define _CALL_AIX/etc.
+ result[n] = *(sp+2);
+#elif defined(__linux)
+ // This check is in case the compiler doesn't define _CALL_SYSV.
+ result[n] = *(sp+1);
+#endif
+
+#if IS_STACK_FRAMES
+ if (next_sp > sp) {
+ sizes[n] = (uintptr_t)next_sp - (uintptr_t)sp;
+ } else {
+ // A frame-size of 0 is used to indicate unknown frame size.
+ sizes[n] = 0;
+ }
+#endif
+ n++;
+ }
+ sp = next_sp;
+ }
+ return n;
+}
diff -Nru google-perftools-2.1/src/stacktrace_powerpc-inl.h google-perftools-2.2.1/src/stacktrace_powerpc-inl.h
--- google-perftools-2.1/src/stacktrace_powerpc-inl.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace_powerpc-inl.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
@@ -125,7 +126,7 @@
// int max_depth: the size of the result (and sizes) array(s)
// int skip_count: how many stack pointers to skip before storing in result
// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-int GET_STACK_TRACE_OR_FRAMES {
+static int GET_STACK_TRACE_OR_FRAMES {
layout_ppc *current;
int n;
@@ -138,8 +139,9 @@
StacktracePowerPCDummyFunction();
n = 0;
+ skip_count++; // skip parent's frame due to indirection in
+ // stacktrace.cc
while (current && n < max_depth) {
- result[n] = current->return_addr;
// The GetStackFrames routine is called when we are in some
// informational context (the failure signal handler for example).
@@ -147,16 +149,21 @@
// that is as complete as possible (even if it contains a few
// bogus entries in some rare cases).
layout_ppc *next = NextStackFrame(current);
-#if IS_STACK_FRAMES
- if (next > current) {
- sizes[n] = (uintptr_t)next - (uintptr_t)current;
+ if (skip_count > 0) {
+ skip_count--;
} else {
- // A frame-size of 0 is used to indicate unknown frame size.
- sizes[n] = 0;
- }
+ result[n] = current->return_addr;
+#if IS_STACK_FRAMES
+ if (next > current) {
+ sizes[n] = (uintptr_t)next - (uintptr_t)current;
+ } else {
+ // A frame-size of 0 is used to indicate unknown frame size.
+ sizes[n] = 0;
+ }
#endif
+ n++;
+ }
current = next;
- n++;
}
// It's possible the second-last stack frame can't return
diff -Nru google-perftools-2.1/src/stacktrace_powerpc-linux-inl.h google-perftools-2.2.1/src/stacktrace_powerpc-linux-inl.h
--- google-perftools-2.1/src/stacktrace_powerpc-linux-inl.h 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/stacktrace_powerpc-linux-inl.h 2014-04-13 03:35:40.000000000 +0200
@@ -0,0 +1,231 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
+// Copyright (c) 2007, Google Inc.
+// 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 Google Inc. 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.
+
+// ---
+// Author: Craig Silverstein
+//
+// Produce stack trace. ABI documentation reference can be found at:
+// * PowerPC32 ABI: https://www.power.org/documentation/
+// power-architecture-32-bit-abi-supplement-1-0-embeddedlinuxunified/
+// * PowerPC64 ABI:
+// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
+
+#ifndef BASE_STACKTRACE_POWERPC_INL_H_
+#define BASE_STACKTRACE_POWERPC_INL_H_
+// Note: this file is included into stacktrace.cc more than once.
+// Anything that should only be defined once should be here:
+
+#include // for uintptr_t
+#include // for NULL
+#include
+#include
+
+#if defined(HAVE_SYS_UCONTEXT_H)
+#include
+#elif defined(HAVE_UCONTEXT_H)
+#include // for ucontext_t
+#endif
+typedef ucontext ucontext_t;
+
+// PowerPC64 Little Endian follows BE wrt. backchain, condition register,
+// and LR save area, so no need to adjust the reading struct.
+struct layout_ppc {
+ struct layout_ppc *next;
+#ifdef __PPC64__
+ long condition_register;
+#endif
+ void *return_addr;
+};
+
+// Signal callbacks are handled by the vDSO symbol:
+//
+// * PowerPC64 Linux (arch/powerpc/kernel/vdso64/sigtramp.S):
+// __kernel_sigtramp_rt64
+// * PowerPC32 Linux (arch/powerpc/kernel/vdso32/sigtramp.S):
+// __kernel_sigtramp32
+// __kernel_sigtramp_rt32
+//
+// So a backtrace may need to specially handling if the symbol readed is
+// the signal trampoline.
+
+// Given a pointer to a stack frame, locate and return the calling
+// stackframe, or return NULL if no stackframe can be found. Perform sanity
+// checks (the strictness of which is controlled by the boolean parameter
+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
+template
+static layout_ppc *NextStackFrame(layout_ppc *current) {
+ uintptr_t old_sp = (uintptr_t)(current);
+ uintptr_t new_sp = (uintptr_t)(current->next);
+
+ // Check that the transition from frame pointer old_sp to frame
+ // pointer new_sp isn't clearly bogus
+ if (STRICT_UNWINDING) {
+ // With the stack growing downwards, older stack frame must be
+ // at a greater address that the current one.
+ if (new_sp <= old_sp)
+ return NULL;
+ // Assume stack frames larger than 100,000 bytes are bogus.
+ if (new_sp - old_sp > 100000)
+ return NULL;
+ } else {
+ // In the non-strict mode, allow discontiguous stack frames.
+ // (alternate-signal-stacks for example).
+ if (new_sp == old_sp)
+ return NULL;
+ // And allow frames upto about 1MB.
+ if ((new_sp > old_sp) && (new_sp - old_sp > 1000000))
+ return NULL;
+ }
+ if (new_sp & (sizeof(void *) - 1))
+ return NULL;
+ return current->next;
+}
+
+// This ensures that GetStackTrace stes up the Link Register properly.
+void StacktracePowerPCDummyFunction() __attribute__((noinline));
+void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
+#endif // BASE_STACKTRACE_POWERPC_INL_H_
+
+// Note: this part of the file is included several times.
+// Do not put globals below.
+
+// Load instruction used on top-of-stack get.
+#if defined(__PPC64__) || defined(__LP64__)
+# define LOAD "ld"
+#else
+# define LOAD "lwz"
+#endif
+
+// The following 4 functions are generated from the code below:
+// GetStack{Trace,Frames}()
+// GetStack{Trace,Frames}WithContext()
+//
+// These functions take the following args:
+// void** result: the stack-trace, as an array
+// int* sizes: the size of each stack frame, as an array
+// (GetStackFrames* only)
+// int max_depth: the size of the result (and sizes) array(s)
+// int skip_count: how many stack pointers to skip before storing in result
+// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
+static int GET_STACK_TRACE_OR_FRAMES {
+ layout_ppc *current;
+ int n;
+
+ // Get the address on top-of-stack
+ current = reinterpret_cast (__builtin_frame_address (0));
+ // And ignore the current symbol
+ current = current->next;
+
+ StacktracePowerPCDummyFunction();
+
+ n = 0;
+ skip_count++; // skip parent's frame due to indirection in
+ // stacktrace.cc
+
+ base::VDSOSupport vdso;
+ base::ElfMemImage::SymbolInfo rt_sigreturn_symbol_info;
+#ifdef __PPC64__
+ const void *sigtramp64_vdso = 0;
+ if (vdso.LookupSymbol("__kernel_sigtramp_rt64", "LINUX_2.6.15", STT_NOTYPE,
+ &rt_sigreturn_symbol_info))
+ sigtramp64_vdso = rt_sigreturn_symbol_info.address;
+#else
+ const void *sigtramp32_vdso = 0;
+ if (vdso.LookupSymbol("__kernel_sigtramp32", "LINUX_2.6.15", STT_NOTYPE,
+ &rt_sigreturn_symbol_info))
+ sigtramp32_vdso = rt_sigreturn_symbol_info.address;
+ const void *sigtramp32_rt_vdso = 0;
+ if (vdso.LookupSymbol("__kernel_sigtramp_rt32", "LINUX_2.6.15", STT_NOTYPE,
+ &rt_sigreturn_symbol_info))
+ sigtramp32_rt_vdso = rt_sigreturn_symbol_info.address;
+#endif
+
+ while (current && n < max_depth) {
+
+ // The GetStackFrames routine is called when we are in some
+ // informational context (the failure signal handler for example).
+ // Use the non-strict unwinding rules to produce a stack trace
+ // that is as complete as possible (even if it contains a few
+ // bogus entries in some rare cases).
+ layout_ppc *next = NextStackFrame(current);
+ if (skip_count > 0) {
+ skip_count--;
+ } else {
+ result[n] = current->return_addr;
+#ifdef __PPC64__
+ if (sigtramp64_vdso && (sigtramp64_vdso == current->return_addr)) {
+ struct signal_frame_64 {
+ char dummy[128];
+ ucontext_t uc;
+ // We don't care about the rest, since the IP value is at 'uc' field.
+ } *sigframe = reinterpret_cast(current);
+ result[n] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
+ }
+#else
+ if (sigtramp32_vdso && (sigtramp32_vdso == current->return_addr)) {
+ struct signal_frame_32 {
+ char dummy[64];
+ struct sigcontext sctx;
+ mcontext_t mctx;
+ // We don't care about the rest, since IP value is at 'mctx' field.
+ } *sigframe = reinterpret_cast(current);
+ result[n] = (void*) sigframe->mctx.gregs[PT_NIP];
+ } else if (sigtramp32_rt_vdso && (sigtramp32_rt_vdso == current->return_addr)) {
+ struct rt_signal_frame_32 {
+ char dummy[64 + 16];
+ siginfo_t info;
+ struct ucontext uc;
+ // We don't care about the rest, since IP value is at 'uc' field.A
+ } *sigframe = reinterpret_cast(current);
+ result[n] = (void*) sigframe->uc.uc_mcontext.uc_regs->gregs[PT_NIP];
+ }
+#endif
+
+#if IS_STACK_FRAMES
+ if (next > current) {
+ sizes[n] = (uintptr_t)next - (uintptr_t)current;
+ } else {
+ // A frame-size of 0 is used to indicate unknown frame size.
+ sizes[n] = 0;
+ }
+#endif
+ n++;
+ }
+ current = next;
+ }
+
+ // It's possible the second-last stack frame can't return
+ // (that is, it's __libc_start_main), in which case
+ // the CRT startup code will have set its LR to 'NULL'.
+ if (n > 0 && result[n-1] == NULL)
+ n--;
+
+ return n;
+}
diff -Nru google-perftools-2.1/src/stack_trace_table.cc google-perftools-2.2.1/src/stack_trace_table.cc
--- google-perftools-2.1/src/stack_trace_table.cc 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stack_trace_table.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2009, Google Inc.
// All rights reserved.
//
@@ -135,7 +136,7 @@
b = b->next;
}
}
- out[idx++] = static_cast(0);
+ out[idx++] = NULL;
ASSERT(idx == out_len);
// Clear state
diff -Nru google-perftools-2.1/src/stack_trace_table.h google-perftools-2.2.1/src/stack_trace_table.h
--- google-perftools-2.1/src/stack_trace_table.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stack_trace_table.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2009, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/stacktrace_win32-inl.h google-perftools-2.2.1/src/stacktrace_win32-inl.h
--- google-perftools-2.1/src/stacktrace_win32-inl.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace_win32-inl.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -70,22 +71,37 @@
(RtlCaptureStackBackTrace_Function*)
GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
-PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
- int skip_count) {
+static int GetStackTrace_win32(void** result, int max_depth,
+ int skip_count) {
if (!RtlCaptureStackBackTrace_fn) {
// TODO(csilvers): should we log an error here?
return 0; // can't find a stacktrace with no function to call
}
- return (int)RtlCaptureStackBackTrace_fn(skip_count + 2, max_depth,
+ return (int)RtlCaptureStackBackTrace_fn(skip_count + 3, max_depth,
result, 0);
}
-PERFTOOLS_DLL_DECL int GetStackFrames(void** /* pcs */,
- int* /* sizes */,
- int /* max_depth */,
- int /* skip_count */) {
+static int not_implemented(void) {
assert(0 == "Not yet implemented");
return 0;
}
+static int GetStackFrames_win32(void** /* pcs */,
+ int* /* sizes */,
+ int /* max_depth */,
+ int /* skip_count */) {
+ return not_implemented();
+}
+
+static int GetStackFramesWithContext_win32(void** result, int* sizes, int max_depth,
+ int skip_count, const void *uc) {
+ return not_implemented();
+}
+
+static int GetStackTraceWithContext_win32(void** result, int max_depth,
+ int skip_count, const void *uc) {
+ return not_implemented();
+}
+
+
#endif // BASE_STACKTRACE_WIN32_INL_H_
diff -Nru google-perftools-2.1/src/stacktrace_x86-inl.h google-perftools-2.2.1/src/stacktrace_x86-inl.h
--- google-perftools-2.1/src/stacktrace_x86-inl.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/stacktrace_x86-inl.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -287,7 +288,7 @@
// int skip_count: how many stack pointers to skip before storing in result
// void* ucp: a ucontext_t* (GetStack{Trace,Frames}WithContext only)
-int GET_STACK_TRACE_OR_FRAMES {
+static int GET_STACK_TRACE_OR_FRAMES {
void **sp;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) || __llvm__
// __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8.
@@ -320,6 +321,8 @@
# error Using stacktrace_x86-inl.h on a non x86 architecture!
#endif
+ skip_count++; // skip parent's frame due to indirection in stacktrace.cc
+
int n = 0;
while (sp && n < max_depth) {
if (*(sp+1) == reinterpret_cast(0)) {
diff -Nru google-perftools-2.1/src/static_vars.cc google-perftools-2.2.1/src/static_vars.cc
--- google-perftools-2.1/src/static_vars.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/static_vars.cc 2014-06-22 00:34:32.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -30,9 +31,13 @@
// ---
// Author: Ken Ashcraft
+#include
#include "static_vars.h"
#include // for NULL
#include // for operator new
+#ifdef HAVE_PTHREAD
+#include // for pthread_atfork
+#endif
#include "internal_logging.h" // for CHECK_CONDITION
#include "common.h"
#include "sampler.h" // for Sampler
@@ -62,17 +67,6 @@
}
#endif
-static inline
-void SetupAtForkLocksHandler()
-{
-#if defined(HAVE_FORK) && defined(HAVE_PTHREAD)
- pthread_atfork(CentralCacheLockAll, // parent calls before fork
- CentralCacheUnlockAll, // parent calls after fork
- CentralCacheUnlockAll); // child calls after fork
-#endif
-}
-
-
SpinLock Static::pageheap_lock_(SpinLock::LINKER_INITIALIZED);
SizeMap Static::sizemap_;
CentralFreeListPadded Static::central_cache_[kNumClasses];
@@ -102,10 +96,23 @@
// in is caches as pointers that are sources of heap object liveness,
// which leads to it missing some memory leaks.
pageheap_ = new (MetaDataAlloc(sizeof(PageHeap))) PageHeap;
+ pageheap_->SetAggressiveDecommit(EnvToBool("TCMALLOC_AGGRESSIVE_DECOMMIT", false));
DLL_Init(&sampled_objects_);
Sampler::InitStatics();
}
+
+#if defined(HAVE_FORK) && defined(HAVE_PTHREAD)
+
+static inline
+void SetupAtForkLocksHandler()
+{
+ pthread_atfork(CentralCacheLockAll, // parent calls before fork
+ CentralCacheUnlockAll, // parent calls after fork
+ CentralCacheUnlockAll); // child calls after fork
+}
REGISTER_MODULE_INITIALIZER(tcmalloc_fork_handler, SetupAtForkLocksHandler());
+#endif
+
} // namespace tcmalloc
diff -Nru google-perftools-2.1/src/static_vars.h google-perftools-2.2.1/src/static_vars.h
--- google-perftools-2.1/src/static_vars.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/static_vars.h 2014-06-22 00:34:32.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/symbolize.cc google-perftools-2.2.1/src/symbolize.cc
--- google-perftools-2.1/src/symbolize.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/symbolize.cc 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2009, Google Inc.
// All rights reserved.
//
@@ -75,9 +76,13 @@
// Returns NULL if we're on an OS where we can't get the invocation name.
// Using a static var is ok because we're not called from a thread.
-static char* GetProgramInvocationName() {
+static const char* GetProgramInvocationName() {
#if defined(HAVE_PROGRAM_INVOCATION_NAME)
+#ifdef __UCLIBC__
+ extern const char* program_invocation_name; // uclibc provides this
+#else
extern char* program_invocation_name; // gcc provides this
+#endif
return program_invocation_name;
#elif defined(__MACH__)
// We don't want to allocate memory for this since we may be
diff -Nru google-perftools-2.1/src/symbolize.h google-perftools-2.2.1/src/symbolize.h
--- google-perftools-2.1/src/symbolize.h 2013-07-29 05:20:40.000000000 +0200
+++ google-perftools-2.2.1/src/symbolize.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2009, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/system-alloc.cc google-perftools-2.2.1/src/system-alloc.cc
--- google-perftools-2.1/src/system-alloc.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/system-alloc.cc 2014-03-01 21:40:51.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -201,8 +202,7 @@
void* SbrkSysAllocator::Alloc(size_t size, size_t *actual_size,
size_t alignment) {
-#ifndef HAVE_SBRK
- failed_ = true;
+#if !defined(HAVE_SBRK) || defined(__UCLIBC__)
return NULL;
#else
// Check if we should use sbrk allocation.
@@ -274,7 +274,6 @@
void* MmapSysAllocator::Alloc(size_t size, size_t *actual_size,
size_t alignment) {
#ifndef HAVE_MMAP
- failed_ = true;
return NULL;
#else
// Check if we should use mmap allocation.
@@ -343,7 +342,6 @@
void* DevMemSysAllocator::Alloc(size_t size, size_t *actual_size,
size_t alignment) {
#ifndef HAVE_MMAP
- failed_ = true;
return NULL;
#else
static bool initialized = false;
@@ -494,17 +492,17 @@
// Enforce minimum alignment
if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner);
+ size_t actual_size_storage;
+ if (actual_size == NULL) {
+ actual_size = &actual_size_storage;
+ }
+
void* result = sys_alloc->Alloc(size, actual_size, alignment);
if (result != NULL) {
- if (actual_size) {
- CheckAddressBits(
- reinterpret_cast(result) + *actual_size - 1);
- TCMalloc_SystemTaken += *actual_size;
- } else {
+ CHECK_CONDITION(
CheckAddressBits(
- reinterpret_cast(result) + size - 1);
- TCMalloc_SystemTaken += size;
- }
+ reinterpret_cast(result) + *actual_size - 1));
+ TCMalloc_SystemTaken += *actual_size;
}
return result;
}
@@ -546,3 +544,9 @@
#endif
return false;
}
+
+void TCMalloc_SystemCommit(void* start, size_t length) {
+ // Nothing to do here. TCMalloc_SystemRelease does not alter pages
+ // such that they need to be re-committed before they can be used by the
+ // application.
+}
diff -Nru google-perftools-2.1/src/system-alloc.h google-perftools-2.2.1/src/system-alloc.h
--- google-perftools-2.1/src/system-alloc.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/system-alloc.h 2014-03-01 21:40:51.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -75,6 +76,13 @@
extern PERFTOOLS_DLL_DECL
bool TCMalloc_SystemRelease(void* start, size_t length);
+// Called to ressurect memory which has been previously released
+// to the system via TCMalloc_SystemRelease. An attempt to
+// commit a page that is already committed does not cause this
+// function to fail.
+extern PERFTOOLS_DLL_DECL
+void TCMalloc_SystemCommit(void* start, size_t length);
+
// The current system allocator.
extern PERFTOOLS_DLL_DECL SysAllocator* sys_alloc;
diff -Nru google-perftools-2.1/src/tcmalloc.cc google-perftools-2.2.1/src/tcmalloc.cc
--- google-perftools-2.1/src/tcmalloc.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tcmalloc.cc 2014-06-21 21:12:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -699,6 +700,11 @@
return true;
}
+ if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
+ *value = size_t(Static::pageheap()->GetAggressiveDecommit());
+ return true;
+ }
+
return false;
}
@@ -711,6 +717,11 @@
return true;
}
+ if (strcmp(name, "tcmalloc.aggressive_memory_decommit") == 0) {
+ Static::pageheap()->SetAggressiveDecommit(value != 0);
+ return true;
+ }
+
return false;
}
@@ -926,7 +937,11 @@
TCMallocGuard::~TCMallocGuard() {
if (--tcmallocguard_refcount == 0) {
- const char* env = getenv("MALLOCSTATS");
+ const char* env = NULL;
+ if (!RunningOnValgrind()) {
+ // Valgrind uses it's own malloc so we cannot do MALLOCSTATS
+ env = getenv("MALLOCSTATS");
+ }
if (env != NULL) {
int level = atoi(env);
if (level < 1) level = 1;
@@ -1720,4 +1735,10 @@
return MallocExtension::instance()->GetAllocatedSize(ptr);
}
+extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) __THROW {
+ void* result = do_malloc(size);
+ MallocHook::InvokeNewHook(result, size);
+ return result;
+}
+
#endif // TCMALLOC_USING_DEBUGALLOCATION
diff -Nru google-perftools-2.1/src/tcmalloc_guard.h google-perftools-2.2.1/src/tcmalloc_guard.h
--- google-perftools-2.1/src/tcmalloc_guard.h 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tcmalloc_guard.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tcmalloc.h google-perftools-2.2.1/src/tcmalloc.h
--- google-perftools-2.1/src/tcmalloc.h 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tcmalloc.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/addressmap_unittest.cc google-perftools-2.2.1/src/tests/addressmap_unittest.cc
--- google-perftools-2.1/src/tests/addressmap_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/addressmap_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/atomicops_unittest.cc google-perftools-2.2.1/src/tests/atomicops_unittest.cc
--- google-perftools-2.1/src/tests/atomicops_unittest.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/atomicops_unittest.cc 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
@@ -37,76 +38,6 @@
#define GG_ULONGLONG(x) static_cast(x)
-template
-static void TestAtomicIncrement(AtomicType (*atomic_increment_func)
- (volatile AtomicType*, AtomicType)) {
- // For now, we just test single threaded execution
-
- // use a guard value to make sure the atomic_increment_func doesn't go
- // outside the expected address bounds. This is in particular to
- // test that some future change to the asm code doesn't cause the
- // 32-bit atomic_increment_func doesn't do the wrong thing on 64-bit
- // machines.
- struct {
- AtomicType prev_word;
- AtomicType count;
- AtomicType next_word;
- } s;
-
- AtomicType prev_word_value, next_word_value;
- memset(&prev_word_value, 0xFF, sizeof(AtomicType));
- memset(&next_word_value, 0xEE, sizeof(AtomicType));
-
- s.prev_word = prev_word_value;
- s.count = 0;
- s.next_word = next_word_value;
-
- ASSERT_EQ(1, (*atomic_increment_func)(&s.count, 1));
- ASSERT_EQ(1, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(3, (*atomic_increment_func)(&s.count, 2));
- ASSERT_EQ(3, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(6, (*atomic_increment_func)(&s.count, 3));
- ASSERT_EQ(6, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(3, (*atomic_increment_func)(&s.count, -3));
- ASSERT_EQ(3, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(1, (*atomic_increment_func)(&s.count, -2));
- ASSERT_EQ(1, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(0, (*atomic_increment_func)(&s.count, -1));
- ASSERT_EQ(0, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(-1, (*atomic_increment_func)(&s.count, -1));
- ASSERT_EQ(-1, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(-5, (*atomic_increment_func)(&s.count, -4));
- ASSERT_EQ(-5, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-
- ASSERT_EQ(0, (*atomic_increment_func)(&s.count, 5));
- ASSERT_EQ(0, s.count);
- ASSERT_EQ(prev_word_value, s.prev_word);
- ASSERT_EQ(next_word_value, s.next_word);
-}
-
#define NUM_BITS(T) (sizeof(T) * 8)
@@ -159,21 +90,6 @@
}
-template
-static void TestAtomicIncrementBounds(AtomicType (*atomic_increment_func)
- (volatile AtomicType*, AtomicType)) {
- // Test increment at the half-width boundary of the atomic type.
- // It is primarily for testing at the 32-bit boundary for 64-bit atomic type.
- AtomicType test_val = GG_ULONGLONG(1) << (NUM_BITS(AtomicType) / 2);
- AtomicType value = test_val - 1;
- AtomicType new_value = (*atomic_increment_func)(&value, 1);
- ASSERT_EQ(test_val, value);
- ASSERT_EQ(value, new_value);
-
- (*atomic_increment_func)(&value, -1);
- ASSERT_EQ(test_val - 1, value);
-}
-
// This is a simple sanity check that values are correct. Not testing
// atomicity
template
@@ -234,42 +150,13 @@
TestAtomicExchange(base::subtle::Acquire_AtomicExchange);
TestAtomicExchange(base::subtle::Release_AtomicExchange);
- TestAtomicIncrementBounds(
- base::subtle::NoBarrier_AtomicIncrement);
- TestAtomicIncrementBounds(
- base::subtle::Barrier_AtomicIncrement);
-
TestStore();
TestLoad();
}
int main(int argc, char** argv) {
- TestAtomicIncrement(base::subtle::NoBarrier_AtomicIncrement);
- TestAtomicIncrement(base::subtle::Barrier_AtomicIncrement);
- TestAtomicIncrement(base::subtle::NoBarrier_AtomicIncrement);
- TestAtomicIncrement(base::subtle::Barrier_AtomicIncrement);
-
TestAtomicOps();
TestAtomicOps();
-
- // I've commented the Atomic64 tests out for now, because Atomic64
- // doesn't work on x86 systems that are not compiled to support mmx
- // registers. Since I want this project to be as portable as
- // possible -- that is, not to assume we've compiled for mmx or even
- // that the processor supports it -- and we don't actually use
- // Atomic64 anywhere, I've commented it out of the test for now.
- // (Luckily, if we ever do use Atomic64 by accident, we'll get told
- // via a compiler error rather than some obscure runtime failure, so
- // this course of action is safe.)
- // If we ever *do* want to enable this, try adding -msse (or -mmmx?)
- // to the CXXFLAGS in Makefile.am.
-#if 0 and defined(BASE_HAS_ATOMIC64)
- TestAtomicIncrement(
- base::subtle::NoBarrier_AtomicIncrement);
- TestAtomicIncrement(
- base::subtle::Barrier_AtomicIncrement);
-#endif
-
printf("PASS\n");
return 0;
}
diff -Nru google-perftools-2.1/src/tests/current_allocated_bytes_test.cc google-perftools-2.2.1/src/tests/current_allocated_bytes_test.cc
--- google-perftools-2.1/src/tests/current_allocated_bytes_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/current_allocated_bytes_test.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/debugallocation_test.cc google-perftools-2.2.1/src/tests/debugallocation_test.cc
--- google-perftools-2.1/src/tests/debugallocation_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/debugallocation_test.cc 2014-04-13 03:35:40.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
@@ -32,8 +33,10 @@
#include
#include
+#include // for memcmp
#include
#include "gperftools/malloc_extension.h"
+#include "gperftools/tcmalloc.h"
#include "base/logging.h"
using std::vector;
@@ -295,6 +298,22 @@
#endif
}
+// based on test program contributed by mikesart@gmail.com aka
+// mikesart@valvesoftware.com. See issue-464.
+TEST(DebugAllocationTest, ReallocAfterMemalign) {
+ char stuff[50];
+ memset(stuff, 0x11, sizeof(stuff));
+ void *p = tc_memalign(16, sizeof(stuff));
+ EXPECT_NE(p, NULL);
+ memcpy(stuff, p, sizeof(stuff));
+
+ p = realloc(p, sizeof(stuff) + 10);
+ EXPECT_NE(p, NULL);
+
+ int rv = memcmp(stuff, p, sizeof(stuff));
+ EXPECT_EQ(rv, 0);
+}
+
int main(int argc, char** argv) {
// If you run without args, we run the non-death parts of the test.
// Otherwise, argv[1] should be a number saying which death-test
diff -Nru google-perftools-2.1/src/tests/frag_unittest.cc google-perftools-2.2.1/src/tests/frag_unittest.cc
--- google-perftools-2.1/src/tests/frag_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/frag_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2003, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/getpc_test.cc google-perftools-2.2.1/src/tests/getpc_test.cc
--- google-perftools-2.1/src/tests/getpc_test.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/getpc_test.cc 2014-03-29 21:35:36.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -99,14 +100,16 @@
char* expected = (char*)&RoutineCallingTheSignal;
char* actual = (char*)getpc_retval;
- // For ia64, ppc64, and parisc64, the function pointer is actually
+ // For ia64, ppc64v1, and parisc64, the function pointer is actually
// a struct. For instance, ia64's dl-fptr.h:
// struct fdesc { /* An FDESC is a function descriptor. */
// ElfW(Addr) ip; /* code entry point */
// ElfW(Addr) gp; /* global pointer */
// };
// We want the code entry point.
-#if defined(__ia64) || defined(__powerpc64__) // NOTE: ppc64 is UNTESTED
+ // NOTE: ppc64 ELFv2 (Little Endian) does not have function pointers
+#if defined(__ia64) || \
+ (defined(__powerpc64__) && _CALL_ELF != 2)
expected = ((char**)expected)[0]; // this is "ip"
#endif
diff -Nru google-perftools-2.1/src/tests/heap-checker-death_unittest.sh google-perftools-2.2.1/src/tests/heap-checker-death_unittest.sh
--- google-perftools-2.1/src/tests/heap-checker-death_unittest.sh 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/heap-checker-death_unittest.sh 2013-12-06 21:16:47.000000000 +0100
@@ -44,7 +44,7 @@
exit 1
fi
-EXE="${1:-$BINDIR}/heap-checker_unittest"
+EXE="${1:-$BINDIR/heap-checker_unittest}"
TMPDIR="/tmp/heap_check_death_info"
ALARM() {
diff -Nru google-perftools-2.1/src/tests/heap-checker_unittest.cc google-perftools-2.2.1/src/tests/heap-checker_unittest.cc
--- google-perftools-2.1/src/tests/heap-checker_unittest.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/heap-checker_unittest.cc 2014-04-13 03:35:40.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -1266,7 +1267,7 @@
// On PPC64 the stacktrace returned by GetStatcTrace contains the function
// address from .text segment while function pointers points to ODP entries.
// The following code decodes the ODP to get the actual symbol address.
-#if defined(__linux) && defined(__PPC64__)
+#if defined(__linux) && defined(__PPC64__) && (_CALL_ELF != 2)
static inline uintptr_t GetFunctionAddress (void* (*func)(uintptr_t*))
{
struct odp_entry_t {
diff -Nru google-perftools-2.1/src/tests/heap-checker_unittest.sh google-perftools-2.2.1/src/tests/heap-checker_unittest.sh
--- google-perftools-2.1/src/tests/heap-checker_unittest.sh 2012-02-10 03:45:37.000000000 +0100
+++ google-perftools-2.2.1/src/tests/heap-checker_unittest.sh 2013-12-06 21:16:47.000000000 +0100
@@ -48,7 +48,7 @@
exit 1
fi
-HEAP_CHECKER="${1:-$BINDIR}/heap-checker_unittest"
+HEAP_CHECKER="${1:-$BINDIR/heap-checker_unittest}"
PPROF_PATH="${2:-$PPROF_PATH}"
TMPDIR=/tmp/heap_check_info
diff -Nru google-perftools-2.1/src/tests/heap-profiler_unittest.cc google-perftools-2.2.1/src/tests/heap-profiler_unittest.cc
--- google-perftools-2.1/src/tests/heap-profiler_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/heap-profiler_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/heap-profiler_unittest.sh google-perftools-2.2.1/src/tests/heap-profiler_unittest.sh
--- google-perftools-2.1/src/tests/heap-profiler_unittest.sh 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/heap-profiler_unittest.sh 2013-12-06 21:16:47.000000000 +0100
@@ -52,7 +52,7 @@
exit 1
fi
-HEAP_PROFILER="${1:-$BINDIR}/heap-profiler_unittest"
+HEAP_PROFILER="${1:-$BINDIR/heap-profiler_unittest}"
PPROF="${2:-$PPROF_PATH}"
TEST_TMPDIR=/tmp/heap_profile_info
diff -Nru google-perftools-2.1/src/tests/low_level_alloc_unittest.cc google-perftools-2.2.1/src/tests/low_level_alloc_unittest.cc
--- google-perftools-2.1/src/tests/low_level_alloc_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/low_level_alloc_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2006, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/tests/malloc_extension_c_test.c google-perftools-2.2.1/src/tests/malloc_extension_c_test.c
--- google-perftools-2.1/src/tests/malloc_extension_c_test.c 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/malloc_extension_c_test.c 2013-12-06 21:16:47.000000000 +0100
@@ -1,3 +1,4 @@
+/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/tests/malloc_extension_test.cc google-perftools-2.2.1/src/tests/malloc_extension_test.cc
--- google-perftools-2.1/src/tests/malloc_extension_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/malloc_extension_test.cc 2014-03-01 20:24:54.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -39,8 +40,6 @@
#include
#include
-using STL_NAMESPACE::vector;
-
int main(int argc, char** argv) {
void* a = malloc(1000);
diff -Nru google-perftools-2.1/src/tests/malloc_hook_test.cc google-perftools-2.2.1/src/tests/malloc_hook_test.cc
--- google-perftools-2.1/src/tests/malloc_hook_test.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/malloc_hook_test.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2011, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/markidle_unittest.cc google-perftools-2.2.1/src/tests/markidle_unittest.cc
--- google-perftools-2.1/src/tests/markidle_unittest.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/markidle_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2003, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/memalign_unittest.cc google-perftools-2.2.1/src/tests/memalign_unittest.cc
--- google-perftools-2.1/src/tests/memalign_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/memalign_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2004, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/packed-cache_test.cc google-perftools-2.2.1/src/tests/packed-cache_test.cc
--- google-perftools-2.1/src/tests/packed-cache_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/packed-cache_test.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/page_heap_test.cc google-perftools-2.2.1/src/tests/page_heap_test.cc
--- google-perftools-2.1/src/tests/page_heap_test.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/page_heap_test.cc 2013-12-06 21:16:47.000000000 +0100
@@ -1,5 +1,9 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright 2009 Google Inc. All Rights Reserved.
// Author: fikes@google.com (Andrew Fikes)
+//
+// Use of this source code is governed by a BSD-style license that can
+// be found in the LICENSE file.
#include "config_for_unittests.h"
#include "page_heap.h"
diff -Nru google-perftools-2.1/src/tests/pagemap_unittest.cc google-perftools-2.2.1/src/tests/pagemap_unittest.cc
--- google-perftools-2.1/src/tests/pagemap_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/pagemap_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2003, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/profiledata_unittest.cc google-perftools-2.2.1/src/tests/profiledata_unittest.cc
--- google-perftools-2.1/src/tests/profiledata_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/profiledata_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/profile-handler_unittest.cc google-perftools-2.2.1/src/tests/profile-handler_unittest.cc
--- google-perftools-2.1/src/tests/profile-handler_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/profile-handler_unittest.cc 2013-12-06 21:16:47.000000000 +0100
@@ -1,7 +1,12 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright 2009 Google Inc. All Rights Reserved.
// Author: Nabeel Mian (nabeelmian@google.com)
// Chris Demetriou (cgd@google.com)
//
+// Use of this source code is governed by a BSD-style license that can
+// be found in the LICENSE file.
+//
+//
// This file contains the unit tests for profile-handler.h interface.
//
// It is linked into three separate unit tests:
diff -Nru google-perftools-2.1/src/tests/profiler_unittest.cc google-perftools-2.2.1/src/tests/profiler_unittest.cc
--- google-perftools-2.1/src/tests/profiler_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/profiler_unittest.cc 2013-12-06 21:16:47.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -110,27 +111,31 @@
ProfilerFlush(); // just because we can
// The other threads, if any, will run only half as long as the main thread
- RunManyThreads(test_other_thread, num_threads);
-
+ if(num_threads > 0) {
+ RunManyThreads(test_other_thread, num_threads);
+ } else {
// Or maybe they asked to fork. The fork test is only interesting
// when we use CPUPROFILE to name, so check for that
#ifdef HAVE_UNISTD_H
- for (; num_threads < 0; ++num_threads) { // - to fork
- if (filename) {
- printf("FORK test only makes sense when no filename is specified.\n");
- return 2;
- }
- switch (fork()) {
- case -1:
- printf("FORK failed!\n");
- return 1;
- case 0: // child
- return execl(argv[0], argv[0], argv[1], NULL);
- default:
- wait(NULL); // we'll let the kids run one at a time
+ for (; num_threads < 0; ++num_threads) { // - to fork
+ if (filename) {
+ printf("FORK test only makes sense when no filename is specified.\n");
+ return 2;
+ }
+ switch (fork()) {
+ case -1:
+ printf("FORK failed!\n");
+ return 1;
+ case 0: // child
+ return execl(argv[0], argv[0], argv[1], NULL);
+ default:
+ wait(NULL); // we'll let the kids run one at a time
+ }
}
- }
+#else
+ fprintf(stderr, "%s was compiled without support for fork() and exec()\n", argv[0]);
#endif
+ }
test_main_thread();
diff -Nru google-perftools-2.1/src/tests/raw_printer_test.cc google-perftools-2.2.1/src/tests/raw_printer_test.cc
--- google-perftools-2.1/src/tests/raw_printer_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/raw_printer_test.cc 2013-12-06 21:16:47.000000000 +0100
@@ -1,5 +1,9 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright 2009 Google Inc. All Rights Reserved.
// Author: sanjay@google.com (Sanjay Ghemawat)
+//
+// Use of this source code is governed by a BSD-style license that can
+// be found in the LICENSE file.
#include "raw_printer.h"
#include
diff -Nru google-perftools-2.1/src/tests/realloc_unittest.cc google-perftools-2.2.1/src/tests/realloc_unittest.cc
--- google-perftools-2.1/src/tests/realloc_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/realloc_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2004, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/sampler_test.cc google-perftools-2.2.1/src/tests/sampler_test.cc
--- google-perftools-2.1/src/tests/sampler_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/sampler_test.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/sampling_test.cc google-perftools-2.2.1/src/tests/sampling_test.cc
--- google-perftools-2.1/src/tests/sampling_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/sampling_test.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/simple_compat_test.cc google-perftools-2.2.1/src/tests/simple_compat_test.cc
--- google-perftools-2.1/src/tests/simple_compat_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/simple_compat_test.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2012, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/stack_trace_table_test.cc google-perftools-2.2.1/src/tests/stack_trace_table_test.cc
--- google-perftools-2.1/src/tests/stack_trace_table_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/stack_trace_table_test.cc 2013-12-06 21:16:47.000000000 +0100
@@ -1,5 +1,10 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright 2009 Google Inc. All Rights Reserved.
// Author: fikes@google.com (Andrew Fikes)
+//
+// Use of this source code is governed by a BSD-style license that can
+// be found in the LICENSE file.
+
#include "config_for_unittests.h"
#include // for puts()
diff -Nru google-perftools-2.1/src/tests/system-alloc_unittest.cc google-perftools-2.2.1/src/tests/system-alloc_unittest.cc
--- google-perftools-2.1/src/tests/system-alloc_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/system-alloc_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/tcmalloc_large_unittest.cc google-perftools-2.2.1/src/tests/tcmalloc_large_unittest.cc
--- google-perftools-2.1/src/tests/tcmalloc_large_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/tcmalloc_large_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/tcmalloc_unittest.cc google-perftools-2.2.1/src/tests/tcmalloc_unittest.cc
--- google-perftools-2.1/src/tests/tcmalloc_unittest.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/tcmalloc_unittest.cc 2014-04-13 03:35:40.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2005, Google Inc.
// All rights reserved.
//
@@ -868,6 +869,23 @@
}
#endif
+class AggressiveDecommitChanger {
+ size_t old_value_;
+public:
+ AggressiveDecommitChanger(size_t new_value) {
+ MallocExtension *inst = MallocExtension::instance();
+ bool rv = inst->GetNumericProperty("tcmalloc.aggressive_memory_decommit", &old_value_);
+ CHECK_CONDITION(rv);
+ rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", new_value);
+ CHECK_CONDITION(rv);
+ }
+ ~AggressiveDecommitChanger() {
+ MallocExtension *inst = MallocExtension::instance();
+ bool rv = inst->SetNumericProperty("tcmalloc.aggressive_memory_decommit", old_value_);
+ CHECK_CONDITION(rv);
+ }
+};
+
static void TestReleaseToSystem() {
// Debug allocation mode adds overhead to each allocation which
// messes up all the equality tests here. I just disable the
@@ -879,6 +897,8 @@
const double old_tcmalloc_release_rate = FLAGS_tcmalloc_release_rate;
FLAGS_tcmalloc_release_rate = 0;
+ AggressiveDecommitChanger disabler(0);
+
static const int MB = 1048576;
void* a = malloc(MB);
void* b = malloc(MB);
@@ -929,6 +949,51 @@
#endif // #ifndef DEBUGALLOCATION
}
+static void TestAggressiveDecommit() {
+ // Debug allocation mode adds overhead to each allocation which
+ // messes up all the equality tests here. I just disable the
+ // teset in this mode.
+#ifndef DEBUGALLOCATION
+
+ if(!HaveSystemRelease) return;
+
+ fprintf(LOGSTREAM, "Testing aggressive de-commit\n");
+
+ AggressiveDecommitChanger enabler(1);
+
+ static const int MB = 1048576;
+ void* a = malloc(MB);
+ void* b = malloc(MB);
+
+ size_t starting_bytes = GetUnmappedBytes();
+
+ // ReleaseToSystem shouldn't do anything either.
+ MallocExtension::instance()->ReleaseToSystem(MB);
+ EXPECT_EQ(starting_bytes, GetUnmappedBytes());
+
+ free(a);
+
+ // The span to release should be 1MB.
+ EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes());
+
+ free(b);
+
+ EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
+
+ // Nothing else to release.
+ MallocExtension::instance()->ReleaseFreeMemory();
+ EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
+
+ a = malloc(MB);
+ free(a);
+
+ EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes());
+
+ fprintf(LOGSTREAM, "Done testing aggressive de-commit\n");
+
+#endif // #ifndef DEBUGALLOCATION
+}
+
// On MSVC10, in release mode, the optimizer convinces itself
// g_no_memory is never changed (I guess it doesn't realize OnNoMemory
// might be called). Work around this by setting the var volatile.
@@ -1067,6 +1132,11 @@
free(p1);
VerifyDeleteHookWasCalled();
+ p1 = tc_malloc_skip_new_handler(10);
+ CHECK(p1 != NULL);
+ VerifyNewHookWasCalled();
+ free(p1);
+ VerifyDeleteHookWasCalled();
p1 = calloc(10, 2);
CHECK(p1 != NULL);
@@ -1307,6 +1377,7 @@
TestHugeThreadCache();
TestRanges();
TestReleaseToSystem();
+ TestAggressiveDecommit();
TestSetNewMode();
return 0;
diff -Nru google-perftools-2.1/src/tests/tcmalloc_unittest.sh google-perftools-2.2.1/src/tests/tcmalloc_unittest.sh
--- google-perftools-2.1/src/tests/tcmalloc_unittest.sh 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/tests/tcmalloc_unittest.sh 2014-04-13 03:28:02.000000000 +0200
@@ -38,17 +38,13 @@
# behavior, just performance.
BINDIR="${BINDIR:-.}"
-TCMALLOC_UNITTEST="${1:-$BINDIR}/tcmalloc_unittest"
+TCMALLOC_UNITTEST="${1:-$BINDIR/tcmalloc_unittest}"
TMPDIR=/tmp/tcmalloc_unittest
rm -rf $TMPDIR || exit 2
mkdir $TMPDIR || exit 3
-# $1: value of tcmalloc_unittest env. var.
-run_check_transfer_num_obj() {
- [ -n "$1" ] && export TCMALLOC_TRANSFER_NUM_OBJ="$1"
-
- echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_TRANSFER_NUM_OBJ=$1 ... "
+run_unittest() {
if $TCMALLOC_UNITTEST > $TMPDIR/output 2>&1; then
echo "OK"
else
@@ -61,8 +57,20 @@
fi
}
+# $1: value of tcmalloc_unittest env. var.
+run_check_transfer_num_obj() {
+ [ -n "$1" ] && export TCMALLOC_TRANSFER_NUM_OBJ="$1"
+
+ echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_TRANSFER_NUM_OBJ=$1 ... "
+ run_unittest
+}
+
run_check_transfer_num_obj ""
run_check_transfer_num_obj "40"
run_check_transfer_num_obj "4096"
+echo -n "Testing $TCMALLOC_UNITTEST with TCMALLOC_AGGRESSIVE_DECOMMIT=t ... "
+
+TCMALLOC_AGGRESSIVE_DECOMMIT=t run_unittest
+
echo "PASS"
diff -Nru google-perftools-2.1/src/tests/testutil.cc google-perftools-2.2.1/src/tests/testutil.cc
--- google-perftools-2.1/src/tests/testutil.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/testutil.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/testutil.h google-perftools-2.2.1/src/tests/testutil.h
--- google-perftools-2.1/src/tests/testutil.h 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/testutil.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/tests/thread_dealloc_unittest.cc google-perftools-2.2.1/src/tests/thread_dealloc_unittest.cc
--- google-perftools-2.1/src/tests/thread_dealloc_unittest.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/tests/thread_dealloc_unittest.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2004, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/thread_cache.cc google-perftools-2.2.1/src/thread_cache.cc
--- google-perftools-2.1/src/thread_cache.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/thread_cache.cc 2014-06-21 21:12:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
@@ -37,19 +38,24 @@
#include // for max, min
#include "base/commandlineflags.h" // for SpinLockHolder
#include "base/spinlock.h" // for SpinLockHolder
+#include "getenv_safe.h" // for TCMallocGetenvSafe
#include "central_freelist.h" // for CentralFreeListPadded
#include "maybe_threads.h"
using std::min;
using std::max;
-DEFINE_int64(tcmalloc_max_total_thread_cache_bytes,
- EnvToInt64("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES",
- kDefaultOverallThreadCacheSize),
- "Bound on the total amount of bytes allocated to "
- "thread caches. This bound is not strict, so it is possible "
- "for the cache to go over this bound in certain circumstances. "
- "Maximum value of this flag is capped to 1 GB.");
+// Note: this is initialized manually in InitModule to ensure that
+// it's configured at right time
+//
+// DEFINE_int64(tcmalloc_max_total_thread_cache_bytes,
+// EnvToInt64("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES",
+// kDefaultOverallThreadCacheSize),
+// "Bound on the total amount of bytes allocated to "
+// "thread caches. This bound is not strict, so it is possible "
+// "for the cache to go over this bound in certain circumstances. "
+// "Maximum value of this flag is capped to 1 GB.");
+
namespace tcmalloc {
@@ -308,6 +314,10 @@
void ThreadCache::InitModule() {
SpinLockHolder h(Static::pageheap_lock());
if (!phinited) {
+ const char *tcb = TCMallocGetenvSafe("TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES");
+ if (tcb) {
+ set_overall_thread_cache_size(strtoll(tcb, NULL, 10));
+ }
Static::InitStaticVars();
threadcache_allocator.Init();
phinited = 1;
diff -Nru google-perftools-2.1/src/thread_cache.h google-perftools-2.2.1/src/thread_cache.h
--- google-perftools-2.1/src/thread_cache.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/thread_cache.h 2014-06-21 21:12:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/windows/auto_testing_hook.h google-perftools-2.2.1/src/windows/auto_testing_hook.h
--- google-perftools-2.1/src/windows/auto_testing_hook.h 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/auto_testing_hook.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff -Nru google-perftools-2.1/src/windows/config.h google-perftools-2.2.1/src/windows/config.h
--- google-perftools-2.1/src/windows/config.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/config.h 2014-06-22 00:52:34.000000000 +0200
@@ -1,4 +1,8 @@
-/* A manual version of config.h fit for windows machines. */
+/* A manual version of config.h fit for windows machines.
+ *
+ * Use of this source code is governed by a BSD-style license that can
+ * be found in the LICENSE file.
+ */
/* Sometimes we accidentally #include this config.h instead of the one
in .. -- this is particularly true for msys/mingw, which uses the
@@ -222,7 +226,7 @@
#define PACKAGE_NAME "gperftools"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gperftools 2.1"
+#define PACKAGE_STRING "gperftools 2.2.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "gperftools"
@@ -231,7 +235,7 @@
#undef PACKAGE_URL
/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.1"
+#define PACKAGE_VERSION "2.2.1"
/* How to access the PC from a struct ucontext */
#undef PC_FROM_UCONTEXT
diff -Nru google-perftools-2.1/src/windows/get_mangled_names.cc google-perftools-2.2.1/src/windows/get_mangled_names.cc
--- google-perftools-2.1/src/windows/get_mangled_names.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/get_mangled_names.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/windows/gperftools/tcmalloc.h google-perftools-2.2.1/src/windows/gperftools/tcmalloc.h
--- google-perftools-2.1/src/windows/gperftools/tcmalloc.h 2013-07-30 11:12:44.000000000 +0200
+++ google-perftools-2.2.1/src/windows/gperftools/tcmalloc.h 2014-06-22 00:53:07.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2003, Google Inc.
* All rights reserved.
*
@@ -49,9 +50,9 @@
// Define the version number so folks can check against it
#define TC_VERSION_MAJOR 2
-#define TC_VERSION_MINOR 1
-#define TC_VERSION_PATCH ""
-#define TC_VERSION_STRING "gperftools 2.1"
+#define TC_VERSION_MINOR 2
+#define TC_VERSION_PATCH ".1"
+#define TC_VERSION_STRING "gperftools 2.2.1"
#include // for struct mallinfo, if it's defined
@@ -78,6 +79,7 @@
const char** patch) __THROW;
PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) __THROW;
PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW;
PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW;
PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) __THROW;
diff -Nru google-perftools-2.1/src/windows/gperftools/tcmalloc.h.in google-perftools-2.2.1/src/windows/gperftools/tcmalloc.h.in
--- google-perftools-2.1/src/windows/gperftools/tcmalloc.h.in 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/gperftools/tcmalloc.h.in 2014-04-13 03:35:40.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2003, Google Inc.
* All rights reserved.
*
@@ -78,6 +79,7 @@
const char** patch) __THROW;
PERFTOOLS_DLL_DECL void* tc_malloc(size_t size) __THROW;
+ PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) __THROW;
PERFTOOLS_DLL_DECL void tc_free(void* ptr) __THROW;
PERFTOOLS_DLL_DECL void* tc_realloc(void* ptr, size_t size) __THROW;
PERFTOOLS_DLL_DECL void* tc_calloc(size_t nmemb, size_t size) __THROW;
diff -Nru google-perftools-2.1/src/windows/mingw.h google-perftools-2.2.1/src/windows/mingw.h
--- google-perftools-2.1/src/windows/mingw.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/mingw.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
@@ -58,7 +59,9 @@
// Some mingw distributions have a pthreads wrapper, but it doesn't
// work as well as native windows spinlocks (at least for us). So
// pretend the pthreads wrapper doesn't exist, even when it does.
+#ifndef HAVE_PTHREAD_DESPITE_ASKING_FOR
#undef HAVE_PTHREAD
+#endif
#define HAVE_PID_T
diff -Nru google-perftools-2.1/src/windows/mini_disassembler.cc google-perftools-2.2.1/src/windows/mini_disassembler.cc
--- google-perftools-2.1/src/windows/mini_disassembler.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/mini_disassembler.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/windows/mini_disassembler.h google-perftools-2.2.1/src/windows/mini_disassembler.h
--- google-perftools-2.1/src/windows/mini_disassembler.h 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/mini_disassembler.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/windows/mini_disassembler_types.h google-perftools-2.2.1/src/windows/mini_disassembler_types.h
--- google-perftools-2.1/src/windows/mini_disassembler_types.h 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/mini_disassembler_types.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/windows/override_functions.cc google-perftools-2.2.1/src/windows/override_functions.cc
--- google-perftools-2.1/src/windows/override_functions.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/override_functions.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
// Copyright (c) 2007, Google Inc.
// All rights reserved.
//
diff -Nru google-perftools-2.1/src/windows/patch_functions.cc google-perftools-2.2.1/src/windows/patch_functions.cc
--- google-perftools-2.1/src/windows/patch_functions.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/patch_functions.cc 2014-06-07 22:54:00.000000000 +0200
@@ -548,13 +548,10 @@
if (windows_fn_[i] && windows_fn_[i] != perftools_fn_[i]) {
// if origstub_fn_ is not NULL, it's left around from a previous
// patch. We need to set it to NULL for the new Patch call.
- // Since we've patched Unpatch() not to delete origstub_fn_ (it
- // causes problems in some contexts, though obviously not this
- // one), we should delete it now, before setting it to NULL.
- // NOTE: casting from a function to a pointer is contra the C++
- // spec. It's not safe on IA64, but is on i386. We use
- // a C-style cast here to emphasize this is not legal C++.
- delete[] (char*)(origstub_fn_[i]);
+ //
+ // Note that origstub_fn_ was logically freed by
+ // PreamblePatcher::Unpatch, so we don't have to do anything
+ // about it.
origstub_fn_[i] = NULL; // Patch() will fill this in
CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
PreamblePatcher::Patch(windows_fn_[i], perftools_fn_[i],
diff -Nru google-perftools-2.1/src/windows/port.cc google-perftools-2.2.1/src/windows/port.cc
--- google-perftools-2.1/src/windows/port.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/port.cc 2014-06-21 21:12:02.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
@@ -40,12 +41,12 @@
#include // for strlen(), memset(), memcmp()
#include
#include // for va_list, va_start, va_end
+#include // for std:{min,max}
#include
#include "port.h"
#include "base/logging.h"
#include "base/spinlock.h"
#include "internal_logging.h"
-#include "system-alloc.h"
// -----------------------------------------------------------------------
// Basic libraries
@@ -216,68 +217,6 @@
}
-// -----------------------------------------------------------------------
-// These functions replace system-alloc.cc
-
-// The current system allocator declaration (unused here)
-SysAllocator* sys_alloc = NULL;
-// Number of bytes taken from system.
-size_t TCMalloc_SystemTaken = 0;
-
-// This is mostly like MmapSysAllocator::Alloc, except it does these weird
-// munmap's in the middle of the page, which is forbidden in windows.
-extern PERFTOOLS_DLL_DECL
-void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
- size_t alignment) {
- // Align on the pagesize boundary
- const int pagesize = getpagesize();
- if (alignment < pagesize) alignment = pagesize;
- size = ((size + alignment - 1) / alignment) * alignment;
-
- // Safest is to make actual_size same as input-size.
- if (actual_size) {
- *actual_size = size;
- }
-
- // Ask for extra memory if alignment > pagesize
- size_t extra = 0;
- if (alignment > pagesize) {
- extra = alignment - pagesize;
- }
-
- void* result = VirtualAlloc(0, size + extra,
- MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
- if (result == NULL)
- return NULL;
-
- TCMalloc_SystemTaken += size + extra;
-
- // Adjust the return memory so it is aligned
- uintptr_t ptr = reinterpret_cast(result);
- size_t adjust = 0;
- if ((ptr & (alignment - 1)) != 0) {
- adjust = alignment - (ptr & (alignment - 1));
- }
-
- ptr += adjust;
- return reinterpret_cast(ptr);
-}
-
-extern PERFTOOLS_DLL_DECL
-bool TCMalloc_SystemRelease(void* start, size_t length) {
- // TODO(csilvers): should I be calling VirtualFree here?
- return false;
-}
-
-bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
- return false; // we don't allow registration on windows, right now
-}
-
-void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
- // We don't dump stats on windows, right now
-}
-
-
// -----------------------------------------------------------------------
// These functions rework existing functions of the same name in the
// Google codebase.
diff -Nru google-perftools-2.1/src/windows/port.h google-perftools-2.2.1/src/windows/port.h
--- google-perftools-2.1/src/windows/port.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/port.h 2014-02-22 21:25:25.000000000 +0100
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
@@ -132,7 +133,14 @@
return left == right;
}
+/*
+ * windows/port.h defines compatibility APIs for several .h files, which
+ * we therefore shouldn't be #including directly. This hack keeps us from
+ * doing so. TODO(csilvers): do something more principled.
+ */
+#define GOOGLE_MAYBE_THREADS_H_ 1
/* This replaces maybe_threads.{h,cc} */
+
EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); /* port.cc */
inline int perftools_pthread_key_create(pthread_key_t *pkey,
@@ -164,12 +172,13 @@
void (*init_routine)(void));
#endif /* __cplusplus */
-#endif /* HAVE_PTHREAD */
inline void sched_yield(void) {
Sleep(0);
}
+#endif /* HAVE_PTHREAD */
+
/*
* __declspec(thread) isn't usable in a dll opened via LoadLibrary().
* But it doesn't work to LoadLibrary() us anyway, because of all the
@@ -447,6 +456,7 @@
#endif
#ifndef __MINGW32__
+#if _MSC_VER < 1800
inline long long int strtoll(const char *nptr, char **endptr, int base) {
return _strtoi64(nptr, endptr, base);
}
@@ -457,6 +467,7 @@
inline long long int strtoq(const char *nptr, char **endptr, int base) {
return _strtoi64(nptr, endptr, base);
}
+#endif
inline unsigned long long int strtouq(const char *nptr, char **endptr,
int base) {
return _strtoui64(nptr, endptr, base);
@@ -473,16 +484,6 @@
/* tcmalloc.cc calls this so we can patch VirtualAlloc() et al. */
extern void PatchWindowsFunctions();
-// ----------------------------------- BUILD-SPECIFIC
-
-/*
- * windows/port.h defines compatibility APIs for several .h files, which
- * we therefore shouldn't be #including directly. This hack keeps us from
- * doing so. TODO(csilvers): do something more principled.
- */
-#define GOOGLE_MAYBE_THREADS_H_ 1
-
-
#endif /* _WIN32 */
#undef inline
diff -Nru google-perftools-2.1/src/windows/preamble_patcher.cc google-perftools-2.2.1/src/windows/preamble_patcher.cc
--- google-perftools-2.1/src/windows/preamble_patcher.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/preamble_patcher.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/windows/preamble_patcher.h google-perftools-2.2.1/src/windows/preamble_patcher.h
--- google-perftools-2.1/src/windows/preamble_patcher.h 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/preamble_patcher.h 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/windows/preamble_patcher_test.cc google-perftools-2.2.1/src/windows/preamble_patcher_test.cc
--- google-perftools-2.1/src/windows/preamble_patcher_test.cc 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/src/windows/preamble_patcher_test.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2011, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/windows/preamble_patcher_with_stub.cc google-perftools-2.2.1/src/windows/preamble_patcher_with_stub.cc
--- google-perftools-2.1/src/windows/preamble_patcher_with_stub.cc 2013-07-30 11:12:11.000000000 +0200
+++ google-perftools-2.2.1/src/windows/preamble_patcher_with_stub.cc 2013-09-22 04:03:49.000000000 +0200
@@ -1,3 +1,4 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
/* Copyright (c) 2007, Google Inc.
* All rights reserved.
*
diff -Nru google-perftools-2.1/src/windows/system-alloc.cc google-perftools-2.2.1/src/windows/system-alloc.cc
--- google-perftools-2.1/src/windows/system-alloc.cc 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/windows/system-alloc.cc 2014-03-29 21:24:54.000000000 +0100
@@ -0,0 +1,204 @@
+// Copyright (c) 2013, Google Inc.
+// 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 Google Inc. 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.
+
+// ---
+// Author: Petr Hosek
+
+#ifndef _WIN32
+# error You should only be including windows/system-alloc.cc in a windows environment!
+#endif
+
+#include
+#include
+#include // std::min
+#include
+#include "base/logging.h"
+#include "base/spinlock.h"
+#include "internal_logging.h"
+#include "system-alloc.h"
+
+static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
+
+// The current system allocator declaration
+SysAllocator* sys_alloc = NULL;
+// Number of bytes taken from system.
+size_t TCMalloc_SystemTaken = 0;
+
+class VirtualSysAllocator : public SysAllocator {
+public:
+ VirtualSysAllocator() : SysAllocator() {
+ }
+ void* Alloc(size_t size, size_t *actual_size, size_t alignment);
+};
+static char virtual_space[sizeof(VirtualSysAllocator)];
+
+// This is mostly like MmapSysAllocator::Alloc, except it does these weird
+// munmap's in the middle of the page, which is forbidden in windows.
+void* VirtualSysAllocator::Alloc(size_t size, size_t *actual_size,
+ size_t alignment) {
+ // Align on the pagesize boundary
+ const int pagesize = getpagesize();
+ if (alignment < pagesize) alignment = pagesize;
+ size = ((size + alignment - 1) / alignment) * alignment;
+
+ // Report the total number of bytes the OS actually delivered. This might be
+ // greater than |size| because of alignment concerns. The full size is
+ // necessary so that adjacent spans can be coalesced.
+ // TODO(antonm): proper processing of alignments
+ // in actual_size and decommitting.
+ if (actual_size) {
+ *actual_size = size;
+ }
+
+ // We currently do not support alignments larger than the pagesize or
+ // alignments that are not multiples of the pagesize after being floored.
+ // If this ability is needed it can be done by the caller (assuming it knows
+ // the page size).
+ assert(alignment <= pagesize);
+
+ void* result = VirtualAlloc(0, size,
+ MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
+ if (result == NULL)
+ return NULL;
+
+ // If the result is not aligned memory fragmentation will result which can
+ // lead to pathological memory use.
+ assert((reinterpret_cast(result) & (alignment - 1)) == 0);
+
+ return result;
+}
+
+#ifdef _MSC_VER
+
+extern "C" SysAllocator* tc_get_sysalloc_override(SysAllocator *def);
+extern "C" SysAllocator* tc_get_sysalloc_default(SysAllocator *def)
+{
+ return def;
+}
+
+#if defined(_M_IX86)
+#pragma comment(linker, "/alternatename:_tc_get_sysalloc_override=_tc_get_sysalloc_default")
+#elif defined(_M_X64)
+#pragma comment(linker, "/alternatename:tc_get_sysalloc_override=tc_get_sysalloc_default")
+#endif
+
+#else // !_MSC_VER
+
+extern "C" ATTRIBUTE_NOINLINE
+SysAllocator* tc_get_sysalloc_override(SysAllocator *def)
+{
+ return def;
+}
+
+#endif
+
+static bool system_alloc_inited = false;
+void InitSystemAllocators(void) {
+ VirtualSysAllocator *alloc = new (virtual_space) VirtualSysAllocator();
+ sys_alloc = tc_get_sysalloc_override(alloc);
+}
+
+extern PERFTOOLS_DLL_DECL
+void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size,
+ size_t alignment) {
+ SpinLockHolder lock_holder(&spinlock);
+
+ if (!system_alloc_inited) {
+ InitSystemAllocators();
+ system_alloc_inited = true;
+ }
+
+ void* result = sys_alloc->Alloc(size, actual_size, alignment);
+ if (result != NULL) {
+ if (actual_size) {
+ TCMalloc_SystemTaken += *actual_size;
+ } else {
+ TCMalloc_SystemTaken += size;
+ }
+ }
+ return result;
+}
+
+extern PERFTOOLS_DLL_DECL
+bool TCMalloc_SystemRelease(void* start, size_t length) {
+ if (VirtualFree(start, length, MEM_DECOMMIT))
+ return true;
+
+ // The decommit may fail if the memory region consists of allocations
+ // from more than one call to VirtualAlloc. In this case, fall back to
+ // using VirtualQuery to retrieve the allocation boundaries and decommit
+ // them each individually.
+
+ char* ptr = static_cast(start);
+ char* end = ptr + length;
+ MEMORY_BASIC_INFORMATION info;
+ while (ptr < end) {
+ size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
+ assert(resultSize == sizeof(info));
+ size_t decommitSize = std::min(info.RegionSize, end - ptr);
+ BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT);
+ assert(success == TRUE);
+ ptr += decommitSize;
+ }
+
+ return true;
+}
+
+extern PERFTOOLS_DLL_DECL
+void TCMalloc_SystemCommit(void* start, size_t length) {
+ if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start)
+ return;
+
+ // The commit may fail if the memory region consists of allocations
+ // from more than one call to VirtualAlloc. In this case, fall back to
+ // using VirtualQuery to retrieve the allocation boundaries and commit them
+ // each individually.
+
+ char* ptr = static_cast(start);
+ char* end = ptr + length;
+ MEMORY_BASIC_INFORMATION info;
+ while (ptr < end) {
+ size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
+ assert(resultSize == sizeof(info));
+
+ size_t commitSize = std::min(info.RegionSize, end - ptr);
+ void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT,
+ PAGE_READWRITE);
+ assert(newAddress == ptr);
+ ptr += commitSize;
+ }
+}
+
+bool RegisterSystemAllocator(SysAllocator *allocator, int priority) {
+ return false; // we don't allow registration on windows, right now
+}
+
+void DumpSystemAllocatorStats(TCMalloc_Printer* printer) {
+ // We don't dump stats on windows, right now
+}
diff -Nru google-perftools-2.1/src/windows/TODO google-perftools-2.2.1/src/windows/TODO
--- google-perftools-2.1/src/windows/TODO 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/src/windows/TODO 2013-05-25 23:42:55.000000000 +0200
@@ -0,0 +1,86 @@
+* Get heap-profile-table.cc using DeleteMatchingFiles
+* Get heap-profile-table.cc using FillProcSelfMaps, DumpProcSelfMaps
+* Play around with ExperimentalGetStackTrace
+* Support the windows-level memory-allocation functions? See
+ /home/build/googleclient/earth/client/tools/memorytracking/client/memorytrace/src/memorytrace.cpp
+ /home/build/googleclient/total_recall/common/sitestep/*
+ http://www.internals.com/articles/apispy/apispy.htm
+ http://www.wheaty.net/APISPY32.zip
+* Verify /proc/xxx/maps:
+ http://www.geocities.com/wah_java_dotnet/procmap/index.html
+* Figure out how to edit the executable IAT so tcmalloc.dll is loaded first
+* Use QueryPerformanceCounter instead of GetTickCount() (also for sparsehash)
+
+----
+More info on windows-level memory-allocation functions:
+ C runtime malloc
+ LocalAlloc
+ GlobalAlloc
+ HeapAlloc
+ VirtualAlloc
+ mmap stuff
+
+malloc, LocalAlloc and GlobalAlloc call HeapAlloc, which calls
+VirtualAlloc when needed, which calls VirtualAllocEx (the __sbrk equiv?)
+
+siggi sez: If you want to do a generic job, you probably need to
+preserve the semantics of all of these Win32 calls:
+ Heap32First
+ Heap32ListFirst
+ Heap32ListNext
+ Heap32Next
+ HeapAlloc
+ HeapCompact
+ HeapCreate
+ HeapCreateTagsW
+ HeapDestroy
+ HeapExtend
+ HeapFree
+ HeapLock
+ HeapQueryInformation
+ HeapQueryTagW
+ HeapReAlloc
+ HeapSetInformation
+ HeapSize
+ HeapSummary
+ HeapUnlock
+ HeapUsage
+ HeapValidate
+ HeapWalk
+
+kernel32.dll export functions and nt.dll export functions:
+ http://www.shorthike.com/svn/trunk/tools_win32/dm/lib/kernel32.def
+ http://undocumented.ntinternals.net/
+
+You can edit the executable IAT to have the patching DLL be the
+first one loaded.
+
+Most complete way to intercept system calls is patch the functions
+(not the IAT).
+
+Microsoft has somee built-in routines for heap-checking:
+ http://support.microsoft.com/kb/268343
+
+----
+Itimer replacement:
+ http://msdn2.microsoft.com/en-us/library/ms712713.aspx
+
+----
+Changes I've had to make to the project file:
+
+0) When creating the project file, click on "no autogenerated files"
+
+--- For each project:
+1) Alt-F7 -> General -> [pulldown "all configurations" ] -> Output Directory -> $(SolutionDir)$(ConfigurationName)
+2) Alt-F7 -> General -> [pulldown "all configurations" ] -> Intermediate Directory -> $(ConfigurationName)
+
+--- For each .cc file:
+1) Alt-F7 -> C/C++ -> General -> [pulldown "all configurations"] -> Additional Include Directives --> src/windows + src/
+2) Alt-F7 -> C/C++ -> Code Generation -> Runtime Library -> Multi-threaded, debug/release, DLL or not
+
+--- For DLL:
+3) Alt-F7 -> Linker -> Input -> [pulldown "all configurations" ] -> Module Definition File -> src\windows\vc7and8.def
+--- For binaries depending on a DLL:
+3) Right-click on project -> Project Dependencies -> [add dll]
+--- For static binaries (not depending on a DLL)
+3) Alt-F7 -> C/C++ -> Command Line -> [pulldown "all configurations"] -> /D PERFTOOLS_DLL_DECL=
diff -Nru google-perftools-2.1/test-driver google-perftools-2.2.1/test-driver
--- google-perftools-2.1/test-driver 2013-07-30 11:12:29.000000000 +0200
+++ google-perftools-2.2.1/test-driver 2014-06-22 00:52:50.000000000 +0200
@@ -1,7 +1,7 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
-scriptversion=2012-06-27.10; # UTC
+scriptversion=2013-07-13.22; # UTC
# Copyright (C) 2011-2013 Free Software Foundation, Inc.
#
@@ -44,13 +44,12 @@
Usage:
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
[--expect-failure={yes|no}] [--color-tests={yes|no}]
- [--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
+ [--enable-hard-errors={yes|no}] [--]
+ TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
END
}
-# TODO: better error handling in option parsing (in particular, ensure
-# TODO: $log_file, $trs_file and $test_name are defined).
test_name= # Used for reporting.
log_file= # Where to save the output of the test script.
trs_file= # Where to save the metadata of the test run.
@@ -69,10 +68,23 @@
--enable-hard-errors) enable_hard_errors=$2; shift;;
--) shift; break;;
-*) usage_error "invalid option: '$1'";;
+ *) break;;
esac
shift
done
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file" = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+ usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+ usage_error "missing argument"
+fi
+
if test $color_tests = yes; then
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
red='[0;31m' # Red.
diff -Nru google-perftools-2.1/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj google-perftools-2.2.1/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj
--- google-perftools-2.1/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcproj 2013-09-22 03:14:21.000000000 +0200
@@ -453,6 +453,23 @@
+
+
+
+
+
+
+
+
diff -Nru google-perftools-2.1/vsprojects/system-alloc_unittest/system-alloc_unittest.vcproj google-perftools-2.2.1/vsprojects/system-alloc_unittest/system-alloc_unittest.vcproj
--- google-perftools-2.1/vsprojects/system-alloc_unittest/system-alloc_unittest.vcproj 1970-01-01 01:00:00.000000000 +0100
+++ google-perftools-2.2.1/vsprojects/system-alloc_unittest/system-alloc_unittest.vcproj 2013-09-22 03:14:21.000000000 +0200
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru google-perftools-2.1/vsprojects/tmu-static/tmu-static.vcproj google-perftools-2.2.1/vsprojects/tmu-static/tmu-static.vcproj
--- google-perftools-2.1/vsprojects/tmu-static/tmu-static.vcproj 2013-07-29 05:20:41.000000000 +0200
+++ google-perftools-2.2.1/vsprojects/tmu-static/tmu-static.vcproj 2013-09-22 03:14:21.000000000 +0200
@@ -489,6 +489,25 @@
+
+
+
+
+
+
+
+