Skip to content
Snippets Groups Projects
Commit dded2c66 authored by mbelshe@google.com's avatar mbelshe@google.com
Browse files

Issue 172109: Enable scavenging in RenderThread::IdleHandler.

Landing of Anton Muhin's patch (antonm@google.com)

BUG=none
TEST=none


Review URL: http://codereview.chromium.org/206017

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26264 0039d316-1c4b-4281-b951-d872f2087c98
parent e0d48158
No related merge requests found
......@@ -2941,6 +2941,10 @@
['OS=="linux"', {
'dependencies': [
'../build/linux/system.gyp:gtk',
'../third_party/tcmalloc/tcmalloc.gyp:tcmalloc',
],
'export_dependent_settings': [
'../third_party/tcmalloc/tcmalloc.gyp:tcmalloc',
],
}],
# Windows-specific rules.
......@@ -2948,6 +2952,12 @@
'include_dirs': [
'third_party/wtl/include',
],
'dependencies': [
'../third_party/tcmalloc/tcmalloc.gyp:tcmalloc',
],
'export_dependent_settings': [
'../third_party/tcmalloc/tcmalloc.gyp:tcmalloc',
],
},],
],
},
......@@ -3612,6 +3622,9 @@
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
],
'export_dependent_settings': [
'renderer',
],
'include_dirs': [
'..',
],
......@@ -3692,6 +3705,9 @@
'../skia/skia.gyp:skia',
'../testing/gtest.gyp:gtest',
],
'export_dependent_settings': [
'test_support_common',
],
'include_dirs': [
'..',
],
......@@ -4694,7 +4710,6 @@
'../net/net.gyp:net_resources',
'../build/util/support/support.gyp:*',
'../third_party/cld/cld.gyp:cld',
'../third_party/tcmalloc/tcmalloc.gyp:tcmalloc',
'../views/views.gyp:views',
'../webkit/webkit.gyp:webkit_resources',
'../gears/gears.gyp:gears',
......
......@@ -13,6 +13,7 @@ include_rules = [
"+webkit/glue/plugins",
"+v8/include",
"+third_party/sqlite/preprocessed",
"+third_party/tcmalloc",
# FIXME - refactor code and remove these dependencies
"+chrome/browser/net",
......
......@@ -48,6 +48,7 @@
#include "webkit/extensions/v8/gears_extension.h"
#include "webkit/extensions/v8/interval_extension.h"
#include "webkit/extensions/v8/playback_extension.h"
#include "third_party/tcmalloc/google/malloc_extension.h"
#if defined(OS_WIN)
#include <windows.h>
......@@ -459,26 +460,29 @@ void RenderThread::IdleHandler() {
if (!widget_count_ || hidden_widget_count_ < widget_count_)
return;
if (v8::V8::IsDead())
return;
LOG(INFO) << "RenderThread calling v8 IdleNotification for " << this;
// When V8::IdleNotification returns true, it means that it has cleaned up
// as much as it can. There is no point in continuing to call it.
if (!v8::V8::IdleNotification(false)) {
// Dampen the delay using the algorithm:
// delay = delay + 1 / (delay + 2)
// Using floor(delay) has a dampening effect such as:
// 1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
idle_notification_delay_in_s_ +=
1.0 / (idle_notification_delay_in_s_ + 2.0);
#if defined(OS_WIN)
MallocExtension::instance()->Scavenge();
#endif
// Schedule the next timer.
MessageLoop::current()->PostDelayedTask(FROM_HERE,
task_factory_->NewRunnableMethod(&RenderThread::IdleHandler),
static_cast<int64>(floor(idle_notification_delay_in_s_)) * 1000);
if (!v8::V8::IsDead()) {
LOG(INFO) << "RenderThread calling v8 IdleNotification for " << this;
v8::V8::IdleNotification(false);
}
// Schedule next invocation.
// Dampen the delay using the algorithm:
// delay = delay + 1 / (delay + 2)
// Using floor(delay) has a dampening effect such as:
// 1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
// Note that idle_notification_delay_in_s_ would be reset to
// kInitialIdleHandlerDelayS in RenderThread::WidgetHidden.
idle_notification_delay_in_s_ +=
1.0 / (idle_notification_delay_in_s_ + 2.0);
// Schedule the next timer.
MessageLoop::current()->PostDelayedTask(FROM_HERE,
task_factory_->NewRunnableMethod(&RenderThread::IdleHandler),
static_cast<int64>(floor(idle_notification_delay_in_s_)) * 1000);
}
void RenderThread::OnExtensionMessageInvoke(const std::string& function_name,
......
......@@ -35,7 +35,7 @@
(on OSes which have ability) which could be performed offline
(either by background thread or in idle time.)
*/
#define DEFER_DECOMMIT 0
#define DEFER_DECOMMIT 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
......
......@@ -65,7 +65,7 @@
(on OSes which have ability) which could be performed offline
(either by background thread or in idle time.)
*/
#define DEFER_DECOMMIT 0
#define DEFER_DECOMMIT 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
......
// 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 <opensource@google.com>
//
// Extra extensions exported by some malloc implementations. These
// extensions are accessed through a virtual base class so an
// application can link against a malloc that does not implement these
// extensions, and it will get default versions that do nothing.
//
// NOTE FOR C USERS: If you wish to use this functionality from within
// a C program, see malloc_extension_c.h.
#ifndef BASE_MALLOC_EXTENSION_H_
#define BASE_MALLOC_EXTENSION_H_
#include <stddef.h>
#include <string>
// 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
static const int kMallocHistogramSize = 64;
// One day, we could support other types of writers (perhaps for C?)
typedef std::string MallocExtensionWriter;
// The default implementations of the following routines do nothing.
// All implementations should be thread-safe; the current one
// (TCMallocImplementation) is.
class PERFTOOLS_DLL_DECL MallocExtension {
public:
virtual ~MallocExtension();
// Call this very early in the program execution -- say, in a global
// constructor -- to set up parameters and state needed by all
// instrumented malloc implemenatations. One example: this routine
// sets environemnt variables to tell STL to use libc's malloc()
// instead of doing its own memory management. This is safe to call
// multiple times, as long as each time is before threads start up.
static void Initialize();
// See "verify_memory.h" to see what these routines do
virtual bool VerifyAllMemory();
virtual bool VerifyNewMemory(void* p);
virtual bool VerifyArrayNewMemory(void* p);
virtual bool VerifyMallocMemory(void* p);
virtual bool MallocMemoryStats(int* blocks, size_t* total,
int histogram[kMallocHistogramSize]);
// Get a human readable description of the current state of the malloc
// data structures. The state is stored as a null-terminated string
// in a prefix of "buffer[0,buffer_length-1]".
// REQUIRES: buffer_length > 0.
virtual void GetStats(char* buffer, int buffer_length);
// Outputs to "writer" a sample of live objects and the stack traces
// that allocated these objects. The format of the returned output
// is equivalent to the output of the heap profiler and can
// therefore be passed to "pprof".
virtual void GetHeapSample(MallocExtensionWriter* writer);
// Outputs to "writer" the stack traces that caused growth in the
// address space size. The format of the returned output is
// equivalent to the output of the heap profiler and can therefore
// be passed to "pprof".
virtual void GetHeapGrowthStacks(MallocExtensionWriter* writer);
// -------------------------------------------------------------------
// Control operations for getting and setting malloc implementation
// specific parameters. Some currently useful properties:
//
// generic
// -------
// "generic.current_allocated_bytes"
// Number of bytes currently allocated by application
// This property is not writable.
//
// "generic.heap_size"
// Number of bytes in the heap ==
// current_allocated_bytes +
// fragmentation +
// freed memory regions
// This property is not writable.
//
// tcmalloc
// --------
// "tcmalloc.max_total_thread_cache_bytes"
// Upper limit on total number of bytes stored across all
// per-thread caches. Default: 16MB.
//
// "tcmalloc.current_total_thread_cache_bytes"
// Number of bytes used across all thread caches.
// This property is not writable.
//
// "tcmalloc.slack_bytes"
// Number of bytes allocated from system, but not currently
// in use by malloced objects. I.e., bytes available for
// allocation without needing more bytes from system.
// This property is not writable.
//
// TODO: Add more properties as necessary
// -------------------------------------------------------------------
// Get the named "property"'s value. Returns true if the property
// is known. Returns false if the property is not a valid property
// name for the current malloc implementation.
// REQUIRES: property != NULL; value != NULL
virtual bool GetNumericProperty(const char* property, size_t* value);
// Set the named "property"'s value. Returns true if the property
// is known and writable. Returns false if the property is not a
// valid property name for the current malloc implementation, or
// is not writable.
// REQUIRES: property != NULL
virtual bool SetNumericProperty(const char* property, size_t value);
// Mark the current thread as "idle". This routine may optionally
// be called by threads as a hint to the malloc implementation that
// any thread-specific resources should be released. Note: this may
// be an expensive routine, so it should not be called too often.
//
// Also, if the code that calls this routine will go to sleep for
// a while, it should take care to not allocate anything between
// the call to this routine and the beginning of the sleep.
//
// Most malloc implementations ignore this routine.
virtual void MarkThreadIdle();
// Scavenge at least some resources and free them back to OS.
// This method doesn't promise to do anything useful (it might be
// implemented as noop), but it's a good idea to invoke it when
// application is idle.
virtual void Scavenge();
// Try to free memory back to the operating system for reuse. Only
// use this extension if the application has recently freed a lot of
// memory, and does not anticipate using it again for a long time --
// to get this memory back may require faulting pages back in by the
// OS, and that may be slow. (Currently only implemented in
// tcmalloc.)
virtual void ReleaseFreeMemory();
// Sets the rate at which we release unused memory to the system.
// Zero means we never release memory back to the system. Increase
// this flag to return memory faster; decrease it to return memory
// slower. Reasonable rates are in the range [0,10]. (Currently
// only implemented in tcmalloc).
virtual void SetMemoryReleaseRate(double rate);
// Gets the release rate. Returns a value < 0 if unknown.
virtual double GetMemoryReleaseRate();
// Returns the estimated number of bytes that will be allocated for
// a request of "size" bytes. This is an estimate: an allocation of
// SIZE bytes may reserve more bytes, but will never reserve less.
// (Currently only implemented in tcmalloc, other implementations
// always return SIZE.)
virtual size_t GetEstimatedAllocatedSize(size_t size);
// Returns the actual number of bytes reserved by tcmalloc for the
// pointer p. This number may be equal to or greater than
// the number of bytes requested when p was allocated.
// p must have been allocated by this malloc implementation,
// must not be an interior pointer -- that is, must be exactly
// the pointer returned to by malloc() et al., not some offset
// from that -- and should not have been freed yet. p may be NULL.
// (Currently only implemented in tcmalloc; other implementations
// will return 0.)
virtual size_t GetAllocatedSize(void* p);
// The current malloc implementation. Always non-NULL.
static MallocExtension* instance();
// Change the malloc implementation. Typically called by the
// malloc implementation during initialization.
static void Register(MallocExtension* implementation);
protected:
// Get a list of stack traces of sampled allocation points. Returns
// a pointer to a "new[]-ed" result array, and stores the sample
// period in "sample_period".
//
// The state is stored as a sequence of adjacent entries
// in the returned array. Each entry has the following form:
// uintptr_t count; // Number of objects with following trace
// uintptr_t size; // Total size of objects with following trace
// uintptr_t depth; // Number of PC values in stack trace
// void* stack[depth]; // PC values that form the stack trace
//
// The list of entries is terminated by a "count" of 0.
//
// It is the responsibility of the caller to "delete[]" the returned array.
//
// May return NULL to indicate no results.
//
// This is an internal extension. Callers should use the more
// convenient "GetHeapSample(string*)" method defined above.
virtual void** ReadStackTraces(int* sample_period);
// Like ReadStackTraces(), but returns stack traces that caused growth
// in the address space size.
virtual void** ReadHeapGrowthStackTraces();
};
#endif // BASE_MALLOC_EXTENSION_H_
// 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 <opensource@google.com>
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#if defined HAVE_STDINT_H
#include <stdint.h>
#elif defined HAVE_INTTYPES_H
#include <inttypes.h>
#else
#include <sys/types.h>
#endif
#include <string>
#include "base/dynamic_annotations.h"
#include "base/sysinfo.h" // for FillProcSelfMaps
#include "google/malloc_extension.h"
#include "maybe_threads.h"
using STL_NAMESPACE::string;
static void DumpAddressMap(string* result) {
*result += "\nMAPPED_LIBRARIES:\n";
// We keep doubling until we get a fit
const size_t old_resultlen = result->size();
for (int amap_size = 10240; amap_size < 10000000; amap_size *= 2) {
result->resize(old_resultlen + amap_size);
const int bytes_written =
tcmalloc::FillProcSelfMaps(&((*result)[old_resultlen]), amap_size);
if (bytes_written < amap_size - 1) { // we fit!
(*result)[old_resultlen + bytes_written] = '\0';
result->resize(old_resultlen + bytes_written);
return;
}
}
result->reserve(old_resultlen); // just don't print anything
}
// Note: this routine is meant to be called before threads are spawned.
void MallocExtension::Initialize() {
static bool initialize_called = false;
if (initialize_called) return;
initialize_called = true;
#ifdef __GLIBC__
// GNU libc++ versions 3.3 and 3.4 obey the environment variables
// GLIBCPP_FORCE_NEW and GLIBCXX_FORCE_NEW respectively. Setting
// one of these variables forces the STL default allocator to call
// new() or delete() for each allocation or deletion. Otherwise
// the STL allocator tries to avoid the high cost of doing
// allocations by pooling memory internally. However, tcmalloc
// does allocations really fast, especially for the types of small
// items one sees in STL, so it's better off just using us.
// TODO: control whether we do this via an environment variable?
setenv("GLIBCPP_FORCE_NEW", "1", false /* no overwrite*/);
setenv("GLIBCXX_FORCE_NEW", "1", false /* no overwrite*/);
// Now we need to make the setenv 'stick', which it may not do since
// the env is flakey before main() is called. But luckily stl only
// looks at this env var the first time it tries to do an alloc, and
// caches what it finds. So we just cause an stl alloc here.
string dummy("I need to be allocated");
dummy += "!"; // so the definition of dummy isn't optimized out
#endif /* __GLIBC__ */
}
// Default implementation -- does nothing
MallocExtension::~MallocExtension() { }
bool MallocExtension::VerifyAllMemory() { return true; }
bool MallocExtension::VerifyNewMemory(void* p) { return true; }
bool MallocExtension::VerifyArrayNewMemory(void* p) { return true; }
bool MallocExtension::VerifyMallocMemory(void* p) { return true; }
bool MallocExtension::GetNumericProperty(const char* property, size_t* value) {
return false;
}
bool MallocExtension::SetNumericProperty(const char* property, size_t value) {
return false;
}
void MallocExtension::GetStats(char* buffer, int length) {
assert(length > 0);
buffer[0] = '\0';
}
bool MallocExtension::MallocMemoryStats(int* blocks, size_t* total,
int histogram[kMallocHistogramSize]) {
*blocks = 0;
*total = 0;
memset(histogram, 0, sizeof(histogram));
return true;
}
void** MallocExtension::ReadStackTraces(int* sample_period) {
return NULL;
}
void** MallocExtension::ReadHeapGrowthStackTraces() {
return NULL;
}
void MallocExtension::MarkThreadIdle() {
// Default implementation does nothing
}
void MallocExtension::ReleaseFreeMemory() {
// Default implementation does nothing
}
void MallocExtension::Scavenge() {
// Default implementation does nothing
}
void MallocExtension::SetMemoryReleaseRate(double rate) {
// Default implementation does nothing
}
double MallocExtension::GetMemoryReleaseRate() {
return -1.0;
}
size_t MallocExtension::GetEstimatedAllocatedSize(size_t size) {
return size;
}
size_t MallocExtension::GetAllocatedSize(void* p) {
return 0;
}
// The current malloc extension object. We also keep a pointer to
// the default implementation so that the heap-leak checker does not
// complain about a memory leak.
static pthread_once_t module_init = PTHREAD_ONCE_INIT;
static MallocExtension* default_instance = NULL;
static MallocExtension* current_instance = NULL;
static void InitModule() {
default_instance = new MallocExtension;
current_instance = default_instance;
}
MallocExtension* MallocExtension::instance() {
perftools_pthread_once(&module_init, InitModule);
return current_instance;
}
void MallocExtension::Register(MallocExtension* implementation) {
perftools_pthread_once(&module_init, InitModule);
// When running under valgrind, our custom malloc is replaced with
// valgrind's one and malloc extensions will not work.
if (!RunningOnValgrind()) {
current_instance = implementation;
}
}
// -----------------------------------------------------------------------
// Heap sampling support
// -----------------------------------------------------------------------
namespace {
// Accessors
uintptr_t Count(void** entry) {
return reinterpret_cast<uintptr_t>(entry[0]);
}
uintptr_t Size(void** entry) {
return reinterpret_cast<uintptr_t>(entry[1]);
}
uintptr_t Depth(void** entry) {
return reinterpret_cast<uintptr_t>(entry[2]);
}
void* PC(void** entry, int i) {
return entry[3+i];
}
void PrintCountAndSize(MallocExtensionWriter* writer,
uintptr_t count, uintptr_t size) {
char buf[100];
snprintf(buf, sizeof(buf),
"%6lld: %8lld [%6lld: %8lld] @",
static_cast<long long>(count),
static_cast<long long>(size),
static_cast<long long>(count),
static_cast<long long>(size));
writer->append(buf, strlen(buf));
}
void PrintHeader(MallocExtensionWriter* writer,
const char* label, void** entries) {
// Compute the total count and total size
uintptr_t total_count = 0;
uintptr_t total_size = 0;
for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
total_count += Count(entry);
total_size += Size(entry);
}
const char* const kTitle = "heap profile: ";
writer->append(kTitle, strlen(kTitle));
PrintCountAndSize(writer, total_count, total_size);
writer->append(" ", 1);
writer->append(label, strlen(label));
writer->append("\n", 1);
}
void PrintStackEntry(MallocExtensionWriter* writer, void** entry) {
PrintCountAndSize(writer, Count(entry), Size(entry));
for (int i = 0; i < Depth(entry); i++) {
char buf[32];
snprintf(buf, sizeof(buf), " %p", PC(entry, i));
writer->append(buf, strlen(buf));
}
writer->append("\n", 1);
}
}
void MallocExtension::GetHeapSample(MallocExtensionWriter* writer) {
int sample_period = 0;
void** entries = ReadStackTraces(&sample_period);
if (entries == NULL) {
const char* const kErrorMsg =
"This malloc implementation does not support sampling.\n"
"As of 2005/01/26, only tcmalloc supports sampling, and\n"
"you are probably running a binary that does not use\n"
"tcmalloc.\n";
writer->append(kErrorMsg, strlen(kErrorMsg));
return;
}
char label[32];
sprintf(label, "heap_v2/%d", sample_period);
PrintHeader(writer, label, entries);
for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
PrintStackEntry(writer, entry);
}
delete[] entries;
DumpAddressMap(writer);
}
void MallocExtension::GetHeapGrowthStacks(MallocExtensionWriter* writer) {
void** entries = ReadHeapGrowthStackTraces();
if (entries == NULL) {
const char* const kErrorMsg =
"This malloc implementation does not support "
"ReadHeapGrowthStackTraces().\n"
"As of 2005/09/27, only tcmalloc supports this, and you\n"
"are probably running a binary that does not use tcmalloc.\n";
writer->append(kErrorMsg, strlen(kErrorMsg));
return;
}
// Do not canonicalize the stack entries, so that we get a
// time-ordered list of stack traces, which may be useful if the
// client wants to focus on the latest stack traces.
PrintHeader(writer, "growth", entries);
for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
PrintStackEntry(writer, entry);
}
delete[] entries;
DumpAddressMap(writer);
}
// These are C shims that work on the current instance.
#define C_SHIM(fn, retval, paramlist, arglist) \
extern "C" PERFTOOLS_DLL_DECL retval MallocExtension_##fn paramlist { \
return MallocExtension::instance()->fn arglist; \
}
C_SHIM(VerifyAllMemory, bool, (), ());
C_SHIM(VerifyNewMemory, bool, (void* p), (p));
C_SHIM(VerifyArrayNewMemory, bool, (void* p), (p));
C_SHIM(VerifyMallocMemory, bool, (void* p), (p));
C_SHIM(MallocMemoryStats, bool,
(int* blocks, size_t* total, int histogram[kMallocHistogramSize]),
(blocks, total, histogram));
C_SHIM(GetStats, void,
(char* buffer, int buffer_length), (buffer, buffer_length));
C_SHIM(GetNumericProperty, bool,
(const char* property, size_t* value), (property, value));
C_SHIM(SetNumericProperty, bool,
(const char* property, size_t value), (property, value));
C_SHIM(MarkThreadIdle, void, (), ());
C_SHIM(ReleaseFreeMemory, void, (), ());
C_SHIM(GetEstimatedAllocatedSize, size_t, (size_t size), (size));
C_SHIM(GetAllocatedSize, size_t, (void* p), (p));
......@@ -616,6 +616,11 @@ class TCMallocImplementation : public MallocExtension {
Static::pageheap()->ReleaseFreePages();
}
virtual void Scavenge() {
SpinLockHolder h(Static::pageheap_lock());
Static::pageheap()->Scavenge();
}
virtual void SetMemoryReleaseRate(double rate) {
FLAGS_tcmalloc_release_rate = rate;
}
......
......@@ -44,6 +44,13 @@
},
},
},
'conditions': [
['OS=="win"', {
'defines': [
['PERFTOOLS_DLL_DECL', '']
],
}],
],
},
'sources': [
'config.h',
......@@ -70,7 +77,6 @@
'tcmalloc/src/internal_logging.cc',
'tcmalloc/src/internal_logging.h',
'tcmalloc/src/linked_list.h',
'tcmalloc/src/malloc_extension.cc',
'tcmalloc/src/malloc_hook.cc',
'tcmalloc/src/malloc_hook-inl.h',
'tcmalloc/src/page_heap.cc',
......@@ -120,6 +126,8 @@
# tcmalloc forked files
'allocator_shim.cc',
'generic_allocators.cc',
'malloc_extension.cc',
'google/malloc_extension.h',
'page_heap.cc',
'page_heap.h',
'port.cc',
......@@ -141,6 +149,8 @@
'generic_allocators.cc',
'tcmalloc.cc',
'win_allocator.cc',
'tcmalloc/src/malloc_extension.cc',
'tcmalloc/src/google/malloc_extension.h',
],
'msvs_settings': {
# TODO(sgk): merge this with build/common.gypi settings
......@@ -164,6 +174,9 @@
},
'conditions': [
['OS=="win"', {
'defines': [
['PERFTOOLS_DLL_DECL', '']
],
'dependencies': [
'libcmt',
],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment