zrthxn updated this revision to Diff 417709.
zrthxn added a comment.

Introduced unordered map for errors in DecodedThread


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D122293/new/

https://reviews.llvm.org/D122293

Files:
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp

Index: lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
+++ lldb/source/Plugins/Trace/intel-pt/IntelPTDecoder.cpp
@@ -104,9 +104,11 @@
 ///
 /// \return
 ///   The decoded instructions.
-static std::vector<IntelPTInstruction>
-DecodeInstructions(pt_insn_decoder &decoder) {
-  std::vector<IntelPTInstruction> instructions;
+static DecodedThread DecodeInstructions(pt_insn_decoder &decoder,
+                                        const ThreadSP &thread_sp,
+                                        const size_t raw_trace_size) {
+  DecodedThread thread = DecodedThread(
+      thread_sp, std::vector<IntelPTInstruction>(), raw_trace_size);
 
   while (true) {
     int errcode = FindNextSynchronizationPoint(decoder);
@@ -114,26 +116,27 @@
       break;
 
     if (errcode < 0) {
-      instructions.emplace_back(make_error<IntelPTError>(errcode));
+      thread.AppendError(0, make_error<IntelPTError>(errcode));
       break;
     }
 
     // We have synchronized, so we can start decoding
     // instructions and events.
+    int insn_index = 0;
     while (true) {
       errcode = ProcessPTEvents(decoder, errcode);
       if (errcode < 0) {
-        instructions.emplace_back(make_error<IntelPTError>(errcode));
+        thread.AppendError(insn_index, make_error<IntelPTError>(errcode));
         break;
       }
-      pt_insn insn;
 
+      pt_insn insn;
       errcode = pt_insn_next(&decoder, &insn, sizeof(insn));
       if (errcode == -pte_eos)
         break;
 
       if (errcode < 0) {
-        instructions.emplace_back(make_error<IntelPTError>(errcode, insn.ip));
+        thread.AppendError(insn_index, make_error<IntelPTError>(errcode, insn.ip));
         break;
       }
 
@@ -142,22 +145,24 @@
       if (time_error == -pte_invalid) {
         // This happens if we invoke the pt_insn_time method incorrectly,
         // but the instruction is good though.
-        instructions.emplace_back(
-            make_error<IntelPTError>(time_error, insn.ip));
-        instructions.emplace_back(insn);
+        thread.AppendError(insn_index, make_error<IntelPTError>(time_error, insn.ip));
+        thread.AppendInstruction(IntelPTInstruction(insn));
         break;
       }
+
       if (time_error == -pte_no_time) {
         // We simply don't have time information, i.e. None of TSC, MTC or CYC
         // was enabled.
-        instructions.emplace_back(insn);
+        thread.AppendInstruction(IntelPTInstruction(insn));
       } else {
-        instructions.emplace_back(insn, time);
+        thread.AppendInstruction(IntelPTInstruction(insn, time));
       }
+
+      insn_index++;
     }
   }
 
-  return instructions;
+  return thread;
 }
 
 /// Callback used by libipt for reading the process memory.
@@ -176,9 +181,9 @@
   return bytes_read;
 }
 
-static Expected<std::vector<IntelPTInstruction>>
-DecodeInMemoryTrace(Process &process, TraceIntelPT &trace_intel_pt,
-                    MutableArrayRef<uint8_t> buffer) {
+static Expected<DecodedThreadSP> DecodeInMemoryTrace(
+    const ThreadSP &thread_sp, Process &process, TraceIntelPT &trace_intel_pt,
+    MutableArrayRef<uint8_t> buffer, const size_t raw_trace_size) {
   Expected<pt_cpu> cpu_info = trace_intel_pt.GetCPUInfo();
   if (!cpu_info)
     return cpu_info.takeError();
@@ -203,77 +208,76 @@
   assert(errcode == 0);
   (void)errcode;
 
-  std::vector<IntelPTInstruction> instructions = DecodeInstructions(*decoder);
+  DecodedThread decoded_thread =
+      DecodeInstructions(*decoder, thread_sp, raw_trace_size);
 
   pt_insn_free_decoder(decoder);
-  return instructions;
+  return decoded_thread.shared_from_this();
 }
+// ---------------------------
 
-static Expected<std::vector<IntelPTInstruction>>
-DecodeTraceFile(Process &process, TraceIntelPT &trace_intel_pt,
-                const FileSpec &trace_file, size_t &raw_trace_size) {
-  ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error =
-      MemoryBuffer::getFile(trace_file.GetPath());
-  if (std::error_code err = trace_or_error.getError())
-    return errorCodeToError(err);
-
-  MemoryBuffer &trace = **trace_or_error;
-  MutableArrayRef<uint8_t> trace_data(
-      // The libipt library does not modify the trace buffer, hence the
-      // following cast is safe.
-      reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart())),
-      trace.getBufferSize());
-  raw_trace_size = trace_data.size();
-  return DecodeInMemoryTrace(process, trace_intel_pt, trace_data);
+DecodedThreadSP ThreadDecoder::Decode() {
+  if (!m_decoded_thread.hasValue())
+    m_decoded_thread = DoDecode();
+  return *m_decoded_thread;
 }
 
-static Expected<std::vector<IntelPTInstruction>>
-DecodeLiveThread(Thread &thread, TraceIntelPT &trace, size_t &raw_trace_size) {
+// LiveThreadDecoder ====================
+
+LiveThreadDecoder::LiveThreadDecoder(Thread &thread, TraceIntelPT &trace)
+    : m_thread_sp(thread.shared_from_this()), m_trace(trace) {}
+
+static Expected<DecodedThreadSP> DecodeLiveThread(const ThreadSP &thread_sp,
+                                                  TraceIntelPT &trace,
+                                                  size_t &raw_trace_size) {
   Expected<std::vector<uint8_t>> buffer =
-      trace.GetLiveThreadBuffer(thread.GetID());
+      trace.GetLiveThreadBuffer(thread_sp->GetID());
   if (!buffer)
     return buffer.takeError();
   raw_trace_size = buffer->size();
   if (Expected<pt_cpu> cpu_info = trace.GetCPUInfo())
-    return DecodeInMemoryTrace(*thread.GetProcess(), trace,
-                               MutableArrayRef<uint8_t>(*buffer));
+    return DecodeInMemoryTrace(thread_sp, *thread_sp->GetProcess(), trace,
+                               MutableArrayRef<uint8_t>(*buffer),
+                               raw_trace_size);
   else
     return cpu_info.takeError();
 }
 
-DecodedThreadSP ThreadDecoder::Decode() {
-  if (!m_decoded_thread.hasValue())
-    m_decoded_thread = DoDecode();
-  return *m_decoded_thread;
+DecodedThreadSP LiveThreadDecoder::DoDecode() {
+  size_t raw_trace_size = 0;
+  return *(DecodeLiveThread(m_thread_sp, m_trace, raw_trace_size));
 }
 
+// PostMortemThreadDecoder =======================
+
 PostMortemThreadDecoder::PostMortemThreadDecoder(
     const lldb::ThreadPostMortemTraceSP &trace_thread, TraceIntelPT &trace)
     : m_trace_thread(trace_thread), m_trace(trace) {}
 
-DecodedThreadSP PostMortemThreadDecoder::DoDecode() {
-  size_t raw_trace_size = 0;
-  if (Expected<std::vector<IntelPTInstruction>> instructions =
-          DecodeTraceFile(*m_trace_thread->GetProcess(), m_trace,
-                          m_trace_thread->GetTraceFile(), raw_trace_size))
-    return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(),
-                                           std::move(*instructions),
-                                           raw_trace_size);
-  else
-    return std::make_shared<DecodedThread>(m_trace_thread->shared_from_this(),
-                                           instructions.takeError());
-}
+static Expected<DecodedThreadSP> DecodeTraceFile(const ThreadSP &thread_sp,
+                                                 Process &process,
+                                                 TraceIntelPT &trace_intel_pt,
+                                                 const FileSpec &trace_file,
+                                                 size_t &raw_trace_size) {
+  ErrorOr<std::unique_ptr<MemoryBuffer>> trace_or_error =
+      MemoryBuffer::getFile(trace_file.GetPath());
+  if (std::error_code err = trace_or_error.getError())
+    return errorCodeToError(err);
 
-LiveThreadDecoder::LiveThreadDecoder(Thread &thread, TraceIntelPT &trace)
-    : m_thread_sp(thread.shared_from_this()), m_trace(trace) {}
+  MemoryBuffer &trace = **trace_or_error;
+  MutableArrayRef<uint8_t> trace_data(
+      // The libipt library does not modify the trace buffer, hence the
+      // following cast is safe.
+      reinterpret_cast<uint8_t *>(const_cast<char *>(trace.getBufferStart())),
+      trace.getBufferSize());
+  raw_trace_size = trace_data.size();
+  return DecodeInMemoryTrace(thread_sp, process, trace_intel_pt, trace_data,
+                             raw_trace_size);
+}
 
-DecodedThreadSP LiveThreadDecoder::DoDecode() {
+DecodedThreadSP PostMortemThreadDecoder::DoDecode() {
   size_t raw_trace_size = 0;
-  if (Expected<std::vector<IntelPTInstruction>> instructions =
-          DecodeLiveThread(*m_thread_sp, m_trace, raw_trace_size))
-    return std::make_shared<DecodedThread>(
-        m_thread_sp, std::move(*instructions), raw_trace_size);
-  else
-    return std::make_shared<DecodedThread>(m_thread_sp,
-                                           instructions.takeError());
+  return *(DecodeTraceFile(m_trace_thread, *m_trace_thread->GetProcess(),
+                           m_trace, m_trace_thread->GetTraceFile(),
+                           raw_trace_size));
 }
Index: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
+++ lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
@@ -139,13 +139,24 @@
   /// decoding process.
   DecodedThread(lldb::ThreadSP thread_sp, llvm::Error error);
 
-  /// Get the instructions from the decoded trace. Some of them might indicate
-  /// errors (i.e. gaps) in the trace.
+  /// Get the instructions from the decoded trace.
   ///
   /// \return
   ///   The instructions of the trace.
   llvm::ArrayRef<IntelPTInstruction> GetInstructions() const;
 
+  /// Get the errors from the decoded trace.
+  ///
+  /// \return
+  ///   The errors of the trace.
+  std::unordered_map<uint64_t, llvm::Error> GetErrors() const;
+
+  /// Append a successfully decoded instruction to thread.
+  void AppendInstruction(IntelPTInstruction ins);
+
+  /// Append a error of instruction decoding to thread.
+  void AppendError(uint64_t insn_index, llvm::Error err);
+
   /// Get a new cursor for the decoded thread.
   lldb::TraceCursorUP GetCursor();
 
@@ -163,8 +174,9 @@
   /// When adding new members to this class, make sure 
   /// to update \a CalculateApproximateMemoryUsage() accordingly.
   lldb::ThreadSP m_thread_sp;
-  std::vector<IntelPTInstruction> m_instructions;
   size_t m_raw_trace_size;
+  std::vector<IntelPTInstruction> m_instructions;
+  std::unordered_map<uint64_t, llvm::Error> m_errors;
 };
 
 using DecodedThreadSP = std::shared_ptr<DecodedThread>;
Index: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
+++ lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
@@ -100,6 +100,10 @@
   return makeArrayRef(m_instructions);
 }
 
+std::unordered_map<uint64_t, llvm::Error> DecodedThread::GetErrors() const {
+  return m_errors;
+}
+
 DecodedThread::DecodedThread(ThreadSP thread_sp, Error error)
     : m_thread_sp(thread_sp) {
   m_instructions.emplace_back(std::move(error));
@@ -119,6 +123,14 @@
   return std::make_unique<TraceCursorIntelPT>(m_thread_sp, shared_from_this());
 }
 
+void DecodedThread::AppendInstruction(IntelPTInstruction ins) {
+  m_instructions.emplace_back(ins);
+}
+
+void DecodedThread::AppendError(uint64_t insn_index, llvm::Error err) {
+  m_errors[insn_index] = std::move(err);
+}
+
 size_t DecodedThread::CalculateApproximateMemoryUsage() const {
   return m_raw_trace_size
     + IntelPTInstruction::GetNonErrorMemoryUsage() * m_instructions.size()
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to