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