diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-28 02:56:38 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-28 02:56:38 +0000 |
commit | 237a14858315c4ba7e9d72ad532df50a07e1a1d1 (patch) | |
tree | 1b8eedf2d3bed0d2a2cff474a344c819a8f4827c /base | |
parent | 6486d9c1aeba559fac1273c09e38585d2d555238 (diff) | |
download | chromium_src-237a14858315c4ba7e9d72ad532df50a07e1a1d1.zip chromium_src-237a14858315c4ba7e9d72ad532df50a07e1a1d1.tar.gz chromium_src-237a14858315c4ba7e9d72ad532df50a07e1a1d1.tar.bz2 |
Route calls to tcmalloc MallocExtension through allocator agnostic interface
Our various libraries should not be picking or depending on a particular
allocator choice - that should be an application level choice. This creates
a generic AllocatorExtension interface that can optionally be backed by
entry points to a particular allocator's MallocExtension interface if the
application chooses to.
BUG=125003
TEST=compiles, chrome://tcmalloc works
Review URL: http://codereview.chromium.org/10239012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134434 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/allocator/allocator.gyp | 33 | ||||
-rw-r--r-- | base/allocator/allocator_extension.cc | 42 | ||||
-rw-r--r-- | base/allocator/allocator_extension.h | 45 | ||||
-rw-r--r-- | base/allocator/allocator_extension_thunks.cc | 42 | ||||
-rw-r--r-- | base/allocator/allocator_extension_thunks.h | 30 | ||||
-rw-r--r-- | base/allocator/allocator_shim.cc | 13 | ||||
-rw-r--r-- | base/base.gypi | 4 |
7 files changed, 209 insertions, 0 deletions
diff --git a/base/allocator/allocator.gyp b/base/allocator/allocator.gyp index ee07ecc..7b1058c 100644 --- a/base/allocator/allocator.gyp +++ b/base/allocator/allocator.gyp @@ -427,7 +427,22 @@ }], ], }, + { + # This library is linked in to libbase and allocator_unittests. + # It can't depend on either and nothing else should depend on it - + # all other code should use the interfaced provided by libbase. + 'target_name': 'allocator_extension_thunks', + 'type': 'static_library', + 'sources': [ + 'allocator_extension_thunks.cc', + 'allocator_extension_thunks.h', ], + 'toolsets': ['host', 'target'], + 'include_dirs': [ + '../../' + ], + }, + ], 'conditions': [ ['OS=="win"', { 'targets': [ @@ -456,6 +471,7 @@ 'type': 'executable', 'dependencies': [ 'allocator', + 'allocator_extension_thunks', '../../testing/gtest.gyp:gtest', ], 'include_dirs': [ @@ -470,6 +486,23 @@ '../profiler/alternate_timer.h', ], }, + { + 'target_name': 'allocator_extension_thunks_win64', + 'type': 'static_library', + 'sources': [ + 'allocator_extension_thunks.cc', + 'allocator_extension_thunks.h', + ], + 'toolsets': ['host', 'target'], + 'include_dirs': [ + '../../' + ], + 'configurations': { + 'Common_Base': { + 'msvs_target_platform': 'x64', + }, + }, + }, ], }], ], diff --git a/base/allocator/allocator_extension.cc b/base/allocator/allocator_extension.cc new file mode 100644 index 0000000..7ae11da --- /dev/null +++ b/base/allocator/allocator_extension.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/allocator/allocator_extension.h" + +#include "base/logging.h" + +namespace base { +namespace allocator { + +void GetStats(char* buffer, int buffer_length) { + DCHECK_GT(buffer_length, 0); + if (thunks::GetStatsFunction* get_stats_function = + base::allocator::thunks::GetGetStatsFunction()) + get_stats_function(buffer, buffer_length); + else + buffer[0] = '\0'; +} + +void ReleaseFreeMemory() { + if (thunks::ReleaseFreeMemoryFunction* release_free_memory_function = + base::allocator::thunks::GetReleaseFreeMemoryFunction()) + release_free_memory_function(); +} + +void SetGetStatsFunction(thunks::GetStatsFunction* get_stats_function) { + DCHECK_EQ(base::allocator::thunks::GetGetStatsFunction(), + reinterpret_cast<thunks::GetStatsFunction*>(NULL)); + base::allocator::thunks::SetGetStatsFunction(get_stats_function); +} + +void SetReleaseFreeMemoryFunction( + thunks::ReleaseFreeMemoryFunction* release_free_memory_function) { + DCHECK_EQ(base::allocator::thunks::GetReleaseFreeMemoryFunction(), + reinterpret_cast<thunks::ReleaseFreeMemoryFunction*>(NULL)); + base::allocator::thunks::SetReleaseFreeMemoryFunction( + release_free_memory_function); +} + +} // namespace allocator +} // namespace base diff --git a/base/allocator/allocator_extension.h b/base/allocator/allocator_extension.h new file mode 100644 index 0000000..d63f189 --- /dev/null +++ b/base/allocator/allocator_extension.h @@ -0,0 +1,45 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_ALLOCATOR_ALLOCATOR_EXTENSION_H +#define BASE_ALLOCATOR_ALLOCATOR_EXTENSION_H +#pragma once + +#include "base/allocator/allocator_extension_thunks.h" +#include "base/base_export.h" +#include "build/build_config.h" + +namespace base { +namespace allocator { + +// 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]. +// +// |buffer| must point to a valid piece of memory +// |buffer_length| must be > 0. +BASE_EXPORT void GetStats(char* buffer, int buffer_length); + +// Request that the allocator release any free memory it knows about to the +// system. +BASE_EXPORT void ReleaseFreeMemory(); + + +// These settings allow specifying a callback used to implement the allocator +// extension functions. These are optional, but if set they must only be set +// once. These will typically called in an allocator-specific initialization +// routine. +// +// 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 SetGetStatsFunction( + thunks::GetStatsFunction* get_stats_function); + +BASE_EXPORT void SetReleaseFreeMemoryFunction( + thunks::ReleaseFreeMemoryFunction* release_free_memory_function); +} // namespace allocator +} // namespace base + +#endif diff --git a/base/allocator/allocator_extension_thunks.cc b/base/allocator/allocator_extension_thunks.cc new file mode 100644 index 0000000..f8985a2 --- /dev/null +++ b/base/allocator/allocator_extension_thunks.cc @@ -0,0 +1,42 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/allocator/allocator_extension_thunks.h" + +#include <cstddef> // for NULL + +namespace base { +namespace allocator { +namespace thunks { + +// This slightly odd translation unit exists because of the peculularity of how +// allocator_unittests works on windows. That target has to perform +// tcmalloc-specific initialization on windows, but it cannot depend on base +// otherwise. This target sits in the middle - both libbase and +// allocator_unittests 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; + +void SetGetStatsFunction(GetStatsFunction* get_stats_function) { + g_get_stats_function = get_stats_function; +} + +GetStatsFunction* GetGetStatsFunction() { + return g_get_stats_function; +} + +void SetReleaseFreeMemoryFunction( + ReleaseFreeMemoryFunction* release_free_memory_function) { + g_release_free_memory_function = release_free_memory_function; +} + +ReleaseFreeMemoryFunction* GetReleaseFreeMemoryFunction() { + return g_release_free_memory_function; +} + +} // namespace thunks +} // namespace allocator +} // namespace base diff --git a/base/allocator/allocator_extension_thunks.h b/base/allocator/allocator_extension_thunks.h new file mode 100644 index 0000000..7c9c231 --- /dev/null +++ b/base/allocator/allocator_extension_thunks.h @@ -0,0 +1,30 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_ALLOCATOR_ALLOCATOR_THUNKS_EXTENSION_H +#define BASE_ALLOCATOR_ALLOCATOR_THUNKS_EXTENSION_H +#pragma once + +namespace base { +namespace allocator { +namespace thunks { + +// WARNING: You probably don't want to use this file unless you are routing a +// 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 void ReleaseFreeMemoryFunction(); +void SetReleaseFreeMemoryFunction( + ReleaseFreeMemoryFunction* release_free_memory_function); +ReleaseFreeMemoryFunction* GetReleaseFreeMemoryFunction(); + +} // namespace thunks +} // namespace allocator +} // namespace base + +#endif diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc index 075828d..8728097 100644 --- a/base/allocator/allocator_shim.cc +++ b/base/allocator/allocator_shim.cc @@ -5,6 +5,7 @@ #include "base/allocator/allocator_shim.h" #include <config.h> +#include "base/allocator/allocator_extension_thunks.h" #include "base/profiler/alternate_timer.h" #include "base/sysinfo.h" @@ -229,6 +230,14 @@ extern "C" intptr_t _get_heap_handle() { return 0; } +static void get_stats_thunk(char* buffer, int buffer_length) { + MallocExtension::instance()->GetStats(buffer, buffer_length); +} + +static void release_free_memory_thunk() { + MallocExtension::instance()->ReleaseFreeMemory(); +} + // The CRT heap initialization stub. extern "C" int _heap_init() { #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING @@ -274,6 +283,10 @@ extern "C" int _heap_init() { tracked_objects::TIME_SOURCE_TYPE_TCMALLOC); } + base::allocator::thunks::SetGetStatsFunction(get_stats_thunk); + base::allocator::thunks::SetReleaseFreeMemoryFunction( + release_free_memory_thunk); + return 1; } diff --git a/base/base.gypi b/base/base.gypi index 302f620..c5fb4cc 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -21,6 +21,8 @@ 'third_party/nspr/prtime.h', 'third_party/nspr/prcpucfg_linux.h', 'third_party/xdg_mime/xdgmime.h', + 'allocator/allocator_extension.cc', + 'allocator/allocator_extension.h', 'android/base_jni_registrar.cc', 'android/base_jni_registrar.h', 'android/build_info.cc', @@ -589,6 +591,7 @@ }, 'dependencies': [ 'base_static', + 'allocator/allocator.gyp:allocator_extension_thunks', '../testing/gtest.gyp:gtest_prod', '../third_party/modp_b64/modp_b64.gyp:modp_b64', 'third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', @@ -808,6 +811,7 @@ }, 'dependencies': [ 'base_static_win64', + 'allocator/allocator.gyp:allocator_extension_thunks_win64', 'third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64', ], # TODO(gregoryd): direct_dependent_settings should be shared with the |