brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · dda6cd7 Raw
147 lines · cpp
1//===-- TraceCursorIntelPT.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "TraceCursorIntelPT.h"10#include "DecodedThread.h"11#include "TraceIntelPT.h"12#include <cstdlib>13#include <optional>14 15using namespace lldb;16using namespace lldb_private;17using namespace lldb_private::trace_intel_pt;18using namespace llvm;19 20TraceCursorIntelPT::TraceCursorIntelPT(21    ThreadSP thread_sp, DecodedThreadSP decoded_thread_sp,22    const std::optional<LinuxPerfZeroTscConversion> &tsc_conversion,23    std::optional<uint64_t> beginning_of_time_nanos)24    : TraceCursor(thread_sp), m_decoded_thread_sp(decoded_thread_sp),25      m_tsc_conversion(tsc_conversion),26      m_beginning_of_time_nanos(beginning_of_time_nanos) {27  Seek(0, lldb::eTraceCursorSeekTypeEnd);28}29 30void TraceCursorIntelPT::Next() {31  m_pos += IsForwards() ? 1 : -1;32  ClearTimingRangesIfInvalid();33}34 35void TraceCursorIntelPT::ClearTimingRangesIfInvalid() {36  if (m_tsc_range_calculated) {37    if (!m_tsc_range || m_pos < 0 || !m_tsc_range->InRange(m_pos)) {38      m_tsc_range = std::nullopt;39      m_tsc_range_calculated = false;40    }41  }42 43  if (m_nanoseconds_range_calculated) {44    if (!m_nanoseconds_range || m_pos < 0 ||45        !m_nanoseconds_range->InRange(m_pos)) {46      m_nanoseconds_range = std::nullopt;47      m_nanoseconds_range_calculated = false;48    }49  }50}51 52const std::optional<DecodedThread::TSCRange> &53TraceCursorIntelPT::GetTSCRange() const {54  if (!m_tsc_range_calculated) {55    m_tsc_range_calculated = true;56    m_tsc_range = m_decoded_thread_sp->GetTSCRangeByIndex(m_pos);57  }58  return m_tsc_range;59}60 61const std::optional<DecodedThread::NanosecondsRange> &62TraceCursorIntelPT::GetNanosecondsRange() const {63  if (!m_nanoseconds_range_calculated) {64    m_nanoseconds_range_calculated = true;65    m_nanoseconds_range =66        m_decoded_thread_sp->GetNanosecondsRangeByIndex(m_pos);67  }68  return m_nanoseconds_range;69}70 71bool TraceCursorIntelPT::Seek(int64_t offset,72                              lldb::TraceCursorSeekType origin) {73  switch (origin) {74  case lldb::eTraceCursorSeekTypeBeginning:75    m_pos = offset;76    break;77  case lldb::eTraceCursorSeekTypeEnd:78    m_pos = m_decoded_thread_sp->GetItemsCount() - 1 + offset;79    break;80  case lldb::eTraceCursorSeekTypeCurrent:81    m_pos += offset;82  }83 84  ClearTimingRangesIfInvalid();85 86  return HasValue();87}88 89bool TraceCursorIntelPT::HasValue() const {90  return m_pos >= 0 &&91         static_cast<uint64_t>(m_pos) < m_decoded_thread_sp->GetItemsCount();92}93 94lldb::TraceItemKind TraceCursorIntelPT::GetItemKind() const {95  return m_decoded_thread_sp->GetItemKindByIndex(m_pos);96}97 98llvm::StringRef TraceCursorIntelPT::GetError() const {99  return m_decoded_thread_sp->GetErrorByIndex(m_pos);100}101 102lldb::addr_t TraceCursorIntelPT::GetLoadAddress() const {103  return m_decoded_thread_sp->GetInstructionLoadAddress(m_pos);104}105 106std::optional<uint64_t> TraceCursorIntelPT::GetHWClock() const {107  if (const std::optional<DecodedThread::TSCRange> &range = GetTSCRange())108    return range->tsc;109  return std::nullopt;110}111 112std::optional<double> TraceCursorIntelPT::GetWallClockTime() const {113  if (const std::optional<DecodedThread::NanosecondsRange> &range =114          GetNanosecondsRange())115    return range->GetInterpolatedTime(m_pos, *m_beginning_of_time_nanos,116                                      *m_tsc_conversion);117  return std::nullopt;118}119 120lldb::cpu_id_t TraceCursorIntelPT::GetCPU() const {121  return m_decoded_thread_sp->GetCPUByIndex(m_pos);122}123 124lldb::TraceEvent TraceCursorIntelPT::GetEventType() const {125  return m_decoded_thread_sp->GetEventByIndex(m_pos);126}127 128bool TraceCursorIntelPT::GoToId(user_id_t id) {129  if (!HasId(id))130    return false;131  m_pos = id;132  ClearTimingRangesIfInvalid();133  return true;134}135 136bool TraceCursorIntelPT::HasId(lldb::user_id_t id) const {137  return id < m_decoded_thread_sp->GetItemsCount();138}139 140user_id_t TraceCursorIntelPT::GetId() const { return m_pos; }141 142std::optional<std::string> TraceCursorIntelPT::GetSyncPointMetadata() const {143  return formatv("offset = 0x{0:x}",144                 m_decoded_thread_sp->GetSyncPointOffsetByIndex(m_pos))145      .str();146}147