Skip to content

Commit 53e01a1

Browse files
committed
Pulsar-Debugger: Reduced unnecessary copies within DebuggerContext.
1 parent dd3972b commit 53e01a1

File tree

2 files changed

+83
-52
lines changed

2 files changed

+83
-52
lines changed

include/pulsar-debugger/context.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ namespace PulsarDebugger
6969

7070
bool RegisterThread(ThreadId id, std::optional<Pulsar::String> name=std::nullopt);
7171

72+
std::optional<Thread> GetThread(ThreadId threadId);
7273
std::optional<StackFrame> GetOrLoadStackFrame(FrameId frameId);
7374
std::optional<Scope> GetOrLoadScope(ScopeId scopeId);
7475

7576
std::optional<Pulsar::List<StackFrame>> GetOrLoadStackFrames(ThreadId threadId, size_t framesStart=0, size_t framesCount=0, size_t* totalFrames=nullptr);
7677
std::optional<Pulsar::List<Scope>> GetOrLoadScopes(FrameId frameId, size_t scopesStart=0, size_t scopesCount=0, size_t* totalScopes=nullptr);
7778
std::optional<Pulsar::List<Variable>> GetVariables(VariablesReference variablesReference, size_t variablesStart=0, size_t variablesCount=0, size_t* totalVariables=nullptr);
7879

79-
std::optional<Thread> GetThread(ThreadId threadId);
8080
// The returned value, if not nullptr, is valid while this instance exists.
8181
const Pulsar::SourceDebugSymbol* GetSource(SourceReference sourceReference) const;
8282

@@ -103,6 +103,11 @@ namespace PulsarDebugger
103103
using ScopeOrLazy = std::variant<Scope, LazyScope>;
104104

105105
private:
106+
Thread* GetThreadPtr(ThreadId threadId);
107+
StackFrame* GetOrLoadStackFramePtr(FrameId frameId);
108+
Scope* GetOrLoadScopePtr(ScopeId scopeId);
109+
Pulsar::List<Variable>* GetVariablesPtr(VariablesReference variablesReference);
110+
106111
FrameId CreateLazyStackFrame(ThreadId threadId, size_t callIndex, ScopeId globalScopeId, bool isCaller, bool hasError);
107112
std::optional<StackFrame> LoadStackFrame(FrameId frameId, const LazyStackFrame& lazyFrame);
108113

src/pulsar-debugger/context.cpp

Lines changed: 77 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -59,54 +59,50 @@ bool DebuggerContext::RegisterThread(ThreadId threadId, std::optional<Pulsar::St
5959
return true;
6060
}
6161

62+
std::optional<DebuggerContext::Thread> DebuggerContext::GetThread(ThreadId threadId)
63+
{
64+
DebuggerContextScopeLock _lock(*this);
65+
const Thread* thread = GetThreadPtr(threadId);
66+
if (!thread) return std::nullopt;
67+
return *thread;
68+
}
69+
6270
std::optional<DebuggerContext::StackFrame> DebuggerContext::GetOrLoadStackFrame(FrameId frameId)
6371
{
6472
DebuggerContextScopeLock _lock(*this);
65-
if (frameId < 0 || static_cast<size_t>(frameId) >= m_StackFrames.Size()) return std::nullopt;
66-
auto& stackFrameOrLazy = m_StackFrames[frameId];
67-
if (std::holds_alternative<LazyStackFrame>(stackFrameOrLazy)) {
68-
auto stackFrame = LoadStackFrame(frameId, std::get<LazyStackFrame>(stackFrameOrLazy));
69-
if (!stackFrame) return std::nullopt;
70-
stackFrameOrLazy = *stackFrame;
71-
}
72-
return std::get<StackFrame>(stackFrameOrLazy);
73+
const StackFrame* stackFrame = GetOrLoadStackFramePtr(frameId);
74+
if (!stackFrame) return std::nullopt;
75+
return *stackFrame;
7376
}
7477

7578
std::optional<DebuggerContext::Scope> DebuggerContext::GetOrLoadScope(ScopeId scopeId)
7679
{
7780
DebuggerContextScopeLock _lock(*this);
78-
if (scopeId < 0 || static_cast<size_t>(scopeId) >= m_Scopes.Size()) return std::nullopt;
79-
auto& scopeOrLazy = m_Scopes[scopeId];
80-
if (std::holds_alternative<LazyScope>(scopeOrLazy)) {
81-
auto scope = LoadScope(std::get<LazyScope>(scopeOrLazy));
82-
if (!scope) return std::nullopt;
83-
scopeOrLazy = *scope;
84-
}
85-
return std::get<Scope>(scopeOrLazy);
81+
const Scope* scope = GetOrLoadScopePtr(scopeId);
82+
if (!scope) return std::nullopt;
83+
return *scope;
8684
}
8785

8886
std::optional<Pulsar::List<DebuggerContext::StackFrame>> DebuggerContext::GetOrLoadStackFrames(ThreadId threadId, size_t framesStart, size_t framesCount, size_t* totalFrames)
8987
{
9088
DebuggerContextScopeLock _lock(*this);
9189

92-
// TODO: Add methods which return references to internal structs (DO NOT MAKE THEM PUBLIC)
93-
const auto* foundThread = m_Threads.Find(threadId);
94-
if (!foundThread) return std::nullopt;
95-
const Thread& thread = foundThread->Value();
90+
const Thread* maybeThread = GetThreadPtr(threadId);
91+
if (!maybeThread) return std::nullopt;
9692

97-
if (totalFrames) *totalFrames = thread.StackFrames.Size();
93+
if (totalFrames) *totalFrames = maybeThread->StackFrames.Size();
9894

99-
if (framesStart >= thread.StackFrames.Size())
95+
if (framesStart >= maybeThread->StackFrames.Size())
10096
return Pulsar::List<StackFrame>();
10197

102-
if (framesCount <= 0 || framesCount > thread.StackFrames.Size() - framesStart) {
103-
framesCount = thread.StackFrames.Size() - framesStart;
98+
if (framesCount <= 0 || framesCount > maybeThread->StackFrames.Size() - framesStart) {
99+
framesCount = maybeThread->StackFrames.Size() - framesStart;
104100
}
105101

106102
Pulsar::List<StackFrame> outFrames(framesCount);
107103
for (size_t i = framesStart, framesEnd = framesStart + framesCount; i < framesEnd; ++i) {
108-
auto maybeFrame = GetOrLoadStackFrame(thread.StackFrames[i]);
109-
if (!maybeFrame) return {};
104+
const StackFrame* maybeFrame = GetOrLoadStackFramePtr(maybeThread->StackFrames[i]);
105+
if (!maybeFrame) return std::nullopt;
110106
outFrames.EmplaceBack(*maybeFrame);
111107
}
112108
return outFrames;
@@ -115,26 +111,23 @@ std::optional<Pulsar::List<DebuggerContext::StackFrame>> DebuggerContext::GetOrL
115111
std::optional<Pulsar::List<DebuggerContext::Scope>> DebuggerContext::GetOrLoadScopes(FrameId frameId, size_t scopesStart, size_t scopesCount, size_t* totalScopes)
116112
{
117113
DebuggerContextScopeLock _lock(*this);
118-
if (frameId < 0 || static_cast<size_t>(frameId) >= m_StackFrames.Size()) return std::nullopt;
119114

120-
// FIXME: This creates a copy, TODO within ::GetOrLoadStackFrames() solves this.
121-
auto maybeFrame = GetOrLoadStackFrame(frameId);
115+
const StackFrame* maybeFrame = GetOrLoadStackFramePtr(frameId);
122116
if (!maybeFrame) return std::nullopt;
123117

124-
const StackFrame& frame = *maybeFrame;
125-
if (totalScopes) *totalScopes = frame.Scopes.Size();
118+
if (totalScopes) *totalScopes = maybeFrame->Scopes.Size();
126119

127-
if (scopesStart >= frame.Scopes.Size())
120+
if (scopesStart >= maybeFrame->Scopes.Size())
128121
return Pulsar::List<Scope>();
129122

130-
if (scopesCount <= 0 || scopesCount > frame.Scopes.Size() - scopesStart) {
131-
scopesCount = frame.Scopes.Size() - scopesStart;
123+
if (scopesCount <= 0 || scopesCount > maybeFrame->Scopes.Size() - scopesStart) {
124+
scopesCount = maybeFrame->Scopes.Size() - scopesStart;
132125
}
133126

134127
Pulsar::List<Scope> outScopes(scopesCount);
135128
for (size_t i = scopesStart, scopesEnd = scopesStart + scopesCount; i < scopesEnd; ++i) {
136-
auto maybeScope = GetOrLoadScope(frame.Scopes[i]);
137-
if (!maybeScope) return {};
129+
const Scope* maybeScope = GetOrLoadScopePtr(maybeFrame->Scopes[i]);
130+
if (!maybeScope) return std::nullopt;
138131
outScopes.EmplaceBack(*maybeScope);
139132
}
140133
return outScopes;
@@ -143,40 +136,73 @@ std::optional<Pulsar::List<DebuggerContext::Scope>> DebuggerContext::GetOrLoadSc
143136
std::optional<Pulsar::List<DebuggerContext::Variable>> DebuggerContext::GetVariables(VariablesReference variablesReference, size_t variablesStart, size_t variablesCount, size_t* totalVariables)
144137
{
145138
DebuggerContextScopeLock _lock(*this);
146-
if (variablesReference < 0 || static_cast<size_t>(variablesReference) >= m_Variables.Size()) return std::nullopt;
147139

148-
const Pulsar::List<Variable>& variables = m_Variables[variablesReference];
149-
if (totalVariables) *totalVariables = variables.Size();
140+
const Pulsar::List<Variable>* maybeVariables = GetVariablesPtr(variablesReference);
141+
if (!maybeVariables) return std::nullopt;
142+
143+
if (totalVariables) *totalVariables = maybeVariables->Size();
150144

151-
if (variablesStart >= variables.Size())
145+
if (variablesStart >= maybeVariables->Size())
152146
return Pulsar::List<Variable>();
153147

154-
if (variablesCount <= 0 || variablesCount > variables.Size() - variablesStart) {
155-
variablesCount = variables.Size() - variablesStart;
148+
if (variablesCount <= 0 || variablesCount > maybeVariables->Size() - variablesStart) {
149+
variablesCount = maybeVariables->Size() - variablesStart;
156150
}
157151

158152
Pulsar::List<Variable> outVariables(variablesCount);
159153
for (size_t i = variablesStart, variablesEnd = variablesStart + variablesCount; i < variablesEnd; ++i) {
160-
outVariables.EmplaceBack(variables[i]);
154+
outVariables.EmplaceBack((*maybeVariables)[i]);
161155
}
162156
return outVariables;
163157
}
164158

165-
std::optional<DebuggerContext::Thread> DebuggerContext::GetThread(ThreadId threadId)
166-
{
167-
DebuggerContextScopeLock _lock(*this);
168-
const auto* thread = m_Threads.Find(threadId);
169-
if (!thread) return std::nullopt;
170-
return thread->Value();
171-
}
172-
173159
const Pulsar::SourceDebugSymbol* DebuggerContext::GetSource(SourceReference sourceReference) const
174160
{
175161
// No need to lock since module is constant
176162
if (!m_DebuggableModule) return nullptr;
177163
return m_DebuggableModule->GetSource(sourceReference);
178164
}
179165

166+
DebuggerContext::Thread* DebuggerContext::GetThreadPtr(ThreadId threadId)
167+
{
168+
auto* thread = m_Threads.Find(threadId);
169+
if (!thread) return nullptr;
170+
return &thread->Value();
171+
}
172+
173+
DebuggerContext::StackFrame* DebuggerContext::GetOrLoadStackFramePtr(FrameId frameId)
174+
{
175+
if (frameId < 0 || static_cast<size_t>(frameId) >= m_StackFrames.Size())
176+
return nullptr;
177+
auto& stackFrameOrLazy = m_StackFrames[frameId];
178+
if (std::holds_alternative<LazyStackFrame>(stackFrameOrLazy)) {
179+
auto stackFrame = LoadStackFrame(frameId, std::get<LazyStackFrame>(stackFrameOrLazy));
180+
if (!stackFrame) return nullptr;
181+
stackFrameOrLazy = *stackFrame;
182+
}
183+
return &std::get<StackFrame>(stackFrameOrLazy);
184+
}
185+
186+
DebuggerContext::Scope* DebuggerContext::GetOrLoadScopePtr(ScopeId scopeId)
187+
{
188+
if (scopeId < 0 || static_cast<size_t>(scopeId) >= m_Scopes.Size())
189+
return nullptr;
190+
auto& scopeOrLazy = m_Scopes[scopeId];
191+
if (std::holds_alternative<LazyScope>(scopeOrLazy)) {
192+
auto scope = LoadScope(std::get<LazyScope>(scopeOrLazy));
193+
if (!scope) return nullptr;
194+
scopeOrLazy = *scope;
195+
}
196+
return &std::get<Scope>(scopeOrLazy);
197+
}
198+
199+
Pulsar::List<DebuggerContext::Variable>* DebuggerContext::GetVariablesPtr(VariablesReference variablesReference)
200+
{
201+
if (variablesReference <= 0 || static_cast<size_t>(variablesReference) >= m_Variables.Size())
202+
return nullptr;
203+
return &m_Variables[variablesReference];
204+
}
205+
180206
FrameId DebuggerContext::CreateLazyStackFrame(ThreadId threadId, size_t callIndex, ScopeId globalScopeId, bool isCaller, bool hasError)
181207
{
182208
FrameId stackFrameId = m_StackFrames.Size();

0 commit comments

Comments
 (0)