• 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 <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