diff options
author | alexeif@chromium.org <alexeif@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-17 11:44:10 +0000 |
---|---|---|
committer | alexeif@chromium.org <alexeif@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-17 11:44:10 +0000 |
commit | 094c893329ffdd23a9350bfd94d40b99334be8f2 (patch) | |
tree | a662cab19b05e7041babedaa19012d0e26dcf69a /base/allocator | |
parent | f657d5140d661aca265c0350772d9fa78a0c8316 (diff) | |
download | chromium_src-094c893329ffdd23a9350bfd94d40b99334be8f2.zip chromium_src-094c893329ffdd23a9350bfd94d40b99334be8f2.tar.gz chromium_src-094c893329ffdd23a9350bfd94d40b99334be8f2.tar.bz2 |
Expose memory allocator internal stats and properties.
Review URL: https://chromiumcodereview.appspot.com/10825250
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157102 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/allocator')
-rw-r--r-- | base/allocator/allocator.gyp | 1 | ||||
-rw-r--r-- | base/allocator/allocator_extension.cc | 31 | ||||
-rw-r--r-- | base/allocator/allocator_extension.h | 18 | ||||
-rw-r--r-- | base/allocator/allocator_extension_thunks.cc | 21 | ||||
-rw-r--r-- | base/allocator/allocator_extension_thunks.h | 18 | ||||
-rw-r--r-- | base/allocator/allocator_shim.cc | 40 |
6 files changed, 107 insertions, 22 deletions
diff --git a/base/allocator/allocator.gyp b/base/allocator/allocator.gyp index 002ce21..db95863 100644 --- a/base/allocator/allocator.gyp +++ b/base/allocator/allocator.gyp @@ -316,6 +316,7 @@ 'libcmt', ], 'include_dirs': [ + '<(jemalloc_dir)', '<(tcmalloc_dir)/src/windows', ], 'sources!': [ diff --git a/base/allocator/allocator_extension.cc b/base/allocator/allocator_extension.cc index 7ae11da..d4ed6d7 100644 --- a/base/allocator/allocator_extension.cc +++ b/base/allocator/allocator_extension.cc @@ -9,31 +9,46 @@ 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); +} + void GetStats(char* buffer, int buffer_length) { DCHECK_GT(buffer_length, 0); - if (thunks::GetStatsFunction* get_stats_function = - base::allocator::thunks::GetGetStatsFunction()) + thunks::GetStatsFunction get_stats_function = + base::allocator::thunks::GetGetStatsFunction(); + if (get_stats_function) get_stats_function(buffer, buffer_length); else buffer[0] = '\0'; } void ReleaseFreeMemory() { - if (thunks::ReleaseFreeMemoryFunction* release_free_memory_function = - base::allocator::thunks::GetReleaseFreeMemoryFunction()) + thunks::ReleaseFreeMemoryFunction release_free_memory_function = + base::allocator::thunks::GetReleaseFreeMemoryFunction(); + if (release_free_memory_function) release_free_memory_function(); } -void SetGetStatsFunction(thunks::GetStatsFunction* get_stats_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 SetGetStatsFunction(thunks::GetStatsFunction get_stats_function) { DCHECK_EQ(base::allocator::thunks::GetGetStatsFunction(), - reinterpret_cast<thunks::GetStatsFunction*>(NULL)); + reinterpret_cast<thunks::GetStatsFunction>(NULL)); base::allocator::thunks::SetGetStatsFunction(get_stats_function); } void SetReleaseFreeMemoryFunction( - thunks::ReleaseFreeMemoryFunction* release_free_memory_function) { + thunks::ReleaseFreeMemoryFunction release_free_memory_function) { DCHECK_EQ(base::allocator::thunks::GetReleaseFreeMemoryFunction(), - reinterpret_cast<thunks::ReleaseFreeMemoryFunction*>(NULL)); + reinterpret_cast<thunks::ReleaseFreeMemoryFunction>(NULL)); base::allocator::thunks::SetReleaseFreeMemoryFunction( release_free_memory_function); } diff --git a/base/allocator/allocator_extension.h b/base/allocator/allocator_extension.h index b71fffe..dda0fd9 100644 --- a/base/allocator/allocator_extension.h +++ b/base/allocator/allocator_extension.h @@ -5,6 +5,8 @@ #ifndef BASE_ALLOCATOR_ALLOCATOR_EXTENSION_H #define BASE_ALLOCATOR_ALLOCATOR_EXTENSION_H +#include <stddef.h> // for size_t + #include "base/allocator/allocator_extension_thunks.h" #include "base/base_export.h" #include "build/build_config.h" @@ -12,6 +14,14 @@ namespace base { namespace allocator { +// Request the allocator to report value of its internal state variable. +// +// |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); + // 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 // buffer[0,buffer_length-1]. @@ -33,11 +43,15 @@ 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 SetGetStatsFunction( - thunks::GetStatsFunction* get_stats_function); + thunks::GetStatsFunction get_stats_function); BASE_EXPORT void SetReleaseFreeMemoryFunction( - thunks::ReleaseFreeMemoryFunction* release_free_memory_function); + thunks::ReleaseFreeMemoryFunction release_free_memory_function); + } // namespace allocator } // namespace base diff --git a/base/allocator/allocator_extension_thunks.cc b/base/allocator/allocator_extension_thunks.cc index 0e97f6a..e5ee8ce 100644 --- a/base/allocator/allocator_extension_thunks.cc +++ b/base/allocator/allocator_extension_thunks.cc @@ -17,23 +17,32 @@ namespace thunks { // can depend on it. This file can't depend on anything else in base, including // logging. -static GetStatsFunction* g_get_stats_function = NULL; -static ReleaseFreeMemoryFunction* g_release_free_memory_function = NULL; +static GetPropertyFunction g_get_property_function = NULL; +static GetStatsFunction g_get_stats_function = NULL; +static ReleaseFreeMemoryFunction g_release_free_memory_function = NULL; -void SetGetStatsFunction(GetStatsFunction* get_stats_function) { +void SetGetPropertyFunction(GetPropertyFunction get_property_function) { + g_get_property_function = get_property_function; +} + +GetPropertyFunction GetGetPropertyFunction() { + return g_get_property_function; +} + +void SetGetStatsFunction(GetStatsFunction get_stats_function) { g_get_stats_function = get_stats_function; } -GetStatsFunction* GetGetStatsFunction() { +GetStatsFunction GetGetStatsFunction() { return g_get_stats_function; } void SetReleaseFreeMemoryFunction( - ReleaseFreeMemoryFunction* release_free_memory_function) { + ReleaseFreeMemoryFunction release_free_memory_function) { g_release_free_memory_function = release_free_memory_function; } -ReleaseFreeMemoryFunction* GetReleaseFreeMemoryFunction() { +ReleaseFreeMemoryFunction GetReleaseFreeMemoryFunction() { return g_release_free_memory_function; } diff --git a/base/allocator/allocator_extension_thunks.h b/base/allocator/allocator_extension_thunks.h index 4a46b45..3b0e4edc 100644 --- a/base/allocator/allocator_extension_thunks.h +++ b/base/allocator/allocator_extension_thunks.h @@ -5,6 +5,8 @@ #ifndef BASE_ALLOCATOR_ALLOCATOR_THUNKS_EXTENSION_H #define BASE_ALLOCATOR_ALLOCATOR_THUNKS_EXTENSION_H +#include <stddef.h> // for size_t + namespace base { namespace allocator { namespace thunks { @@ -13,14 +15,18 @@ namespace thunks { // new allocator extension from a specific allocator implementation to base. // See allocator_extension.h to see the interface that base exports. -typedef void GetStatsFunction(char*, int); -void SetGetStatsFunction(GetStatsFunction* get_stats_function); -GetStatsFunction* GetGetStatsFunction(); +typedef bool (*GetPropertyFunction)(const char* name, size_t* value); +void SetGetPropertyFunction(GetPropertyFunction get_property_function); +GetPropertyFunction GetGetPropertyFunction(); + +typedef void (*GetStatsFunction)(char* buffer, int buffer_length); +void SetGetStatsFunction(GetStatsFunction get_stats_function); +GetStatsFunction GetGetStatsFunction(); -typedef void ReleaseFreeMemoryFunction(); +typedef void (*ReleaseFreeMemoryFunction)(); void SetReleaseFreeMemoryFunction( - ReleaseFreeMemoryFunction* release_free_memory_function); -ReleaseFreeMemoryFunction* GetReleaseFreeMemoryFunction(); + ReleaseFreeMemoryFunction release_free_memory_function); +ReleaseFreeMemoryFunction GetReleaseFreeMemoryFunction(); } // namespace thunks } // namespace allocator diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc index 9d3d932..bcc84aa 100644 --- a/base/allocator/allocator_shim.cc +++ b/base/allocator/allocator_shim.cc @@ -8,6 +8,7 @@ #include "base/allocator/allocator_extension_thunks.h" #include "base/profiler/alternate_timer.h" #include "base/sysinfo.h" +#include "jemalloc.h" // When defined, different heap allocators can be used via an environment // variable set before running the program. This may reduce the amount @@ -231,6 +232,44 @@ 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) { +#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. + return false; + } +#endif + return MallocExtension::instance()->GetNumericProperty(name, value); +} + static void get_stats_thunk(char* buffer, int buffer_length) { MallocExtension::instance()->GetStats(buffer, buffer_length); } @@ -284,6 +323,7 @@ extern "C" int _heap_init() { tracked_objects::TIME_SOURCE_TYPE_TCMALLOC); } + base::allocator::thunks::SetGetPropertyFunction(get_property_thunk); base::allocator::thunks::SetGetStatsFunction(get_stats_thunk); base::allocator::thunks::SetReleaseFreeMemoryFunction( release_free_memory_thunk); |