diff options
author | alexeif@chromium.org <alexeif@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 12:19:51 +0000 |
---|---|---|
committer | alexeif@chromium.org <alexeif@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 12:19:51 +0000 |
commit | 3b875959cf00fdb428911f1877582c2ed1322782 (patch) | |
tree | 6372435b76779d4071e7275aff908c54a52ae615 | |
parent | 6e1a7d3974d7e13d66bd5d829e12a3e0a5912289 (diff) | |
download | chromium_src-3b875959cf00fdb428911f1877582c2ed1322782.zip chromium_src-3b875959cf00fdb428911f1877582c2ed1322782.tar.gz chromium_src-3b875959cf00fdb428911f1877582c2ed1322782.tar.bz2 |
Report memory usage retained by TCMalloc freelists.
Review URL: https://chromiumcodereview.appspot.com/10823205
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171767 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/allocator/allocator_extension.cc | 33 | ||||
-rw-r--r-- | base/allocator/allocator_extension.h | 17 | ||||
-rw-r--r-- | base/allocator/allocator_extension_thunks.cc | 11 | ||||
-rw-r--r-- | base/allocator/allocator_extension_thunks.h | 7 | ||||
-rw-r--r-- | base/allocator/allocator_shim.cc | 44 | ||||
-rw-r--r-- | content/app/content_main_runner.cc | 18 | ||||
-rw-r--r-- | webkit/glue/webkitplatformsupport_impl.cc | 5 | ||||
-rw-r--r-- | webkit/glue/webkitplatformsupport_impl.h | 1 |
8 files changed, 71 insertions, 65 deletions
diff --git a/base/allocator/allocator_extension.cc b/base/allocator/allocator_extension.cc index d4ed6d7..83e460a 100644 --- a/base/allocator/allocator_extension.cc +++ b/base/allocator/allocator_extension.cc @@ -9,16 +9,16 @@ namespace base { namespace allocator { -bool GetProperty(const char* name, size_t* value) { - thunks::GetPropertyFunction get_property_function = - base::allocator::thunks::GetGetPropertyFunction(); - return get_property_function != NULL && get_property_function(name, value); +bool GetAllocatorWasteSize(size_t* size) { + thunks::GetAllocatorWasteSizeFunction get_allocator_waste_size_function = + thunks::GetGetAllocatorWasteSizeFunction(); + return get_allocator_waste_size_function != NULL && + get_allocator_waste_size_function(size); } void GetStats(char* buffer, int buffer_length) { DCHECK_GT(buffer_length, 0); - thunks::GetStatsFunction get_stats_function = - base::allocator::thunks::GetGetStatsFunction(); + thunks::GetStatsFunction get_stats_function = thunks::GetGetStatsFunction(); if (get_stats_function) get_stats_function(buffer, buffer_length); else @@ -27,30 +27,29 @@ void GetStats(char* buffer, int buffer_length) { void ReleaseFreeMemory() { thunks::ReleaseFreeMemoryFunction release_free_memory_function = - base::allocator::thunks::GetReleaseFreeMemoryFunction(); + thunks::GetReleaseFreeMemoryFunction(); if (release_free_memory_function) release_free_memory_function(); } -void SetGetPropertyFunction( - thunks::GetPropertyFunction get_property_function) { - DCHECK_EQ(base::allocator::thunks::GetGetPropertyFunction(), - reinterpret_cast<thunks::GetPropertyFunction>(NULL)); - base::allocator::thunks::SetGetPropertyFunction(get_property_function); +void SetGetAllocatorWasteSizeFunction( + thunks::GetAllocatorWasteSizeFunction get_allocator_waste_size_function) { + DCHECK_EQ(thunks::GetGetAllocatorWasteSizeFunction(), + reinterpret_cast<thunks::GetAllocatorWasteSizeFunction>(NULL)); + thunks::SetGetAllocatorWasteSizeFunction(get_allocator_waste_size_function); } void SetGetStatsFunction(thunks::GetStatsFunction get_stats_function) { - DCHECK_EQ(base::allocator::thunks::GetGetStatsFunction(), + DCHECK_EQ(thunks::GetGetStatsFunction(), reinterpret_cast<thunks::GetStatsFunction>(NULL)); - base::allocator::thunks::SetGetStatsFunction(get_stats_function); + thunks::SetGetStatsFunction(get_stats_function); } void SetReleaseFreeMemoryFunction( thunks::ReleaseFreeMemoryFunction release_free_memory_function) { - DCHECK_EQ(base::allocator::thunks::GetReleaseFreeMemoryFunction(), + DCHECK_EQ(thunks::GetReleaseFreeMemoryFunction(), reinterpret_cast<thunks::ReleaseFreeMemoryFunction>(NULL)); - base::allocator::thunks::SetReleaseFreeMemoryFunction( - release_free_memory_function); + thunks::SetReleaseFreeMemoryFunction(release_free_memory_function); } } // namespace allocator diff --git a/base/allocator/allocator_extension.h b/base/allocator/allocator_extension.h index dda0fd9..de3119f 100644 --- a/base/allocator/allocator_extension.h +++ b/base/allocator/allocator_extension.h @@ -14,13 +14,14 @@ namespace base { namespace allocator { -// Request the allocator to report value of its internal state variable. +// Request the allocator to report value of its waste memory size. +// Waste size corresponds to memory that has been allocated from the OS but +// not passed up to the application. It e.g. includes memory retained by free +// lists, internal data, chunks padding, etc. // -// |name| name of the variable -// |value| pointer to the returned value, must be not NULL. -// Returns true if the value has been returned, false if a variable with such -// name does not exist. -BASE_EXPORT bool GetProperty(const char* name, size_t* value); +// |size| pointer to the returned value, must be not NULL. +// Returns true if the value has been returned, false otherwise. +BASE_EXPORT bool GetAllocatorWasteSize(size_t* size); // Request that the allocator print a human-readable description of the current // state of the allocator into a null-terminated string in the memory segment @@ -43,8 +44,8 @@ BASE_EXPORT void ReleaseFreeMemory(); // No threading promises are made. The caller is responsible for making sure // these pointers are set before any other threads attempt to call the above // functions. -BASE_EXPORT void SetGetPropertyFunction( - thunks::GetPropertyFunction get_property_function); +BASE_EXPORT void SetGetAllocatorWasteSizeFunction( + thunks::GetAllocatorWasteSizeFunction get_allocator_waste_size_function); BASE_EXPORT void SetGetStatsFunction( thunks::GetStatsFunction get_stats_function); diff --git a/base/allocator/allocator_extension_thunks.cc b/base/allocator/allocator_extension_thunks.cc index e5ee8ce..e4024fb 100644 --- a/base/allocator/allocator_extension_thunks.cc +++ b/base/allocator/allocator_extension_thunks.cc @@ -17,16 +17,17 @@ namespace thunks { // can depend on it. This file can't depend on anything else in base, including // logging. -static GetPropertyFunction g_get_property_function = NULL; +static GetAllocatorWasteSizeFunction g_get_allocator_waste_size_function = NULL; static GetStatsFunction g_get_stats_function = NULL; static ReleaseFreeMemoryFunction g_release_free_memory_function = NULL; -void SetGetPropertyFunction(GetPropertyFunction get_property_function) { - g_get_property_function = get_property_function; +void SetGetAllocatorWasteSizeFunction( + GetAllocatorWasteSizeFunction get_allocator_waste_size_function) { + g_get_allocator_waste_size_function = get_allocator_waste_size_function; } -GetPropertyFunction GetGetPropertyFunction() { - return g_get_property_function; +GetAllocatorWasteSizeFunction GetGetAllocatorWasteSizeFunction() { + return g_get_allocator_waste_size_function; } void SetGetStatsFunction(GetStatsFunction get_stats_function) { diff --git a/base/allocator/allocator_extension_thunks.h b/base/allocator/allocator_extension_thunks.h index 3b0e4edc..1e97a84 100644 --- a/base/allocator/allocator_extension_thunks.h +++ b/base/allocator/allocator_extension_thunks.h @@ -15,9 +15,10 @@ namespace thunks { // new allocator extension from a specific allocator implementation to base. // See allocator_extension.h to see the interface that base exports. -typedef bool (*GetPropertyFunction)(const char* name, size_t* value); -void SetGetPropertyFunction(GetPropertyFunction get_property_function); -GetPropertyFunction GetGetPropertyFunction(); +typedef bool (*GetAllocatorWasteSizeFunction)(size_t* size); +void SetGetAllocatorWasteSizeFunction( + GetAllocatorWasteSizeFunction get_allocator_waste_size_function); +GetAllocatorWasteSizeFunction GetGetAllocatorWasteSizeFunction(); typedef void (*GetStatsFunction)(char* buffer, int buffer_length); void SetGetStatsFunction(GetStatsFunction get_stats_function); diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc index 5acc533..6e41327 100644 --- a/base/allocator/allocator_shim.cc +++ b/base/allocator/allocator_shim.cc @@ -232,42 +232,27 @@ extern "C" intptr_t _get_heap_handle() { return 0; } -static bool get_jemalloc_property_thunk(const char* name, size_t* value) { - jemalloc_stats_t stats; - jemalloc_stats(&stats); -#define EXTRACT_JEMALLOC_PROPERTY(property) \ - if (strcmp(name, "jemalloc." #property) == 0) \ - return *value = stats.property, true; - EXTRACT_JEMALLOC_PROPERTY(narenas); - EXTRACT_JEMALLOC_PROPERTY(balance_threshold); - EXTRACT_JEMALLOC_PROPERTY(quantum); - EXTRACT_JEMALLOC_PROPERTY(small_max); - EXTRACT_JEMALLOC_PROPERTY(large_max); - EXTRACT_JEMALLOC_PROPERTY(chunksize); - EXTRACT_JEMALLOC_PROPERTY(dirty_max); - EXTRACT_JEMALLOC_PROPERTY(reserve_min); - EXTRACT_JEMALLOC_PROPERTY(reserve_max); - EXTRACT_JEMALLOC_PROPERTY(mapped); - EXTRACT_JEMALLOC_PROPERTY(committed); - EXTRACT_JEMALLOC_PROPERTY(allocated); - EXTRACT_JEMALLOC_PROPERTY(dirty); - EXTRACT_JEMALLOC_PROPERTY(reserve_cur); -#undef EXTRACT_JEMALLOC_PROPERTY - return false; -} - -static bool get_property_thunk(const char* name, size_t* value) { +static bool get_allocator_waste_size_thunk(size_t* size) { #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING switch (allocator) { case JEMALLOC: - return get_jemalloc_property_thunk(name, value); case WINHEAP: case WINLFH: - // TODO(alexeif): Implement for other allocators. + // TODO(alexeif): Implement for allocators other than tcmalloc. return false; } #endif - return MallocExtension::instance()->GetNumericProperty(name, value); + size_t heap_size, allocated_bytes, unmapped_bytes; + MallocExtension* ext = MallocExtension::instance(); + if (ext->GetNumericProperty("generic.heap_size", &heap_size) && + ext->GetNumericProperty("generic.current_allocated_bytes", + &allocated_bytes) && + ext->GetNumericProperty("tcmalloc.pageheap_unmapped_bytes", + &unmapped_bytes)) { + *size = heap_size - allocated_bytes - unmapped_bytes; + return true; + } + return false; } static void get_stats_thunk(char* buffer, int buffer_length) { @@ -323,7 +308,8 @@ extern "C" int _heap_init() { tracked_objects::TIME_SOURCE_TYPE_TCMALLOC); } - base::allocator::thunks::SetGetPropertyFunction(get_property_thunk); + base::allocator::thunks::SetGetAllocatorWasteSizeFunction( + get_allocator_waste_size_thunk); base::allocator::thunks::SetGetStatsFunction(get_stats_thunk); base::allocator::thunks::SetReleaseFreeMemoryFunction( release_free_memory_thunk); diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index a74e7b6..463d0ec 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc @@ -485,8 +485,19 @@ class ContentMainRunnerImpl : public ContentMainRunner { } #if defined(USE_TCMALLOC) -static bool GetPropertyThunk(const char* name, size_t* value) { - return MallocExtension::instance()->GetNumericProperty(name, value); +static bool GetAllocatorWasteSizeThunk(size_t* size) { + size_t heap_size, allocated_bytes, unmapped_bytes; + MallocExtension* ext = MallocExtension::instance(); + if (ext->GetNumericProperty("generic.heap_size", &heap_size) && + ext->GetNumericProperty("generic.current_allocated_bytes", + &allocated_bytes) && + ext->GetNumericProperty("tcmalloc.pageheap_unmapped_bytes", + &unmapped_bytes)) { + *size = heap_size - allocated_bytes - unmapped_bytes; + return true; + } + DCHECK(false); + return false; } static void GetStatsThunk(char* buffer, int buffer_length) { @@ -534,7 +545,8 @@ static void ReleaseFreeMemoryThunk() { tc_set_new_mode(1); // On windows, we've already set these thunks up in _heap_init() - base::allocator::SetGetPropertyFunction(GetPropertyThunk); + base::allocator::SetGetAllocatorWasteSizeFunction( + GetAllocatorWasteSizeThunk); base::allocator::SetGetStatsFunction(GetStatsThunk); base::allocator::SetReleaseFreeMemoryFunction(ReleaseFreeMemoryThunk); diff --git a/webkit/glue/webkitplatformsupport_impl.cc b/webkit/glue/webkitplatformsupport_impl.cc index dfa8a43..c688b5d 100644 --- a/webkit/glue/webkitplatformsupport_impl.cc +++ b/webkit/glue/webkitplatformsupport_impl.cc @@ -12,6 +12,7 @@ #include <vector> +#include "base/allocator/allocator_extension.h" #include "base/bind.h" #include "base/debug/trace_event.h" #include "base/memory/scoped_ptr.h" @@ -831,6 +832,10 @@ bool WebKitPlatformSupportImpl::processMemorySizesInBytes( return CurrentProcessMetrics()->GetMemoryBytes(private_bytes, shared_bytes); } +bool WebKitPlatformSupportImpl::memoryAllocatorWasteInBytes(size_t* size) { + return base::allocator::GetAllocatorWasteSize(size); +} + void WebKitPlatformSupportImpl::SuspendSharedTimer() { ++shared_timer_suspended_; } diff --git a/webkit/glue/webkitplatformsupport_impl.h b/webkit/glue/webkitplatformsupport_impl.h index 5bbea48..0ad0e74 100644 --- a/webkit/glue/webkitplatformsupport_impl.h +++ b/webkit/glue/webkitplatformsupport_impl.h @@ -70,6 +70,7 @@ class WEBKIT_GLUE_EXPORT WebKitPlatformSupportImpl : #endif virtual bool processMemorySizesInBytes(size_t* private_bytes, size_t* shared_bytes); + virtual bool memoryAllocatorWasteInBytes(size_t* size); virtual WebKit::WebURLLoader* createURLLoader(); virtual WebKit::WebSocketStreamHandle* createSocketStreamHandle(); virtual WebKit::WebString userAgent(const WebKit::WebURL& url); |