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 
106423b502SWalter Erquinigo #include "llvm/Support/MemoryBuffer.h"
116423b502SWalter Erquinigo 
126423b502SWalter Erquinigo #include "../common/ThreadPostMortemTrace.h"
136423b502SWalter Erquinigo #include "LibiptDecoder.h"
146423b502SWalter Erquinigo #include "TraceIntelPT.h"
156423b502SWalter Erquinigo 
166423b502SWalter Erquinigo #include <utility>
176423b502SWalter Erquinigo 
186423b502SWalter Erquinigo using namespace lldb;
196423b502SWalter Erquinigo using namespace lldb_private;
206423b502SWalter Erquinigo using namespace lldb_private::trace_intel_pt;
216423b502SWalter Erquinigo using namespace llvm;
226423b502SWalter Erquinigo 
ThreadDecoder(const ThreadSP & thread_sp,TraceIntelPT & trace)23e0cfe20aSWalter Erquinigo ThreadDecoder::ThreadDecoder(const ThreadSP &thread_sp, TraceIntelPT &trace)
24e0cfe20aSWalter Erquinigo     : m_thread_sp(thread_sp), m_trace(trace) {}
256423b502SWalter Erquinigo 
FindLowestTSC()26*4f676c25SWalter Erquinigo Expected<Optional<uint64_t>> ThreadDecoder::FindLowestTSC() {
27*4f676c25SWalter Erquinigo   Optional<uint64_t> lowest_tsc;
28*4f676c25SWalter Erquinigo   Error err = m_trace.OnThreadBufferRead(
29*4f676c25SWalter Erquinigo       m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) -> llvm::Error {
30*4f676c25SWalter Erquinigo         Expected<Optional<uint64_t>> tsc = FindLowestTSCInTrace(m_trace, data);
31*4f676c25SWalter Erquinigo         if (!tsc)
32*4f676c25SWalter Erquinigo           return tsc.takeError();
33*4f676c25SWalter Erquinigo         lowest_tsc = *tsc;
34*4f676c25SWalter Erquinigo         return Error::success();
35*4f676c25SWalter Erquinigo       });
36*4f676c25SWalter Erquinigo   if (err)
37*4f676c25SWalter Erquinigo     return std::move(err);
38*4f676c25SWalter Erquinigo   return lowest_tsc;
39*4f676c25SWalter Erquinigo }
40*4f676c25SWalter Erquinigo 
Decode()41a7d6c3efSWalter Erquinigo Expected<DecodedThreadSP> ThreadDecoder::Decode() {
42a7d6c3efSWalter Erquinigo   if (!m_decoded_thread.hasValue()) {
43a7d6c3efSWalter Erquinigo     if (Expected<DecodedThreadSP> decoded_thread = DoDecode()) {
44a7d6c3efSWalter Erquinigo       m_decoded_thread = *decoded_thread;
45a7d6c3efSWalter Erquinigo     } else {
46a7d6c3efSWalter Erquinigo       return decoded_thread.takeError();
47a7d6c3efSWalter Erquinigo     }
48a7d6c3efSWalter Erquinigo   }
496423b502SWalter Erquinigo   return *m_decoded_thread;
506423b502SWalter Erquinigo }
516423b502SWalter Erquinigo 
DoDecode()52a7d6c3efSWalter Erquinigo llvm::Expected<DecodedThreadSP> ThreadDecoder::DoDecode() {
539f9464e0SPeicong Wu   return m_trace.GetThreadTimer(m_thread_sp->GetID())
549f9464e0SPeicong Wu       .TimeTask(
55a7d6c3efSWalter Erquinigo           "Decoding instructions", [&]() -> Expected<DecodedThreadSP> {
56*4f676c25SWalter Erquinigo             DecodedThreadSP decoded_thread_sp = std::make_shared<DecodedThread>(
57*4f676c25SWalter Erquinigo                 m_thread_sp, m_trace.GetPerfZeroTscConversion());
586423b502SWalter Erquinigo 
59e0cfe20aSWalter Erquinigo             Error err = m_trace.OnThreadBufferRead(
60e0cfe20aSWalter Erquinigo                 m_thread_sp->GetID(), [&](llvm::ArrayRef<uint8_t> data) {
61a7d6c3efSWalter Erquinigo                   return DecodeSingleTraceForThread(*decoded_thread_sp, m_trace,
62a7d6c3efSWalter Erquinigo                                                     data);
63e0cfe20aSWalter Erquinigo                 });
64bdf3e7e5SWalter Erquinigo 
65e0cfe20aSWalter Erquinigo             if (err)
66a7d6c3efSWalter Erquinigo               return std::move(err);
676423b502SWalter Erquinigo             return decoded_thread_sp;
68bdf3e7e5SWalter Erquinigo           });
696423b502SWalter Erquinigo }
70