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 <cinttypes> 21 #include <functional> 22 #include <set> 23 24 #include "perfetto/ext/tracing/core/trace_writer.h" 25 #include "src/profiling/common/interner.h" 26 #include "src/profiling/common/interning_output.h" 27 #include "src/profiling/memory/bookkeeping.h" 28 29 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h" 30 #include "protos/perfetto/trace/profiling/profile_common.pbzero.h" 31 #include "protos/perfetto/trace/profiling/profile_packet.pbzero.h" 32 #include "protos/perfetto/trace/trace_packet.pbzero.h" 33 34 namespace perfetto { 35 namespace profiling { 36 37 class DumpState { 38 public: DumpState(TraceWriter * trace_writer,std::function<void (protos::pbzero::ProfilePacket::ProcessHeapSamples *)> process_fill_header,InterningOutputTracker * intern_state)39 DumpState( 40 TraceWriter* trace_writer, 41 std::function<void(protos::pbzero::ProfilePacket::ProcessHeapSamples*)> 42 process_fill_header, 43 InterningOutputTracker* intern_state) 44 : trace_writer_(trace_writer), 45 intern_state_(intern_state), 46 current_process_fill_header_(std::move(process_fill_header)) { 47 MakeProfilePacket(); 48 } 49 50 // This should be a temporary object, only used on the stack for dumping a 51 // single process. 52 DumpState(const DumpState&) = delete; 53 DumpState& operator=(const DumpState&) = delete; 54 DumpState(DumpState&&) = delete; 55 DumpState& operator=(DumpState&&) = delete; 56 57 void WriteAllocation(const HeapTracker::CallstackAllocations& alloc, 58 bool dump_at_max_mode); 59 void DumpCallstacks(GlobalCallstackTrie* callsites); 60 61 private: 62 void WriteMap(const Interned<Mapping> map); 63 void WriteFrame(const Interned<Frame> frame); 64 void WriteBuildIDString(const Interned<std::string>& str); 65 void WriteMappingPathString(const Interned<std::string>& str); 66 void WriteFunctionNameString(const Interned<std::string>& str); 67 MakeTracePacket()68 void MakeTracePacket() { 69 last_written_ = trace_writer_->written(); 70 71 if (current_trace_packet_) 72 current_trace_packet_->Finalize(); 73 current_trace_packet_ = trace_writer_->NewTracePacket(); 74 current_trace_packet_->set_timestamp( 75 static_cast<uint64_t>(base::GetBootTimeNs().count())); 76 current_profile_packet_ = nullptr; 77 current_interned_data_ = nullptr; 78 current_process_heap_samples_ = nullptr; 79 } 80 MakeProfilePacket()81 void MakeProfilePacket() { 82 MakeTracePacket(); 83 84 current_profile_packet_ = current_trace_packet_->set_profile_packet(); 85 uint64_t* next_index = intern_state_->HeapprofdNextIndexMutable(); 86 current_profile_packet_->set_index((*next_index)++); 87 } 88 currently_written()89 uint64_t currently_written() { 90 return trace_writer_->written() - last_written_; 91 } 92 93 protos::pbzero::ProfilePacket::ProcessHeapSamples* 94 GetCurrentProcessHeapSamples(); 95 protos::pbzero::InternedData* GetCurrentInternedData(); 96 97 std::set<GlobalCallstackTrie::Node*> callstacks_to_dump_; 98 99 TraceWriter* trace_writer_; 100 InterningOutputTracker* intern_state_; 101 102 protos::pbzero::ProfilePacket* current_profile_packet_ = nullptr; 103 protos::pbzero::InternedData* current_interned_data_ = nullptr; 104 TraceWriter::TracePacketHandle current_trace_packet_; 105 protos::pbzero::ProfilePacket::ProcessHeapSamples* 106 current_process_heap_samples_ = nullptr; 107 std::function<void(protos::pbzero::ProfilePacket::ProcessHeapSamples*)> 108 current_process_fill_header_; 109 110 uint64_t last_written_ = 0; 111 }; 112 113 } // namespace profiling 114 } // namespace perfetto 115 116 #endif // SRC_PROFILING_MEMORY_BOOKKEEPING_DUMP_H_ 117