1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SRC_PROFILING_MEMORY_BOOKKEEPING_DUMP_H_ 18 #define SRC_PROFILING_MEMORY_BOOKKEEPING_DUMP_H_ 19 20 #include <functional> 21 #include <set> 22 23 #include <inttypes.h> 24 25 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h" 26 #include "protos/perfetto/trace/profiling/profile_common.pbzero.h" 27 #include "protos/perfetto/trace/profiling/profile_packet.pbzero.h" 28 #include "protos/perfetto/trace/trace_packet.pbzero.h" 29 30 #include "perfetto/ext/tracing/core/trace_writer.h" 31 32 #include "src/profiling/common/interner.h" 33 #include "src/profiling/common/interning_output.h" 34 #include "src/profiling/memory/bookkeeping.h" 35 36 namespace perfetto { 37 namespace profiling { 38 39 class DumpState { 40 public: DumpState(TraceWriter * trace_writer,std::function<void (protos::pbzero::ProfilePacket::ProcessHeapSamples *)> process_fill_header,InterningOutputTracker * intern_state)41 DumpState( 42 TraceWriter* trace_writer, 43 std::function<void(protos::pbzero::ProfilePacket::ProcessHeapSamples*)> 44 process_fill_header, 45 InterningOutputTracker* intern_state) 46 : trace_writer_(trace_writer), 47 intern_state_(intern_state), 48 current_process_fill_header_(std::move(process_fill_header)) { 49 MakeProfilePacket(); 50 } 51 52 // This should be a temporary object, only used on the stack for dumping a 53 // single process. 54 DumpState(const DumpState&) = delete; 55 DumpState& operator=(const DumpState&) = delete; 56 DumpState(DumpState&&) = delete; 57 DumpState& operator=(DumpState&&) = delete; 58 59 void AddIdleBytes(uint64_t callstack_id, uint64_t bytes); 60 61 void WriteAllocation(const HeapTracker::CallstackAllocations& alloc, 62 bool dump_at_max_mode); 63 void DumpCallstacks(GlobalCallstackTrie* callsites); 64 65 private: 66 void WriteMap(const Interned<Mapping> map); 67 void WriteFrame(const Interned<Frame> frame); 68 void WriteBuildIDString(const Interned<std::string>& str); 69 void WriteMappingPathString(const Interned<std::string>& str); 70 void WriteFunctionNameString(const Interned<std::string>& str); 71 MakeTracePacket()72 void MakeTracePacket() { 73 last_written_ = trace_writer_->written(); 74 75 if (current_trace_packet_) 76 current_trace_packet_->Finalize(); 77 current_trace_packet_ = trace_writer_->NewTracePacket(); 78 current_trace_packet_->set_timestamp( 79 static_cast<uint64_t>(base::GetBootTimeNs().count())); 80 current_profile_packet_ = nullptr; 81 current_interned_data_ = nullptr; 82 current_process_heap_samples_ = nullptr; 83 } 84 MakeProfilePacket()85 void MakeProfilePacket() { 86 MakeTracePacket(); 87 88 current_profile_packet_ = current_trace_packet_->set_profile_packet(); 89 uint64_t* next_index = intern_state_->HeapprofdNextIndexMutable(); 90 current_profile_packet_->set_index((*next_index)++); 91 } 92 currently_written()93 uint64_t currently_written() { 94 return trace_writer_->written() - last_written_; 95 } 96 97 protos::pbzero::ProfilePacket::ProcessHeapSamples* 98 GetCurrentProcessHeapSamples(); 99 protos::pbzero::InternedData* GetCurrentInternedData(); 100 101 std::set<GlobalCallstackTrie::Node*> callstacks_to_dump_; 102 103 TraceWriter* trace_writer_; 104 InterningOutputTracker* intern_state_; 105 106 protos::pbzero::ProfilePacket* current_profile_packet_ = nullptr; 107 protos::pbzero::InternedData* current_interned_data_ = nullptr; 108 TraceWriter::TracePacketHandle current_trace_packet_; 109 protos::pbzero::ProfilePacket::ProcessHeapSamples* 110 current_process_heap_samples_ = nullptr; 111 std::function<void(protos::pbzero::ProfilePacket::ProcessHeapSamples*)> 112 current_process_fill_header_; 113 std::map<uint64_t /* callstack_id */, uint64_t> current_process_idle_allocs_; 114 115 uint64_t last_written_ = 0; 116 }; 117 118 } // namespace profiling 119 } // namespace perfetto 120 121 #endif // SRC_PROFILING_MEMORY_BOOKKEEPING_DUMP_H_ 122