Index: base/allocator/allocator_extension.cc |
diff --git a/base/allocator/allocator_extension.cc b/base/allocator/allocator_extension.cc |
index bcfe89beb0ea7339bc52b38621bb3d5094110b4f..db9f97fe1a05d12ebefffa9d741195c14f39a830 100644 |
--- a/base/allocator/allocator_extension.cc |
+++ b/base/allocator/allocator_extension.cc |
@@ -5,20 +5,48 @@ |
#include "base/allocator/allocator_extension.h" |
#include "base/logging.h" |
+#include "build/build_config.h" |
namespace base { |
namespace allocator { |
+#if defined(USE_TCMALLOC) |
+// Since the base library does not know about allocator, the initialization |
+// method would call this function which is declared as a weak symbol. This |
+// should be replaced by a strong symbol linked from the actual allocator |
+// library. The executable target is expected include an allocator shim layer |
Primiano Tucci (use gerrit)
2015/11/25 12:47:17
remove "shim layer"
|
+// replaces this weak symbol. |
+// Such an implementation of this method should return a set of callbacks that |
+// are used to implement the required allocator extension functions. |
+// This method is defined in .cc file so that the allocator implementation can |
+// still include the header file without getting a "weak" declaration of this |
+// function. |
+__attribute__((weak, visibility("default"), noinline)) |
+thunks::AllocatorExtensionFunctions |
+InitializeAllocatorWeak(); |
+#endif |
+ |
+void InitializeAllocator() { |
+#if defined(USE_TCMALLOC) |
+ // This calls into the weak function declared above. If a specific allocator |
+ // implementation needs initialization then it should define and link a strong |
+ // symbol of "InitializeAllocatorWeak" function, that returns the necessary |
+ // callbacks. |
+ thunks::AllocatorExtensionFunctions functions = InitializeAllocatorWeak(); |
+ thunks::SetAllocatorExtensionFunctions(functions); |
+#endif |
+} |
+ |
bool GetAllocatorWasteSize(size_t* size) { |
- thunks::GetAllocatorWasteSizeFunction get_allocator_waste_size_function = |
- thunks::GetGetAllocatorWasteSizeFunction(); |
+ auto get_allocator_waste_size_function = |
+ thunks::GetAllocatorExtensionFunctions().get_allocator_waste_size; |
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 = thunks::GetGetStatsFunction(); |
+ auto get_stats_function = thunks::GetAllocatorExtensionFunctions().get_stats; |
if (get_stats_function) |
get_stats_function(buffer, buffer_length); |
else |
@@ -26,37 +54,61 @@ void GetStats(char* buffer, int buffer_length) { |
} |
void ReleaseFreeMemory() { |
- thunks::ReleaseFreeMemoryFunction release_free_memory_function = |
- thunks::GetReleaseFreeMemoryFunction(); |
+ auto release_free_memory_function = |
+ thunks::GetAllocatorExtensionFunctions().release_free_memory; |
if (release_free_memory_function) |
release_free_memory_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); |
+size_t GetBytesAllocatedOnCurrentThread() { |
+ auto get_bytes_allocated_on_current_thread_function = |
+ thunks::GetAllocatorExtensionFunctions() |
+ .get_bytes_allocated_on_current_thread; |
+ DCHECK(get_bytes_allocated_on_current_thread_function); |
+ return get_bytes_allocated_on_current_thread_function(); |
+} |
+ |
+bool GetNumericProperty(const char* name, size_t* value) { |
+ auto get_numeric_property_function = |
+ thunks::GetAllocatorExtensionFunctions().get_numeric_property; |
+ return get_numeric_property_function != NULL && |
+ get_numeric_property_function(name, value); |
+} |
+ |
+void HeapProfilerStart(StackGeneratorFunction callback) { |
+ auto heap_profiler_start_function = |
+ thunks::GetAllocatorExtensionFunctions().heap_profiler_start; |
+ if (heap_profiler_start_function) |
+ heap_profiler_start_function(callback); |
+} |
+ |
+void HeapProfilerStop() { |
+ auto heap_profiler_stop_function = |
+ thunks::GetAllocatorExtensionFunctions().heap_profiler_stop; |
+ if (heap_profiler_stop_function) |
+ heap_profiler_stop_function(); |
} |
-void SetGetStatsFunction(thunks::GetStatsFunction get_stats_function) { |
- DCHECK_EQ(thunks::GetGetStatsFunction(), |
- reinterpret_cast<thunks::GetStatsFunction>(NULL)); |
- thunks::SetGetStatsFunction(get_stats_function); |
+char* GetHeapProfile() { |
+ auto get_heap_profile_function = |
+ thunks::GetAllocatorExtensionFunctions().get_heap_profile; |
+ if (get_heap_profile_function) |
+ return get_heap_profile_function(); |
+ return NULL; |
} |
-void SetReleaseFreeMemoryFunction( |
- thunks::ReleaseFreeMemoryFunction release_free_memory_function) { |
- DCHECK_EQ(thunks::GetReleaseFreeMemoryFunction(), |
- reinterpret_cast<thunks::ReleaseFreeMemoryFunction>(NULL)); |
- thunks::SetReleaseFreeMemoryFunction(release_free_memory_function); |
+void HeapProfilerDump(const char* reason) { |
+ auto heap_profiler_dump_function = |
+ thunks::GetAllocatorExtensionFunctions().heap_profiler_dump; |
+ if (heap_profiler_dump_function) |
+ heap_profiler_dump_function(reason); |
} |
-void SetGetNumericPropertyFunction( |
- thunks::GetNumericPropertyFunction get_numeric_property_function) { |
- DCHECK_EQ(thunks::GetGetNumericPropertyFunction(), |
- reinterpret_cast<thunks::GetNumericPropertyFunction>(NULL)); |
- thunks::SetGetNumericPropertyFunction(get_numeric_property_function); |
+bool IsHeapProfilerRunning() { |
+ auto is_heap_profiler_running_function = |
+ thunks::GetAllocatorExtensionFunctions().is_heap_profiler_running; |
+ return is_heap_profiler_running_function != NULL && |
+ is_heap_profiler_running_function(); |
} |
} // namespace allocator |