LLDB  mainline
TraceHTR.cpp
Go to the documentation of this file.
1 //===-- TraceHTR.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TraceHTR.h"
10 
11 #include "lldb/Symbol/Function.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Target.h"
14 #include "llvm/Support/JSON.h"
15 #include <sstream>
16 #include <string>
17 
18 using namespace lldb_private;
19 using namespace lldb;
20 
22  return m_num_instructions;
23 }
24 
25 llvm::Optional<llvm::StringRef>
27  size_t max_ncalls = 0;
28  llvm::Optional<llvm::StringRef> max_name = llvm::None;
29  for (const auto &it : m_func_calls) {
30  ConstString name = it.first;
31  size_t ncalls = it.second;
32  if (ncalls > max_ncalls) {
33  max_ncalls = ncalls;
34  max_name = name.GetStringRef();
35  }
36  }
37  return max_name;
38 }
39 
40 llvm::DenseMap<ConstString, size_t> const &
42  return m_func_calls;
43 }
44 
46  return m_first_instruction_load_address;
47 }
48 
49 size_t HTRBlock::GetOffset() const { return m_offset; }
50 
51 size_t HTRBlock::GetSize() const { return m_size; }
52 
53 HTRBlockMetadata const &HTRBlock::GetMetadata() const { return m_metadata; }
54 
55 llvm::ArrayRef<HTRBlockLayerUP> TraceHTR::GetBlockLayers() const {
56  return m_block_layer_ups;
57 }
58 
60  return *m_instruction_layer_up;
61 }
62 
64  m_block_layer_ups.emplace_back(std::move(block_layer));
65 }
66 
67 size_t IHTRLayer::GetLayerId() const { return m_layer_id; }
68 
69 void HTRBlockLayer::AppendNewBlock(size_t block_id, HTRBlock &&block) {
70  m_block_id_trace.emplace_back(block_id);
71  m_block_defs.emplace(block_id, block);
72 }
73 
74 void HTRBlockLayer::AppendRepeatedBlock(size_t block_id) {
75  m_block_id_trace.emplace_back(block_id);
76 }
77 
78 llvm::ArrayRef<lldb::addr_t> HTRInstructionLayer::GetInstructionTrace() const {
79  return m_instruction_trace;
80 }
81 
83  lldb::addr_t load_addr, llvm::Optional<ConstString> func_name) {
84  m_call_isns.emplace(load_addr, func_name);
85 }
86 
88  m_instruction_trace.emplace_back(load_addr);
89 }
90 
91 HTRBlock const *HTRBlockLayer::GetBlockById(size_t block_id) const {
92  auto block_it = m_block_defs.find(block_id);
93  if (block_it == m_block_defs.end())
94  return nullptr;
95  else
96  return &block_it->second;
97 }
98 
99 llvm::ArrayRef<size_t> HTRBlockLayer::GetBlockIdTrace() const {
100  return m_block_id_trace;
101 }
102 
103 size_t HTRBlockLayer::GetNumUnits() const { return m_block_id_trace.size(); }
104 
106  lldb::addr_t instruction_load_address = m_instruction_trace[index];
107  llvm::DenseMap<ConstString, size_t> func_calls;
108 
109  auto func_name_it = m_call_isns.find(instruction_load_address);
110  if (func_name_it != m_call_isns.end()) {
111  if (llvm::Optional<ConstString> func_name = func_name_it->second) {
112  func_calls[*func_name] = 1;
113  }
114  }
115  return {instruction_load_address, 1, std::move(func_calls)};
116 }
117 
119  return m_instruction_trace.size();
120 }
121 
123  size_t block_id = m_block_id_trace[index];
124  HTRBlock block = m_block_defs.find(block_id)->second;
125  return block.GetMetadata();
126 }
127 
129  : m_instruction_layer_up(std::make_unique<HTRInstructionLayer>(0)) {
130 
131  // Move cursor to the first instruction in the trace
132  cursor.SetForwards(true);
133  cursor.Seek(0, TraceCursor::SeekType::Set);
134 
135  Target &target = thread.GetProcess()->GetTarget();
136  auto function_name_from_load_address =
137  [&](lldb::addr_t load_address) -> llvm::Optional<ConstString> {
138  lldb_private::Address pc_addr;
139  SymbolContext sc;
140  if (target.ResolveLoadAddress(load_address, pc_addr) &&
141  pc_addr.CalculateSymbolContext(&sc))
142  return sc.GetFunctionName()
143  ? llvm::Optional<ConstString>(sc.GetFunctionName())
144  : llvm::None;
145  else
146  return llvm::None;
147  };
148 
149  bool more_data_in_trace = true;
150  while (more_data_in_trace) {
151  if (cursor.IsError()) {
152  // Append a load address of 0 for all instructions that an error occured
153  // while decoding.
154  // TODO: Make distinction between errors by storing the error messages.
155  // Currently, all errors are treated the same.
156  m_instruction_layer_up->AppendInstruction(0);
157  more_data_in_trace = cursor.Next();
158  } else {
159  lldb::addr_t current_instruction_load_address = cursor.GetLoadAddress();
160  lldb::TraceInstructionControlFlowType current_instruction_type =
162 
163  m_instruction_layer_up->AppendInstruction(
164  current_instruction_load_address);
165  more_data_in_trace = cursor.Next();
166  if (current_instruction_type &
167  lldb::eTraceInstructionControlFlowTypeCall) {
168  if (more_data_in_trace && !cursor.IsError()) {
169  m_instruction_layer_up->AddCallInstructionMetadata(
170  current_instruction_load_address,
171  function_name_from_load_address(cursor.GetLoadAddress()));
172  } else {
173  // Next instruction is not known - pass None to indicate the name
174  // of the function being called is not known
175  m_instruction_layer_up->AddCallInstructionMetadata(
176  current_instruction_load_address, llvm::None);
177  }
178  }
179  }
180  }
181 }
182 
184  HTRBlockMetadata &merged_metadata,
185  HTRBlockMetadata const &metadata_to_merge) {
186  merged_metadata.m_num_instructions += metadata_to_merge.m_num_instructions;
187  for (const auto &it : metadata_to_merge.m_func_calls) {
188  ConstString name = it.first;
189  size_t num_calls = it.second;
190  merged_metadata.m_func_calls[name] += num_calls;
191  }
192 }
193 
194 HTRBlock IHTRLayer::MergeUnits(size_t start_unit_index, size_t num_units) {
195  // TODO: make this function take `end_unit_index` as a parameter instead of
196  // unit and merge the range [start_unit_indx, end_unit_index] inclusive.
197  HTRBlockMetadata merged_metadata = GetMetadataByIndex(start_unit_index);
198  for (size_t i = start_unit_index + 1; i < start_unit_index + num_units; i++) {
199  // merge the new metadata into merged_metadata
201  }
202  return {start_unit_index, num_units, merged_metadata};
203 }
204 
206  auto are_passes_done = [](IHTRLayer &l1, IHTRLayer &l2) {
207  return l1.GetNumUnits() == l2.GetNumUnits();
208  };
209  HTRBlockLayerUP current_block_layer_up =
211  HTRBlockLayer &current_block_layer = *current_block_layer_up;
212  if (are_passes_done(*m_instruction_layer_up, *current_block_layer_up))
213  return;
214 
215  AddNewBlockLayer(std::move(current_block_layer_up));
216  while (true) {
217  HTRBlockLayerUP new_block_layer_up =
218  BasicSuperBlockMerge(current_block_layer);
219  if (are_passes_done(current_block_layer, *new_block_layer_up))
220  return;
221 
222  current_block_layer = *new_block_layer_up;
223  AddNewBlockLayer(std::move(new_block_layer_up));
224  }
225 }
226 
228  std::error_code ec;
229  llvm::raw_fd_ostream os(outfile, ec, llvm::sys::fs::OF_Text);
230  if (ec) {
231  return llvm::make_error<llvm::StringError>(
232  "unable to open destination file: " + outfile, os.error());
233  } else {
234  os << toJSON(*this);
235  os.close();
236  if (os.has_error()) {
237  return llvm::make_error<llvm::StringError>(
238  "unable to write to destination file: " + outfile, os.error());
239  }
240  }
241  return llvm::Error::success();
242 }
243 
245  std::unique_ptr<HTRBlockLayer> new_block_layer =
246  std::make_unique<HTRBlockLayer>(layer.GetLayerId() + 1);
247 
248  if (layer.GetNumUnits()) {
249  // Future Improvement: split this into two functions - one for finding heads
250  // and tails, one for merging/creating the next layer A 'head' is defined to
251  // be a block whose occurrences in the trace do not have a unique preceding
252  // block.
253  std::unordered_set<size_t> heads;
254 
255  // The load address of the first instruction of a block is the unique ID for
256  // that block (i.e. blocks with the same first instruction load address are
257  // the same block)
258 
259  // Future Improvement: no need to store all its preceding block ids, all we
260  // care about is that there is more than one preceding block id, so an enum
261  // could be used
262  std::unordered_map<lldb::addr_t, std::unordered_set<lldb::addr_t>> head_map;
263  lldb::addr_t prev_id =
265  size_t num_units = layer.GetNumUnits();
266  // This excludes the first unit since it has no previous unit
267  for (size_t i = 1; i < num_units; i++) {
268  lldb::addr_t current_id =
270  head_map[current_id].insert(prev_id);
271  prev_id = current_id;
272  }
273  for (const auto &it : head_map) {
274  // ID of 0 represents an error - errors can't be heads or tails
275  lldb::addr_t id = it.first;
276  const std::unordered_set<lldb::addr_t> predecessor_set = it.second;
277  if (id && predecessor_set.size() > 1)
278  heads.insert(id);
279  }
280 
281  // Future Improvement: identify heads and tails in the same loop
282  // A 'tail' is defined to be a block whose occurrences in the trace do
283  // not have a unique succeeding block.
284  std::unordered_set<lldb::addr_t> tails;
285  std::unordered_map<lldb::addr_t, std::unordered_set<lldb::addr_t>> tail_map;
286 
287  // This excludes the last unit since it has no next unit
288  for (size_t i = 0; i < num_units - 1; i++) {
289  lldb::addr_t current_id =
291  lldb::addr_t next_id =
293  tail_map[current_id].insert(next_id);
294  }
295 
296  // Mark last block as tail so the algorithm stops gracefully
297  lldb::addr_t last_id = layer.GetMetadataByIndex(num_units - 1)
299  tails.insert(last_id);
300  for (const auto &it : tail_map) {
301  lldb::addr_t id = it.first;
302  const std::unordered_set<lldb::addr_t> successor_set = it.second;
303  // ID of 0 represents an error - errors can't be heads or tails
304  if (id && successor_set.size() > 1)
305  tails.insert(id);
306  }
307 
308  // Need to keep track of size of string since things we push are variable
309  // length
310  size_t superblock_size = 0;
311  // Each super block always has the same first unit (we call this the
312  // super block head) This gurantee allows us to use the super block head as
313  // the unique key mapping to the super block it begins
314  llvm::Optional<size_t> superblock_head = llvm::None;
315  auto construct_next_layer = [&](size_t merge_start, size_t n) -> void {
316  if (!superblock_head)
317  return;
318  if (new_block_layer->GetBlockById(*superblock_head)) {
319  new_block_layer->AppendRepeatedBlock(*superblock_head);
320  } else {
321  HTRBlock new_block = layer.MergeUnits(merge_start, n);
322  new_block_layer->AppendNewBlock(*superblock_head, std::move(new_block));
323  }
324  };
325 
326  for (size_t i = 0; i < num_units; i++) {
327  lldb::addr_t unit_id =
329  auto isHead = heads.count(unit_id) > 0;
330  auto isTail = tails.count(unit_id) > 0;
331 
332  if (isHead && isTail) {
333  // Head logic
334  if (superblock_size) { // this handles (tail, head) adjacency -
335  // otherwise an empty
336  // block is created
337  // End previous super block
338  construct_next_layer(i - superblock_size, superblock_size);
339  }
340  // Current id is first in next super block since it's a head
341  superblock_head = unit_id;
342  superblock_size = 1;
343 
344  // Tail logic
345  construct_next_layer(i - superblock_size + 1, superblock_size);
346  // Reset the block_head since the prev super block has come to and end
347  superblock_head = llvm::None;
348  superblock_size = 0;
349  } else if (isHead) {
350  if (superblock_size) { // this handles (tail, head) adjacency -
351  // otherwise an empty
352  // block is created
353  // End previous super block
354  construct_next_layer(i - superblock_size, superblock_size);
355  }
356  // Current id is first in next super block since it's a head
357  superblock_head = unit_id;
358  superblock_size = 1;
359  } else if (isTail) {
360  if (!superblock_head)
361  superblock_head = unit_id;
362  superblock_size++;
363 
364  // End previous super block
365  construct_next_layer(i - superblock_size + 1, superblock_size);
366  // Reset the block_head since the prev super block has come to and end
367  superblock_head = llvm::None;
368  superblock_size = 0;
369  } else {
370  if (!superblock_head)
371  superblock_head = unit_id;
372  superblock_size++;
373  }
374  }
375  }
376  return new_block_layer;
377 }
378 
379 llvm::json::Value lldb_private::toJSON(const TraceHTR &htr) {
380  std::vector<llvm::json::Value> layers_as_json;
381  for (size_t i = 0; i < htr.GetInstructionLayer().GetInstructionTrace().size();
382  i++) {
383  size_t layer_id = htr.GetInstructionLayer().GetLayerId();
385  lldb::addr_t load_address = metadata.GetFirstInstructionLoadAddress();
386 
387  std::string display_name;
388 
389  std::stringstream stream;
390  stream << "0x" << std::hex << load_address;
391  std::string load_address_hex_string(stream.str());
392  display_name.assign(load_address_hex_string);
393 
394  // name: load address of the first instruction of the block and the name
395  // of the most frequently called function from the block (if applicable)
396 
397  // ph: the event type - 'X' for Complete events (see link to documentation
398  // below)
399 
400  // Since trace timestamps aren't yet supported in HTR, the ts (timestamp) is
401  // based on the instruction's offset in the trace and the dur (duration) is
402  // 1 since this layer contains single instructions. Using the instruction
403  // offset and a duration of 1 oversimplifies the true timing information of
404  // the trace, nonetheless, these approximate timestamps/durations provide an
405  // clear visualization of the trace.
406 
407  // ts: offset from the beginning of the trace for the first instruction in
408  // the block
409 
410  // dur: 1 since this layer contains single instructions.
411 
412  // pid: the ID of the HTR layer the blocks belong to
413 
414  // See
415  // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.j75x71ritcoy
416  // for documentation on the Trace Event Format
417  layers_as_json.emplace_back(llvm::json::Object{
418  {"name", display_name},
419  {"ph", "X"},
420  {"ts", (int64_t)i},
421  {"dur", 1},
422  {"pid", (int64_t)layer_id},
423  });
424  }
425 
426  for (const auto &layer : htr.GetBlockLayers()) {
427  size_t start_ts = 0;
428  std::vector<size_t> block_id_trace = layer->GetBlockIdTrace();
429  for (size_t i = 0; i < block_id_trace.size(); i++) {
430  size_t id = block_id_trace[i];
431  // Guranteed that this ID is valid, so safe to dereference here.
432  HTRBlock block = *layer->GetBlockById(id);
433  llvm::json::Value block_json = toJSON(block);
434  size_t layer_id = layer->GetLayerId();
435 
436  HTRBlockMetadata metadata = block.GetMetadata();
437 
438  llvm::Optional<llvm::StringRef> most_freq_func =
440  std::stringstream stream;
441  stream << "0x" << std::hex << metadata.GetFirstInstructionLoadAddress();
442  std::string offset_hex_string(stream.str());
443  std::string display_name =
444  most_freq_func ? offset_hex_string + ": " + most_freq_func->str()
445  : offset_hex_string;
446 
447  // Since trace timestamps aren't yet supported in HTR, the ts (timestamp)
448  // and dur (duration) are based on the block's offset in the trace and
449  // number of instructions in the block, respectively. Using the block
450  // offset and the number of instructions oversimplifies the true timing
451  // information of the trace, nonetheless, these approximate
452  // timestamps/durations provide an understandable visualization of the
453  // trace.
454  auto duration = metadata.GetNumInstructions();
455  layers_as_json.emplace_back(llvm::json::Object{
456  {"name", display_name},
457  {"ph", "X"},
458  {"ts", (int64_t)start_ts},
459  {"dur", (int64_t)duration},
460  {"pid", (int64_t)layer_id},
461  {"args", block_json},
462  });
463  start_ts += duration;
464  }
465  }
466  return layers_as_json;
467 }
468 
469 llvm::json::Value lldb_private::toJSON(const HTRBlock &block) {
470  return llvm::json::Value(
471  llvm::json::Object{{"Metadata", block.GetMetadata()}});
472 }
473 
474 llvm::json::Value lldb_private::toJSON(const HTRBlockMetadata &metadata) {
475  std::vector<llvm::json::Value> function_calls;
476  for (const auto &it : metadata.GetFunctionCalls()) {
477  ConstString name = it.first;
478  size_t n_calls = it.second;
479  function_calls.emplace_back(llvm::formatv("({0}: {1})", name, n_calls));
480  }
481 
482  return llvm::json::Value(llvm::json::Object{
483  {"Number of Instructions", (ssize_t)metadata.GetNumInstructions()},
484  {"Functions", function_calls}});
485 }
lldb_private::toJSON
llvm::json::Value toJSON(const TraceSupportedResponse &packet)
Definition: TraceGDBRemotePackets.cpp:24
lldb_private::IHTRLayer::GetMetadataByIndex
virtual HTRBlockMetadata GetMetadataByIndex(size_t index) const =0
Get the metadata of a unit (instruction or block) in the layer.
lldb_private::HTRBlockLayer::GetMetadataByIndex
HTRBlockMetadata GetMetadataByIndex(size_t index) const override
Get the metadata of a unit (instruction or block) in the layer.
Definition: TraceHTR.cpp:122
TraceHTR.h
lldb_private::HTRBlock
Block structure representing a sequence of trace "units" (ie instructions).
Definition: TraceHTR.h:91
lldb_private::IHTRLayer::GetNumUnits
virtual size_t GetNumUnits() const =0
Get the total number of units (instruction or block) in this layer.
lldb_private::HTRInstructionLayer::GetMetadataByIndex
HTRBlockMetadata GetMetadataByIndex(size_t index) const override
Get the metadata of a unit (instruction or block) in the layer.
Definition: TraceHTR.cpp:105
lldb_private::IHTRLayer
HTR layer interface See lldb/docs/htr.rst for comprehensive HTR documentation.
Definition: TraceHTR.h:138
lldb_private::TraceCursor
Class used for iterating over the instructions of a thread's trace.
Definition: TraceCursor.h:73
lldb_private::TraceCursor::Next
virtual bool Next()=0
Move the cursor to the next instruction that matches the current granularity.
lldb_private::HTRBlockMetadata::m_func_calls
llvm::DenseMap< ConstString, size_t > m_func_calls
Definition: TraceHTR.h:85
lldb_private::HTRBlock::GetSize
size_t GetSize() const
Get the number of blocks/instructions that make up this block in the previous layer.
Definition: TraceHTR.cpp:51
lldb_private::TraceCursor::GetInstructionControlFlowType
virtual lldb::TraceInstructionControlFlowType GetInstructionControlFlowType()=0
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::HTRInstructionLayer::AppendInstruction
void AppendInstruction(lldb::addr_t load_addr)
Append the load address of an instruction to the dynamic instruction trace.
Definition: TraceHTR.cpp:87
lldb_private::Target::ResolveLoadAddress
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow)
Definition: Target.cpp:2818
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::Target
Definition: Target.h:450
lldb_private::IHTRLayer::GetLayerId
size_t GetLayerId() const
Get the ID of the layer.
Definition: TraceHTR.cpp:67
Process.h
lldb_private::HTRInstructionLayer::GetNumUnits
size_t GetNumUnits() const override
Get the total number of units (instruction or block) in this layer.
Definition: TraceHTR.cpp:118
lldb_private::HTRBlockMetadata::GetMostFrequentlyCalledFunction
llvm::Optional< llvm::StringRef > GetMostFrequentlyCalledFunction() const
Get the name of the most frequently called function from the block.
Definition: TraceHTR.cpp:26
Target.h
lldb_private::Thread::GetProcess
lldb::ProcessSP GetProcess() const
Definition: Thread.h:152
lldb_private::HTRInstructionLayer
"Base" layer of HTR representing the dynamic instructions of the trace.
Definition: TraceHTR.h:193
lldb_private::HTRBlockLayer::AppendRepeatedBlock
void AppendRepeatedBlock(size_t block_id)
Appends a repeated block to the layer.
Definition: TraceHTR.cpp:74
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
lldb_private::HTRBlock::GetMetadata
const HTRBlockMetadata & GetMetadata() const
Get the metadata for this block.
Definition: TraceHTR.cpp:53
lldb_private::Thread
Definition: Thread.h:60
lldb_private::TraceHTR::GetInstructionLayer
const HTRInstructionLayer & GetInstructionLayer() const
Get the instruction layer of this HTR.
Definition: TraceHTR.cpp:59
lldb_private::TraceHTR::GetBlockLayers
llvm::ArrayRef< HTRBlockLayerUP > GetBlockLayers() const
Get the block layers of this HTR.
Definition: TraceHTR.cpp:55
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::SymbolContext::GetFunctionName
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
Definition: SymbolContext.cpp:653
lldb_private::HTRBlock::GetOffset
size_t GetOffset() const
Get the offset of the start of this block in the previous layer.
Definition: TraceHTR.cpp:49
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::HTRBlockMetadata::GetFunctionCalls
const llvm::DenseMap< ConstString, size_t > & GetFunctionCalls() const
Get the function calls map for the block.
Definition: TraceHTR.cpp:41
lldb_private::TraceCursor::GetLoadAddress
virtual lldb::addr_t GetLoadAddress()=0
lldb_private::TraceCursor::Seek
virtual size_t Seek(ssize_t offset, SeekType origin)=0
Make the cursor point to an item in the trace based on an origin point and an offset.
lldb_private::HTRBlockMetadata::MergeMetadata
static void MergeMetadata(HTRBlockMetadata &merged_metadata, HTRBlockMetadata const &metadata_to_merge)
Merge two HTRBlockMetadata in place.
Definition: TraceHTR.cpp:183
lldb_private::HTRBlockMetadata::GetNumInstructions
size_t GetNumInstructions() const
Get the number of instructions in the block.
Definition: TraceHTR.cpp:21
lldb_private::TraceHTR::ExecutePasses
void ExecutePasses()
Executes passes on the HTR layers until no further summarization/compression is achieved.
Definition: TraceHTR.cpp:205
lldb_private::TraceHTR::Export
llvm::Error Export(std::string outfile)
Export HTR layers to the specified format and outfile.
Definition: TraceHTR.cpp:227
lldb_private::HTRBlockLayerUP
std::unique_ptr< lldb_private::HTRBlockLayer > HTRBlockLayerUP
Definition: TraceHTR.h:299
lldb_private::TraceHTR::m_instruction_layer_up
HTRInstructionLayerUP m_instruction_layer_up
Definition: TraceHTR.h:350
lldb_private::HTRBlockMetadata::GetFirstInstructionLoadAddress
lldb::addr_t GetFirstInstructionLoadAddress() const
Get the load address of the first instruction in the block.
Definition: TraceHTR.cpp:45
lldb_private::Address
Definition: Address.h:59
lldb_private::HTRBlockLayer::GetBlockIdTrace
llvm::ArrayRef< size_t > GetBlockIdTrace() const
Get the block ID trace for this layer.
Definition: TraceHTR.cpp:99
lldb_private::HTRInstructionLayer::AddCallInstructionMetadata
void AddCallInstructionMetadata(lldb::addr_t load_addr, llvm::Optional< ConstString > func_name)
Add metadata for a 'call' instruction of the trace.
Definition: TraceHTR.cpp:82
lldb_private::HTRInstructionLayer::GetInstructionTrace
llvm::ArrayRef< lldb::addr_t > GetInstructionTrace() const
Get the dynamic instruction trace.
Definition: TraceHTR.cpp:78
lldb_private::HTRBlockLayer::AppendNewBlock
void AppendNewBlock(size_t block_id, HTRBlock &&block)
Appends a new block to the layer.
Definition: TraceHTR.cpp:69
Function.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:29
lldb_private::BasicSuperBlockMerge
HTRBlockLayerUP BasicSuperBlockMerge(IHTRLayer &layer)
The HTR passes are defined below:
Definition: TraceHTR.cpp:244
lldb_private::TraceCursor::SeekType::Set
@ Set
The beginning of the trace, i.e the oldest item.
lldb_private::TraceHTR::AddNewBlockLayer
void AddNewBlockLayer(HTRBlockLayerUP &&block_layer)
Add a new block layer to this HTR.
Definition: TraceHTR.cpp:63
lldb_private::HTRBlockLayer
HTR layer composed of blocks of the trace.
Definition: TraceHTR.h:244
lldb_private::HTRBlockMetadata::m_num_instructions
size_t m_num_instructions
Definition: TraceHTR.h:84
lldb_private::TraceHTR
Top-level HTR class See lldb/docs/htr.rst for comprehensive HTR documentation.
Definition: TraceHTR.h:305
lldb_private::TraceCursor::IsError
virtual bool IsError()=0
Instruction or error information.
lldb_private::TraceCursor::SetForwards
void SetForwards(bool forwards)
Set the direction to use in the TraceCursor::Next() method.
Definition: TraceCursor.cpp:33
lldb
Definition: SBAddress.h:15
lldb_private::TraceHTR::TraceHTR
TraceHTR(Thread &thread, TraceCursor &cursor)
Constructor for a trace's HTR.
Definition: TraceHTR.cpp:128
lldb_private::HTRBlockMetadata
Metadata associated with an HTR block See lldb/docs/htr.rst for comprehensive HTR documentation.
Definition: TraceHTR.h:23
lldb_private::HTRBlockLayer::GetBlockById
const HTRBlock * GetBlockById(size_t block_id) const
Get an HTRBlock from its block id.
Definition: TraceHTR.cpp:91
lldb_private::Address::CalculateSymbolContext
uint32_t CalculateSymbolContext(SymbolContext *sc, lldb::SymbolContextItem resolve_scope=lldb::eSymbolContextEverything) const
Reconstruct a symbol context from an address.
Definition: Address.cpp:808
lldb_private::HTRBlockLayer::GetNumUnits
size_t GetNumUnits() const override
Get the total number of units (instruction or block) in this layer.
Definition: TraceHTR.cpp:103
lldb_private::IHTRLayer::MergeUnits
HTRBlock MergeUnits(size_t start_unit_index, size_t num_units)
Creates a new block from the result of merging a contiguous sequence of "units" (instructions or bloc...
Definition: TraceHTR.cpp:194