• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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