Chromium Code Reviews| 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 |