summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-28 02:56:38 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-28 02:56:38 +0000
commit237a14858315c4ba7e9d72ad532df50a07e1a1d1 (patch)
tree1b8eedf2d3bed0d2a2cff474a344c819a8f4827c /base
parent6486d9c1aeba559fac1273c09e38585d2d555238 (diff)
downloadchromium_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.gyp33
-rw-r--r--base/allocator/allocator_extension.cc42
-rw-r--r--base/allocator/allocator_extension.h45
-rw-r--r--base/allocator/allocator_extension_thunks.cc42
-rw-r--r--base/allocator/allocator_extension_thunks.h30
-rw-r--r--base/allocator/allocator_shim.cc13
-rw-r--r--base/base.gypi4
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