1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/trace_event/heap_profiler_event_filter.h" 6 7 #include "base/trace_event/category_registry.h" 8 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" 9 #include "base/trace_event/trace_category.h" 10 #include "base/trace_event/trace_event.h" 11 #include "base/trace_event/trace_event_impl.h" 12 13 namespace base { 14 namespace trace_event { 15 16 namespace { 17 IsPseudoStackEnabled()18inline bool IsPseudoStackEnabled() { 19 // Only PSEUDO_STACK and MIXED_STACK modes require trace events. 20 return AllocationContextTracker::capture_mode() == 21 AllocationContextTracker::CaptureMode::PSEUDO_STACK || 22 AllocationContextTracker::capture_mode() == 23 AllocationContextTracker::CaptureMode::MIXED_STACK; 24 } 25 GetThreadLocalTracker()26inline AllocationContextTracker* GetThreadLocalTracker() { 27 return AllocationContextTracker::GetInstanceForCurrentThread(); 28 } 29 30 } // namespace 31 32 // static 33 const char HeapProfilerEventFilter::kName[] = "heap_profiler_predicate"; 34 35 HeapProfilerEventFilter::HeapProfilerEventFilter() = default; 36 HeapProfilerEventFilter::~HeapProfilerEventFilter() = default; 37 FilterTraceEvent(const TraceEvent & trace_event) const38bool HeapProfilerEventFilter::FilterTraceEvent( 39 const TraceEvent& trace_event) const { 40 if (!IsPseudoStackEnabled()) 41 return true; 42 43 // TODO(primiano): Add support for events with copied name crbug.com/581079. 44 if (trace_event.flags() & TRACE_EVENT_FLAG_COPY) 45 return true; 46 47 const auto* category = CategoryRegistry::GetCategoryByStatePtr( 48 trace_event.category_group_enabled()); 49 AllocationContextTracker::PseudoStackFrame frame = {category->name(), 50 trace_event.name()}; 51 if (trace_event.phase() == TRACE_EVENT_PHASE_BEGIN || 52 trace_event.phase() == TRACE_EVENT_PHASE_COMPLETE) { 53 GetThreadLocalTracker()->PushPseudoStackFrame(frame); 54 } else if (trace_event.phase() == TRACE_EVENT_PHASE_END) { 55 // The pop for |TRACE_EVENT_PHASE_COMPLETE| events is in |EndEvent|. 56 GetThreadLocalTracker()->PopPseudoStackFrame(frame); 57 } 58 // Do not filter-out any events and always return true. TraceLog adds the 59 // event only if it is enabled for recording. 60 return true; 61 } 62 EndEvent(const char * category_name,const char * event_name) const63void HeapProfilerEventFilter::EndEvent(const char* category_name, 64 const char* event_name) const { 65 if (IsPseudoStackEnabled()) 66 GetThreadLocalTracker()->PopPseudoStackFrame({category_name, event_name}); 67 } 68 69 } // namespace trace_event 70 } // namespace base 71