19 size_t nslots = debugTrace ? debugTrace->fSlotInfo.size() : 0;
20 fDebugTrace = debugTrace;
24 fSlots.resize(nslots, {0,
31 fDirtyMask.emplace(nslots);
32 fReturnValues.emplace(nslots);
35 for (
size_t slotIdx = 0; slotIdx < nslots; ++slotIdx) {
36 if (fDebugTrace->fSlotInfo[slotIdx].fnReturnValue >= 0) {
37 fReturnValues->set(slotIdx);
41 for (
const TraceInfo& trace : fDebugTrace->fTraceInfo) {
43 fLineNumbers[trace.
data[0]] += 1;
52 if (this->execute(fCursor++)) {
60 size_t initialStackDepth = fStack.size();
62 bool canEscapeFromThisStackDepth = (fStack.size() <= initialStackDepth);
63 if (this->execute(fCursor++)) {
64 if (canEscapeFromThisStackDepth || this->
atBreakpoint()) {
73 size_t initialStackDepth = fStack.size();
75 if (this->execute(fCursor++)) {
76 bool hasEscapedFromInitialStackDepth = (fStack.size() < initialStackDepth);
77 if (hasEscapedFromInitialStackDepth || this->
atBreakpoint()) {
87 if (this->execute(fCursor++)) {
95void SkSLDebugTracePlayer::tidyState() {
100 fReturnValues->forEachSetIndex([&](
int slot) {
101 fStack.back().fDisplayMask.reset(slot);
106 return !fDebugTrace || fCursor >= fDebugTrace->fTraceInfo.size();
111 return fStack.back().fLine;
119 SkASSERT((
size_t)stackFrameIndex < fStack.size());
120 return fStack[stackFrameIndex].fLine;
128 fBreakpointLines = std::move(breakpointLines);
132 fBreakpointLines.insert(
line);
136 fBreakpointLines.erase(
line);
141 std::vector<int> funcs;
142 funcs.reserve(fStack.size() - 1);
143 for (
size_t index = 1; index < fStack.size(); ++index) {
144 funcs.push_back(fStack[index].fFunction);
151 return fStack.size() - 1;
154std::vector<SkSLDebugTracePlayer::VariableData> SkSLDebugTracePlayer::getVariablesForDisplayMask(
155 const SkBitSet& displayMask)
const {
158 std::vector<VariableData>
vars;
160 double typedValue = fDebugTrace->interpretValueBits(slot, fSlots[slot].fValue);
161 vars.push_back({slot, fDirtyMask->test(slot), typedValue});
164 std::stable_sort(
vars.begin(),
vars.end(), [&](
const VariableData&
a,
const VariableData&
b) {
165 return fSlots[a.fSlotIndex].fWriteTime > fSlots[b.fSlotIndex].fWriteTime;
171 int stackFrameIndex)
const {
175 if (stackFrameIndex <= 0 || (
size_t)stackFrameIndex >= fStack.size()) {
176 SkDEBUGFAILF(
"stack frame %d doesn't exist", stackFrameIndex - 1);
179 return this->getVariablesForDisplayMask(fStack[stackFrameIndex].fDisplayMask);
183 if (fStack.empty()) {
186 return this->getVariablesForDisplayMask(fStack.front().fDisplayMask);
189void SkSLDebugTracePlayer::updateVariableWriteTime(
int slotIdx,
size_t cursor) {
196 SkASSERT(slotIdx < (
int)fDebugTrace->fSlotInfo.size());
199 fSlots[slotIdx++].fWriteTime =
cursor;
202 if (slotIdx >= (
int)fDebugTrace->fSlotInfo.size()) {
206 if (fDebugTrace->fSlotInfo[slotIdx].groupIndex == 0) {
212bool SkSLDebugTracePlayer::execute(
size_t position) {
213 if (position >= fDebugTrace->fTraceInfo.size()) {
218 const TraceInfo& trace = fDebugTrace->fTraceInfo[position];
222 int lineNumber = trace.data[0];
224 SkASSERT((
size_t)lineNumber < fDebugTrace->fSource.size());
225 SkASSERT(fLineNumbers[lineNumber] > 0);
226 fStack.back().fLine = lineNumber;
227 fLineNumbers[lineNumber] -= 1;
231 int slotIdx = trace.data[0];
232 int value = trace.data[1];
234 SkASSERT((
size_t)slotIdx < fDebugTrace->fSlotInfo.size());
235 fSlots[slotIdx].fValue =
value;
236 fSlots[slotIdx].fScope = std::min<>(fSlots[slotIdx].fScope, fScope);
237 this->updateVariableWriteTime(slotIdx, position);
238 if (fDebugTrace->fSlotInfo[slotIdx].fnReturnValue < 0) {
241 fStack.rbegin()[0].fDisplayMask.set(slotIdx);
246 fStack.rbegin()[1].fDisplayMask.set(slotIdx);
248 fDirtyMask->set(slotIdx);
252 int fnIdx = trace.data[0];
254 SkASSERT((
size_t)fnIdx < fDebugTrace->fFuncInfo.size());
255 fStack.push_back({fnIdx,
257 SkBitSet(fDebugTrace->fSlotInfo.size())});
262 SkASSERT(fStack.back().fFunction == trace.data[0]);
268 fScope += trace.data[0];
269 if (trace.data[0] < 0) {
271 for (
size_t slotIdx = 0; slotIdx < fSlots.size(); ++slotIdx) {
272 if (fScope < fSlots[slotIdx].fScope) {
273 fSlots[slotIdx].fScope = INT_MAX;
274 fStack.back().fDisplayMask.reset(slotIdx);
#define SkDEBUGFAILF(fmt,...)
void forEachSetIndex(FN f) const
int getStackDepth() const
void reset(sk_sp< DebugTracePriv > trace)
std::vector< VariableData > getGlobalVariables() const
std::vector< VariableData > getLocalVariables(int stackFrameIndex) const
int32_t getCurrentLineInStackFrame(int stackFrameIndex) const
void removeBreakpoint(int line)
void setBreakpoints(std::unordered_set< int > breakpointLines)
bool traceHasCompleted() const
int32_t getCurrentLine() const
std::vector< int > getCallStack() const
void addBreakpoint(int line)
bool atBreakpoint() const