xref: /llvm-project/lldb/source/Plugins/Trace/intel-pt/ThreadDecoder.cpp (revision 2fe8327406050d2585d2ced910a678e28caefcf5)
16423b502SWalter Erquinigo //===-- ThreadDecoder.cpp --======-----------------------------------------===//
26423b502SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
36423b502SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information.
46423b502SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
56423b502SWalter Erquinigo //
66423b502SWalter Erquinigo //===----------------------------------------------------------------------===//
76423b502SWalter Erquinigo 
86423b502SWalter Erquinigo #include "ThreadDecoder.h"
96423b502SWalter Erquinigo #include "../common/ThreadPostMortemTrace.h"
106423b502SWalter Erquinigo #include "LibiptDecoder.h"
116423b502SWalter Erquinigo #include "TraceIntelPT.h"
12c4fb631cSWalter Erquinigo #include "llvm/Support/MemoryBuffer.h"
13f190ce62SKazu Hirata #include <optional>
146423b502SWalter Erquinigo #include <utility>
156423b502SWalter Erquinigo 
166423b502SWalter Erquinigo using namespace lldb;
176423b502SWalter Erquinigo using namespace lldb_private;
186423b502SWalter Erquinigo using namespace lldb_private::trace_intel_pt;
196423b502SWalter Erquinigo using namespace llvm;
206423b502SWalter Erquinigo 
ThreadDecoder(const ThreadSP & thread_sp,TraceIntelPT & trace)21e0cfe20aSWalter Erquinigo ThreadDecoder::ThreadDecoder(const ThreadSP &thread_sp, TraceIntelPT &trace)
22e0cfe20aSWalter Erquinigo     : m_thread_sp(thread_sp), m_trace(trace) {}
236423b502SWalter Erquinigo 
FindLowestTSC()24*2fe83274SKazu Hirata Expected<std::optional<uint64_t>> ThreadDecoder::FindLowestTSC() {
25*2fe83274SKazu Hirata   std::optional<uint64_t> lowest_tsc;
264f676c25SWalter Erquinigo   Error err = m_trace.OnThreadBufferRead(
274f676c25SWalter Erquinigo       m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) -> llvm::Error {
28*2fe83274SKazu Hirata         Expected<std::optional<uint64_t>> tsc =
29*2fe83274SKazu Hirata             FindLowestTSCInTrace(m_trace, data);
304f676c25SWalter Erquinigo         if (!tsc)
314f676c25SWalter Erquinigo           return tsc.takeError();
324f676c25SWalter Erquinigo         lowest_tsc = *tsc;
334f676c25SWalter Erquinigo         return Error::success();
344f676c25SWalter Erquinigo       });
354f676c25SWalter Erquinigo   if (err)
364f676c25SWalter Erquinigo     return std::move(err);
374f676c25SWalter Erquinigo   return lowest_tsc;
384f676c25SWalter Erquinigo }
394f676c25SWalter Erquinigo 
Decode()40a7d6c3efSWalter Erquinigo Expected<DecodedThreadSP> ThreadDecoder::Decode() {
41c903136fSKazu Hirata   if (!m_decoded_thread.has_value()) {
42a7d6c3efSWalter Erquinigo     if (Expected<DecodedThreadSP> decoded_thread = DoDecode()) {
43a7d6c3efSWalter Erquinigo       m_decoded_thread = *decoded_thread;
44a7d6c3efSWalter Erquinigo     } else {
45a7d6c3efSWalter Erquinigo       return decoded_thread.takeError();
46a7d6c3efSWalter Erquinigo     }
47a7d6c3efSWalter Erquinigo   }
486423b502SWalter Erquinigo   return *m_decoded_thread;
496423b502SWalter Erquinigo }
506423b502SWalter Erquinigo 
DoDecode()51a7d6c3efSWalter Erquinigo llvm::Expected<DecodedThreadSP> ThreadDecoder::DoDecode() {
529f9464e0SPeicong Wu   return m_trace.GetThreadTimer(m_thread_sp->GetID())
53d179ea12SWalter Erquinigo       .TimeTask("Decoding instructions", [&]() -> Expected<DecodedThreadSP> {
544f676c25SWalter Erquinigo         DecodedThreadSP decoded_thread_sp = std::make_shared<DecodedThread>(
554f676c25SWalter Erquinigo             m_thread_sp, m_trace.GetPerfZeroTscConversion());
566423b502SWalter Erquinigo 
57e0cfe20aSWalter Erquinigo         Error err = m_trace.OnThreadBufferRead(
58e0cfe20aSWalter Erquinigo             m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) {
59a7d6c3efSWalter Erquinigo               return DecodeSingleTraceForThread(*decoded_thread_sp, m_trace,
60a7d6c3efSWalter Erquinigo                                                 data);
61e0cfe20aSWalter Erquinigo             });
62bdf3e7e5SWalter Erquinigo 
63e0cfe20aSWalter Erquinigo         if (err)
64a7d6c3efSWalter Erquinigo           return std::move(err);
656423b502SWalter Erquinigo         return decoded_thread_sp;
66bdf3e7e5SWalter Erquinigo       });
676423b502SWalter Erquinigo }
68