23 : m_libipt_error_code(libipt_error_code), m_address(address) {
24 assert(libipt_error_code < 0);
39 return item_index >= first_item_index &&
40 item_index < first_item_index + items_count;
44 uint64_t item_index, uint64_t begin_of_time_nanos,
46 uint64_t items_since_last_tsc = item_index - first_item_index;
48 auto interpolate = [&](uint64_t next_range_start_ns) {
49 if (next_range_start_ns == nanos) {
53 next_range_start_ns++;
55 long double item_duration =
56 static_cast<long double>(items_count) / (next_range_start_ns - nanos);
57 return (nanos - begin_of_time_nanos) + items_since_last_tsc * item_duration;
65 return interpolate(tsc_conversion.
ToNanos(tsc + items_count));
67 if (items_count < (next_range->tsc - tsc)) {
79 std::min(tsc_conversion.
ToNanos(tsc + items_count), next_range->nanos));
85 return interpolate(next_range->nanos);
92 return std::get<lldb::addr_t>(
m_item_data[item_index]);
102template <
typename Data>
108 (*m_last_tsc)->second.items_count++;
110 (*m_last_nanoseconds)->second.items_count++;
121 if (
m_last_tsc && (*m_last_tsc)->second.tsc == tsc)
124 assert(tsc >= (*m_last_tsc)->second.tsc &&
125 "We can't have decreasing times");
140 prev_range->second.next_range = &(*m_last_nanoseconds)->second;
156 auto it =
m_cpus.upper_bound(item_index);
160std::optional<DecodedThread::TSCRange>
162 auto next_it =
m_tscs.upper_bound(item_index);
163 if (next_it ==
m_tscs.begin())
165 return prev(next_it)->second;
168std::optional<DecodedThread::NanosecondsRange>
173 return prev(next_it)->second;
201 return std::get<lldb::TraceEvent>(
m_item_data[item_index]);
209 events_counts[event]++;
215 for (
const auto &[kind, count] : libipt_errors)
218 return total + other_errors + fatal_errors;
229 libipt_errors[pt_errstr(pt_errcode(libipt_error_code))]++;
248 return llvm::StringRef();
249 return std::get<std::string>(
m_item_data[item_index]);
254 const std::optional<LinuxPerfZeroTscConversion> &tsc_conversion)
259 (
sizeof(uint64_t) +
sizeof(
TSC)) *
m_tscs.size() +
260 (
sizeof(uint64_t) +
sizeof(uint64_t)) *
m_nanoseconds.size() +
static llvm::raw_ostream & error(Stream &strm)
uint64_t m_insn_count
Total number of instructions in the trace.
const EventsStats & GetEventsStats() const
Return an object with statistics of the trace events that happened.
const ErrorStats & GetErrorStats() const
Return an object with statistics of the trace errors that happened.
std::optional< uint64_t > m_last_cpu
This is the chronologically last CPU ID.
std::optional< std::map< uint64_t, TSCRange >::iterator > m_last_tsc
This is the chronologically last TSC that has been added.
lldb::TraceItemKind GetItemKindByIndex(uint64_t item_index) const
void AppendEvent(lldb::TraceEvent)
Append an event.
std::map< uint64_t, NanosecondsRange > m_nanoseconds
This map contains the non-interpolated nanoseconds timestamps of the decoded trace items.
llvm::StringRef GetErrorByIndex(uint64_t item_index) const
lldb::ThreadSP GetThread()
std::deque< TraceItemStorage > m_item_data
Most of the trace data is stored here.
EventsStats m_events_stats
Statistics of all tracing events.
lldb::addr_t GetInstructionLoadAddress(uint64_t item_index) const
llvm::DenseMap< uint64_t, lldb::addr_t > m_psb_offsets
std::optional< DecodedThread::NanosecondsRange > GetNanosecondsRangeByIndex(uint64_t item_index)
Get a maximal range of trace items that include the given item_index that have the same nanoseconds t...
void AppendError(const IntelPTError &error)
Append a decoding error.
lldb::TraceEvent GetEventByIndex(int item_index) const
void NotifyCPU(lldb::cpu_id_t cpu_id)
Notify this object that a CPU has been seen.
size_t CalculateApproximateMemoryUsage() const
The approximate size in bytes used by this instance, including all the already decoded instructions.
std::optional< LinuxPerfZeroTscConversion > m_tsc_conversion
TSC -> nanos conversion utility.
uint64_t GetTotalInstructionCount() const
ErrorStats m_error_stats
Statistics of all tracing errors.
std::map< uint64_t, lldb::cpu_id_t > m_cpus
std::variant< std::string, lldb::TraceEvent, lldb::addr_t > TraceItemStorage
void NotifySyncPoint(lldb::addr_t psb_offset)
Notify this object that a new PSB has been seen.
std::optional< DecodedThread::TSCRange > GetTSCRangeByIndex(uint64_t item_index) const
Get a maximal range of trace items that include the given item_index that have the same TSC value.
DecodedThread::TraceItemStorage & CreateNewTraceItem(lldb::TraceItemKind kind, Data &&data)
Create a new trace item.
void AppendCustomError(llvm::StringRef error, bool fatal=false)
Append a custom decoding.
lldb::cpu_id_t GetCPUByIndex(uint64_t item_index) const
Get the most recent CPU id before or at the given trace item index.
void NotifyTsc(TSC tsc)
Notify this object that a new tsc has been seen.
lldb::addr_t GetSyncPointOffsetByIndex(uint64_t item_index) const
std::map< uint64_t, TSCRange > m_tscs
This map contains the TSCs of the decoded trace items.
uint64_t GetItemsCount() const
Get the total number of instruction, errors and events from the decoded trace.
lldb::ThreadSP m_thread_sp
When adding new members to this class, make sure to update CalculateApproximateMemoryUsage() accordin...
DecodedThread(lldb::ThreadSP thread_sp, const std::optional< LinuxPerfZeroTscConversion > &tsc_conversion)
std::optional< std::map< uint64_t, NanosecondsRange >::iterator > m_last_nanoseconds
void AppendInstruction(const pt_insn &insn)
Append an instruction.
Class for representing a libipt decoding error.
void log(llvm::raw_ostream &OS) const override
IntelPTError(int libipt_error_code, lldb::addr_t address=LLDB_INVALID_ADDRESS)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_CPU_ID
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Thread > ThreadSP
TraceEvent
Events that might happen during a trace session.
@ eTraceEventSyncPoint
The underlying tracing technology emitted a synchronization event used by trace processors.
@ eTraceEventCPUChanged
Event due to CPU change for a thread.
@ eTraceEventHWClockTick
Event due to a CPU HW clock tick.
@ eTraceItemKindInstruction
jLLDBTraceGetState gdb-remote packet
uint64_t ToNanos(uint64_t tsc) const
Convert TSC value to nanosecond wall time.
void RecordError(int libipt_error_code)
uint64_t GetTotalCount() const
void RecordEvent(lldb::TraceEvent event)
A structure that represents a maximal range of trace items associated to the same non-interpolated ti...
double GetInterpolatedTime(uint64_t item_index, uint64_t beginning_of_time_nanos, const LinuxPerfZeroTscConversion &tsc_conversion) const
Calculate an interpolated timestamp in nanoseconds for the given item index.
bool InRange(uint64_t item_index) const
A structure that represents a maximal range of trace items associated to the same TSC value.
uint64_t items_count
Number of trace items in this range.
uint64_t first_item_index
Index of the first trace item in this range.
bool InRange(uint64_t item_index) const