summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAliaksey Kandratsenka <alkondratenko@gmail.com>2015-10-04 21:12:28 -0700
committerAliaksey Kandratsenka <alkondratenko@gmail.com>2015-10-05 21:07:00 -0700
commit1e7b733a217b2e92f6188b27951dfaf22ac1e2f3 (patch)
tree5f2924633f980b63e47713d6ea49160260cf41da
parentfdb443e8e5fc5115b68da3be8201d3bef0722ba4 (diff)
downloadgperftools-wip-from-alk-for-review.tar.gz
implemented (disabled by default) sized delete supportwip-from-alk-for-review
gcc 5 and clang++-3.7 support sized deallocation from C++14. We are taking advantage of that by defining sized versions of operator delete. This is off by default so that if some existing programs that define own global operator delete without sized variant are not broken by tcmalloc's sized delete operator. There is also risk of breaking exiting code that deletes objects using wrong class (i.e. base class) without having virtual destructors.
-rw-r--r--configure.ac32
-rw-r--r--src/gperftools/tcmalloc.h.in2
-rw-r--r--src/libc_override_gcc_and_weak.h7
-rw-r--r--src/libc_override_redefine.h6
-rw-r--r--src/tcmalloc.cc18
-rw-r--r--src/windows/gperftools/tcmalloc.h2
-rw-r--r--src/windows/gperftools/tcmalloc.h.in2
7 files changed, 59 insertions, 10 deletions
diff --git a/configure.ac b/configure.ac
index 1148c21..321a0f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -323,16 +323,28 @@ AC_CACHE_CHECK([if the compiler supports -Wno-unused-result],
AM_CONDITIONAL(HAVE_W_NO_UNUSED_RESULT,
test "$perftools_cv_w_no_unused_result" = yes)
-AC_CACHE_CHECK([if C++ compiler supports -fsized-deallocation],
- perftools_cv_sized_deallocation_result,
- [AC_LANG_PUSH(C++)
- OLD_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS="$CXXFLAGS -fsized-deallocation"
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,)],
- perftools_cv_sized_deallocation_result=yes,
- perftools_cv_sized_deallocation_result=no)
- CXXFLAGS="$OLD_CXXFLAGS"
- AC_LANG_POP(C++)])
+AC_ARG_ENABLE([sized-delete],
+ [AS_HELP_STRING([--enable-sized-delete],
+ [build sized delete operator])],
+ [enable_sized_delete="$enableval"],
+ [enable_sized_delete="no"])
+AS_IF([test "x$enable_sized_delete" = xyes],
+ [AC_DEFINE([ENABLE_SIZED_DELETE], 1, [Build sized deletion operators])
+ AC_MSG_NOTICE([Will build sized deallocation operators])],
+ [AC_MSG_NOTICE([Will not build sized deallocation operators])])
+
+AS_IF([test "x$enable_sized_delete" = xyes],
+ [AC_CACHE_CHECK([if C++ compiler supports -fsized-deallocation],
+ perftools_cv_sized_deallocation_result,
+ [AC_LANG_PUSH(C++)
+ OLD_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -fsized-deallocation"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,)],
+ perftools_cv_sized_deallocation_result="$enable_sized_delete",
+ perftools_cv_sized_deallocation_result=no)
+ CXXFLAGS="$OLD_CXXFLAGS"
+ AC_LANG_POP(C++)])])
+
AM_CONDITIONAL(HAVE_SIZED_DEALLOCATION,
test "$perftools_cv_sized_deallocation_result" = yes)
diff --git a/src/gperftools/tcmalloc.h.in b/src/gperftools/tcmalloc.h.in
index 0334d3f..0eaa21a 100644
--- a/src/gperftools/tcmalloc.h.in
+++ b/src/gperftools/tcmalloc.h.in
@@ -122,12 +122,14 @@ extern "C" {
PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) throw();
PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) throw();
PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
const std::nothrow_t&) __THROW;
}
diff --git a/src/libc_override_gcc_and_weak.h b/src/libc_override_gcc_and_weak.h
index 818e43d..5c0def2 100644
--- a/src/libc_override_gcc_and_weak.h
+++ b/src/libc_override_gcc_and_weak.h
@@ -71,6 +71,13 @@ void operator delete(void* p, const std::nothrow_t& nt) __THROW
void operator delete[](void* p, const std::nothrow_t& nt) __THROW
ALIAS(tc_deletearray_nothrow);
+#ifdef ENABLE_SIZED_DELETE
+void operator delete(void *p, size_t size) throw()
+ ALIAS(tc_delete_sized);
+void operator delete[](void *p, size_t size) throw()
+ ALIAS(tc_deletearray_sized);
+#endif
+
extern "C" {
void* malloc(size_t size) __THROW ALIAS(tc_malloc);
void free(void* ptr) __THROW ALIAS(tc_free);
diff --git a/src/libc_override_redefine.h b/src/libc_override_redefine.h
index a1e50f8..4c61116 100644
--- a/src/libc_override_redefine.h
+++ b/src/libc_override_redefine.h
@@ -66,6 +66,12 @@ void operator delete(void* ptr, const std::nothrow_t& nt) __THROW {
void operator delete[](void* ptr, const std::nothrow_t& nt) __THROW {
return tc_deletearray_nothrow(ptr, nt);
}
+
+#ifdef ENABLE_SIZED_DELETE
+void operator delete(void* p, size_t s) __THROW { tc_delete_sized(p, s); }
+void operator delete[](void* p, size_t s) __THROW{ tc_deletearray_sized(p); }
+#endif
+
extern "C" {
void* malloc(size_t s) __THROW { return tc_malloc(s); }
void free(void* p) __THROW { tc_free(p); }
diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc
index f168dfd..d1e7167 100644
--- a/src/tcmalloc.cc
+++ b/src/tcmalloc.cc
@@ -1595,6 +1595,24 @@ extern "C" PERFTOOLS_DLL_DECL void tc_free_sized(void *ptr, size_t size) __THROW
do_free_with_callback(ptr, &InvalidFree, true, size);
}
+#if defined(__GNUC__) && !defined(WIN32)
+
+extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) throw()
+ __attribute__((alias("tc_free_sized")));
+extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) throw()
+ __attribute__((alias("tc_free_sized")));
+
+#else
+
+extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized(void *p, size_t size) throw() {
+ tc_free_sized(p, size);
+}
+extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_sized(void *p, size_t size) throw() {
+ tc_free_sized(p, size);
+}
+
+#endif
+
extern "C" PERFTOOLS_DLL_DECL void* tc_calloc(size_t n,
size_t elem_size) __THROW {
void* result = do_calloc(n, elem_size);
diff --git a/src/windows/gperftools/tcmalloc.h b/src/windows/gperftools/tcmalloc.h
index 5867c7c..9c4753f 100644
--- a/src/windows/gperftools/tcmalloc.h
+++ b/src/windows/gperftools/tcmalloc.h
@@ -112,12 +112,14 @@ extern "C" {
PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) throw();
PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) throw();
PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
const std::nothrow_t&) __THROW;
}
diff --git a/src/windows/gperftools/tcmalloc.h.in b/src/windows/gperftools/tcmalloc.h.in
index a7ec70f..c963e31 100644
--- a/src/windows/gperftools/tcmalloc.h.in
+++ b/src/windows/gperftools/tcmalloc.h.in
@@ -112,12 +112,14 @@ extern "C" {
PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_delete_sized(void* p, size_t size) throw();
PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void* tc_newarray(size_t size);
PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size,
const std::nothrow_t&) __THROW;
PERFTOOLS_DLL_DECL void tc_deletearray(void* p) __THROW;
+ PERFTOOLS_DLL_DECL void tc_deletearray_sized(void* p, size_t size) throw();
PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p,
const std::nothrow_t&) __THROW;
}