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 WriteAllocation(const HeapTracker::CallstackAllocations& alloc, 60 bool dump_at_max_mode); 61 void DumpCallstacks(GlobalCallstackTrie* callsites); 62 63 private: 64 void WriteMap(const Interned<Mapping> map); 65 void WriteFrame(const Interned<Frame> frame); 66 void WriteBuildIDString(const Interned<std::string>& str); 67 void WriteMappingPathString(const Interned<std::string>& str); 68 void WriteFunctionNameString(const Interned<std::string>& str); 69 MakeTracePacket()70 void MakeTracePacket() { 71 last_written_ = trace_writer_->written(); 72 73 if (current_trace_packet_) 74 current_trace_packet_->Finalize(); 75 current_trace_packet_ = trace_writer_->NewTracePacket(); 76 current_trace_packet_->set_timestamp( 77 static_cast<uint64_t>(base::GetBootTimeNs().count())); 78 current_profile_packet_ = nullptr; 79 current_interned_data_ = nullptr; 80 current_process_heap_samples_ = nullptr; 81 } 82 MakeProfilePacket()83 void MakeProfilePacket() { 84 MakeTracePacket(); 85 86 current_profile_packet_ = current_trace_packet_->set_profile_packet(); 87 uint64_t* next_index = intern_state_->HeapprofdNextIndexMutable(); 88 current_profile_packet_->set_index((*next_index)++); 89 } 90 currently_written()91 uint64_t currently_written() { 92 return trace_writer_->written() - last_written_; 93 } 94 95 protos::pbzero::ProfilePacket::ProcessHeapSamples* 96 GetCurrentProcessHeapSamples(); 97 protos::pbzero::InternedData* GetCurrentInternedData(); 98 99 std::set<GlobalCallstackTrie::Node*> callstacks_to_dump_; 100 101 TraceWriter* trace_writer_; 102 InterningOutputTracker* intern_state_; 103 104 protos::pbzero::ProfilePacket* current_profile_packet_ = nullptr; 105 protos::pbzero::InternedData* current_interned_data_ = nullptr; 106 TraceWriter::TracePacketHandle current_trace_packet_; 107 protos::pbzero::ProfilePacket::ProcessHeapSamples* 108 current_process_heap_samples_ = nullptr; 109 std::function<void(protos::pbzero::ProfilePacket::ProcessHeapSamples*)> 110 current_process_fill_header_; 111 112 uint64_t last_written_ = 0; 113 }; 114 115 } // namespace profiling 116 } // namespace perfetto 117 118 #endif // SRC_PROFILING_MEMORY_BOOKKEEPING_DUMP_H_ 119