[Avida-SVN] r3475 - in branches/tcmalloc-1.4: Avida.xcodeproj source/platform/tcmalloc-1.4
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Wed Oct 14 10:30:34 PDT 2009
Author: brysonda
Date: 2009-10-14 13:30:34 -0400 (Wed, 14 Oct 2009)
New Revision: 3475
Removed:
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_config.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_generic-inl.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_libunwind-inl.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_powerpc-inl.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_win32-inl.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_with_context.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86-inl.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86_64-inl.h
Modified:
branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/common.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/span.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.h
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc
branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h
Log:
Remove unused stack trace instrumentation and sampler overhead from tcmalloc-1.4.
Modified: branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/Avida.xcodeproj/project.pbxproj 2009-10-14 17:30:34 UTC (rev 3475)
@@ -52,10 +52,8 @@
702246E2107FCA900079CD25 /* maybe_threads.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246C1107FCA590079CD25 /* maybe_threads.cc */; };
702246E3107FCA900079CD25 /* memfs_malloc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246C3107FCA590079CD25 /* memfs_malloc.cc */; };
702246E4107FCA900079CD25 /* page_heap.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246C6107FCA590079CD25 /* page_heap.cc */; };
- 702246E5107FCA900079CD25 /* sampler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246C9107FCA590079CD25 /* sampler.cc */; };
702246E6107FCA900079CD25 /* span.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246CB107FCA590079CD25 /* span.cc */; };
702246E7107FCA900079CD25 /* spinlock.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246CD107FCA590079CD25 /* spinlock.cc */; };
- 702246E8107FCA900079CD25 /* stack_trace_table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246CF107FCA590079CD25 /* stack_trace_table.cc */; };
702246E9107FCA900079CD25 /* static_vars.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D1107FCA590079CD25 /* static_vars.cc */; };
702246EA107FCA900079CD25 /* symbolize.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D3107FCA590079CD25 /* symbolize.cc */; };
702246EB107FCA900079CD25 /* system-alloc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702246D5107FCA590079CD25 /* system-alloc.cc */; };
@@ -64,8 +62,6 @@
7022476010861BD30079CD25 /* dynamic_annotations.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7022475E10861BD30079CD25 /* dynamic_annotations.cc */; };
7022479E108620E40079CD25 /* sysinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7022479C108620E40079CD25 /* sysinfo.cc */; };
702247F2108625920079CD25 /* libtcmalloc-1.4.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7022469D107FC4F10079CD25 /* libtcmalloc-1.4.a */; };
- 702247FF1086272F0079CD25 /* stacktrace_with_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702247FD1086272F0079CD25 /* stacktrace_with_context.cc */; };
- 702248001086272F0079CD25 /* stacktrace.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702247FE1086272F0079CD25 /* stacktrace.cc */; };
7022480E108627DC0079CD25 /* vdso_support.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7022480D108627DC0079CD25 /* vdso_support.cc */; };
70224818108628640079CD25 /* logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70224817108628640079CD25 /* logging.cc */; };
7023EC3A0C0A431B00362B9C /* avida.cc in Sources */ = {isa = PBXBuildFile; fileRef = DCC3109C0762539E008F7A48 /* avida.cc */; };
@@ -505,14 +501,10 @@
702246C6107FCA590079CD25 /* page_heap.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = page_heap.cc; sourceTree = "<group>"; };
702246C7107FCA590079CD25 /* page_heap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = page_heap.h; sourceTree = "<group>"; };
702246C8107FCA590079CD25 /* pagemap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pagemap.h; sourceTree = "<group>"; };
- 702246C9107FCA590079CD25 /* sampler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sampler.cc; sourceTree = "<group>"; };
- 702246CA107FCA590079CD25 /* sampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sampler.h; sourceTree = "<group>"; };
702246CB107FCA590079CD25 /* span.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = span.cc; sourceTree = "<group>"; };
702246CC107FCA590079CD25 /* span.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = span.h; sourceTree = "<group>"; };
702246CD107FCA590079CD25 /* spinlock.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spinlock.cc; sourceTree = "<group>"; };
702246CE107FCA590079CD25 /* spinlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spinlock.h; sourceTree = "<group>"; };
- 702246CF107FCA590079CD25 /* stack_trace_table.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stack_trace_table.cc; sourceTree = "<group>"; };
- 702246D0107FCA590079CD25 /* stack_trace_table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack_trace_table.h; sourceTree = "<group>"; };
702246D1107FCA590079CD25 /* static_vars.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = static_vars.cc; sourceTree = "<group>"; };
702246D2107FCA590079CD25 /* static_vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = static_vars.h; sourceTree = "<group>"; };
702246D3107FCA590079CD25 /* symbolize.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = symbolize.cc; sourceTree = "<group>"; };
@@ -531,22 +523,12 @@
7022479D108620E40079CD25 /* sysinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sysinfo.h; sourceTree = "<group>"; };
702247A4108621060079CD25 /* logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = logging.h; sourceTree = "<group>"; };
702247AD108621660079CD25 /* malloc_extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = malloc_extension.h; sourceTree = "<group>"; };
- 702247BF108622430079CD25 /* stacktrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stacktrace.h; sourceTree = "<group>"; };
702247D51086236F0079CD25 /* cycleclock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cycleclock.h; sourceTree = "<group>"; };
702247D61086236F0079CD25 /* spinlock_linux-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spinlock_linux-inl.h"; sourceTree = "<group>"; };
702247D71086236F0079CD25 /* spinlock_posix-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spinlock_posix-inl.h"; sourceTree = "<group>"; };
702247D81086236F0079CD25 /* spinlock_win32-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spinlock_win32-inl.h"; sourceTree = "<group>"; };
702247DA108623920079CD25 /* linux_syscall_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linux_syscall_support.h; sourceTree = "<group>"; };
702247E3108624160079CD25 /* tcmalloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcmalloc.h; sourceTree = "<group>"; };
- 702247F6108627220079CD25 /* stacktrace_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stacktrace_config.h; sourceTree = "<group>"; };
- 702247F7108627220079CD25 /* stacktrace_generic-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "stacktrace_generic-inl.h"; sourceTree = "<group>"; };
- 702247F8108627220079CD25 /* stacktrace_libunwind-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "stacktrace_libunwind-inl.h"; sourceTree = "<group>"; };
- 702247F9108627220079CD25 /* stacktrace_powerpc-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "stacktrace_powerpc-inl.h"; sourceTree = "<group>"; };
- 702247FA108627220079CD25 /* stacktrace_win32-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "stacktrace_win32-inl.h"; sourceTree = "<group>"; };
- 702247FB108627220079CD25 /* stacktrace_x86_64-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "stacktrace_x86_64-inl.h"; sourceTree = "<group>"; };
- 702247FC108627220079CD25 /* stacktrace_x86-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "stacktrace_x86-inl.h"; sourceTree = "<group>"; };
- 702247FD1086272F0079CD25 /* stacktrace_with_context.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stacktrace_with_context.cc; sourceTree = "<group>"; };
- 702247FE1086272F0079CD25 /* stacktrace.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stacktrace.cc; sourceTree = "<group>"; };
7022480D108627DC0079CD25 /* vdso_support.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vdso_support.cc; sourceTree = "<group>"; };
7022480F108627E60079CD25 /* vdso_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vdso_support.h; sourceTree = "<group>"; };
70224817108628640079CD25 /* logging.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = logging.cc; sourceTree = "<group>"; };
@@ -1184,22 +1166,12 @@
70224817108628640079CD25 /* logging.cc */,
7022480F108627E60079CD25 /* vdso_support.h */,
7022480D108627DC0079CD25 /* vdso_support.cc */,
- 702247FD1086272F0079CD25 /* stacktrace_with_context.cc */,
- 702247FE1086272F0079CD25 /* stacktrace.cc */,
- 702247F6108627220079CD25 /* stacktrace_config.h */,
- 702247F7108627220079CD25 /* stacktrace_generic-inl.h */,
- 702247F8108627220079CD25 /* stacktrace_libunwind-inl.h */,
- 702247F9108627220079CD25 /* stacktrace_powerpc-inl.h */,
- 702247FA108627220079CD25 /* stacktrace_win32-inl.h */,
- 702247FB108627220079CD25 /* stacktrace_x86_64-inl.h */,
- 702247FC108627220079CD25 /* stacktrace_x86-inl.h */,
702247E3108624160079CD25 /* tcmalloc.h */,
702247DA108623920079CD25 /* linux_syscall_support.h */,
702247D51086236F0079CD25 /* cycleclock.h */,
702247D61086236F0079CD25 /* spinlock_linux-inl.h */,
702247D71086236F0079CD25 /* spinlock_posix-inl.h */,
702247D81086236F0079CD25 /* spinlock_win32-inl.h */,
- 702247BF108622430079CD25 /* stacktrace.h */,
702247AD108621660079CD25 /* malloc_extension.h */,
702247A4108621060079CD25 /* logging.h */,
7022479C108620E40079CD25 /* sysinfo.cc */,
@@ -1232,14 +1204,10 @@
702246C6107FCA590079CD25 /* page_heap.cc */,
702246C7107FCA590079CD25 /* page_heap.h */,
702246C8107FCA590079CD25 /* pagemap.h */,
- 702246C9107FCA590079CD25 /* sampler.cc */,
- 702246CA107FCA590079CD25 /* sampler.h */,
702246CB107FCA590079CD25 /* span.cc */,
702246CC107FCA590079CD25 /* span.h */,
702246CD107FCA590079CD25 /* spinlock.cc */,
702246CE107FCA590079CD25 /* spinlock.h */,
- 702246CF107FCA590079CD25 /* stack_trace_table.cc */,
- 702246D0107FCA590079CD25 /* stack_trace_table.h */,
702246D1107FCA590079CD25 /* static_vars.cc */,
702246D2107FCA590079CD25 /* static_vars.h */,
702246D3107FCA590079CD25 /* symbolize.cc */,
@@ -2285,10 +2253,8 @@
702246E2107FCA900079CD25 /* maybe_threads.cc in Sources */,
702246E3107FCA900079CD25 /* memfs_malloc.cc in Sources */,
702246E4107FCA900079CD25 /* page_heap.cc in Sources */,
- 702246E5107FCA900079CD25 /* sampler.cc in Sources */,
702246E6107FCA900079CD25 /* span.cc in Sources */,
702246E7107FCA900079CD25 /* spinlock.cc in Sources */,
- 702246E8107FCA900079CD25 /* stack_trace_table.cc in Sources */,
702246E9107FCA900079CD25 /* static_vars.cc in Sources */,
702246EA107FCA900079CD25 /* symbolize.cc in Sources */,
702246EB107FCA900079CD25 /* system-alloc.cc in Sources */,
@@ -2296,8 +2262,6 @@
702246ED107FCA900079CD25 /* thread_cache.cc in Sources */,
7022476010861BD30079CD25 /* dynamic_annotations.cc in Sources */,
7022479E108620E40079CD25 /* sysinfo.cc in Sources */,
- 702247FF1086272F0079CD25 /* stacktrace_with_context.cc in Sources */,
- 702248001086272F0079CD25 /* stacktrace.cc in Sources */,
7022480E108627DC0079CD25 /* vdso_support.cc in Sources */,
70224818108628640079CD25 /* logging.cc in Sources */,
);
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/common.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/common.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/common.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -183,15 +183,6 @@
// Requires pageheap_lock is held.
uint64_t metadata_system_bytes();
-// size/depth are made the same size as a pointer so that some generic
-// code below can conveniently cast them back and forth to void*.
-static const int kMaxStackDepth = 31;
-struct StackTrace {
- uintptr_t size; // Size of object
- uintptr_t depth; // Number of PC values stored in array below
- void* stack[kMaxStackDepth];
-};
-
} // namespace tcmalloc
#endif // TCMALLOC_COMMON_H_
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -187,7 +187,6 @@
ASSERT(GetDescriptor(span->start) == span);
ASSERT(GetDescriptor(span->start + span->length - 1) == span);
span->sizeclass = 0;
- span->sample = 0;
// Coalesce -- we guarantee that "p" != 0, so no bounds checking
// necessary. We do not bother resetting the stale pagemap
@@ -370,14 +369,6 @@
PagesToMB(total_returned));
}
-static void RecordGrowth(size_t growth) {
- StackTrace* t = Static::stacktrace_allocator()->New();
- t->depth = GetStackTrace(t->stack, kMaxStackDepth-1, 3);
- t->size = growth;
- t->stack[kMaxStackDepth-1] = reinterpret_cast<void*>(Static::growth_stacks());
- Static::set_growth_stacks(t);
-}
-
bool PageHeap::GrowHeap(Length n) {
ASSERT(kMaxPages >= kMinSystemAlloc);
if (n > kMaxValidPages) return false;
@@ -393,7 +384,6 @@
if (ptr == NULL) return false;
}
ask = actual_size >> kPageShift;
- RecordGrowth(ask << kPageShift);
uint64_t old_system_bytes = system_bytes_;
system_bytes_ += (ask << kPageShift);
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/page_heap.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -39,14 +39,6 @@
#include "pagemap.h"
#include "span.h"
-// This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if
-// you're porting to a system where you really can't get a stacktrace.
-#ifdef NO_TCMALLOC_SAMPLES
- // We use #define so code compiles even if you #include stacktrace.h somehow.
-# define GetStackTrace(stack, depth, skip) (0)
-#else
-# include "stacktrace.h"
-#endif
namespace tcmalloc {
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,130 +0,0 @@
-// Copyright (c) 2008, 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.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-
-#include "sampler.h"
-
-#include <algorithm> // For min()
-#include <cmath>
-
-using std::min;
-
-// The approximate gap in bytes between sampling actions.
-// I.e., we take one sample approximately once every
-// tcmalloc_sample_parameter bytes of allocation
-// i.e. about once every 512KB.
-#ifdef NO_TCMALLOC_SAMPLES
-DEFINE_int64(tcmalloc_sample_parameter, 0,
- "Unused: code is compiled with NO_TCMALLOC_SAMPLES");
-#else
-DEFINE_int64(tcmalloc_sample_parameter,
- EnvToInt64("TCMALLOC_SAMPLE_PARAMETER", 1<<19),
- "The approximate gap in bytes between sampling actions."
- "This must be between 1 and 1<<58.");
-// Note: there are other places in this file where the number 19 occurs.
-#endif
-
-namespace tcmalloc {
-
-// Statics for Sampler
-double Sampler::log_table_[1<<kFastlogNumBits];
-
-// Populate the lookup table for FastLog2.
-// This approximates the log2 curve with a step function.
-// Steps have height equal to log2 of the mid-point of the step.
-void Sampler::PopulateFastLog2Table() {
- for (int i = 0; i < (1<<kFastlogNumBits); i++) {
- log_table_[i] = (log(1.0 + static_cast<double>(i+0.5)/(1<<kFastlogNumBits))
- / log(2.0));
- }
-}
-
-int Sampler::GetSamplePeriod() {
- return FLAGS_tcmalloc_sample_parameter;
-}
-
-// Run this before using your sampler
-void Sampler::Init(uint32_t seed) {
- // Initialize PRNG
- if (seed != 0) {
- rnd_ = seed;
- } else {
- rnd_ = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this));
- if (rnd_ == 0) {
- rnd_ = 1;
- }
- }
- // Step it forward 20 times for good measure
- for (int i = 0; i < 20; i++) {
- rnd_ = NextRandom(rnd_);
- }
- // Initialize counter
- bytes_until_sample_ = PickNextSamplingPoint();
-}
-
-// Initialize the Statics for the Sampler class
-void Sampler::InitStatics() {
- PopulateFastLog2Table();
-}
-
-// Generates a geometric variable with the specified mean (512K by default).
-// This is done by generating a random number between 0 and 1 and applying
-// the inverse cumulative distribution function for an exponential.
-// Specifically: Let m be the inverse of the sample period, then
-// the probability distribution function is m*exp(-mx) so the CDF is
-// p = 1 - exp(-mx), so
-// q = 1 - p = exp(-mx)
-// log_e(q) = -mx
-// -log_e(q)/m = x
-// log_2(q) * (-log_e(2) * 1/m) = x
-// In the code, q is actually in the range 1 to 2**26, hence the -26 below
-size_t Sampler::PickNextSamplingPoint() {
- rnd_ = NextRandom(rnd_);
- // Take the top 26 bits as the random number
- // (This plus the 1<<58 sampling bound give a max possible step of
- // 5194297183973780480 bytes.)
- const uint64_t prng_mod_power = 48; // Number of bits in prng
- // The uint32_t cast is to prevent a (hard-to-reproduce) NAN
- // under piii debug for some binaries.
- double q = static_cast<uint32_t>(rnd_ >> (prng_mod_power - 26)) + 1.0;
- // Put the computed p-value through the CDF of a geometric.
- // For faster performance (save ~1/20th exec time), replace
- // min(0.0, FastLog2(q) - 26) by (Fastlog2(q) - 26.000705)
- // The value 26.000705 is used rather than 26 to compensate
- // for inaccuracies in FastLog2 which otherwise result in a
- // negative answer.
- return static_cast<size_t>(min(0.0, (FastLog2(q) - 26)) * (-log(2.0)
- * FLAGS_tcmalloc_sample_parameter) + 1);
-}
-
-} // namespace tcmalloc
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/sampler.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,174 +0,0 @@
-// Copyright (c) 2008, 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.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Daniel Ford
-
-#ifndef TCMALLOC_SAMPLER_H_
-#define TCMALLOC_SAMPLER_H_
-
-#include "tcmalloc-platform.h"
-#include "common.h"
-#include "static_vars.h"
-
-namespace tcmalloc {
-
-//-------------------------------------------------------------------
-// Sampler to decide when to create a sample trace for an allocation
-// Not thread safe: Each thread should have it's own sampler object.
-// Caller must use external synchronization if used
-// from multiple threads.
-//
-// With 512K average sample step (the default):
-// the probability of sampling a 4K allocation is about 0.00778
-// the probability of sampling a 1MB allocation is about 0.865
-// the probability of sampling a 1GB allocation is about 1.00000
-// In general, the probablity of sampling is an allocation of size X
-// given a flag value of Y (default 1M) is:
-// 1 - e^(-X/Y)
-//
-// With 128K average sample step:
-// the probability of sampling a 1MB allocation is about 0.99966
-// the probability of sampling a 1GB allocation is about 1.0
-// (about 1 - 2**(-26))
-// With 1M average sample step:
-// the probability of sampling a 4K allocation is about 0.00390
-// the probability of sampling a 1MB allocation is about 0.632
-// the probability of sampling a 1GB allocation is about 1.0
-//
-// The sampler works by representing memory as a long stream from
-// which allocations are taken. Some of the bytes in this stream are
-// marked and if an allocation includes a marked byte then it is
-// sampled. Bytes are marked according to a Poisson point process
-// with each byte being marked independently with probability
-// p = 1/tcmalloc_sample_parameter. This makes the probability
-// of sampling an allocation of X bytes equal to the CDF of
-// a geometric with mean tcmalloc_sample_parameter. (ie. the
-// probability that at least one byte in the range is marked). This
-// is accurately given by the CDF of the corresponding exponential
-// distribution : 1 - e^(X/tcmalloc_sample_parameter_)
-// Independence of the byte marking ensures independence of
-// the sampling of each allocation.
-//
-// This scheme is implemented by noting that, starting from any
-// fixed place, the number of bytes until the next marked byte
-// is geometrically distributed. This number is recorded as
-// bytes_until_sample_. Every allocation subtracts from this
-// number until it is less than 0. When this happens the current
-// allocation is sampled.
-//
-// When an allocation occurs, bytes_until_sample_ is reset to
-// a new independtly sampled geometric number of bytes. The
-// memoryless property of the point process means that this may
-// be taken as the number of bytes after the end of the current
-// allocation until the next marked byte. This ensures that
-// very large allocations which would intersect many marked bytes
-// only result in a single call to PickNextSamplingPoint.
-//-------------------------------------------------------------------
-
-class PERFTOOLS_DLL_DECL Sampler {
- public:
- // Initialize this sampler.
- // Passing a seed of 0 gives a non-deterministic
- // seed value given by casting the object ("this")
- void Init(uint32_t seed);
- void Cleanup();
-
- // Record allocation of "k" bytes. Return true iff allocation
- // should be sampled
- bool SampleAllocation(size_t k);
-
- // Generate a geometric with mean 512K (or FLAG_tcmalloc_sample_parameter)
- size_t PickNextSamplingPoint();
-
- // Initialize the statics for the Sampler class
- static void InitStatics();
-
- // Returns the current sample period
- int GetSamplePeriod();
-
- // The following are public for the purposes of testing
- static uint64_t NextRandom(uint64_t rnd_); // Returns the next prng value
- static double FastLog2(const double & d); // Computes Log2(x) quickly
- static void PopulateFastLog2Table(); // Populate the lookup table
-
- private:
- size_t bytes_until_sample_; // Bytes until we sample next
- uint64_t rnd_; // Cheap random number generator
-
- // Statics for the fast log
- // Note that this code may not depend on anything in //util
- // hence the duplication of functionality here
- static const int kFastlogNumBits = 10;
- static const int kFastlogMask = (1 << kFastlogNumBits) - 1;
- static double log_table_[1<<kFastlogNumBits]; // Constant
-};
-
-inline bool Sampler::SampleAllocation(size_t k) {
- if (bytes_until_sample_ < k) {
- bytes_until_sample_ = PickNextSamplingPoint();
- return true;
- } else {
- bytes_until_sample_ -= k;
- return false;
- }
-}
-
-// Inline functions which are public for testing purposes
-
-// Returns the next prng value.
-// pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48
-// This is the lrand64 generator.
-inline uint64_t Sampler::NextRandom(uint64_t rnd) {
- const uint64_t prng_mult = 0x5DEECE66DLL;
- const uint64_t prng_add = 0xB;
- const uint64_t prng_mod_power = 48;
- const uint64_t prng_mod_mask =
- ~((~static_cast<uint64_t>(0)) << prng_mod_power);
- return (prng_mult * rnd + prng_add) & prng_mod_mask;
-}
-
-// Adapted from //util/math/fastmath.[h|cc] by Noam Shazeer
-// This mimics the VeryFastLog2 code in those files
-inline double Sampler::FastLog2(const double & d) {
- ASSERT(d>0);
- COMPILE_ASSERT(sizeof(d) == sizeof(uint64_t), DoubleMustBe64Bits);
- uint64_t x;
- memcpy(&x, &d, sizeof(x)); // we depend on the compiler inlining this
- const uint32_t x_high = x >> 32;
- const uint32_t y = x_high >> (20 - kFastlogNumBits) & kFastlogMask;
- const int32_t exponent = ((x_high >> 20) & 0x7FF) - 1023;
- return exponent + log_table_[y];
-}
-
-} // namespace tcmalloc
-
-#endif // TCMALLOC_SAMPLER_H_
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/span.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/span.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/span.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -50,7 +50,6 @@
unsigned int refcount : 16; // Number of non-free objects
unsigned int sizeclass : 8; // Size-class for small objects (or 0)
unsigned int location : 2; // Is the span on a freelist, and if so, which?
- unsigned int sample : 1; // Sampled object?
#undef SPAN_HISTORY
#ifdef SPAN_HISTORY
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,154 +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: Andrew Fikes
-
-#include "tcmalloc-platform.h"
-#include "spinlock.h"
-#include "common.h"
-#include "static_vars.h"
-#include "stack_trace_table.h"
-
-namespace tcmalloc {
-
-bool StackTraceTable::Bucket::KeyEqual(uintptr_t h,
- const StackTrace& t) const {
- const bool eq = (this->hash == h && this->trace.depth == t.depth);
- for (int i = 0; eq && i < t.depth; ++i) {
- if (this->trace.stack[i] != t.stack[i]) {
- return false;
- }
- }
- return eq;
-}
-
-StackTraceTable::StackTraceTable()
- : error_(false),
- depth_total_(0),
- bucket_total_(0),
- table_(new Bucket*[kHashTableSize]()) {
- memset(table_, 0, kHashTableSize * sizeof(Bucket*));
-}
-
-StackTraceTable::~StackTraceTable() {
- delete[] table_;
-}
-
-void StackTraceTable::AddTrace(const StackTrace& t) {
- if (error_) {
- return;
- }
-
- // Hash function borrowed from heap-profile-table.cc
- uintptr_t h = 0;
- for (int i = 0; i < t.depth; ++i) {
- h += reinterpret_cast<uintptr_t>(t.stack[i]);
- h += h << 10;
- h ^= h >> 6;
- }
- h += h << 3;
- h ^= h >> 11;
-
- const int idx = h % kHashTableSize;
-
- Bucket* b = table_[idx];
- while (b != NULL && !b->KeyEqual(h, t)) {
- b = b->next;
- }
- if (b != NULL) {
- b->count++;
- b->trace.size += t.size; // keep cumulative size
- } else {
- depth_total_ += t.depth;
- bucket_total_++;
- b = Static::bucket_allocator()->New();
- if (b == NULL) {
- MESSAGE("tcmalloc: could not allocate bucket", sizeof(*b));
- error_ = true;
- } else {
- b->hash = h;
- b->trace = t;
- b->count = 1;
- b->next = table_[idx];
- table_[idx] = b;
- }
- }
-}
-
-void** StackTraceTable::ReadStackTracesAndClear() {
- if (error_) {
- return NULL;
- }
-
- // Allocate output array
- const int out_len = bucket_total_ * 3 + depth_total_ + 1;
- void** out = new void*[out_len];
- if (out == NULL) {
- MESSAGE("tcmalloc: allocation failed for stack traces\n",
- out_len * sizeof(*out));
- return NULL;
- }
-
- // Fill output array
- int idx = 0;
- for (int i = 0; i < kHashTableSize; ++i) {
- Bucket* b = table_[i];
- while (b != NULL) {
- out[idx++] = reinterpret_cast<void*>(static_cast<uintptr_t>(b->count));
- out[idx++] = reinterpret_cast<void*>(b->trace.size); // cumulative size
- out[idx++] = reinterpret_cast<void*>(b->trace.depth);
- for (int d = 0; d < b->trace.depth; ++d) {
- out[idx++] = b->trace.stack[d];
- }
- b = b->next;
- }
- }
- out[idx++] = static_cast<uintptr_t>(0);
- ASSERT(idx == out_len);
-
- // Clear state
- error_ = false;
- depth_total_ = 0;
- bucket_total_ = 0;
- SpinLockHolder h(Static::pageheap_lock());
- for (int i = 0; i < kHashTableSize; ++i) {
- Bucket* b = table_[i];
- while (b != NULL) {
- Bucket* next = b->next;
- Static::bucket_allocator()->Delete(b);
- b = next;
- }
- table_[i] = NULL;
- }
-
- return out;
-}
-
-} // namespace tcmalloc
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stack_trace_table.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,88 +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: Andrew Fikes
-//
-// Utility class for coalescing sampled stack traces. Not thread-safe.
-
-#ifndef TCMALLOC_STACK_TRACE_TABLE_H_
-#define TCMALLOC_STACK_TRACE_TABLE_H_
-
-#include "tcmalloc-platform.h"
-#include "common.h"
-
-namespace tcmalloc {
-
-class PERFTOOLS_DLL_DECL StackTraceTable {
- public:
- // REQUIRES: L < pageheap_lock
- StackTraceTable();
- ~StackTraceTable();
-
- // Adds stack trace "t" to table.
- //
- // REQUIRES: L >= pageheap_lock
- void AddTrace(const StackTrace& t);
-
- // Returns stack traces formatted per MallocExtension guidelines.
- // May return NULL on error. Clears state before returning.
- //
- // REQUIRES: L < pageheap_lock
- void** ReadStackTracesAndClear();
-
- // Exposed for PageHeapAllocator
- struct Bucket {
- // Key
- uintptr_t hash;
- StackTrace trace;
-
- // Payload
- int count;
- Bucket* next;
-
- bool KeyEqual(uintptr_t h, const StackTrace& t) const;
- };
-
- // For testing
- int depth_total() const { return depth_total_; }
- int bucket_total() const { return bucket_total_; }
-
- private:
- static const int kHashTableSize = 1 << 14; // => table_ is 128k
-
- bool error_;
- int depth_total_;
- int bucket_total_;
- Bucket** table_;
-};
-
-} // namespace tcmalloc
-
-#endif // TCMALLOC_STACK_TRACE_TABLE_H_
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,71 +0,0 @@
-// 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
-// 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: Sanjay Ghemawat
-//
-// Produce stack trace.
-//
-// There are three different ways we can try to get the stack trace:
-//
-// 1) Our hand-coded stack-unwinder. This depends on a certain stack
-// layout, which is used by gcc (and those systems using a
-// gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
-// It uses the frame pointer to do its work.
-//
-// 2) The libunwind library. This is still in development, and as a
-// separate library adds a new dependency, abut doesn't need a frame
-// pointer. It also doesn't call malloc.
-//
-// 3) The gdb unwinder -- also the one used by the c++ exception code.
-// It's obviously well-tested, but has a fatal flaw: it can call
-// malloc() from the unwinder. This is a problem because we're
-// trying to use the unwinder to instrument malloc().
-//
-// Note: if you add a new implementation here, make sure it works
-// correctly when GetStackTrace() is called with max_depth == 0.
-// Some code may do that.
-
-#include "tcmalloc-platform.h"
-#include "stacktrace.h"
-#include "stacktrace_config.h"
-
-#if defined(STACKTRACE_INL_HEADER)
-# include STACKTRACE_INL_HEADER
-#elif 0
-// This is for the benefit of code analysis tools that may have
-// trouble with the computed #include above.
-# include "stacktrace_x86-inl.h"
-# include "stacktrace_libunwind-inl.h"
-# include "stacktrace_generic-inl.h"
-# include "stacktrace_powerpc-inl.h"
-# include "stacktrace_win32-inl.h"
-#else
-# error Cannot calculate stack trace: will need to write for your environment
-#endif
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,116 +0,0 @@
-// 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
-// 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: Sanjay Ghemawat
-//
-// Routines to extract the current stack trace. These functions are
-// thread-safe.
-
-#ifndef GOOGLE_STACKTRACE_H_
-#define GOOGLE_STACKTRACE_H_
-
-// Annoying stuff for windows -- makes sure clients can import these functions
-#ifndef PERFTOOLS_DLL_DECL
-# ifdef _WIN32
-# define PERFTOOLS_DLL_DECL __declspec(dllimport)
-# else
-# define PERFTOOLS_DLL_DECL
-# endif
-#endif
-
-
-// Skips the most recent "skip_count" stack frames (also skips the
-// frame generated for the "GetStackFrames" routine itself), and then
-// records the pc values for up to the next "max_depth" frames in
-// "pcs", and the corresponding stack frame sizes in "sizes". Returns
-// the number of values recorded in "pcs"/"sizes".
-//
-// Example:
-// main() { foo(); }
-// foo() { bar(); }
-// bar() {
-// void* pcs[10];
-// int sizes[10];
-// int depth = GetStackFrames(pcs, sizes, 10, 1);
-// }
-//
-// The GetStackFrames call will skip the frame for "bar". It will
-// return 2 and will produce pc values that map to the following
-// procedures:
-// pcs[0] foo
-// pcs[1] main
-// (Actually, there may be a few more entries after "main" to account for
-// startup procedures.)
-// And corresponding stack frame sizes will also be recorded:
-// sizes[0] 16
-// sizes[1] 16
-// (Stack frame sizes of 16 above are just for illustration purposes.)
-// Stack frame sizes of 0 or less indicate that those frame sizes couldn't
-// be identified.
-//
-// This routine may return fewer stack frame entries than are
-// available. Also note that "pcs" and "sizes" must both be non-NULL.
-extern PERFTOOLS_DLL_DECL int GetStackFrames(void** pcs, int* sizes, int max_depth,
- int skip_count);
-
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackFramesWithContext(void** pcs, int* sizes, int max_depth,
- int skip_count, const void *uc);
-
-// This is similar to the GetStackFrames routine, except that it returns
-// the stack trace only, and not the stack frame sizes as well.
-// Example:
-// main() { foo(); }
-// foo() { bar(); }
-// bar() {
-// void* result[10];
-// int depth = GetStackTrace(result, 10, 1);
-// }
-//
-// This produces:
-// result[0] foo
-// result[1] main
-// .... ...
-//
-// "result" must not be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackTrace(void** result, int max_depth,
- int skip_count);
-
-// Same as above, but to be used from a signal handler. The "uc" parameter
-// should be the pointer to ucontext_t which was passed as the 3rd parameter
-// to sa_sigaction signal handler. It may help the unwinder to get a
-// better stack trace under certain conditions. The "uc" may safely be NULL.
-extern PERFTOOLS_DLL_DECL int GetStackTraceWithContext(void** result, int max_depth,
- int skip_count, const void *uc);
-
-#endif /* GOOGLE_STACKTRACE_H_ */
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_config.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_config.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_config.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -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 case.
-#if defined(__i386__) && __GNUC__ >= 2
-# if !defined(NO_FRAME_POINTER)
-# define STACKTRACE_INL_HEADER "stacktrace_x86-inl.h"
-# define STACKTRACE_SKIP_CONTEXT_ROUTINES 1
-# else
-# define STACKTRACE_INL_HEADER "stacktrace_generic-inl.h"
-# endif
-
-// Now, the x86_64 case.
-#elif 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"
-# 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 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_
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_generic-inl.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_generic-inl.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_generic-inl.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,106 +0,0 @@
-// 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
-// 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: Sanjay Ghemawat
-//
-// Portable implementation - just use glibc
-//
-// Note: The glibc implementation may cause a call to malloc.
-// This can cause a deadlock in HeapProfiler.
-#include <execinfo.h>
-#include <string.h>
-#include "stacktrace.h"
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
- 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
- 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];
-
- return result_count;
-}
-
-// If you change this function, also change GetStackTrace above:
-//
-// This GetStackFrames routine shares a lot of code with GetStackTrace
-// above. This code could have been refactored into a common routine,
-// and then both GetStackTrace/GetStackFrames could call that routine.
-// There are two problems with that:
-//
-// (1) The performance of the refactored-code suffers substantially - the
-// refactored needs to be able to record the stack trace when called
-// from GetStackTrace, and both the stack trace and stack frame sizes,
-// when called from GetStackFrames - this introduces enough new
-// conditionals that GetStackTrace performance can degrade by as much
-// as 50%.
-//
-// (2) Whether the refactored routine gets inlined into GetStackTrace and
-// GetStackFrames depends on the compiler, and we can't guarantee the
-// behavior either-way, even with "__attribute__ ((always_inline))"
-// or "__attribute__ ((noinline))". But we need this guarantee or the
-// frame counts may be off by one.
-//
-// Both (1) and (2) can be addressed without this code duplication, by
-// clever use of template functions, and by defining GetStackTrace and
-// GetStackFrames as macros that expand to these template functions.
-// However, this approach comes with its own set of problems - namely,
-// macros and preprocessor trouble - for example, if GetStackTrace
-// and/or GetStackFrames is ever defined as a member functions in some
-// class, we are in trouble.
-int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
- 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
- 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++)
- pcs[i] = stack[i + skip_count];
-
- // No implementation for finding out the stack frame sizes yet.
- memset(sizes, 0, sizeof(*sizes) * result_count);
-
- return result_count;
-}
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_libunwind-inl.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_libunwind-inl.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_libunwind-inl.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,156 +0,0 @@
-// 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
-// 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: Arun Sharma
-//
-// Produce stack trace using libunwind
-
-// We only need local unwinder.
-#define UNW_LOCAL_ONLY
-
-extern "C" {
-#include <assert.h>
-#include <string.h> // for memset()
-#include <libunwind.h>
-}
-#include "stacktrace.h"
-#include "logging.h"
-#include "spinlock.h"
-
-// Sometimes, we can try to get a stack trace from within a stack
-// trace, because libunwind can call mmap (maybe indirectly via an
-// internal mmap based memory allocator), and that mmap gets trapped
-// and causes a stack-trace request. If were to try to honor that
-// recursive request, we'd end up with infinite recursion or deadlock.
-// Luckily, it's safe to ignore those subsequent traces. In such
-// cases, we return 0 to indicate the situation.
-static SpinLock libunwind_lock(SpinLock::LINKER_INITIALIZED);
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
- void *ip;
- int n = 0;
- unw_cursor_t cursor;
- unw_context_t uc;
-
- if (!libunwind_lock.TryLock()) {
- return 0;
- }
-
- unw_getcontext(&uc);
- int ret = unw_init_local(&cursor, &uc);
- assert(ret >= 0);
- skip_count++; // Do not include the "GetStackTrace" frame
-
- while (n < max_depth) {
- int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip);
- if (ret < 0)
- break;
- if (skip_count > 0) {
- skip_count--;
- } else {
- result[n++] = ip;
- }
- ret = unw_step(&cursor);
- if (ret <= 0)
- break;
- }
-
- libunwind_lock.Unlock();
- return n;
-}
-
-// If you change this function, also change GetStackTrace above:
-//
-// This GetStackFrames routine shares a lot of code with GetStackTrace
-// above. This code could have been refactored into a common routine,
-// and then both GetStackTrace/GetStackFrames could call that routine.
-// There are two problems with that:
-//
-// (1) The performance of the refactored-code suffers substantially - the
-// refactored needs to be able to record the stack trace when called
-// from GetStackTrace, and both the stack trace and stack frame sizes,
-// when called from GetStackFrames - this introduces enough new
-// conditionals that GetStackTrace performance can degrade by as much
-// as 50%.
-//
-// (2) Whether the refactored routine gets inlined into GetStackTrace and
-// GetStackFrames depends on the compiler, and we can't guarantee the
-// behavior either-way, even with "__attribute__ ((always_inline))"
-// or "__attribute__ ((noinline))". But we need this guarantee or the
-// frame counts may be off by one.
-//
-// Both (1) and (2) can be addressed without this code duplication, by
-// clever use of template functions, and by defining GetStackTrace and
-// GetStackFrames as macros that expand to these template functions.
-// However, this approach comes with its own set of problems - namely,
-// macros and preprocessor trouble - for example, if GetStackTrace
-// and/or GetStackFrames is ever defined as a member functions in some
-// class, we are in trouble.
-int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
- void *ip;
- int n = 0;
- unw_cursor_t cursor;
- unw_context_t uc;
- unw_word_t sp = 0, next_sp = 0;
-
- if (!libunwind_lock.TryLock()) {
- return 0;
- }
-
- unw_getcontext(&uc);
- RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed");
- skip_count++; // Do not include the "GetStackFrames" frame
-
- while (skip_count--) {
- if (unw_step(&cursor) <= 0 ||
- unw_get_reg(&cursor, UNW_REG_SP, &next_sp) < 0) {
- goto out;
- }
- }
- while (n < max_depth) {
- sp = next_sp;
- if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0)
- break;
- if (unw_step(&cursor) <= 0 ||
- unw_get_reg(&cursor, UNW_REG_SP, &next_sp)) {
- // We couldn't step any further (possibly because we reached _start).
- // Provide the last good PC we've got, and get out.
- sizes[n] = 0;
- pcs[n++] = ip;
- break;
- }
- sizes[n] = next_sp - sp;
- pcs[n++] = ip;
- }
- out:
- libunwind_lock.Unlock();
- return n;
-}
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_powerpc-inl.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_powerpc-inl.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_powerpc-inl.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,206 +0,0 @@
-// 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. I'm guessing (hoping!) the code is much like
-// for x86. For apple machines, at least, it seems to be; see
-// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html
-// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
-// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882
-
-#include <stdint.h> // for uintptr_t
-#include <stdlib.h> // for NULL
-#include <stacktrace.h>
-
-// 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<bool STRICT_UNWINDING>
-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(""); }
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
- 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
-#ifdef __APPLE__
- __asm__ volatile ("mr %0,r1" : "=r" (sp));
-#else
- __asm__ volatile ("mr %0,1" : "=r" (sp));
-#endif
-
- // 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();
-
- // The LR save area is used by the callee, so the top entry is bogus.
- skip_count++;
-
- int n = 0;
- while (sp && n < max_depth) {
- 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(_CALL_AIX) || defined(_CALL_DARWIN)
- result[n++] = *(sp+2);
-#elif defined(_CALL_SYSV)
- result[n++] = *(sp+1);
-#elif defined(__APPLE__) || (defined(__linux) && 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);
-#else
-#error Need to specify the PPC ABI for your archiecture.
-#endif
- }
- // Use strict unwinding rules.
- sp = NextStackFrame<true>(sp);
- }
- return n;
-}
-
-// If you change this function, also change GetStackTrace above:
-//
-// This GetStackFrames routine shares a lot of code with GetStackTrace
-// above. This code could have been refactored into a common routine,
-// and then both GetStackTrace/GetStackFrames could call that routine.
-// There are two problems with that:
-//
-// (1) The performance of the refactored-code suffers substantially - the
-// refactored needs to be able to record the stack trace when called
-// from GetStackTrace, and both the stack trace and stack frame sizes,
-// when called from GetStackFrames - this introduces enough new
-// conditionals that GetStackTrace performance can degrade by as much
-// as 50%.
-//
-// (2) Whether the refactored routine gets inlined into GetStackTrace and
-// GetStackFrames depends on the compiler, and we can't guarantee the
-// behavior either-way, even with "__attribute__ ((always_inline))"
-// or "__attribute__ ((noinline))". But we need this guarantee or the
-// frame counts may be off by one.
-//
-// Both (1) and (2) can be addressed without this code duplication, by
-// clever use of template functions, and by defining GetStackTrace and
-// GetStackFrames as macros that expand to these template functions.
-// However, this approach comes with its own set of problems - namely,
-// macros and preprocessor trouble - for example, if GetStackTrace
-// and/or GetStackFrames is ever defined as a member functions in some
-// class, we are in trouble.
-int GetStackFrames(void** pcs, int *sizes, int max_depth, int skip_count) {
- void **sp;
-#ifdef __APPLE__
- __asm__ volatile ("mr %0,r1" : "=r" (sp));
-#else
- __asm__ volatile ("mr %0,1" : "=r" (sp));
-#endif
-
- StacktracePowerPCDummyFunction();
- // 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).
-
- 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<false>(sp);
- if (skip_count > 0) {
- skip_count--;
- } else {
-#if defined(_CALL_AIX) || defined(_CALL_DARWIN)
- pcs[n++] = *(sp+2);
-#elif defined(_CALL_SYSV)
- pcs[n++] = *(sp+1);
-#elif defined(__APPLE__) || (defined(__linux) && defined(__PPC64__))
- // This check is in case the compiler doesn't define _CALL_AIX/etc.
- pcs[n++] = *(sp+2);
-#elif defined(__linux)
- // This check is in case the compiler doesn't define _CALL_SYSV.
- pcs[n++] = *(sp+1);
-#else
-#error Need to specify the PPC ABI for your archiecture.
-#endif
- 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;
- }
- n++;
- }
- sp = next_sp;
- }
- return n;
-}
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_win32-inl.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_win32-inl.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_win32-inl.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,84 +0,0 @@
-// Copyright (c) 2008, 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.
-//
-// ---
-// Produces a stack trace for Windows. Normally, one could use
-// stacktrace_x86-inl.h or stacktrace_x86_64-inl.h -- and indeed, that
-// should work for binaries compiled using MSVC in "debug" mode.
-// However, in "release" mode, Windows uses frame-pointer
-// optimization, which makes getting a stack trace very difficult.
-//
-// There are several approaches one can take. One is to use Windows
-// intrinsics like StackWalk64. These can work, but have restrictions
-// on how successful they can be. Another attempt is to write a
-// version of stacktrace_x86-inl.h that has heuristic support for
-// dealing with FPO, similar to what WinDbg does (see
-// http://www.nynaeve.net/?p=97).
-//
-// The solution we've ended up doing is to call the undocumented
-// windows function RtlCaptureStackBackTrace, which probably doesn't
-// work with FPO but at least is fast, and doesn't require a symbol
-// server.
-//
-// This code is inspired by a patch from David Vitek:
-// http://code.google.com/p/google-perftools/issues/detail?id=83
-
-#include "tcmalloc-platform.h"
-#include <windows.h> // for GetProcAddress and GetModuleHandle
-#include <assert.h>
-
-typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
- IN ULONG frames_to_skip,
- IN ULONG frames_to_capture,
- OUT PVOID *backtrace,
- OUT PULONG backtrace_hash);
-
-// Load the function we need at static init time, where we don't have
-// to worry about someone else holding the loader's lock.
-static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
- (RtlCaptureStackBackTrace_Function*)
- GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
-
-PERFTOOLS_DLL_DECL int GetStackTrace(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,
- result, 0);
-}
-
-PERFTOOLS_DLL_DECL int GetStackFrames(void** /* pcs */,
- int* /* sizes */,
- int /* max_depth */,
- int /* skip_count */) {
- assert(0 == "Not yet implemented");
- return 0;
-}
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_with_context.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_with_context.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_with_context.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,61 +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
-//
-// This code logically belongs in stacktrace.cc, but
-// it is moved into (this) separate file in order to
-// prevent inlining of routines defined here.
-//
-// Inlining causes skip_count to be incorrect, and there
-// is no portable way to prevent it.
-//
-// Eventually LTO (link-time optimization) and/or LLVM
-// may inline this code anyway. Let's hope they respect
-// ATTRIBUTE_NOINLINE.
-
-#include "tcmalloc-platform.h"
-#include "stacktrace.h"
-#include "stacktrace_config.h"
-#include "basictypes.h"
-
-#if !defined(STACKTRACE_SKIP_CONTEXT_ROUTINES)
-ATTRIBUTE_NOINLINE PERFTOOLS_DLL_DECL
-int GetStackFramesWithContext(void** pcs, int* sizes, int max_depth,
- int skip_count, const void * /* uc */) {
- return GetStackFrames(pcs, sizes, max_depth, skip_count + 1);
-}
-
-ATTRIBUTE_NOINLINE PERFTOOLS_DLL_DECL
-int GetStackTraceWithContext(void** result, int max_depth,
- int skip_count, const void * /* uc */) {
- return GetStackTrace(result, max_depth, skip_count + 1);
-}
-#endif
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86-inl.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86-inl.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86-inl.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,525 +0,0 @@
-// 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
-// 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: Sanjay Ghemawat
-//
-// Produce stack trace
-//
-// NOTE: there is code duplication between
-// GetStackTrace, GetStackTraceWithContext, GetStackFrames and
-// GetStackFramesWithContext. If you update one, update them all.
-//
-// There is no easy way to avoid this, because inlining
-// interferes with skip_count, and there is no portable
-// way to turn inlining off, or force it always on.
-
-#include "tcmalloc-platform.h"
-
-#include <stdlib.h> // for NULL
-#include <assert.h>
-#if HAVE_UCONTEXT_H
-#include <ucontext.h> // for ucontext_t
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h> // for uintptr_t
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h> // for msync
-#include "vdso_support.h"
-#endif
-
-#include "stacktrace.h"
-
-#if defined(__linux__) && defined(__i386__) && defined(__ELF__) && defined(HAVE_MMAP)
-// Count "push %reg" instructions in VDSO __kernel_vsyscall(),
-// preceeding "syscall" or "sysenter".
-// If __kernel_vsyscall uses frame pointer, answer 0.
-//
-// kMaxBytes tells how many instruction bytes of __kernel_vsyscall
-// to analyze before giving up. Up to kMaxBytes+1 bytes of
-// instructions could be accessed.
-//
-// Here are known __kernel_vsyscall instruction sequences:
-//
-// SYSENTER (linux-2.6.26/arch/x86/vdso/vdso32/sysenter.S).
-// Used on Intel.
-// 0xffffe400 <__kernel_vsyscall+0>: push %ecx
-// 0xffffe401 <__kernel_vsyscall+1>: push %edx
-// 0xffffe402 <__kernel_vsyscall+2>: push %ebp
-// 0xffffe403 <__kernel_vsyscall+3>: mov %esp,%ebp
-// 0xffffe405 <__kernel_vsyscall+5>: sysenter
-//
-// SYSCALL (see linux-2.6.26/arch/x86/vdso/vdso32/syscall.S).
-// Used on AMD.
-// 0xffffe400 <__kernel_vsyscall+0>: push %ebp
-// 0xffffe401 <__kernel_vsyscall+1>: mov %ecx,%ebp
-// 0xffffe403 <__kernel_vsyscall+3>: syscall
-//
-// i386 (see linux-2.6.26/arch/x86/vdso/vdso32/int80.S)
-// 0xffffe400 <__kernel_vsyscall+0>: int $0x80
-// 0xffffe401 <__kernel_vsyscall+1>: ret
-//
-static const int kMaxBytes = 10;
-
-// We use assert()s instead of DCHECK()s -- this is too low level
-// for DCHECK().
-
-static int CountPushInstructions(const unsigned char *const addr) {
- int result = 0;
- for (int i = 0; i < kMaxBytes; ++i) {
- if (addr[i] == 0x89) {
- // "mov reg,reg"
- if (addr[i + 1] == 0xE5) {
- // Found "mov %esp,%ebp".
- return 0;
- }
- ++i; // Skip register encoding byte.
- } else if (addr[i] == 0x0F &&
- (addr[i + 1] == 0x34 || addr[i + 1] == 0x05)) {
- // Found "sysenter" or "syscall".
- return result;
- } else if ((addr[i] & 0xF0) == 0x50) {
- // Found "push %reg".
- ++result;
- } else if (addr[i] == 0xCD && addr[i + 1] == 0x80) {
- // Found "int $0x80"
- assert(result == 0);
- return 0;
- } else {
- // Unexpected instruction.
- assert(0 == "unexpected instruction in __kernel_vsyscall");
- return 0;
- }
- }
- // Unexpected: didn't find SYSENTER or SYSCALL in
- // [__kernel_vsyscall, __kernel_vsyscall + kMaxBytes) interval.
- assert(0 == "did not find SYSENTER or SYSCALL in __kernel_vsyscall");
- return 0;
-}
-#endif
-
-// 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<bool STRICT_UNWINDING, bool WITH_CONTEXT>
-static void **NextStackFrame(void **old_sp, const void *uc) {
- void **new_sp = (void **) *old_sp;
-
-#if defined(__linux__) && defined(__i386__) && defined(HAVE_VDSO_SUPPORT)
- if (WITH_CONTEXT && uc != NULL) {
- // How many "push %reg" instructions are there at __kernel_vsyscall?
- // This is constant for a given kernel and processor, so compute
- // it only once.
- static int num_push_instructions = -1; // Sentinel: not computed yet.
- // Initialize with sentinel value: __kernel_rt_sigreturn can not possibly
- // be there.
- static const unsigned char *kernel_rt_sigreturn_address = NULL;
- static const unsigned char *kernel_vsyscall_address = NULL;
- if (num_push_instructions == -1) {
- base::VDSOSupport vdso;
- if (vdso.IsPresent()) {
- base::VDSOSupport::SymbolInfo rt_sigreturn_symbol_info;
- base::VDSOSupport::SymbolInfo vsyscall_symbol_info;
- if (!vdso.LookupSymbol("__kernel_rt_sigreturn", "LINUX_2.5",
- STT_FUNC, &rt_sigreturn_symbol_info) ||
- !vdso.LookupSymbol("__kernel_vsyscall", "LINUX_2.5",
- STT_FUNC, &vsyscall_symbol_info) ||
- rt_sigreturn_symbol_info.address == NULL ||
- vsyscall_symbol_info.address == NULL) {
- // Unexpected: 32-bit VDSO is present, yet one of the expected
- // symbols is missing or NULL.
- assert(0 == "VDSO is present, but doesn't have expected symbols");
- num_push_instructions = 0;
- } else {
- kernel_rt_sigreturn_address =
- reinterpret_cast<const unsigned char *>(
- rt_sigreturn_symbol_info.address);
- kernel_vsyscall_address =
- reinterpret_cast<const unsigned char *>(
- vsyscall_symbol_info.address);
- num_push_instructions =
- CountPushInstructions(kernel_vsyscall_address);
- }
- } else {
- num_push_instructions = 0;
- }
- }
- if (num_push_instructions != 0 && kernel_rt_sigreturn_address != NULL &&
- old_sp[1] == kernel_rt_sigreturn_address) {
- const ucontext_t *ucv = static_cast<const ucontext_t *>(uc);
- // This kernel does not use frame pointer in its VDSO code,
- // and so %ebp is not suitable for unwinding.
- const void **const reg_ebp =
- reinterpret_cast<const void **>(ucv->uc_mcontext.gregs[REG_EBP]);
- const unsigned char *const reg_eip =
- reinterpret_cast<unsigned char *>(ucv->uc_mcontext.gregs[REG_EIP]);
- if (new_sp == reg_ebp &&
- kernel_vsyscall_address <= reg_eip &&
- reg_eip - kernel_vsyscall_address < kMaxBytes) {
- // We "stepped up" to __kernel_vsyscall, but %ebp is not usable.
- // Restore from 'ucv' instead.
- void **const reg_esp =
- reinterpret_cast<void **>(ucv->uc_mcontext.gregs[REG_ESP]);
- // Check that alleged %esp is not NULL and is reasonably aligned.
- if (reg_esp &&
- ((uintptr_t)reg_esp & (sizeof(reg_esp) - 1)) == 0) {
- // Check that alleged %esp is actually readable. This is to prevent
- // "double fault" in case we hit the first fault due to e.g. stack
- // corruption.
- //
- // page_size is linker-initalized to avoid async-unsafe locking
- // that GCC would otherwise insert (__cxa_guard_acquire etc).
- static int page_size;
- if (page_size == 0) {
- // First time through.
- page_size = getpagesize();
- }
- void *const reg_esp_aligned =
- reinterpret_cast<void *>(
- (uintptr_t)(reg_esp + num_push_instructions - 1) &
- ~(page_size - 1));
- if (msync(reg_esp_aligned, page_size, MS_ASYNC) == 0) {
- // Alleged %esp is readable, use it for further unwinding.
- new_sp = reinterpret_cast<void **>(
- reg_esp[num_push_instructions - 1]);
- }
- }
- }
- }
- }
-#endif
-
- // 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;
-#ifdef __i386__
- // On 64-bit machines, the stack pointer can be very close to
- // 0xffffffff, so we explicitly check for a pointer into the
- // last two pages in the address space
- if ((uintptr_t)new_sp >= 0xffffe000) return NULL;
-#endif
-#ifdef HAVE_MMAP
- if (!STRICT_UNWINDING) {
- // Lax sanity checks cause a crash on AMD-based machines with
- // VDSO-enabled kernels.
- // Make an extra sanity check to insure new_sp is readable.
- // Note: NextStackFrame<false>() is only called while the program
- // is already on its last leg, so it's ok to be slow here.
- static int page_size = getpagesize();
- void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1));
- if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1)
- return NULL;
- }
-#endif
- return new_sp;
-}
-
-// If you change this function, see NOTE at the top of file.
-// Same as above, but with signal ucontext_t pointer.
-int GetStackTraceWithContext(void** result,
- int max_depth,
- int skip_count,
- const void *uc) {
- 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.
- // It's always correct on llvm, and the techniques below aren't (in
- // particular, llvm-gcc will make a copy of pcs, so it's not in sp[2]),
- // so we also prefer __builtin_frame_address when running under llvm.
- sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#elif defined(__i386__)
- // Stack frame format:
- // sp[0] pointer to previous frame
- // sp[1] caller address
- // sp[2] first argument
- // ...
- // NOTE: This will break under llvm, since result is a copy and not in sp[2]
- sp = (void **)&result - 2;
-#elif defined(__x86_64__)
- unsigned long rbp;
- // Move the value of the register %rbp into the local variable rbp.
- // We need 'volatile' to prevent this instruction from getting moved
- // around during optimization to before function prologue is done.
- // An alternative way to achieve this
- // would be (before this __asm__ instruction) to call Noop() defined as
- // static void Noop() __attribute__ ((noinline)); // prevent inlining
- // static void Noop() { asm(""); } // prevent optimizing-away
- __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
- // Arguments are passed in registers on x86-64, so we can't just
- // offset from &result
- sp = (void **) rbp;
-#else
-# error Using stacktrace_x86-inl.h on a non x86 architecture!
-#endif
-
- int n = 0;
- while (sp && n < max_depth) {
- if (*(sp+1) == reinterpret_cast<void *>(0)) {
- // In 64-bit code, we often see a frame that
- // points to itself and has a return address of 0.
- break;
- }
- if (skip_count > 0) {
- skip_count--;
- } else {
- result[n++] = *(sp+1);
- }
- // Use strict unwinding rules.
- sp = NextStackFrame<true, true>(sp, uc);
- }
- return n;
-}
-
-int GetStackTrace(void** result, int max_depth, int skip_count) {
- 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.
- // It's always correct on llvm, and the techniques below aren't (in
- // particular, llvm-gcc will make a copy of pcs, so it's not in sp[2]),
- // so we also prefer __builtin_frame_address when running under llvm.
- sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#elif defined(__i386__)
- // Stack frame format:
- // sp[0] pointer to previous frame
- // sp[1] caller address
- // sp[2] first argument
- // ...
- // NOTE: This will break under llvm, since result is a copy and not in sp[2]
- sp = (void **)&result - 2;
-#elif defined(__x86_64__)
- unsigned long rbp;
- // Move the value of the register %rbp into the local variable rbp.
- // We need 'volatile' to prevent this instruction from getting moved
- // around during optimization to before function prologue is done.
- // An alternative way to achieve this
- // would be (before this __asm__ instruction) to call Noop() defined as
- // static void Noop() __attribute__ ((noinline)); // prevent inlining
- // static void Noop() { asm(""); } // prevent optimizing-away
- __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
- // Arguments are passed in registers on x86-64, so we can't just
- // offset from &result
- sp = (void **) rbp;
-#else
-# error Using stacktrace_x86-inl.h on a non x86 architecture!
-#endif
-
- int n = 0;
- while (sp && n < max_depth) {
- if (*(sp+1) == reinterpret_cast<void *>(0)) {
- // In 64-bit code, we often see a frame that
- // points to itself and has a return address of 0.
- break;
- }
- if (skip_count > 0) {
- skip_count--;
- } else {
- result[n++] = *(sp+1);
- }
- // Use strict unwinding rules.
- sp = NextStackFrame<true, false>(sp, NULL);
- }
- return n;
-}
-
-// If you change this function, see NOTE at the top of file.
-//
-// This GetStackFrames routine shares a lot of code with GetStackTrace
-// above. This code could have been refactored into a common routine,
-// and then both GetStackTrace/GetStackFrames could call that routine.
-// There are two problems with that:
-//
-// (1) The performance of the refactored-code suffers substantially - the
-// refactored needs to be able to record the stack trace when called
-// from GetStackTrace, and both the stack trace and stack frame sizes,
-// when called from GetStackFrames - this introduces enough new
-// conditionals that GetStackTrace performance can degrade by as much
-// as 50%.
-//
-// (2) Whether the refactored routine gets inlined into GetStackTrace and
-// GetStackFrames depends on the compiler, and we can't guarantee the
-// behavior either-way, even with "__attribute__ ((always_inline))"
-// or "__attribute__ ((noinline))". But we need this guarantee or the
-// frame counts may be off by one.
-//
-// Both (1) and (2) can be addressed without this code duplication, by
-// clever use of template functions, and by defining GetStackTrace and
-// GetStackFrames as macros that expand to these template functions.
-// However, this approach comes with its own set of problems - namely,
-// macros and preprocessor trouble - for example, if GetStackTrace
-// and/or GetStackFrames is ever defined as a member functions in some
-// class, we are in trouble.
-int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
- 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.
- // It's always correct on llvm, and the techniques below aren't (in
- // particular, llvm-gcc will make a copy of pcs, so it's not in sp[2]),
- // so we also prefer __builtin_frame_address when running under llvm.
- sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#elif defined(__i386__)
- // Stack frame format:
- // sp[0] pointer to previous frame
- // sp[1] caller address
- // sp[2] first argument
- // ...
- sp = (void **)&pcs - 2;
-#elif defined(__x86_64__)
- unsigned long rbp;
- // Move the value of the register %rbp into the local variable rbp.
- // We need 'volatile' to prevent this instruction from getting moved
- // around during optimization to before function prologue is done.
- // An alternative way to achieve this
- // would be (before this __asm__ instruction) to call Noop() defined as
- // static void Noop() __attribute__ ((noinline)); // prevent inlining
- // static void Noop() { asm(""); } // prevent optimizing-away
- __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
- // Arguments are passed in registers on x86-64, so we can't just
- // offset from &result
- sp = (void **) rbp;
-#else
-# error Using stacktrace_x86-inl.h on a non x86 architecture!
-#endif
-
- int n = 0;
- while (sp && n < max_depth) {
- if (*(sp+1) == reinterpret_cast<void *>(0)) {
- // In 64-bit code, we often see a frame that
- // points to itself and has a return address of 0.
- break;
- }
- // 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<false, false>(sp, NULL);
- if (skip_count > 0) {
- skip_count--;
- } else {
- pcs[n] = *(sp+1);
- 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;
- }
- n++;
- }
- sp = next_sp;
- }
- return n;
-}
-
-// If you change this function, see NOTE at the top of file.
-// Same as above, but with signal ucontext_t pointer.
-int GetStackFramesWithContext(void** pcs,
- int* sizes,
- int max_depth,
- int skip_count,
- const void *uc) {
- 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.
- // It's always correct on llvm, and the techniques below aren't (in
- // particular, llvm-gcc will make a copy of pcs, so it's not in sp[2]),
- // so we also prefer __builtin_frame_address when running under llvm.
- sp = reinterpret_cast<void**>(__builtin_frame_address(0));
-#elif defined(__i386__)
- // Stack frame format:
- // sp[0] pointer to previous frame
- // sp[1] caller address
- // sp[2] first argument
- // ...
- // NOTE: This will break under llvm, since result is a copy and not in sp[2]
- sp = (void **)&pcs - 2;
-#elif defined(__x86_64__)
- unsigned long rbp;
- // Move the value of the register %rbp into the local variable rbp.
- // We need 'volatile' to prevent this instruction from getting moved
- // around during optimization to before function prologue is done.
- // An alternative way to achieve this
- // would be (before this __asm__ instruction) to call Noop() defined as
- // static void Noop() __attribute__ ((noinline)); // prevent inlining
- // static void Noop() { asm(""); } // prevent optimizing-away
- __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
- // Arguments are passed in registers on x86-64, so we can't just
- // offset from &result
- sp = (void **) rbp;
-#else
-# error Using stacktrace_x86-inl.h on a non x86 architecture!
-#endif
-
- int n = 0;
- while (sp && n < max_depth) {
- if (*(sp+1) == reinterpret_cast<void *>(0)) {
- // In 64-bit code, we often see a frame that
- // points to itself and has a return address of 0.
- break;
- }
- // 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<false, true>(sp, uc);
- if (skip_count > 0) {
- skip_count--;
- } else {
- pcs[n] = *(sp+1);
- 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;
- }
- n++;
- }
- sp = next_sp;
- }
- return n;
-}
Deleted: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86_64-inl.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86_64-inl.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/stacktrace_x86_64-inl.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -1,151 +0,0 @@
-// 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
-// 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: Arun Sharma
-//
-// Produce stack trace using libgcc
-
-extern "C" {
-#include <stdlib.h> // for NULL
-#include <unwind.h> // ABI defined unwinder
-#include <string.h> // for memset
-}
-#include "stacktrace.h"
-
-typedef struct {
- void **result;
- int max_depth;
- int skip_count;
- int count;
-} trace_arg_t;
-
-
-// Workaround for the malloc() in _Unwind_Backtrace() issue.
-static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) {
- return _URC_NO_REASON;
-}
-
-
-// This code is not considered ready to run until
-// static initializers run so that we are guaranteed
-// that any malloc-related initialization is done.
-static bool ready_to_run = false;
-class StackTraceInit {
- public:
- StackTraceInit() {
- // Extra call to force initialization
- _Unwind_Backtrace(nop_backtrace, NULL);
- ready_to_run = true;
- }
-};
-
-static StackTraceInit module_initializer; // Force initialization
-
-static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
- trace_arg_t *targ = (trace_arg_t *) opq;
-
- if (targ->skip_count > 0) {
- targ->skip_count--;
- } else {
- targ->result[targ->count++] = (void *) _Unwind_GetIP(uc);
- }
-
- if (targ->count == targ->max_depth)
- return _URC_END_OF_STACK;
-
- return _URC_NO_REASON;
-}
-
-// If you change this function, also change GetStackFrames below.
-int GetStackTrace(void** result, int max_depth, int skip_count) {
- if (!ready_to_run)
- return 0;
-
- trace_arg_t targ;
-
- skip_count += 1; // Do not include the "GetStackTrace" frame
-
- targ.result = result;
- targ.max_depth = max_depth;
- targ.skip_count = skip_count;
- targ.count = 0;
-
- _Unwind_Backtrace(GetOneFrame, &targ);
-
- return targ.count;
-}
-
-// If you change this function, also change GetStackTrace above:
-//
-// This GetStackFrames routine shares a lot of code with GetStackTrace
-// above. This code could have been refactored into a common routine,
-// and then both GetStackTrace/GetStackFrames could call that routine.
-// There are two problems with that:
-//
-// (1) The performance of the refactored-code suffers substantially - the
-// refactored needs to be able to record the stack trace when called
-// from GetStackTrace, and both the stack trace and stack frame sizes,
-// when called from GetStackFrames - this introduces enough new
-// conditionals that GetStackTrace performance can degrade by as much
-// as 50%.
-//
-// (2) Whether the refactored routine gets inlined into GetStackTrace and
-// GetStackFrames depends on the compiler, and we can't guarantee the
-// behavior either-way, even with "__attribute__ ((always_inline))"
-// or "__attribute__ ((noinline))". But we need this guarantee or the
-// frame counts may be off by one.
-//
-// Both (1) and (2) can be addressed without this code duplication, by
-// clever use of template functions, and by defining GetStackTrace and
-// GetStackFrames as macros that expand to these template functions.
-// However, this approach comes with its own set of problems - namely,
-// macros and preprocessor trouble - for example, if GetStackTrace
-// and/or GetStackFrames is ever defined as a member functions in some
-// class, we are in trouble.
-int GetStackFrames(void** pcs, int* sizes, int max_depth, int skip_count) {
- if (!ready_to_run)
- return 0;
-
- trace_arg_t targ;
-
- skip_count += 1; // Do not include the "GetStackFrames" frame
-
- targ.result = pcs;
- targ.max_depth = max_depth;
- targ.skip_count = skip_count;
- targ.count = 0;
-
- _Unwind_Backtrace(GetOneFrame, &targ);
-
- // No implementation for finding out the stack frame sizes yet.
- memset(sizes, 0, sizeof(*sizes) * targ.count);
-
- return targ.count;
-}
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -31,7 +31,6 @@
// Author: Ken Ashcraft <opensource at google.com>
#include "static_vars.h"
-#include "sampler.h" // for the init function
namespace tcmalloc {
@@ -39,10 +38,6 @@
SizeMap Static::sizemap_;
CentralFreeListPadded Static::central_cache_[kNumClasses];
PageHeapAllocator<Span> Static::span_allocator_;
-PageHeapAllocator<StackTrace> Static::stacktrace_allocator_;
-Span Static::sampled_objects_;
-PageHeapAllocator<StackTraceTable::Bucket> Static::bucket_allocator_;
-StackTrace* Static::growth_stacks_ = NULL;
char Static::pageheap_memory_[sizeof(PageHeap)];
void Static::InitStaticVars() {
@@ -50,16 +45,12 @@
span_allocator_.Init();
span_allocator_.New(); // Reduce cache conflicts
span_allocator_.New(); // Reduce cache conflicts
- stacktrace_allocator_.Init();
- bucket_allocator_.Init();
// Do a bit of sanitizing: make sure central_cache is aligned properly
CHECK_CONDITION((sizeof(central_cache_[0]) % 64) == 0);
for (int i = 0; i < kNumClasses; ++i) {
central_cache_[i].Init(i);
}
new ((void*)pageheap_memory_) PageHeap;
- DLL_Init(&sampled_objects_);
- Sampler::InitStatics();
}
} // namespace tcmalloc
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/static_vars.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -42,7 +42,6 @@
#include "page_heap.h"
#include "page_heap_allocator.h"
#include "span.h"
-#include "stack_trace_table.h"
namespace tcmalloc {
@@ -71,19 +70,7 @@
static PageHeapAllocator<Span>* span_allocator() { return &span_allocator_; }
- static PageHeapAllocator<StackTrace>* stacktrace_allocator() {
- return &stacktrace_allocator_;
- }
- static StackTrace* growth_stacks() { return growth_stacks_; }
- static void set_growth_stacks(StackTrace* s) { growth_stacks_ = s; }
-
- // State kept for sampled allocations (/pprof/heap support)
- static Span* sampled_objects() { return &sampled_objects_; }
- static PageHeapAllocator<StackTraceTable::Bucket>* bucket_allocator() {
- return &bucket_allocator_;
- }
-
private:
static SpinLock pageheap_lock_;
@@ -95,16 +82,8 @@
static SizeMap sizemap_;
static CentralFreeListPadded central_cache_[kNumClasses];
static PageHeapAllocator<Span> span_allocator_;
- static PageHeapAllocator<StackTrace> stacktrace_allocator_;
static Span sampled_objects_;
- static PageHeapAllocator<StackTraceTable::Bucket> bucket_allocator_;
- // Linked list of stack traces recorded every time we allocated memory
- // from the system. Useful for finding allocation sites that cause
- // increase in the footprint of the system. The linked list pointer
- // is stored in trace->stack[kMaxStackDepth-1].
- static StackTrace* growth_stacks_;
-
// PageHeap uses a constructor for initialization. Like the members above,
// we can't depend on initialization order, so pageheap is new'd
// into this buffer.
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/tcmalloc.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -139,7 +139,6 @@
using tcmalloc::PageHeapAllocator;
using tcmalloc::SizeMap;
using tcmalloc::Span;
-using tcmalloc::StackTrace;
using tcmalloc::Static;
using tcmalloc::ThreadCache;
@@ -420,52 +419,6 @@
delete[] buffer;
}
-static void** DumpHeapGrowthStackTraces() {
- // Count how much space we need
- int needed_slots = 0;
- {
- SpinLockHolder h(Static::pageheap_lock());
- for (StackTrace* t = Static::growth_stacks();
- t != NULL;
- t = reinterpret_cast<StackTrace*>(
- t->stack[tcmalloc::kMaxStackDepth-1])) {
- needed_slots += 3 + t->depth;
- }
- needed_slots += 100; // Slop in case list grows
- needed_slots += needed_slots/8; // An extra 12.5% slop
- }
-
- void** result = new void*[needed_slots];
- if (result == NULL) {
- MESSAGE("tcmalloc: allocation failed for stack trace slots",
- needed_slots * sizeof(*result));
- return NULL;
- }
-
- SpinLockHolder h(Static::pageheap_lock());
- int used_slots = 0;
- for (StackTrace* t = Static::growth_stacks();
- t != NULL;
- t = reinterpret_cast<StackTrace*>(
- t->stack[tcmalloc::kMaxStackDepth-1])) {
- ASSERT(used_slots < needed_slots); // Need to leave room for terminator
- if (used_slots + 3 + t->depth >= needed_slots) {
- // No more room
- break;
- }
-
- result[used_slots+0] = reinterpret_cast<void*>(static_cast<uintptr_t>(1));
- result[used_slots+1] = reinterpret_cast<void*>(t->size);
- result[used_slots+2] = reinterpret_cast<void*>(t->depth);
- for (int d = 0; d < t->depth; d++) {
- result[used_slots+3+d] = t->stack[d];
- }
- used_slots += 3 + t->depth;
- }
- result[used_slots] = reinterpret_cast<void*>(static_cast<uintptr_t>(0));
- return result;
-}
-
// TCMalloc's support for extra malloc interfaces
class TCMallocImplementation : public MallocExtension {
public:
@@ -481,23 +434,6 @@
}
}
- virtual void** ReadStackTraces(int* sample_period) {
- tcmalloc::StackTraceTable table;
- {
- SpinLockHolder h(Static::pageheap_lock());
- Span* sampled = Static::sampled_objects();
- for (Span* s = sampled->next; s != sampled; s = s->next) {
- table.AddTrace(*reinterpret_cast<StackTrace*>(s->objects));
- }
- }
- *sample_period = ThreadCache::GetCache()->GetSamplePeriod();
- return table.ReadStackTracesAndClear(); // grabs and releases pageheap_lock
- }
-
- virtual void** ReadHeapGrowthStackTraces() {
- return DumpHeapGrowthStackTraces();
- }
-
virtual bool GetNumericProperty(const char* name, size_t* value) {
ASSERT(name != NULL);
@@ -637,34 +573,6 @@
// Helpers for the exported routines below
//-------------------------------------------------------------------
-static Span* DoSampledAllocation(size_t size) {
- // Grab the stack trace outside the heap lock
- StackTrace tmp;
- tmp.depth = GetStackTrace(tmp.stack, tcmalloc::kMaxStackDepth, 1);
- tmp.size = size;
-
- SpinLockHolder h(Static::pageheap_lock());
- // Allocate span
- Span *span = Static::pageheap()->New(tcmalloc::pages(size == 0 ? 1 : size));
- if (span == NULL) {
- return NULL;
- }
-
- // Allocate stack trace
- StackTrace *stack = Static::stacktrace_allocator()->New();
- if (stack == NULL) {
- // Sampling failed because of lack of memory
- return span;
- }
-
- *stack = tmp;
- span->sample = 1;
- span->objects = stack;
- tcmalloc::DLL_Prepend(Static::sampled_objects(), span);
-
- return span;
-}
-
static inline bool CheckCachedSizeClass(void *ptr) {
PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
size_t cached_value = Static::pageheap()->GetSizeClassIfCached(p);
@@ -684,53 +592,18 @@
CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift));
}
-// Copy of FLAGS_tcmalloc_large_alloc_report_threshold with
-// automatic increases factored in.
-static int64_t large_alloc_threshold =
- (kPageSize > FLAGS_tcmalloc_large_alloc_report_threshold
- ? kPageSize : FLAGS_tcmalloc_large_alloc_report_threshold);
-static void ReportLargeAlloc(Length num_pages, void* result) {
- StackTrace stack;
- stack.depth = GetStackTrace(stack.stack, tcmalloc::kMaxStackDepth, 1);
-
- static const int N = 1000;
- char buffer[N];
- TCMalloc_Printer printer(buffer, N);
- printer.printf("tcmalloc: large alloc %llu bytes == %p @ ",
- static_cast<unsigned long long>(num_pages) << kPageShift,
- result);
- for (int i = 0; i < stack.depth; i++) {
- printer.printf(" %p", stack.stack[i]);
- }
- printer.printf("\n");
- write(STDERR_FILENO, buffer, strlen(buffer));
-}
-
namespace {
// Helper for do_malloc().
inline void* do_malloc_pages(Length num_pages) {
Span *span;
- bool report_large = false;
{
SpinLockHolder h(Static::pageheap_lock());
span = Static::pageheap()->New(num_pages);
- 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.
- // We cap the threshold at 8GB to avoid overflow problems.
- large_alloc_threshold = (threshold + threshold/8 < 8ll<<30
- ? threshold + threshold/8 : 8ll<<30);
- report_large = true;
- }
}
- void* result = (span == NULL ? NULL : SpanToMallocResult(span));
- if (report_large) {
- ReportLargeAlloc(num_pages, result);
- }
- return result;
+ return (span == NULL ? NULL : SpanToMallocResult(span));
}
inline void* do_malloc(size_t size) {
@@ -738,12 +611,7 @@
// The following call forces module initialization
ThreadCache* heap = ThreadCache::GetCache();
- if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) {
- Span* span = DoSampledAllocation(size);
- if (span != NULL) {
- ret = SpanToMallocResult(span);
- }
- } else if (size <= kMaxSize) {
+ if (size <= kMaxSize) {
// The common case, and also the simplest. This just pops the
// size-appropriate freelist, after replenishing it if it's empty.
ret = CheckedMallocResult(heap->Allocate(size));
@@ -797,7 +665,6 @@
Static::pageheap()->CacheSizeClass(p, cl);
}
if (cl != 0) {
- ASSERT(!Static::pageheap()->GetDescriptor(p)->sample);
ThreadCache* heap = GetCacheIfPresent();
if (heap != NULL) {
heap->Deallocate(ptr, cl);
@@ -810,12 +677,6 @@
SpinLockHolder h(Static::pageheap_lock());
ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0);
ASSERT(span != NULL && span->start == p);
- if (span->sample) {
- tcmalloc::DLL_Remove(span);
- Static::stacktrace_allocator()->Delete(
- reinterpret_cast<StackTrace*>(span->objects));
- span->objects = NULL;
- }
Static::pageheap()->Delete(span);
}
}
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.cc 2009-10-14 17:30:34 UTC (rev 3475)
@@ -124,7 +124,6 @@
uint32_t sampler_seed;
memcpy(&sampler_seed, &tid, sizeof(sampler_seed));
- sampler_.Init(sampler_seed);
}
void ThreadCache::Cleanup() {
@@ -294,10 +293,6 @@
}
}
-int ThreadCache::GetSamplePeriod() {
- return sampler_.GetSamplePeriod();
-}
-
void ThreadCache::InitModule() {
// There is a slight potential race here because of double-checked
// locking idiom. However, as long as the program does a small
Modified: branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h
===================================================================
--- branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h 2009-10-14 16:31:56 UTC (rev 3474)
+++ branches/tcmalloc-1.4/source/platform/tcmalloc-1.4/thread_cache.h 2009-10-14 17:30:34 UTC (rev 3475)
@@ -41,7 +41,6 @@
#include "linked_list.h"
#include "maybe_threads.h"
#include "page_heap_allocator.h"
-#include "sampler.h"
#include "static_vars.h"
namespace tcmalloc {
@@ -85,12 +84,6 @@
void Scavenge();
void Print(TCMalloc_Printer* out) const;
- int GetSamplePeriod();
-
- // Record allocation of "k" bytes. Return true iff allocation
- // should be sampled
- bool SampleAllocation(size_t k);
-
static void InitModule();
static void InitTSD();
static ThreadCache* GetThreadHeap();
@@ -312,9 +305,6 @@
static void DeleteCache(ThreadCache* heap);
static void RecomputePerThreadCacheSize();
-
- // We sample allocations, biased by the size of the allocation
- Sampler sampler_; // A sampler
};
// Allocator for thread heaps
@@ -327,9 +317,6 @@
return threadcache_allocator.inuse();
}
-inline bool ThreadCache::SampleAllocation(size_t k) {
- return sampler_.SampleAllocation(k);
-}
inline void* ThreadCache::Allocate(size_t size) {
ASSERT(size <= kMaxSize);
More information about the Avida-cvs
mailing list