commit
296d692eda
@ -1,64 +0,0 @@
|
||||
From 893bff51bcf220b724a812d340d878b5fb8ce911 Mon Sep 17 00:00:00 2001
|
||||
From: Aliaksey Kandratsenka <alkondratenko@gmail.com>
|
||||
Date: Sun, 26 Aug 2018 11:35:44 -0700
|
||||
Subject: [PATCH 23/39] Avoid static initialization of pprof path for
|
||||
symbolization.
|
||||
|
||||
This is one of the things that chrome's fork fixes, but with c++11 we
|
||||
can do it even nicer. Proposed fix is to use c++11 local static
|
||||
variable to ensure that pprof path is initialized once on as-needed
|
||||
basis.
|
||||
---
|
||||
src/symbolize.cc | 20 +++++++++++---------
|
||||
1 file changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/symbolize.cc b/src/symbolize.cc
|
||||
index 88609ff..4c71010 100755
|
||||
--- a/src/symbolize.cc
|
||||
+++ b/src/symbolize.cc
|
||||
@@ -67,15 +67,17 @@
|
||||
using std::string;
|
||||
using tcmalloc::DumpProcSelfMaps; // from sysinfo.h
|
||||
|
||||
-
|
||||
-DEFINE_string(symbolize_pprof,
|
||||
- EnvToString("PPROF_PATH", "pprof"),
|
||||
- "Path to pprof to call for reporting function names.");
|
||||
-
|
||||
-// heap_profile_table_pprof may be referenced after destructors are
|
||||
+// pprof may be used after destructors are
|
||||
// called (since that's when leak-checking is done), so we make
|
||||
// a more-permanent copy that won't ever get destroyed.
|
||||
-static string* g_pprof_path = new string(FLAGS_symbolize_pprof);
|
||||
+static char* get_pprof_path() {
|
||||
+ static char* result = ([] () {
|
||||
+ string pprof_string = EnvToString("PPROF_PATH", "pprof");
|
||||
+ return strdup(pprof_string.c_str());
|
||||
+ })();
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
|
||||
// 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.
|
||||
@@ -144,7 +146,7 @@ int SymbolTable::Symbolize() {
|
||||
PrintError("Cannot figure out the name of this executable (argv0)");
|
||||
return 0;
|
||||
}
|
||||
- if (access(g_pprof_path->c_str(), R_OK) != 0) {
|
||||
+ if (access(get_pprof_path(), R_OK) != 0) {
|
||||
PrintError("Cannot find 'pprof' (is PPROF_PATH set correctly?)");
|
||||
return 0;
|
||||
}
|
||||
@@ -206,7 +208,7 @@ int SymbolTable::Symbolize() {
|
||||
unsetenv("HEAPPROFILE");
|
||||
unsetenv("HEAPCHECK");
|
||||
unsetenv("PERFTOOLS_VERBOSE");
|
||||
- execlp(g_pprof_path->c_str(), g_pprof_path->c_str(),
|
||||
+ execlp(get_pprof_path(), get_pprof_path(),
|
||||
"--symbols", argv0, NULL);
|
||||
_exit(3); // if execvp fails, it's bad news for us
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,70 +0,0 @@
|
||||
From fe87ffb7ea5a7c6ce4dea45222331716907ddbf4 Mon Sep 17 00:00:00 2001
|
||||
From: Junhao Li <streaver91@gmail.com>
|
||||
Date: Sun, 20 May 2018 13:45:32 -0400
|
||||
Subject: [PATCH] Disable large allocation report by default
|
||||
|
||||
Fixes issue #360.
|
||||
|
||||
[alkondratenko@gmail.com: adjusted commit message a bit]
|
||||
[alkondratenko@gmail.com: adjusted configure help message]
|
||||
Signed-off-by: Aliaksey Kandratsenka <alkondratenko@gmail.com>
|
||||
---
|
||||
configure.ac | 9 +++++++++
|
||||
src/tcmalloc.cc | 4 ++++
|
||||
2 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 497103e..7b5e710 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -653,6 +653,15 @@ AC_COMPILE_IFELSE(
|
||||
AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
|
||||
+# Disable large allocation report by default.
|
||||
+AC_ARG_ENABLE([large-alloc-report],
|
||||
+ [AS_HELP_STRING([--enable-large-alloc-report],
|
||||
+ [report very large allocations to stderr])],
|
||||
+ [enable_large_alloc_report="$enableval"],
|
||||
+ [enable_large_alloc_report=no])
|
||||
+AS_IF([test "x$enable_large_alloc_report" = xyes],
|
||||
+ [AC_DEFINE([ENABLE_LARGE_ALLOC_REPORT], 1, [report large allocation])])
|
||||
+
|
||||
# Write generated configuration file
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/gperftools/tcmalloc.h src/windows/gperftools/tcmalloc.h])
|
||||
diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc
|
||||
index 7b18ddb..48d4530 100644
|
||||
--- a/src/tcmalloc.cc
|
||||
+++ b/src/tcmalloc.cc
|
||||
@@ -1272,9 +1272,11 @@ void* handle_oom(malloc_fn retry_fn,
|
||||
|
||||
// Copy of FLAGS_tcmalloc_large_alloc_report_threshold with
|
||||
// automatic increases factored in.
|
||||
+#ifdef ENABLE_LARGE_ALLOC_REPORT
|
||||
static int64_t large_alloc_threshold =
|
||||
(kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
|
||||
? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
|
||||
+#endif
|
||||
|
||||
static void ReportLargeAlloc(Length num_pages, void* result) {
|
||||
StackTrace stack;
|
||||
@@ -1295,6 +1297,7 @@ static void ReportLargeAlloc(Length num_pages, void* result) {
|
||||
|
||||
// Must be called with the page lock held.
|
||||
inline bool should_report_large(Length num_pages) {
|
||||
+#ifdef ENABLE_LARGE_ALLOC_REPORT
|
||||
const int64 threshold = large_alloc_threshold;
|
||||
if (threshold > 0 && num_pages >= (threshold >> kPageShift)) {
|
||||
// Increase the threshold by 1/8 every time we generate a report.
|
||||
@@ -1303,6 +1306,7 @@ inline bool should_report_large(Length num_pages) {
|
||||
? threshold + threshold/8 : 8ll<<30);
|
||||
return true;
|
||||
}
|
||||
+#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,196 +0,0 @@
|
||||
From 630c9ce77822212a4ce3ee92afabbec0eea0f94b Mon Sep 17 00:00:00 2001
|
||||
From: Aliaksey Kandratsenka <alkondratenko@gmail.com>
|
||||
Date: Sun, 7 Oct 2018 08:17:04 -0700
|
||||
Subject: [PATCH] Drop not very portable and not very useful unwind benchmark.
|
||||
|
||||
---
|
||||
Makefile.am | 8 ----
|
||||
benchmark/getcontext_light.cc | 60 -----------------------------
|
||||
benchmark/unwind_bench.cc | 89 -------------------------------------------
|
||||
3 files changed, 157 deletions(-)
|
||||
delete mode 100644 benchmark/getcontext_light.cc
|
||||
delete mode 100644 benchmark/unwind_bench.cc
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index c79227a..1f52d3d 100755
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -881,14 +881,6 @@ malloc_bench_shared_full_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTI
|
||||
malloc_bench_shared_full_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
|
||||
malloc_bench_shared_full_LDADD = librun_benchmark.la libtcmalloc.la $(PTHREAD_LIBS)
|
||||
|
||||
-if !OSX
|
||||
-noinst_PROGRAMS += unwind_bench
|
||||
-unwind_bench_SOURCES = benchmark/unwind_bench.cc benchmark/getcontext_light.cc
|
||||
-unwind_bench_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) $(NO_BUILTIN_CXXFLAGS)
|
||||
-unwind_bench_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS)
|
||||
-unwind_bench_LDADD = librun_benchmark.la libtcmalloc.la $(PTHREAD_LIBS)
|
||||
-endif !OSX
|
||||
-
|
||||
endif WITH_HEAP_PROFILER_OR_CHECKER
|
||||
|
||||
binary_trees_SOURCES = benchmark/binary_trees.cc
|
||||
diff --git a/benchmark/getcontext_light.cc b/benchmark/getcontext_light.cc
|
||||
deleted file mode 100644
|
||||
index e8ff8b3..0000000
|
||||
--- a/benchmark/getcontext_light.cc
|
||||
+++ /dev/null
|
||||
@@ -1,60 +0,0 @@
|
||||
-#include <ucontext.h>
|
||||
-#include <stddef.h>
|
||||
-
|
||||
-extern "C" void getcontext_light(ucontext_t *ctx);
|
||||
-
|
||||
-// clang's built-in asm cannot handle .set directives
|
||||
-#if defined(__GNUC__) && !defined(__llvm__) && defined(__x86_64) && defined(_LP64)
|
||||
-
|
||||
-#define R(r) offsetof(ucontext_t, uc_mcontext.gregs[r])
|
||||
-
|
||||
-static __attribute__((used))
|
||||
-void getcontext_tramp(ucontext_t *ctx) {
|
||||
- __asm__ __volatile__(".set oRBX, %c0\n"
|
||||
- ".set oRBP, %c1\n"
|
||||
- ".set oR12, %c2\n"
|
||||
- ".set oR13, %c3\n"
|
||||
- ".set oR14, %c4\n"
|
||||
- ".set oR15, %c5\n"
|
||||
- ".set oRIP, %c6\n"
|
||||
- ".set oRSP, %c7\n"
|
||||
- : :
|
||||
- "p" (R(REG_RBX)),
|
||||
- "p" (R(REG_RBP)),
|
||||
- "p" (R(REG_R12)),
|
||||
- "p" (R(REG_R13)),
|
||||
- "p" (R(REG_R14)),
|
||||
- "p" (R(REG_R15)),
|
||||
- "p" (R(REG_RIP)),
|
||||
- "p" (R(REG_RSP)));
|
||||
- getcontext_light(ctx);
|
||||
-}
|
||||
-
|
||||
-__asm__(".pushsection .text; .globl getcontext_light\n"
|
||||
- ".type getcontext_light, @function\n"
|
||||
-"getcontext_light:\n"
|
||||
- "\t.cfi_startproc\n"
|
||||
- "\tmovq %rbx, oRBX(%rdi)\n"
|
||||
- "\tmovq %rbp, oRBP(%rdi)\n"
|
||||
- "\tmovq %r12, oR12(%rdi)\n"
|
||||
- "\tmovq %r13, oR13(%rdi)\n"
|
||||
- "\tmovq %r14, oR14(%rdi)\n"
|
||||
- "\tmovq %r15, oR14(%rdi)\n"
|
||||
-
|
||||
- "\tmovq (%rsp), %rcx\n"
|
||||
- "\tmovq %rcx, oRIP(%rdi)\n"
|
||||
- "\tleaq 8(%rsp), %rcx\n" /* Exclude the return address. */
|
||||
- "\tmovq %rcx, oRSP(%rdi)\n"
|
||||
- "\tret\n"
|
||||
- ".cfi_endproc\n"
|
||||
- ".size getcontext_light, .-getcontext_light\n"
|
||||
- ".popsection\n"
|
||||
- );
|
||||
-
|
||||
-#else
|
||||
-
|
||||
-extern "C" void getcontext_light(ucontext_t *ctx) {
|
||||
- getcontext(ctx);
|
||||
-}
|
||||
-
|
||||
-#endif
|
||||
diff --git a/benchmark/unwind_bench.cc b/benchmark/unwind_bench.cc
|
||||
deleted file mode 100644
|
||||
index 9c4e2f8..0000000
|
||||
--- a/benchmark/unwind_bench.cc
|
||||
+++ /dev/null
|
||||
@@ -1,89 +0,0 @@
|
||||
-// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*-
|
||||
-#include "config.h"
|
||||
-
|
||||
-#include "base/basictypes.h"
|
||||
-#include "gperftools/stacktrace.h"
|
||||
-
|
||||
-#include <stdlib.h>
|
||||
-#include <stdio.h>
|
||||
-#include <stdint.h>
|
||||
-#include <sys/ucontext.h>
|
||||
-#if HAVE_LIBUNWIND_H
|
||||
-#include <libunwind.h>
|
||||
-#endif
|
||||
-
|
||||
-#include "run_benchmark.h"
|
||||
-
|
||||
-extern "C" void getcontext_light(ucontext_t *ctx);
|
||||
-
|
||||
-#define MAX_FRAMES 1024
|
||||
-static void *frames[MAX_FRAMES];
|
||||
-
|
||||
-enum measure_mode {
|
||||
- MODE_NOOP,
|
||||
- MODE_WITH_CONTEXT,
|
||||
- MODE_WITHOUT_CONTEXT
|
||||
-};
|
||||
-
|
||||
-static int ATTRIBUTE_NOINLINE measure_unwind(int maxlevel, int mode) {
|
||||
- int n;
|
||||
-
|
||||
- if (mode == MODE_NOOP)
|
||||
- return 0;
|
||||
-
|
||||
- if (mode == MODE_WITH_CONTEXT) {
|
||||
- ucontext_t uc;
|
||||
- getcontext_light(&uc);
|
||||
- n = GetStackTraceWithContext(frames, MAX_FRAMES, 0, &uc);
|
||||
- } else {
|
||||
- n = GetStackTrace(frames, MAX_FRAMES, 0);
|
||||
- }
|
||||
- if (n < maxlevel) {
|
||||
- fprintf(stderr, "Expected at least %d frames, got %d\n", maxlevel, n);
|
||||
- abort();
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ATTRIBUTE_NOINLINE frame_forcer(int rv) {
|
||||
- return rv;
|
||||
-}
|
||||
-
|
||||
-static int ATTRIBUTE_NOINLINE f1(int level, int maxlevel, int mode) {
|
||||
- if (level == maxlevel)
|
||||
- return frame_forcer(measure_unwind(maxlevel, mode));
|
||||
- return frame_forcer(f1(level + 1, maxlevel, mode));
|
||||
-}
|
||||
-
|
||||
-static void bench_unwind_no_op(long iterations, uintptr_t param) {
|
||||
- do {
|
||||
- f1(0, param, MODE_NOOP);
|
||||
- iterations -= param;
|
||||
- } while (iterations > 0);
|
||||
-}
|
||||
-
|
||||
-static void bench_unwind_context(long iterations, uintptr_t param) {
|
||||
- do {
|
||||
- f1(0, param, MODE_WITH_CONTEXT);
|
||||
- iterations -= param;
|
||||
- } while (iterations > 0);
|
||||
-}
|
||||
-
|
||||
-static void bench_unwind_no_context(long iterations, uintptr_t param) {
|
||||
- do {
|
||||
- f1(0, param, MODE_WITHOUT_CONTEXT);
|
||||
- iterations -= param;
|
||||
- } while (iterations > 0);
|
||||
-}
|
||||
-
|
||||
-int main(void) {
|
||||
- report_benchmark("unwind_no_op", bench_unwind_no_op, 100);
|
||||
- report_benchmark("unwind_context", bench_unwind_context, 100);
|
||||
- report_benchmark("unwind_no_context", bench_unwind_no_context, 100);
|
||||
-
|
||||
-//// TODO: somehow this fails at linking step. Figure out why this is missing
|
||||
-// #if HAVE_LIBUNWIND_H
|
||||
-// unw_set_caching_policy(unw_local_addr_space, UNW_CACHE_PER_THREAD);
|
||||
-// #endif
|
||||
- return 0;
|
||||
-}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,101 +0,0 @@
|
||||
From 71c8cedacafe700e662c008b65f5064b23426070 Mon Sep 17 00:00:00 2001
|
||||
From: Aliaksey Kandratsenka <alkondratenko@gmail.com>
|
||||
Date: Sun, 5 Aug 2018 18:54:01 -0700
|
||||
Subject: [PATCH 19/39] Fix incompatible aliasing warnings
|
||||
|
||||
We aliased functions with different signatures and gcc now correctly
|
||||
gives warning for that. Originally gcc 5 same code merging feature
|
||||
caused us to alias more than necessary, but I am not able to reproduce
|
||||
this problem anymore. So we're now aliasing only compatible functions.
|
||||
---
|
||||
src/libc_override_gcc_and_weak.h | 8 ++++----
|
||||
src/tcmalloc.cc | 16 ----------------
|
||||
2 files changed, 4 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/libc_override_gcc_and_weak.h b/src/libc_override_gcc_and_weak.h
|
||||
index 6875164..bb99b69 100644
|
||||
--- a/src/libc_override_gcc_and_weak.h
|
||||
+++ b/src/libc_override_gcc_and_weak.h
|
||||
@@ -126,9 +126,9 @@ void operator delete[](void *p, size_t size) CPP_NOTHROW
|
||||
#else /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
|
||||
|
||||
void operator delete(void *p, size_t size) CPP_NOTHROW
|
||||
- ALIAS(tc_delete);
|
||||
+ ALIAS(tc_delete_sized);
|
||||
void operator delete[](void *p, size_t size) CPP_NOTHROW
|
||||
- ALIAS(tc_deletearray);
|
||||
+ ALIAS(tc_deletearray_sized);
|
||||
|
||||
#endif /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
|
||||
|
||||
@@ -197,9 +197,9 @@ void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
|
||||
#else /* defined(ENABLE_DYN_SIZED_DELETE) */
|
||||
|
||||
void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
|
||||
- ALIAS(tc_delete);
|
||||
+ ALIAS(tc_delete_sized_aligned);
|
||||
void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
|
||||
- ALIAS(tc_deletearray);
|
||||
+ ALIAS(tc_deletearray_sized_aligned);
|
||||
|
||||
#endif /* defined(ENABLE_DYN_SIZED_DELETE) */
|
||||
|
||||
diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc
|
||||
index 37c1440..b320b30 100644
|
||||
--- a/src/tcmalloc.cc
|
||||
+++ b/src/tcmalloc.cc
|
||||
@@ -1998,9 +1998,6 @@ TC_ALIAS(tc_free);
|
||||
// (via ::operator delete(ptr, nothrow)).
|
||||
// But it's really the same as normal delete, so we just do the same thing.
|
||||
extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW
|
||||
-#ifdef TC_ALIAS
|
||||
-TC_ALIAS(tc_free);
|
||||
-#else
|
||||
{
|
||||
if (PREDICT_FALSE(!base::internal::delete_hooks_.empty())) {
|
||||
tcmalloc::invoke_hooks_and_free(p);
|
||||
@@ -2008,7 +2005,6 @@ TC_ALIAS(tc_free);
|
||||
}
|
||||
do_free(p);
|
||||
}
|
||||
-#endif
|
||||
|
||||
extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size)
|
||||
#ifdef TC_ALIAS
|
||||
@@ -2080,33 +2076,21 @@ extern "C" PERFTOOLS_DLL_DECL void* tc_new_aligned_nothrow(size_t size, std::ali
|
||||
}
|
||||
|
||||
extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned(void* p, std::align_val_t) PERFTOOLS_NOTHROW
|
||||
-#ifdef TC_ALIAS
|
||||
-TC_ALIAS(tc_delete);
|
||||
-#else
|
||||
{
|
||||
free_fast_path(p);
|
||||
}
|
||||
-#endif
|
||||
|
||||
// There is no easy way to obtain the actual size used by do_memalign to allocate aligned storage, so for now
|
||||
// just ignore the size. It might get useful in the future.
|
||||
extern "C" PERFTOOLS_DLL_DECL void tc_delete_sized_aligned(void* p, size_t size, std::align_val_t align) PERFTOOLS_NOTHROW
|
||||
-#ifdef TC_ALIAS
|
||||
-TC_ALIAS(tc_delete);
|
||||
-#else
|
||||
{
|
||||
free_fast_path(p);
|
||||
}
|
||||
-#endif
|
||||
|
||||
extern "C" PERFTOOLS_DLL_DECL void tc_delete_aligned_nothrow(void* p, std::align_val_t, const std::nothrow_t&) PERFTOOLS_NOTHROW
|
||||
-#ifdef TC_ALIAS
|
||||
-TC_ALIAS(tc_delete);
|
||||
-#else
|
||||
{
|
||||
free_fast_path(p);
|
||||
}
|
||||
-#endif
|
||||
|
||||
extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_aligned(size_t size, std::align_val_t align)
|
||||
#ifdef TC_ALIAS
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
From 1de76671d478e848f0dd210e00df43bfa463ca9f Mon Sep 17 00:00:00 2001
|
||||
From: Gabriel Marin <gmx@chromium.org>
|
||||
Date: Thu, 4 Oct 2018 22:52:35 +0000
|
||||
Subject: [PATCH 31/39] Fix mmap region iteration while no regions are
|
||||
recorded.
|
||||
|
||||
If no mmap regions are recorded, iteration failed since the RegionSet
|
||||
(std::set) object is not initialized.
|
||||
|
||||
Original CL https://codereview.chromium.org/14769008
|
||||
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/1130807
|
||||
---
|
||||
src/memory_region_map.cc | 19 +++++++++++++------
|
||||
src/memory_region_map.h | 3 +++
|
||||
2 files changed, 16 insertions(+), 6 deletions(-)
|
||||
mode change 100755 => 100644 src/memory_region_map.cc
|
||||
|
||||
diff --git a/src/memory_region_map.cc b/src/memory_region_map.cc
|
||||
old mode 100755
|
||||
new mode 100644
|
||||
index 841d6f3..06b6fb0
|
||||
--- a/src/memory_region_map.cc
|
||||
+++ b/src/memory_region_map.cc
|
||||
@@ -234,6 +234,9 @@ void MemoryRegionMap::Init(int max_stack_depth, bool use_buckets) {
|
||||
memset(bucket_table_, 0, table_bytes);
|
||||
num_buckets_ = 0;
|
||||
}
|
||||
+ if (regions_ == NULL) { // init regions_
|
||||
+ InitRegionSetLocked();
|
||||
+ }
|
||||
Unlock();
|
||||
RAW_VLOG(10, "MemoryRegionMap Init done");
|
||||
}
|
||||
@@ -536,6 +539,15 @@ void MemoryRegionMap::RestoreSavedBucketsLocked() {
|
||||
}
|
||||
}
|
||||
|
||||
+inline void MemoryRegionMap::InitRegionSetLocked() {
|
||||
+ RAW_VLOG(12, "Initializing region set");
|
||||
+ regions_ = regions_rep.region_set();
|
||||
+ recursive_insert = true;
|
||||
+ new (regions_) RegionSet();
|
||||
+ HandleSavedRegionsLocked(&DoInsertRegionLocked);
|
||||
+ recursive_insert = false;
|
||||
+}
|
||||
+
|
||||
inline void MemoryRegionMap::InsertRegionLocked(const Region& region) {
|
||||
RAW_CHECK(LockIsHeld(), "should be held (by this thread)");
|
||||
// We can be called recursively, because RegionSet constructor
|
||||
@@ -556,12 +568,7 @@ inline void MemoryRegionMap::InsertRegionLocked(const Region& region) {
|
||||
saved_regions[saved_regions_count++] = region;
|
||||
} else { // not a recusrive call
|
||||
if (regions_ == NULL) { // init regions_
|
||||
- RAW_VLOG(12, "Initializing region set");
|
||||
- regions_ = regions_rep.region_set();
|
||||
- recursive_insert = true;
|
||||
- new(regions_) RegionSet();
|
||||
- HandleSavedRegionsLocked(&DoInsertRegionLocked);
|
||||
- recursive_insert = false;
|
||||
+ InitRegionSetLocked();
|
||||
}
|
||||
recursive_insert = true;
|
||||
// Do the actual insertion work to put new regions into regions_:
|
||||
diff --git a/src/memory_region_map.h b/src/memory_region_map.h
|
||||
index ec388e1..f774994 100644
|
||||
--- a/src/memory_region_map.h
|
||||
+++ b/src/memory_region_map.h
|
||||
@@ -362,6 +362,9 @@ class MemoryRegionMap {
|
||||
// table where all buckets eventually should be.
|
||||
static void RestoreSavedBucketsLocked();
|
||||
|
||||
+ // Initialize RegionSet regions_.
|
||||
+ inline static void InitRegionSetLocked();
|
||||
+
|
||||
// Wrapper around DoInsertRegionLocked
|
||||
// that handles the case of recursive allocator calls.
|
||||
inline static void InsertRegionLocked(const Region& region);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,194 +0,0 @@
|
||||
From f2bca77aed83107197abadee0652c39e2c4c73d3 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Silverman <brian@peloton-tech.com>
|
||||
Date: Thu, 9 Aug 2018 16:33:39 -0700
|
||||
Subject: [PATCH 21/39] Fix page_heap_test flakiness
|
||||
|
||||
After 71fa9f87 (use 2-level page map for 48-bit addresses), there is a
|
||||
potential for allocs of additional leaves in the middle of the test.
|
||||
With ASLR enabled on amd64 (without TCMALLOC_SMALL_BUT_SLOW), this
|
||||
results in the test failing sometimes (< 1% of the time). Instead, make
|
||||
sure all those leaves are allocated before deciding on the baseline heap
|
||||
usage in the test.
|
||||
---
|
||||
src/tests/page_heap_test.cc | 79 ++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 56 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/src/tests/page_heap_test.cc b/src/tests/page_heap_test.cc
|
||||
index e82a1da..3caacc0 100644
|
||||
--- a/src/tests/page_heap_test.cc
|
||||
+++ b/src/tests/page_heap_test.cc
|
||||
@@ -6,9 +6,13 @@
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#include "config_for_unittests.h"
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include <memory>
|
||||
+
|
||||
#include "page_heap.h"
|
||||
#include "system-alloc.h"
|
||||
-#include <stdio.h>
|
||||
#include "base/logging.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -39,33 +43,63 @@ static void CheckStats(const tcmalloc::PageHeap* ph,
|
||||
}
|
||||
|
||||
static void TestPageHeap_Stats() {
|
||||
- tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
|
||||
+ std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
|
||||
|
||||
// Empty page heap
|
||||
- CheckStats(ph, 0, 0, 0);
|
||||
+ CheckStats(ph.get(), 0, 0, 0);
|
||||
|
||||
// Allocate a span 's1'
|
||||
tcmalloc::Span* s1 = ph->New(256);
|
||||
- CheckStats(ph, 256, 0, 0);
|
||||
+ CheckStats(ph.get(), 256, 0, 0);
|
||||
|
||||
// Split span 's1' into 's1', 's2'. Delete 's2'
|
||||
tcmalloc::Span* s2 = ph->Split(s1, 128);
|
||||
ph->Delete(s2);
|
||||
- CheckStats(ph, 256, 128, 0);
|
||||
+ CheckStats(ph.get(), 256, 128, 0);
|
||||
|
||||
// Unmap deleted span 's2'
|
||||
ph->ReleaseAtLeastNPages(1);
|
||||
- CheckStats(ph, 256, 0, 128);
|
||||
+ CheckStats(ph.get(), 256, 0, 128);
|
||||
|
||||
// Delete span 's1'
|
||||
ph->Delete(s1);
|
||||
- CheckStats(ph, 256, 128, 128);
|
||||
+ CheckStats(ph.get(), 256, 128, 128);
|
||||
+}
|
||||
|
||||
- delete ph;
|
||||
+// The number of kMaxPages-sized Spans we will allocate and free during the
|
||||
+// tests.
|
||||
+// We will also do twice this many kMaxPages/2-sized ones.
|
||||
+static constexpr int kNumberMaxPagesSpans = 10;
|
||||
+
|
||||
+// Allocates all the last-level page tables we will need. Doing this before
|
||||
+// calculating the base heap usage is necessary, because otherwise if any of
|
||||
+// these are allocated during the main test it will throw the heap usage
|
||||
+// calculations off and cause the test to fail.
|
||||
+static void AllocateAllPageTables() {
|
||||
+ // Make a separate PageHeap from the main test so the test can start without
|
||||
+ // any pages in the lists.
|
||||
+ std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
|
||||
+ tcmalloc::Span *spans[kNumberMaxPagesSpans * 2];
|
||||
+ for (int i = 0; i < kNumberMaxPagesSpans; ++i) {
|
||||
+ spans[i] = ph->New(kMaxPages);
|
||||
+ EXPECT_NE(spans[i], NULL);
|
||||
+ }
|
||||
+ for (int i = 0; i < kNumberMaxPagesSpans; ++i) {
|
||||
+ ph->Delete(spans[i]);
|
||||
+ }
|
||||
+ for (int i = 0; i < kNumberMaxPagesSpans * 2; ++i) {
|
||||
+ spans[i] = ph->New(kMaxPages >> 1);
|
||||
+ EXPECT_NE(spans[i], NULL);
|
||||
+ }
|
||||
+ for (int i = 0; i < kNumberMaxPagesSpans * 2; ++i) {
|
||||
+ ph->Delete(spans[i]);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void TestPageHeap_Limit() {
|
||||
- tcmalloc::PageHeap* ph = new tcmalloc::PageHeap();
|
||||
+ AllocateAllPageTables();
|
||||
+
|
||||
+ std::unique_ptr<tcmalloc::PageHeap> ph(new tcmalloc::PageHeap());
|
||||
|
||||
CHECK_EQ(kMaxPages, 1 << (20 - kPageShift));
|
||||
|
||||
@@ -77,25 +111,26 @@ static void TestPageHeap_Limit() {
|
||||
while((s = ph->New(kMaxPages)) == NULL) {
|
||||
FLAGS_tcmalloc_heap_limit_mb++;
|
||||
}
|
||||
- FLAGS_tcmalloc_heap_limit_mb += 9;
|
||||
+ FLAGS_tcmalloc_heap_limit_mb += kNumberMaxPagesSpans - 1;
|
||||
ph->Delete(s);
|
||||
// We are [10, 11) mb from the limit now.
|
||||
}
|
||||
|
||||
// Test AllocLarge and GrowHeap first:
|
||||
{
|
||||
- tcmalloc::Span * spans[10];
|
||||
- for (int i=0; i<10; ++i) {
|
||||
+ tcmalloc::Span * spans[kNumberMaxPagesSpans];
|
||||
+ for (int i=0; i<kNumberMaxPagesSpans; ++i) {
|
||||
spans[i] = ph->New(kMaxPages);
|
||||
EXPECT_NE(spans[i], NULL);
|
||||
}
|
||||
EXPECT_EQ(ph->New(kMaxPages), NULL);
|
||||
|
||||
- for (int i=0; i<10; i += 2) {
|
||||
+ for (int i=0; i<kNumberMaxPagesSpans; i += 2) {
|
||||
ph->Delete(spans[i]);
|
||||
}
|
||||
|
||||
- tcmalloc::Span *defragmented = ph->New(5 * kMaxPages);
|
||||
+ tcmalloc::Span *defragmented =
|
||||
+ ph->New(kNumberMaxPagesSpans / 2 * kMaxPages);
|
||||
|
||||
if (HaveSystemRelease) {
|
||||
// EnsureLimit should release deleted normal spans
|
||||
@@ -109,15 +144,15 @@ static void TestPageHeap_Limit() {
|
||||
EXPECT_TRUE(ph->CheckExpensive());
|
||||
}
|
||||
|
||||
- for (int i=1; i<10; i += 2) {
|
||||
+ for (int i=1; i<kNumberMaxPagesSpans; i += 2) {
|
||||
ph->Delete(spans[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Once again, testing small lists this time (twice smaller spans):
|
||||
{
|
||||
- tcmalloc::Span * spans[20];
|
||||
- for (int i=0; i<20; ++i) {
|
||||
+ tcmalloc::Span * spans[kNumberMaxPagesSpans * 2];
|
||||
+ for (int i=0; i<kNumberMaxPagesSpans * 2; ++i) {
|
||||
spans[i] = ph->New(kMaxPages >> 1);
|
||||
EXPECT_NE(spans[i], NULL);
|
||||
}
|
||||
@@ -125,12 +160,12 @@ static void TestPageHeap_Limit() {
|
||||
tcmalloc::Span * lastHalf = ph->New(kMaxPages >> 1);
|
||||
EXPECT_EQ(ph->New(kMaxPages >> 1), NULL);
|
||||
|
||||
- for (int i=0; i<20; i += 2) {
|
||||
+ for (int i=0; i<kNumberMaxPagesSpans * 2; i += 2) {
|
||||
ph->Delete(spans[i]);
|
||||
}
|
||||
|
||||
- for(Length len = kMaxPages >> 2; len < 5 * kMaxPages; len = len << 1)
|
||||
- {
|
||||
+ for (Length len = kMaxPages >> 2;
|
||||
+ len < kNumberMaxPagesSpans / 2 * kMaxPages; len = len << 1) {
|
||||
if(len <= kMaxPages >> 1 || HaveSystemRelease) {
|
||||
tcmalloc::Span *s = ph->New(len);
|
||||
EXPECT_NE(s, NULL);
|
||||
@@ -140,7 +175,7 @@ static void TestPageHeap_Limit() {
|
||||
|
||||
EXPECT_TRUE(ph->CheckExpensive());
|
||||
|
||||
- for (int i=1; i<20; i += 2) {
|
||||
+ for (int i=1; i<kNumberMaxPagesSpans * 2; i += 2) {
|
||||
ph->Delete(spans[i]);
|
||||
}
|
||||
|
||||
@@ -148,8 +183,6 @@ static void TestPageHeap_Limit() {
|
||||
ph->Delete(lastHalf);
|
||||
}
|
||||
}
|
||||
-
|
||||
- delete ph;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 0b588e7490eac4ef37b59c9265f1f3f05f4bb27c Mon Sep 17 00:00:00 2001
|
||||
From: Brian Silverman <brian@peloton-tech.com>
|
||||
Date: Tue, 31 Jul 2018 15:53:47 -0700
|
||||
Subject: [PATCH 05/39] Fix uninitialized memory use in sampler_test
|
||||
|
||||
Sampler's documentation states the following:
|
||||
C++03 requires that types stored in TLS be POD. As a result, you must
|
||||
initialize these members to {0, 0, false} before using this class!
|
||||
|
||||
However, the test code wasn't doing that. MemorySanitizer and
|
||||
UndefinedBehaviorSanitizer both failed because of it.
|
||||
---
|
||||
src/tests/sampler_test.cc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/tests/sampler_test.cc b/src/tests/sampler_test.cc
|
||||
index e0d24d4..9a55b70 100755
|
||||
--- a/src/tests/sampler_test.cc
|
||||
+++ b/src/tests/sampler_test.cc
|
||||
@@ -361,7 +361,7 @@ double StandardDeviationsErrorInSample(
|
||||
}
|
||||
|
||||
TEST(Sampler, LargeAndSmallAllocs_CombinedTest) {
|
||||
- tcmalloc::Sampler sampler;
|
||||
+ tcmalloc::Sampler sampler{0, 0, false};
|
||||
sampler.Init(1);
|
||||
int counter_big = 0;
|
||||
int counter_small = 0;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
From 8dd304035848e780372a5a4bb1afac2b2d20bc43 Mon Sep 17 00:00:00 2001
|
||||
From: Aliaksey Kandratsenka <alkondratenko@gmail.com>
|
||||
Date: Sun, 5 Aug 2018 19:52:11 -0700
|
||||
Subject: [PATCH 18/39] Format and fix out of bound access in CpuProfilerSwitch
|
||||
|
||||
GCC was giving warning on snprintf and it hinted at base_profile_name
|
||||
and full_profile_name not being long enough.
|
||||
|
||||
Fix is to ensure base_profile_name is long enough for PATH_MAX and
|
||||
that full_profile_name is enough longer to fit extra chars.
|
||||
---
|
||||
src/profiler.cc | 49 +++++++++++++++++++++++--------------------------
|
||||
1 file changed, 23 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/src/profiler.cc b/src/profiler.cc
|
||||
index f4f5990..3bd0ed9 100644
|
||||
--- a/src/profiler.cc
|
||||
+++ b/src/profiler.cc
|
||||
@@ -144,34 +144,31 @@ class CpuProfiler {
|
||||
// number is defined in the environment variable CPUPROFILESIGNAL.
|
||||
static void CpuProfilerSwitch(int signal_number)
|
||||
{
|
||||
- bool static started = false;
|
||||
- static unsigned profile_count = 0;
|
||||
- static char base_profile_name[1024] = "\0";
|
||||
-
|
||||
- if (base_profile_name[0] == '\0') {
|
||||
- if (!GetUniquePathFromEnv("CPUPROFILE", base_profile_name)) {
|
||||
- RAW_LOG(FATAL,"Cpu profiler switch is registered but no CPUPROFILE is defined");
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
- if (!started)
|
||||
- {
|
||||
- char full_profile_name[1024];
|
||||
-
|
||||
- snprintf(full_profile_name, sizeof(full_profile_name), "%s.%u",
|
||||
- base_profile_name, profile_count++);
|
||||
-
|
||||
- if(!ProfilerStart(full_profile_name))
|
||||
- {
|
||||
- RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
|
||||
- full_profile_name, strerror(errno));
|
||||
- }
|
||||
+ static unsigned profile_count;
|
||||
+ static char base_profile_name[PATH_MAX];
|
||||
+ static bool started = false;
|
||||
+
|
||||
+ if (base_profile_name[0] == '\0') {
|
||||
+ if (!GetUniquePathFromEnv("CPUPROFILE", base_profile_name)) {
|
||||
+ RAW_LOG(FATAL,"Cpu profiler switch is registered but no CPUPROFILE is defined");
|
||||
+ return;
|
||||
}
|
||||
- else
|
||||
- {
|
||||
- ProfilerStop();
|
||||
+ }
|
||||
+
|
||||
+ if (!started) {
|
||||
+ char full_profile_name[PATH_MAX + 16];
|
||||
+
|
||||
+ snprintf(full_profile_name, sizeof(full_profile_name), "%s.%u",
|
||||
+ base_profile_name, profile_count++);
|
||||
+
|
||||
+ if(!ProfilerStart(full_profile_name)) {
|
||||
+ RAW_LOG(FATAL, "Can't turn on cpu profiling for '%s': %s\n",
|
||||
+ full_profile_name, strerror(errno));
|
||||
}
|
||||
- started = !started;
|
||||
+ } else {
|
||||
+ ProfilerStop();
|
||||
+ }
|
||||
+ started = !started;
|
||||
}
|
||||
|
||||
// Profile data structure singleton: Constructor will check to see if
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
From 1e36ed705548ae2a5170bb00dfee0954b8ef76de Mon Sep 17 00:00:00 2001
|
||||
From: Romain Geissler <romain.geissler@amadeus.com>
|
||||
Date: Tue, 29 Jan 2019 18:31:19 +0000
|
||||
Subject: [PATCH 38/39] Use initial exec TLS model for all thread local
|
||||
variables from thread_cache.cc
|
||||
|
||||
This avoids a deadlock when a library which is being dlopen'ed creates
|
||||
as part of its static constructors a thread which quickly need to call
|
||||
malloc. We are still in the dlopen call (so with some internal glibc
|
||||
mutex taken) when the thread executes code and later needs to call
|
||||
malloc which in term calls tls_get_addr_tail, which wait for the dlopen
|
||||
mutex to be unlocked. If later the dlopen'ing thread also calls malloc
|
||||
as part of its constructors, we are in a deadlock.
|
||||
|
||||
Fix is similar to
|
||||
https://github.com/gperftools/gperftools/commit/7852eeb75b9375cf52a7da01be044da6e915dd08
|
||||
|
||||
Stack of the dlopening thread:
|
||||
#0 0x00007fd5406ca93c in __lll_lock_wait () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libpthread.so.0
|
||||
#1 0x00007fd5406c45a5 in pthread_mutex_lock () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libpthread.so.0
|
||||
... proprietary code in the stack
|
||||
#9 0x00007fd5074f0367 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at src/ClientImpl.cpp:15
|
||||
#10 0x00007fd5074f06d7 in _GLOBAL__sub_I_ClientImpl.cpp(void) () at src/ClientImpl.cpp:85
|
||||
#11 0x00007fd50757aa46 in __do_global_ctors_aux ()
|
||||
#12 0x00007fd5073e985f in _init () from ...
|
||||
#13 0x00007fd53bf9dec8 in ?? () from ...
|
||||
#14 0x00007fd54d637a5d in call_init.part () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/ld-linux-x86-64.so.2
|
||||
#15 0x00007fd54d637bab in _dl_init () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/ld-linux-x86-64.so.2
|
||||
#16 0x00007fd54d63c160 in dl_open_worker () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/ld-linux-x86-64.so.2
|
||||
#17 0x00007fd54d637944 in _dl_catch_error () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/ld-linux-x86-64.so.2
|
||||
#18 0x00007fd54d63b7d9 in _dl_open () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/ld-linux-x86-64.so.2
|
||||
#19 0x00007fd54d61f2b9 in dlopen_doit () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libdl.so.2
|
||||
#20 0x00007fd54d637944 in _dl_catch_error () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/ld-linux-x86-64.so.2
|
||||
#21 0x00007fd54d61f889 in _dlerror_run () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libdl.so.2
|
||||
#22 0x00007fd54d61f351 in dlopen@@GLIBC_2.2.5 () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libdl.so.2
|
||||
|
||||
Stack of the newly created thread calling tls_get_addr_tail:
|
||||
#0 0x00007fd5406ca93c in __lll_lock_wait () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libpthread.so.0
|
||||
#1 0x00007fd5406c4622 in pthread_mutex_lock () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libpthread.so.0
|
||||
#2 0x00007fd54d63a2ed in tls_get_addr_tail () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/ld-linux-x86-64.so.2
|
||||
#3 0x00007fd53fee877d in tcmalloc::ThreadCache::CreateCacheIfNecessary () at src/thread_cache.cc:344
|
||||
#4 0x00007fd53fecb4ab in tcmalloc::ThreadCache::GetCache () at src/thread_cache.h:437
|
||||
#5 0x00007fd53fefeccb in (anonymous namespace)::do_malloc (size=56) at src/tcmalloc.cc:1354
|
||||
#6 tcmalloc::do_allocate_full<tcmalloc::cpp_throw_oom> (size=56) at src/tcmalloc.cc:1762
|
||||
#7 tcmalloc::allocate_full_cpp_throw_oom (size=56) at src/tcmalloc.cc:1776
|
||||
#8 0x00007fd53ff01b80 in tcmalloc::dispatch_allocate_full<tcmalloc::cpp_throw_oom> (size=56) at src/tcmalloc.cc:1785
|
||||
#9 malloc_fast_path<tcmalloc::cpp_throw_oom> (size=56) at src/tcmalloc.cc:1845
|
||||
#10 tc_new (size=56) at src/tcmalloc.cc:1980
|
||||
... proprietary code in the stack
|
||||
#26 0x00007fd5406c1ef4 in start_thread () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libpthread.so.0
|
||||
#27 0x00007fd5403ba01d in clone () from /data3/mwrep/rgeissler/core.tls/opt/1A/toolchain/x86_64-2.6.32-v2/lib64/libc.so.6
|
||||
---
|
||||
src/thread_cache.cc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/thread_cache.cc b/src/thread_cache.cc
|
||||
index 6d2f832..97f3ffe 100644
|
||||
--- a/src/thread_cache.cc
|
||||
+++ b/src/thread_cache.cc
|
||||
@@ -334,7 +334,7 @@ ThreadCache* ThreadCache::CreateCacheIfNecessary() {
|
||||
|
||||
bool seach_condition = true;
|
||||
#ifdef HAVE_TLS
|
||||
- static __thread ThreadCache** current_heap_ptr;
|
||||
+ static __thread ThreadCache** current_heap_ptr ATTR_INITIAL_EXEC;
|
||||
if (tsd_inited_) {
|
||||
// In most common case we're avoiding expensive linear search
|
||||
// through all heaps (see below). Working TLS enables faster
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From c41688bf20186723367b560ceb539b2330951ddb Mon Sep 17 00:00:00 2001
|
||||
From: Aliaksey Kandratsenka <alkondratenko@gmail.com>
|
||||
Date: Sun, 5 Aug 2018 20:39:07 -0700
|
||||
Subject: [PATCH 20/39] Use standard-conforming alignof in debugallocation.cc
|
||||
|
||||
Clang was giving warning that alignof(<variable>) is extension. So
|
||||
we're now doing alignof of decltype.
|
||||
---
|
||||
src/debugallocation.cc | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/debugallocation.cc b/src/debugallocation.cc
|
||||
index 7c438f2..39dea5a 100644
|
||||
--- a/src/debugallocation.cc
|
||||
+++ b/src/debugallocation.cc
|
||||
@@ -1152,8 +1152,8 @@ static union {
|
||||
|
||||
REGISTER_MODULE_INITIALIZER(debugallocation, {
|
||||
#if (__cplusplus >= 201103L)
|
||||
- COMPILE_ASSERT(alignof(debug_malloc_implementation_space) >= alignof(DebugMallocImplementation),
|
||||
- debug_malloc_implementation_space_is_not_properly_aligned);
|
||||
+ static_assert(alignof(decltype(debug_malloc_implementation_space)) >= alignof(DebugMallocImplementation),
|
||||
+ "DebugMallocImplementation is expected to need just word alignment");
|
||||
#endif
|
||||
// Either we or valgrind will control memory management. We
|
||||
// register our extension if we're the winner. Otherwise let
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
From 3af509d4f91aa1fae3f8caeb17b158f20e9b5e59 Mon Sep 17 00:00:00 2001
|
||||
From: Gabriel Marin <gmx@chromium.org>
|
||||
Date: Tue, 17 Jul 2018 18:28:01 -0700
|
||||
Subject: [PATCH 13/39] benchmark: use angle brackets to include ucontext.h
|
||||
|
||||
Using quotes for a system header file fails a presubmit check in Chromium.
|
||||
---
|
||||
benchmark/unwind_bench.cc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/benchmark/unwind_bench.cc b/benchmark/unwind_bench.cc
|
||||
index f919fc0..9c4e2f8 100644
|
||||
--- a/benchmark/unwind_bench.cc
|
||||
+++ b/benchmark/unwind_bench.cc
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
-#include "sys/ucontext.h"
|
||||
+#include <sys/ucontext.h>
|
||||
#if HAVE_LIBUNWIND_H
|
||||
#include <libunwind.h>
|
||||
#endif
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
From 9e5b1628737c67b4587f937164572774592978c4 Mon Sep 17 00:00:00 2001
|
||||
From: Aliaksey Kandratsenka <alkondratenko@gmail.com>
|
||||
Date: Sun, 10 Feb 2019 12:46:18 -0800
|
||||
Subject: [PATCH 39/39] don't try to mark rsp as clobbered in linux syscall
|
||||
support
|
||||
|
||||
rsp is not actually clobbered by that code and later gccs actually (correctly) bark
|
||||
at it.
|
||||
|
||||
Fixed issue #1076.
|
||||
---
|
||||
src/base/linux_syscall_support.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/base/linux_syscall_support.h b/src/base/linux_syscall_support.h
|
||||
index 13aa415..199061a 100644
|
||||
--- a/src/base/linux_syscall_support.h
|
||||
+++ b/src/base/linux_syscall_support.h
|
||||
@@ -1485,7 +1485,7 @@ struct kernel_stat {
|
||||
"d"(LSS_SYSCALL_ARG(parent_tidptr)),
|
||||
"r"(LSS_SYSCALL_ARG(newtls)),
|
||||
"r"(LSS_SYSCALL_ARG(child_tidptr))
|
||||
- : "rsp", "memory", "r8", "r10", "r11", "rcx");
|
||||
+ : "memory", "r8", "r10", "r11", "rcx");
|
||||
}
|
||||
LSS_RETURN(int, __res);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Binary file not shown.
BIN
gperftools-2.8.tar.gz
Normal file
BIN
gperftools-2.8.tar.gz
Normal file
Binary file not shown.
@ -1,25 +1,11 @@
|
||||
Name: gperftools
|
||||
Version: 2.7
|
||||
Release: 7
|
||||
Version: 2.8
|
||||
Release: 1
|
||||
Summary: high-performance malloc and performance analysis tools
|
||||
|
||||
License: BSD
|
||||
URL: https://github.com/gperftools/gperftools
|
||||
Source0: https://github.com/gperftools/gperftools/releases/download/%{name}-%{version}/%{name}-%{version}.tar.gz
|
||||
Patch1: Disable-large-allocation-report-by-default.patch
|
||||
Patch2: Fix-uninitialized-memory-use-in-sampler_test.patch
|
||||
Patch3: benchmark-use-angle-brackets-to-include-ucontext.h.patch
|
||||
Patch4: Format-and-fix-out-of-bound-access-in-CpuProfilerSwi.patch
|
||||
Patch5: Fix-incompatible-aliasing-warnings.patch
|
||||
Patch6: Use-standard-conforming-alignof-in-debugallocation.c.patch
|
||||
Patch7: Fix-page_heap_test-flakiness.patch
|
||||
Patch8: Avoid-static-initialization-of-pprof-path-for-symbol.patch
|
||||
Patch9: Fix-mmap-region-iteration-while-no-regions-are-recor.patch
|
||||
Patch10: Drop-not-very-portable-and-not-very-useful-unwind-be.patch
|
||||
Patch11: undef-mmap64-function.patch
|
||||
Patch12: Use-initial-exec-TLS-model-for-all-thread-local-vari.patch
|
||||
Patch13: don-t-try-to-mark-rsp-as-clobbered-in-linux-syscall-.patch
|
||||
|
||||
Patch9000: issue-1122-fix-bus-error-on-aarch64.patch
|
||||
|
||||
BuildRequires: autoconf automake gcc-c++ gdb
|
||||
@ -112,6 +98,9 @@ make
|
||||
%{_mandir}/man1/*.1.gz
|
||||
|
||||
%changelog
|
||||
* Thu Jul 23 2020 jinzhimin <jinzhimin2@huawei.com> - 2.8-1
|
||||
- update to 2.8
|
||||
|
||||
* Thu Mar 19 2020 yuxiangyang <yuxiangyang4@huawei.com> - 2.7-7
|
||||
- fix build src.rpm error
|
||||
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
From e9ab4c53041ac62feefbbb076d326e9a77dd1567 Mon Sep 17 00:00:00 2001
|
||||
From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
|
||||
Date: Sun, 7 Oct 2018 18:12:03 +0200
|
||||
Subject: [PATCH 34/39] undef mmap64 function
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
mmap64 can already been defined and as a result the following error is
|
||||
raised:
|
||||
|
||||
In file included from src/malloc_hook.cc:686:0:
|
||||
src/malloc_hook_mmap_linux.h: In function ‘void* mmap(void*, size_t, int, int, int, off_t)’:
|
||||
src/malloc_hook_mmap_linux.h:173:18: error: redefinition of ‘void* mmap(void*, size_t, int, int, int, off_t)’
|
||||
extern "C" void* mmap(void *start, size_t length, int prot, int flags,
|
||||
^~~~
|
||||
In file included from src/malloc_hook.cc:41:0:
|
||||
src/malloc_hook_mmap_linux.h:159:18: note: ‘void* mmap(void*, size_t, int, int, int, off_t)’ previously defined here
|
||||
extern "C" void* mmap64(void *start, size_t length, int prot, int flags,
|
||||
^
|
||||
Makefile:4874: recipe for target 'src/libtcmalloc_minimal_internal_la-malloc_hook.lo' failed
|
||||
|
||||
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
|
||||
---
|
||||
src/malloc_hook_mmap_linux.h | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/malloc_hook_mmap_linux.h b/src/malloc_hook_mmap_linux.h
|
||||
index 0eec895..34de715 100644
|
||||
--- a/src/malloc_hook_mmap_linux.h
|
||||
+++ b/src/malloc_hook_mmap_linux.h
|
||||
@@ -137,7 +137,8 @@ static inline void* do_mmap64(void *start, size_t length,
|
||||
// malloc_hook section,
|
||||
// so that MallocHook::GetCallerStackTrace can function accurately:
|
||||
|
||||
-// Make sure mmap doesn't get #define'd away by <sys/mman.h>
|
||||
+// Make sure mmap64 and mmap doesn't get #define'd away by <sys/mman.h>
|
||||
+# undef mmap64
|
||||
# undef mmap
|
||||
|
||||
extern "C" {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user