Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move thread plan stacks into the Process, indexed by TID.
Differential Revision: https://reviews.llvm.org/D75880
- Loading branch information
Showing
10 changed files
with
668 additions
and
340 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
//===-- ThreadPlanStack.h ---------------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLDB_TARGET_THREADPLANSTACK_H | ||
#define LLDB_TARGET_THREADPLANSTACK_H | ||
|
||
#include <mutex> | ||
#include <string> | ||
#include <unordered_map> | ||
#include <vector> | ||
|
||
#include "lldb/Target/Target.h" | ||
#include "lldb/Target/Thread.h" | ||
#include "lldb/lldb-private-forward.h" | ||
#include "lldb/lldb-private.h" | ||
|
||
namespace lldb_private { | ||
|
||
// The ThreadPlans have a thread for use when they are asked all the ThreadPlan | ||
// state machine questions, but they should never cache any pointers from their | ||
// owning lldb_private::Thread. That's because we want to be able to detach | ||
// them from an owning thread, then reattach them by TID. | ||
// The ThreadPlanStack holds the ThreadPlans for a given TID. All its methods | ||
// are private, and it should only be accessed through the owning thread. When | ||
// it is detached from a thread, all you can do is reattach it or delete it. | ||
class ThreadPlanStack { | ||
friend class lldb_private::Thread; | ||
|
||
public: | ||
ThreadPlanStack(Thread &thread) {} | ||
~ThreadPlanStack() {} | ||
|
||
enum StackKind { ePlans, eCompletedPlans, eDiscardedPlans }; | ||
|
||
using PlanStack = std::vector<lldb::ThreadPlanSP>; | ||
|
||
void DumpThreadPlans(Stream *s, lldb::DescriptionLevel desc_level, | ||
bool include_internal) const; | ||
|
||
size_t CheckpointCompletedPlans(); | ||
|
||
void RestoreCompletedPlanCheckpoint(size_t checkpoint); | ||
|
||
void DiscardCompletedPlanCheckpoint(size_t checkpoint); | ||
|
||
void ThreadDestroyed(Thread *thread); | ||
|
||
void EnableTracer(bool value, bool single_stepping); | ||
|
||
void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp); | ||
|
||
void PushPlan(lldb::ThreadPlanSP new_plan_sp); | ||
|
||
lldb::ThreadPlanSP PopPlan(); | ||
|
||
lldb::ThreadPlanSP DiscardPlan(); | ||
|
||
// If the input plan is nullptr, discard all plans. Otherwise make sure this | ||
// plan is in the stack, and if so discard up to and including it. | ||
void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr); | ||
|
||
void DiscardAllPlans(); | ||
|
||
void DiscardConsultingMasterPlans(); | ||
|
||
lldb::ThreadPlanSP GetCurrentPlan() const; | ||
|
||
lldb::ThreadPlanSP GetCompletedPlan(bool skip_private = true) const; | ||
|
||
lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx, | ||
bool skip_private = true) const; | ||
|
||
lldb::ValueObjectSP GetReturnValueObject() const; | ||
|
||
lldb::ExpressionVariableSP GetExpressionVariable() const; | ||
|
||
bool AnyPlans() const; | ||
|
||
bool AnyCompletedPlans() const; | ||
|
||
bool AnyDiscardedPlans() const; | ||
|
||
bool IsPlanDone(ThreadPlan *plan) const; | ||
|
||
bool WasPlanDiscarded(ThreadPlan *plan) const; | ||
|
||
ThreadPlan *GetPreviousPlan(ThreadPlan *current_plan) const; | ||
|
||
ThreadPlan *GetInnermostExpression() const; | ||
|
||
void WillResume(); | ||
|
||
private: | ||
const PlanStack &GetStackOfKind(ThreadPlanStack::StackKind kind) const; | ||
|
||
PlanStack m_plans; ///< The stack of plans this thread is executing. | ||
PlanStack m_completed_plans; ///< Plans that have been completed by this | ||
/// stop. They get deleted when the thread | ||
/// resumes. | ||
PlanStack m_discarded_plans; ///< Plans that have been discarded by this | ||
/// stop. They get deleted when the thread | ||
/// resumes. | ||
size_t m_completed_plan_checkpoint = 0; // Monotonically increasing token for | ||
// completed plan checkpoints. | ||
std::unordered_map<size_t, PlanStack> m_completed_plan_store; | ||
}; | ||
|
||
class ThreadPlanStackMap { | ||
public: | ||
ThreadPlanStackMap() {} | ||
~ThreadPlanStackMap() {} | ||
|
||
void AddThread(Thread &thread) { | ||
lldb::tid_t tid = thread.GetID(); | ||
auto result = m_plans_list.emplace(tid, thread); | ||
} | ||
|
||
bool RemoveTID(lldb::tid_t tid) { | ||
auto result = m_plans_list.find(tid); | ||
if (result == m_plans_list.end()) | ||
return false; | ||
result->second.ThreadDestroyed(nullptr); | ||
m_plans_list.erase(result); | ||
return true; | ||
} | ||
|
||
ThreadPlanStack *Find(lldb::tid_t tid) { | ||
auto result = m_plans_list.find(tid); | ||
if (result == m_plans_list.end()) | ||
return nullptr; | ||
else | ||
return &result->second; | ||
} | ||
|
||
void Clear() { | ||
for (auto plan : m_plans_list) | ||
plan.second.ThreadDestroyed(nullptr); | ||
m_plans_list.clear(); | ||
} | ||
|
||
private: | ||
using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack>; | ||
PlansList m_plans_list; | ||
}; | ||
|
||
} // namespace lldb_private | ||
|
||
#endif // LLDB_TARGET_THREADPLANSTACK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.