diff options
author | gab <gab@chromium.org> | 2016-03-22 06:51:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-22 13:52:38 +0000 |
commit | bd637823bfb7e2f56a7dd56f2b6b3acf3384243b (patch) | |
tree | 7e48a75cbedcc94fc3920b4de0c3641cf8f97f90 | |
parent | 489ec0ba4f1b4d10c9c7f08fee75b0eae4dcdf5d (diff) | |
download | chromium_src-bd637823bfb7e2f56a7dd56f2b6b3acf3384243b.zip chromium_src-bd637823bfb7e2f56a7dd56f2b6b3acf3384243b.tar.gz chromium_src-bd637823bfb7e2f56a7dd56f2b6b3acf3384243b.tar.bz2 |
Revert of tracing: add dump provider for malloc heap profiler (patchset #11 id:200001 of https://codereview.chromium.org/1675183006/ )
Reason for revert:
Breaks Google Chrome Mac bot.
Looks like it fails to find base/allocator/features.h for the pnacl build.
FWICT features.h is a generated header that goes in out/Debug/gen/base/allocator/features.h and it isn't found in the NaCL build for some reason.
Weird that it was not caught when this landed but rather much later. It probably depends on which part of the incremental build are triggered..? Missing dependency somewhere perhaps?
Full error log: https://build.chromium.org/p/chromium.chrome/builders/Google%20Chrome%20Mac/builds/8808
Snippet:
(...)
FAILED: cd ../../base; export BUILT_FRAMEWORKS_DIR=/b/build/slave/google-chrome-rel-mac/build/src/out/Release; export BUILT_PRODUCTS_DIR=/b/build/slave/google-chrome-rel-mac/build/src/out/Release; export CONFIGURATION=Release; export PRODUCT_NAME=base_nacl; export SDKROOT=/Applications/Xcode5.1.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk; export SRCROOT=/b/build/slave/google-chrome-rel-mac/build/src/out/Release/../../base; export SOURCE_ROOT="${SRCROOT}"; export TARGET_BUILD_DIR=/b/build/slave/google-chrome-rel-
(...)
list=../out/gypfiles/base/pnacl_newlib.base_nacl.source_list.gypcmd"
trace_event/malloc_dump_provider.cc:11:10: fatal error: 'base/allocator/features.h' file not found
#include "base/allocator/features.h"
^
1 error generated.
FAILED with 1: /b/build/goma/gomacc ../native_client/toolchain/mac_x86/pnacl_newlib/bin/pnacl-clang++ -c trace_event/malloc_dump_provider.cc -o ../out/Release/obj/base/base_nacl.gen/pnacl_newlib-pnacl/base_nacl/malloc_dump_provider_eeff7b85.o -MD -MF ../out/Release/obj/base/base_nacl.gen/pnacl_newlib-pnacl/base_nacl/malloc_dump_provider_eeff7b85.d -O2 -g -Wall -fdiagnostics-show-option -Werror -fno-strict-aliasing -Wno-unused-function -Wno-char-subscripts -Wno-c++11-extensions -Wno-unnamed-type-template-args -Wno-extra-semi -Wno-unused-private-field -Wno-char-subscripts -Wno-unused-function -std=gnu++11 -D__STDC_LIMIT_MACROS=1 -D__STDC_FORMAT_MACROS=1 -D_GNU_SOURCE=1 -D_POSIX_C_SOURCE=199506 -D_XOPEN_SOURCE=600 -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DDYNAMIC_ANNOTATIONS_PREFIX=NACL_ -DV8_DEPRECATION_WARNINGS -DCLD_VERSION=2 -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORE=0 -DGOOGLE_CHROME_BUILD -DCR_CLANG_REVISION=263324-1 -DENABLE_RLZ -DUSE_LIBJPEG_TURBO=1 -DENABLE_WEBRTC=1 -DENABLE_MEDIA_ROUTER=1 -DUSE_PROPRIETARY_CODECS -DENABLE_PEPPER_CDMS -DENABLE_CONFIGURATION_POLICY -DENABLE_NOTIFICATIONS -DENABLE_TOPCHROME_MD=1 -DENABLE_TASK_MANAGER=1 -DENABLE_EXTENSIONS=1 -DENABLE_PDF=1 -DENABLE_PLUGIN_INSTALLATION=1 -DENABLE_PLUGINS=1 -DENABLE_SESSION_SERVICE=1 -DENABLE_THEMES=1 -DENABLE_AUTOFILL_DIALOG=1 -DENABLE_PROD_WALLET_SERVICE=1 -DENABLE_PRINTING=1 -DENABLE_BASIC_PRINTING=1 -DENABLE_PRINT_PREVIEW=1 -DENABLE_SPELLCHECK=1 -DUSE_BROWSER_SPELLCHECKER=1 -DENABLE_CAPTIVE_PORTAL_DETECTION=1 -DENABLE_APP_LIST=1 -DENABLE_SETTINGS_APP=1 -DENABLE_SUPERVISED_USERS=1 -DENABLE_SERVICE_DISCOVERY=1 -DENABLE_HANGOUT_SERVICES_EXTENSION=1 -DV8_USE_EXTERNAL_STARTUP_DATA -DFULL_SAFE_BROWSING -DSAFE_BROWSING_CSD -DSAFE_BROWSING_DB_LOCAL -DUSE_LIBPCI=1 -DUSE_OPENSSL=1 -DUSE_OPENSSL_CERTS=1 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -DBASE_IMPLEMENTATION -DSYSTEM_NATIVE_UTF8 -DNACL_WINDOWS=0 -DNACL_OSX=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_BUILD_ARCH=pnacl -I../out/Release/gen/tc_pnacl_newlib/include -I.. -I../out/Release/gen -I.. -DNDEBUG -std=gnu++0x -Wno-deprecated-register
Compile options: ['-O2', '-g', '-Wall', '-fdiagnostics-show-option', '-Werror', '-fno-strict-aliasing', '-Wno-unused-function', '-Wno-char-subscripts', '-Wno-c++11-extensions', '-Wno-unnamed-type-template-args', '-Wno-extra-semi', '-Wno-unused-private-field', '-Wno-char-subscripts', '-Wno-unused-function', '-std=gnu++11', '-D__STDC_LIMIT_MACROS=1', '-D__STDC_FORMAT_MACROS=1', '-D_GNU_SOURCE=1', '-D_POSIX_C_SOURCE=199506', '-D_XOPEN_SOURCE=600', '-DDYNAMIC_ANNOTATIONS_ENABLED=1', '-DDYNAMIC_ANNOTATIONS_PREFIX=NACL_', '-DV8_DEPRECATION_WARNINGS', '-DCLD_VERSION=2', '-D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORE=0', '-DGOOGLE_CHROME_BUILD', '-DCR_CLANG_REVISION=263324-1', '-DENABLE_RLZ', '-DUSE_LIBJPEG_TURBO=1', '-DENABLE_WEBRTC=1', '-DENABLE_MEDIA_ROUTER=1', '-DUSE_PROPRIETARY_CODECS', '-DENABLE_PEPPER_CDMS', '-DENABLE_CONFIGURATION_POLICY', '-DENABLE_NOTIFICATIONS', '-DENABLE_TOPCHROME_MD=1', '-DENABLE_TASK_MANAGER=1', '-DENABLE_EXTENSIONS=1', '-DENABLE_PDF=1', '-DENABLE_PLUGIN_INSTALLATION=1', '-DENABLE_PLUGINS=1', '-DENABLE_SESSION_SERVICE=1', '-DENABLE_THEMES=1', '-DENABLE_AUTOFILL_DIALOG=1', '-DENABLE_PROD_WALLET_SERVICE=1', '-DENABLE_PRINTING=1', '-DENABLE_BASIC_PRINTING=1', '-DENABLE_PRINT_PREVIEW=1', '-DENABLE_SPELLCHECK=1', '-DUSE_BROWSER_SPELLCHECKER=1', '-DENABLE_CAPTIVE_PORTAL_DETECTION=1', '-DENABLE_APP_LIST=1', '-DENABLE_SETTINGS_APP=1', '-DENABLE_SUPERVISED_USERS=1', '-DENABLE_SERVICE_DISCOVERY=1', '-DENABLE_HANGOUT_SERVICES_EXTENSION=1', '-DV8_USE_EXTERNAL_STARTUP_DATA', '-DFULL_SAFE_BROWSING', '-DSAFE_BROWSING_CSD', '-DSAFE_BROWSING_DB_LOCAL', '-DUSE_LIBPCI=1', '-DUSE_OPENSSL=1', '-DUSE_OPENSSL_CERTS=1', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS', '-DBASE_IMPLEMENTATION', '-DSYSTEM_NATIVE_UTF8', '-DNACL_WINDOWS=0', '-DNACL_OSX=0', '-DNACL_LINUX=0', '-DNACL_ANDROID=0', '-DNACL_BUILD_ARCH=pnacl', '-I../out/Release/gen/tc_pnacl_newlib/include', '-I..', '-I../out/Release/gen', '-I..', '-DNDEBUG']
Linker options: ['-B../out/Release/gen/tc_pnacl_newlib/lib']
Traceback (most recent call last):
File "../native_client/build/build_nexe.py", line 845, in CompileProcess
output_queue.put((filename, build.Compile(filename)))
File "../native_client/build/build_nexe.py", line 575, in Compile
raise Error('FAILED with %d: %s' % (err, ' '.join(cmd_line)))
Error: FAILED with 1: /b/build/goma/gomacc ../native_client/toolchain/mac_x86/pnacl_newlib/bin/pnacl-clang++ -c trace_event/malloc_dump_provider.cc -o ../out/Release/obj/base/base_nacl.gen/pnacl_newlib-pnacl/base_nacl/malloc_dump_provider_eeff7b85.o -MD -MF ../out/Release/obj/base/base_nacl.gen/pnacl_newlib-pnacl/base_nacl/malloc_dump_provider_eeff7b85.d -O2 -g -Wall -fdiagnostics-show-option -Werror -fno-strict-aliasing -Wno-unused-function -Wno-char-subscripts -Wno-c++11-extensions -Wno-unnamed-type-template-args -Wno-extra-semi -Wno-unused-private-field -Wno-char-subscripts -Wno-unused-function -std=gnu++11 -D__STDC_LIMIT_MACROS=1 -D__STDC_FORMAT_MACROS=1 -D_GNU_SOURCE=1 -D_POSIX_C_SOURCE=199506 -D_XOPEN_SOURCE=600 -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DDYNAMIC_ANNOTATIONS_PREFIX=NACL_ -DV8_DEPRECATION_WARNINGS -DCLD_VERSION=2 -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORE=0 -DGOOGLE_CHROME_BUILD -DCR_CLANG_REVISION=263324-1 -DENABLE_RLZ -DUSE_LIBJPEG_TURBO=1 -DENABLE_WEBRTC=1 -DENABLE_MEDIA_ROUTER=1 -DUSE_PROPRIETARY_CODECS -DENABLE_PEPPER_CDMS -DENABLE_CONFIGURATION_POLICY -DENABLE_NOTIFICATIONS -DENABLE_TOPCHROME_MD=1 -DENABLE_TASK_MANAGER=1 -DENABLE_EXTENSIONS=1 -DENABLE_PDF=1 -DENABLE_PLUGIN_INSTALLATION=1 -DENABLE_PLUGINS=1 -DENABLE_SESSION_SERVICE=1 -DENABLE_THEMES=1 -DENABLE_AUTOFILL_DIALOG=1 -DENABLE_PROD_WALLET_SERVICE=1 -DENABLE_PRINTING=1 -DENABLE_BASIC_PRINTING=1 -DENABLE_PRINT_PREVIEW=1 -DENABLE_SPELLCHECK=1 -DUSE_BROWSER_SPELLCHECKER=1 -DENABLE_CAPTIVE_PORTAL_DETECTION=1 -DENABLE_APP_LIST=1 -DENABLE_SETTINGS_APP=1 -DENABLE_SUPERVISED_USERS=1 -DENABLE_SERVICE_DISCOVERY=1 -DENABLE_HANGOUT_SERVICES_EXTENSION=1 -DV8_USE_EXTERNAL_STARTUP_DATA -DFULL_SAFE_BROWSING -DSAFE_BROWSING_CSD -DSAFE_BROWSING_DB_LOCAL -DUSE_LIBPCI=1 -DUSE_OPENSSL=1 -DUSE_OPENSSL_CERTS=1 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -DBASE_IMPLEMENTATION -DSYSTEM_NATIVE_UTF8 -DNACL_WINDOWS=0 -DNACL_OSX=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_BUILD_ARCH=pnacl -I../out/Release/gen/tc_pnacl_newlib/include -I.. -I../out/Release/gen -I.. -DNDEBUG -std=gnu++0x -Wno-deprecated-register
(...)
Original issue's description:
> tracing: add dump provider for malloc heap profiler
>
> Now that the allocator shim is landing (the base API landed in
> crre.com/1675143004, Linux support in crrev.com/1781573002) we
> can use that to implement the malloc heap profiler on top of that.
> This CL leverages the new shim API to collect information about
> malloc/free and injecting that into the heap profiler, leveraging
> the same infrastructure we are already using for PartitionAlloc
> and BlinkGC (oilpan).
>
> Next steps
> ----------
> Currently this heap profiler reports also the memory used by the
> tracing subsystem itself, which is not desirable. Will come up
> with some scoped suppression semantic to bypass the reporting.
>
> BUG=550886
> TBR=haraken
>
> Committed: https://crrev.com/14c8b52dac1285bbf23514d05e6109aa7edc427f
> Cr-Commit-Position: refs/heads/master@{#382505}
TBR=ssid@chromium.org,petrcermak@chromium.org,dskiba@google.com,haraken@chromium.org,primiano@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=550886, 596873
Review URL: https://codereview.chromium.org/1822013002
Cr-Commit-Position: refs/heads/master@{#382566}
9 files changed, 37 insertions, 236 deletions
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc index 2877d2a..791ab7a 100644 --- a/base/trace_event/heap_profiler_allocation_context_tracker.cc +++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc @@ -18,10 +18,6 @@ subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; namespace { -const size_t kMaxStackDepth = 128u; -AllocationContextTracker* const kInitializingSentinel = - reinterpret_cast<AllocationContextTracker*>(-1); - ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; // This function is added to the TLS slot to clean up the instance when the @@ -32,16 +28,15 @@ void DestructAllocationContextTracker(void* alloc_ctx_tracker) { } // namespace +AllocationContextTracker::AllocationContextTracker() {} +AllocationContextTracker::~AllocationContextTracker() {} + // static -AllocationContextTracker* -AllocationContextTracker::GetInstanceForCurrentThread() { - AllocationContextTracker* tracker = +AllocationContextTracker* AllocationContextTracker::GetThreadLocalTracker() { + auto tracker = static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); - if (tracker == kInitializingSentinel) - return nullptr; // Re-entrancy case. if (!tracker) { - g_tls_alloc_ctx_tracker.Set(kInitializingSentinel); tracker = new AllocationContextTracker(); g_tls_alloc_ctx_tracker.Set(tracker); } @@ -49,11 +44,6 @@ AllocationContextTracker::GetInstanceForCurrentThread() { return tracker; } -AllocationContextTracker::AllocationContextTracker() { - pseudo_stack_.reserve(kMaxStackDepth); -} -AllocationContextTracker::~AllocationContextTracker() {} - // static void AllocationContextTracker::SetCaptureEnabled(bool enabled) { // When enabling capturing, also initialize the TLS slot. This does not create @@ -66,41 +56,45 @@ void AllocationContextTracker::SetCaptureEnabled(bool enabled) { subtle::Release_Store(&capture_enabled_, enabled); } +// static void AllocationContextTracker::PushPseudoStackFrame(StackFrame frame) { + auto tracker = AllocationContextTracker::GetThreadLocalTracker(); + // Impose a limit on the height to verify that every push is popped, because // in practice the pseudo stack never grows higher than ~20 frames. - if (pseudo_stack_.size() < kMaxStackDepth) - pseudo_stack_.push_back(frame); - else - NOTREACHED(); + DCHECK_LT(tracker->pseudo_stack_.size(), 128u); + tracker->pseudo_stack_.push_back(frame); } // static void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) { + auto tracker = AllocationContextTracker::GetThreadLocalTracker(); + // Guard for stack underflow. If tracing was started with a TRACE_EVENT in // scope, the frame was never pushed, so it is possible that pop is called // on an empty stack. - if (pseudo_stack_.empty()) + if (tracker->pseudo_stack_.empty()) return; // Assert that pushes and pops are nested correctly. This DCHECK can be // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call // without a corresponding TRACE_EVENT_BEGIN). - DCHECK_EQ(frame, pseudo_stack_.back()) + DCHECK_EQ(frame, tracker->pseudo_stack_.back()) << "Encountered an unmatched TRACE_EVENT_END"; - pseudo_stack_.pop_back(); + tracker->pseudo_stack_.pop_back(); } // static AllocationContext AllocationContextTracker::GetContextSnapshot() { + AllocationContextTracker* tracker = GetThreadLocalTracker(); AllocationContext ctx; // Fill the backtrace. { - auto src = pseudo_stack_.begin(); + auto src = tracker->pseudo_stack_.begin(); auto dst = std::begin(ctx.backtrace.frames); - auto src_end = pseudo_stack_.end(); + auto src_end = tracker->pseudo_stack_.end(); auto dst_end = std::end(ctx.backtrace.frames); // Copy as much of the bottom of the pseudo stack into the backtrace as diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.h b/base/trace_event/heap_profiler_allocation_context_tracker.h index 20a6e30..9c9a313 100644 --- a/base/trace_event/heap_profiler_allocation_context_tracker.h +++ b/base/trace_event/heap_profiler_allocation_context_tracker.h @@ -43,25 +43,22 @@ class BASE_EXPORT AllocationContextTracker { return subtle::Acquire_Load(&capture_enabled_) != 0; } - // Returns the thread-local instance, creating one if necessary. Returns - // always a valid instance, unless it is called re-entrantly, in which case - // returns nullptr in the nested calls. - static AllocationContextTracker* GetInstanceForCurrentThread(); - // Pushes a frame onto the thread-local pseudo stack. - void PushPseudoStackFrame(StackFrame frame); + static void PushPseudoStackFrame(StackFrame frame); // Pops a frame from the thread-local pseudo stack. - void PopPseudoStackFrame(StackFrame frame); + static void PopPseudoStackFrame(StackFrame frame); // Returns a snapshot of the current thread-local context. - AllocationContext GetContextSnapshot(); + static AllocationContext GetContextSnapshot(); ~AllocationContextTracker(); private: AllocationContextTracker(); + static AllocationContextTracker* GetThreadLocalTracker(); + static subtle::Atomic32 capture_enabled_; // The pseudo stack where frames are |TRACE_EVENT| names. diff --git a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc index 2498fcd..58255ad 100644 --- a/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc +++ b/base/trace_event/heap_profiler_allocation_context_tracker_unittest.cc @@ -27,9 +27,7 @@ const char kGingerbread[] = "Gingerbread"; // in |AllocationContextTracker::GetContextSnapshot|. template <size_t N> void AssertBacktraceEquals(const StackFrame(&expected_backtrace)[N]) { - AllocationContext ctx = - AllocationContextTracker::GetInstanceForCurrentThread() - ->GetContextSnapshot(); + AllocationContext ctx = AllocationContextTracker::GetContextSnapshot(); auto actual = std::begin(ctx.backtrace.frames); auto actual_bottom = std::end(ctx.backtrace.frames); @@ -48,9 +46,7 @@ void AssertBacktraceEquals(const StackFrame(&expected_backtrace)[N]) { } void AssertBacktraceEmpty() { - AllocationContext ctx = - AllocationContextTracker::GetInstanceForCurrentThread() - ->GetContextSnapshot(); + AllocationContext ctx = AllocationContextTracker::GetContextSnapshot(); for (StackFrame frame : ctx.backtrace.frames) ASSERT_EQ(nullptr, frame); @@ -211,9 +207,7 @@ TEST_F(AllocationContextTrackerTest, BacktraceTakesTop) { { TRACE_EVENT0("Testing", kGingerbread); - AllocationContext ctx = - AllocationContextTracker::GetInstanceForCurrentThread() - ->GetContextSnapshot(); + AllocationContext ctx = AllocationContextTracker::GetContextSnapshot(); // The pseudo stack relies on pointer equality, not deep string comparisons. ASSERT_EQ(kCupcake, ctx.backtrace.frames[0]); @@ -221,9 +215,7 @@ TEST_F(AllocationContextTrackerTest, BacktraceTakesTop) { } { - AllocationContext ctx = - AllocationContextTracker::GetInstanceForCurrentThread() - ->GetContextSnapshot(); + AllocationContext ctx = AllocationContextTracker::GetContextSnapshot(); ASSERT_EQ(kCupcake, ctx.backtrace.frames[0]); ASSERT_EQ(kFroyo, ctx.backtrace.frames[11]); } diff --git a/base/trace_event/malloc_dump_provider.cc b/base/trace_event/malloc_dump_provider.cc index d8f82ed..6f9aa96 100644 --- a/base/trace_event/malloc_dump_provider.cc +++ b/base/trace_event/malloc_dump_provider.cc @@ -7,14 +7,7 @@ #include <stddef.h> #include "base/allocator/allocator_extension.h" -#include "base/allocator/allocator_shim.h" -#include "base/allocator/features.h" -#include "base/trace_event/heap_profiler_allocation_context.h" -#include "base/trace_event/heap_profiler_allocation_context_tracker.h" -#include "base/trace_event/heap_profiler_allocation_register.h" -#include "base/trace_event/heap_profiler_heap_dump_writer.h" #include "base/trace_event/process_memory_dump.h" -#include "base/trace_event/trace_event_argument.h" #include "build/build_config.h" #if defined(OS_MACOSX) @@ -26,65 +19,6 @@ namespace base { namespace trace_event { -#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) -namespace { - -using allocator::AllocatorDispatch; - -void* HookAlloc(const AllocatorDispatch* self, size_t size) { - const AllocatorDispatch* const next = self->next; - void* ptr = next->alloc_function(next, size); - if (ptr) - MallocDumpProvider::GetInstance()->InsertAllocation(ptr, size); - return ptr; -} - -void* HookZeroInitAlloc(const AllocatorDispatch* self, size_t n, size_t size) { - const AllocatorDispatch* const next = self->next; - void* ptr = next->alloc_zero_initialized_function(next, n, size); - if (ptr) - MallocDumpProvider::GetInstance()->InsertAllocation(ptr, n * size); - return ptr; -} - -void* HookllocAligned(const AllocatorDispatch* self, - size_t alignment, - size_t size) { - const AllocatorDispatch* const next = self->next; - void* ptr = next->alloc_aligned_function(next, alignment, size); - if (ptr) - MallocDumpProvider::GetInstance()->InsertAllocation(ptr, size); - return ptr; -} - -void* HookRealloc(const AllocatorDispatch* self, void* address, size_t size) { - const AllocatorDispatch* const next = self->next; - void* ptr = next->realloc_function(next, address, size); - MallocDumpProvider::GetInstance()->RemoveAllocation(address); - if (size > 0) // realloc(size == 0) means free(). - MallocDumpProvider::GetInstance()->InsertAllocation(ptr, size); - return ptr; -} - -void HookFree(const AllocatorDispatch* self, void* address) { - if (address) - MallocDumpProvider::GetInstance()->RemoveAllocation(address); - const AllocatorDispatch* const next = self->next; - next->free_function(next, address); -} - -AllocatorDispatch g_allocator_hooks = { - &HookAlloc, /* alloc_function */ - &HookZeroInitAlloc, /* alloc_zero_initialized_function */ - &HookllocAligned, /* alloc_aligned_function */ - &HookRealloc, /* realloc_function */ - &HookFree, /* free_function */ - nullptr, /* next */ -}; - -} // namespace -#endif // BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) - // static const char MallocDumpProvider::kAllocatedObjects[] = "malloc/allocated_objects"; @@ -94,8 +28,7 @@ MallocDumpProvider* MallocDumpProvider::GetInstance() { LeakySingletonTraits<MallocDumpProvider>>::get(); } -MallocDumpProvider::MallocDumpProvider() - : heap_profiler_enabled_(false), tid_dumping_heap_(kInvalidThreadId) {} +MallocDumpProvider::MallocDumpProvider() {} MallocDumpProvider::~MallocDumpProvider() {} @@ -163,99 +96,8 @@ bool MallocDumpProvider::OnMemoryDump(const MemoryDumpArgs& args, resident_size - allocated_objects_size); } - // Heap profiler dumps. - if (!heap_profiler_enabled_) - return true; - - // The dumps of the heap profiler should be created only when heap profiling - // was enabled (--enable-heap-profiling) AND a DETAILED dump is requested. - // However, when enabled, the overhead of the heap profiler should be always - // reported to avoid oscillations of the malloc total in LIGHT dumps. - - tid_dumping_heap_ = PlatformThread::CurrentId(); - // At this point the Insert/RemoveAllocation hooks will ignore this thread. - // Enclosing all the temporariy data structures in a scope, so that the heap - // profiler does not see unabalanced malloc/free calls from these containers. - { - TraceEventMemoryOverhead overhead; - hash_map<AllocationContext, size_t> bytes_by_context; - { - AutoLock lock(allocation_register_lock_); - if (allocation_register_) { - if (args.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { - for (const auto& alloc_size : *allocation_register_) - bytes_by_context[alloc_size.context] += alloc_size.size; - } - allocation_register_->EstimateTraceMemoryOverhead(&overhead); - } - } // lock(allocation_register_lock_) - - if (!bytes_by_context.empty()) { - scoped_ptr<TracedValue> heap_dump = ExportHeapDump( - bytes_by_context, pmd->session_state()->stack_frame_deduplicator(), - pmd->session_state()->type_name_deduplicator()); - pmd->AddHeapDump("malloc", std::move(heap_dump)); - } - overhead.DumpInto("tracing/heap_profiler_malloc", pmd); - } - tid_dumping_heap_ = kInvalidThreadId; - return true; } -void MallocDumpProvider::OnHeapProfilingEnabled(bool enabled) { -#if BUILDFLAG(USE_EXPERIMENTAL_ALLOCATOR_SHIM) - if (enabled) { - { - AutoLock lock(allocation_register_lock_); - allocation_register_.reset(new AllocationRegister()); - } - allocator::InsertAllocatorDispatch(&g_allocator_hooks); - } else { - AutoLock lock(allocation_register_lock_); - allocation_register_.reset(); - // Insert/RemoveAllocation below will no-op if the register is torn down. - // Once disabled, heap profiling will not re-enabled anymore for the - // lifetime of the process. - } -#endif - heap_profiler_enabled_ = enabled; -} - -void MallocDumpProvider::InsertAllocation(void* address, size_t size) { - // CurrentId() can be a slow operation (crbug.com/497226). This apparently - // redundant condition short circuits the CurrentID() calls when unnecessary. - if (tid_dumping_heap_ != kInvalidThreadId && - tid_dumping_heap_ == PlatformThread::CurrentId()) - return; - - // AllocationContextTracker will return nullptr when called re-reentrantly. - // This is the case of GetInstanceForCurrentThread() being called for the - // first time, which causes a new() inside the tracker which re-enters the - // heap profiler, in which case we just want to early out. - auto tracker = AllocationContextTracker::GetInstanceForCurrentThread(); - if (!tracker) - return; - AllocationContext context = tracker->GetContextSnapshot(); - - AutoLock lock(allocation_register_lock_); - if (!allocation_register_) - return; - - allocation_register_->Insert(address, size, context); -} - -void MallocDumpProvider::RemoveAllocation(void* address) { - // No re-entrancy is expected here as none of the calls below should - // cause a free()-s (|allocation_register_| does its own heap management). - if (tid_dumping_heap_ != kInvalidThreadId && - tid_dumping_heap_ == PlatformThread::CurrentId()) - return; - AutoLock lock(allocation_register_lock_); - if (!allocation_register_) - return; - allocation_register_->Remove(address); -} - } // namespace trace_event } // namespace base diff --git a/base/trace_event/malloc_dump_provider.h b/base/trace_event/malloc_dump_provider.h index d9d7021..63fc1b0 100644 --- a/base/trace_event/malloc_dump_provider.h +++ b/base/trace_event/malloc_dump_provider.h @@ -8,10 +8,7 @@ #include <istream> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" -#include "base/synchronization/lock.h" -#include "base/threading/platform_thread.h" #include "base/trace_event/memory_dump_provider.h" #include "build/build_config.h" @@ -23,8 +20,6 @@ namespace base { namespace trace_event { -class AllocationRegister; - // Dump provider which collects process-wide memory stats. class BASE_EXPORT MallocDumpProvider : public MemoryDumpProvider { public: @@ -38,28 +33,12 @@ class BASE_EXPORT MallocDumpProvider : public MemoryDumpProvider { bool OnMemoryDump(const MemoryDumpArgs& args, ProcessMemoryDump* pmd) override; - void OnHeapProfilingEnabled(bool enabled) override; - - // For heap profiling. - void InsertAllocation(void* address, size_t size); - void RemoveAllocation(void* address); - private: friend struct DefaultSingletonTraits<MallocDumpProvider>; MallocDumpProvider(); ~MallocDumpProvider() override; - // For heap profiling. - bool heap_profiler_enabled_; - scoped_ptr<AllocationRegister> allocation_register_; - Lock allocation_register_lock_; - - // When in OnMemoryDump(), this contains the current thread ID. - // This is to prevent re-entrancy in the heap profiler when the heap dump - // generation is malloc/new-ing for its own bookeeping data structures. - PlatformThreadId tid_dumping_heap_; - DISALLOW_COPY_AND_ASSIGN(MallocDumpProvider); }; diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index 3b1d2c9..dcedb44 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc @@ -1318,14 +1318,12 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( if (!(flags & TRACE_EVENT_FLAG_COPY)) { if (AllocationContextTracker::capture_enabled()) { if (phase == TRACE_EVENT_PHASE_BEGIN || - phase == TRACE_EVENT_PHASE_COMPLETE) { - AllocationContextTracker::GetInstanceForCurrentThread() - ->PushPseudoStackFrame(name); - } else if (phase == TRACE_EVENT_PHASE_END) + phase == TRACE_EVENT_PHASE_COMPLETE) + AllocationContextTracker::PushPseudoStackFrame(name); + else if (phase == TRACE_EVENT_PHASE_END) // The pop for |TRACE_EVENT_PHASE_COMPLETE| events // is in |TraceLog::UpdateTraceEventDuration|. - AllocationContextTracker::GetInstanceForCurrentThread() - ->PopPseudoStackFrame(name); + AllocationContextTracker::PopPseudoStackFrame(name); } } @@ -1449,8 +1447,7 @@ void TraceLog::UpdateTraceEventDuration( if (base::trace_event::AllocationContextTracker::capture_enabled()) { // The corresponding push is in |AddTraceEventWithThreadIdAndTimestamp|. - base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread() - ->PopPseudoStackFrame(name); + base::trace_event::AllocationContextTracker::PopPseudoStackFrame(name); } } diff --git a/components/tracing/docs/heap_profiler_internals.md b/components/tracing/docs/heap_profiler_internals.md index d1019c8..d7026ca 100644 --- a/components/tracing/docs/heap_profiler_internals.md +++ b/components/tracing/docs/heap_profiler_internals.md @@ -25,7 +25,7 @@ When there is a way to get notified of all allocations and frees, this is the normal flow: 1. When an allocation occurs, call - [`AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot()`][context-tracker] + [`AllocationContextTracker::GetContextSnapshot()`][context-tracker] to get an [`AllocationContext`][alloc-context]. 2. Insert that context together with the address and size into an [`AllocationRegister`][alloc-register] by calling `Insert()`. @@ -121,7 +121,7 @@ class FooDumpProvider : public MemoryDumpProvider { static FooDumpProvider* GetInstance(); void InsertAllocation(void* address, size_t size) { - AllocationContext context = AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot(); + AllocationContext context = AllocationContextTracker::GetContextSnapshot(); AutoLock lock(allocation_register_lock_); allocation_register_->Insert(address, size, context); } diff --git a/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp b/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp index d269b29..9a00c34 100644 --- a/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp +++ b/third_party/WebKit/Source/platform/PartitionAllocMemoryDumpProvider.cpp @@ -170,7 +170,7 @@ void PartitionAllocMemoryDumpProvider::onHeapProfilingEnabled(bool enabled) void PartitionAllocMemoryDumpProvider::insert(void* address, size_t size, const char* typeName) { - base::trace_event::AllocationContext context = base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot(); + base::trace_event::AllocationContext context = base::trace_event::AllocationContextTracker::GetContextSnapshot(); context.type_name = typeName; MutexLocker locker(m_allocationRegisterMutex); if (m_allocationRegister) diff --git a/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp b/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp index a94fc9e..73c78c7 100644 --- a/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp +++ b/third_party/WebKit/Source/platform/heap/BlinkGCMemoryDumpProvider.cpp @@ -117,7 +117,7 @@ BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider() void BlinkGCMemoryDumpProvider::insert(Address address, size_t size, const char* typeName) { - base::trace_event::AllocationContext context = base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot(); + base::trace_event::AllocationContext context = base::trace_event::AllocationContextTracker::GetContextSnapshot(); context.type_name = typeName; MutexLocker locker(m_allocationRegisterMutex); if (m_allocationRegister) |