Report slot updates using a dirty mask.
By tracking slot writes using a dirty mask, and reporting these in the VariableData, we will be able to highlight assigned-to variables in the debugger. Change-Id: I93a767095c9c1b6dedc55a08424649f83aa1c960 Bug: skia:12666 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/483598 Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
e4bccab4ac
commit
9247feb52c
@ -19,9 +19,11 @@ void SkVMDebugTracePlayer::reset(sk_sp<SkVMDebugTrace> debugTrace) {
|
||||
fStack.push_back({/*fFunction=*/-1,
|
||||
/*fLine=*/-1,
|
||||
/*fDisplayMask=*/SkBitSet(nslots)});
|
||||
fDirtyMask.emplace(nslots);
|
||||
}
|
||||
|
||||
void SkVMDebugTracePlayer::step() {
|
||||
fDirtyMask->reset();
|
||||
while (!this->traceHasCompleted()) {
|
||||
if (this->execute(fCursor++)) {
|
||||
break;
|
||||
@ -30,6 +32,7 @@ void SkVMDebugTracePlayer::step() {
|
||||
}
|
||||
|
||||
void SkVMDebugTracePlayer::stepOver() {
|
||||
fDirtyMask->reset();
|
||||
size_t initialStackDepth = fStack.size();
|
||||
while (!this->traceHasCompleted()) {
|
||||
bool canEscapeFromThisStackDepth = (fStack.size() <= initialStackDepth);
|
||||
@ -40,6 +43,7 @@ void SkVMDebugTracePlayer::stepOver() {
|
||||
}
|
||||
|
||||
void SkVMDebugTracePlayer::stepOut() {
|
||||
fDirtyMask->reset();
|
||||
size_t initialStackDepth = fStack.size();
|
||||
while (!this->traceHasCompleted()) {
|
||||
if (this->execute(fCursor++) && (fStack.size() < initialStackDepth)) {
|
||||
@ -78,7 +82,7 @@ std::vector<SkVMDebugTracePlayer::VariableData> SkVMDebugTracePlayer::getVariabl
|
||||
|
||||
std::vector<VariableData> vars;
|
||||
bits.forEachSetIndex([&](int slot) {
|
||||
vars.push_back({slot, fSlots[slot]});
|
||||
vars.push_back({slot, fDirtyMask->test(slot), fSlots[slot]});
|
||||
});
|
||||
return vars;
|
||||
}
|
||||
@ -134,6 +138,7 @@ bool SkVMDebugTracePlayer::execute(size_t position) {
|
||||
SkASSERT(fStack.size() > 1);
|
||||
fStack.rbegin()[1].fDisplayMask.set(slot);
|
||||
}
|
||||
fDirtyMask->set(slot);
|
||||
break;
|
||||
}
|
||||
case SkVMTraceInfo::Op::kEnter: { // data: function index, (unused)
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/private/SkTOptional.h"
|
||||
#include "src/sksl/tracing/SkVMDebugTrace.h"
|
||||
#include "src/utils/SkBitSet.h"
|
||||
|
||||
@ -45,6 +46,7 @@ public:
|
||||
/** Returns variables from a stack frame, or from global scope. */
|
||||
struct VariableData {
|
||||
int fSlotIndex;
|
||||
bool fDirty; // has this slot been written-to since the last step call?
|
||||
int32_t fValue; // caller must type-pun bits to float/bool based on slot type
|
||||
};
|
||||
std::vector<VariableData> getLocalVariables(int stackFrameIndex) const;
|
||||
@ -69,6 +71,8 @@ private:
|
||||
size_t fCursor = 0; // position of the read head
|
||||
std::vector<int32_t> fSlots; // values in each slot
|
||||
std::vector<StackFrame> fStack; // the execution stack
|
||||
skstd::optional<SkBitSet> fDirtyMask; // variable slots touched during the most-recently
|
||||
// executed step
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -70,6 +70,7 @@ static std::string make_vars_string(
|
||||
}
|
||||
|
||||
const SkSL::SkVMSlotInfo& slot = trace.fSlotInfo[var.fSlotIndex];
|
||||
text += var.fDirty ? "##": "";
|
||||
text += slot.name;
|
||||
text += trace.getSlotComponentSuffix(var.fSlotIndex);
|
||||
text += " = ";
|
||||
@ -150,7 +151,7 @@ int main() { // Line 2
|
||||
REPORTER_ASSERT(r, player.traceHasCompleted());
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == -1);
|
||||
REPORTER_ASSERT(r, player.getCallStack().empty());
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "[main].result = 4");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "##[main].result = 4");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLTracePlayerReset, r) {
|
||||
@ -227,7 +228,7 @@ int main() { // Line 8
|
||||
REPORTER_ASSERT(r, player.traceHasCompleted());
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == -1);
|
||||
REPORTER_ASSERT(r, player.getCallStack().empty());
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "[main].result = 4");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "##[main].result = 4");
|
||||
|
||||
// Watch the stack grow and shrink as single-step.
|
||||
player.reset(trace);
|
||||
@ -249,17 +250,17 @@ int main() { // Line 8
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main() -> int fnA()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "[fnB].result = 4");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##[fnB].result = 4");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "[fnA].result = 4");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##[fnA].result = 4");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "");
|
||||
|
||||
player.step();
|
||||
REPORTER_ASSERT(r, player.traceHasCompleted());
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "[main].result = 4");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "##[main].result = 4");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLTracePlayerVariables, r) {
|
||||
@ -290,12 +291,12 @@ int main() { // Line 6
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 8);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "a = 123");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##a = 123");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 9);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "a = 123, b = true");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "a = 123, ##b = true");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 3);
|
||||
@ -305,7 +306,7 @@ int main() { // Line 6
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 4);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main() -> void func()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "z = 456");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##z = 456");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 9);
|
||||
@ -321,22 +322,23 @@ int main() { // Line 6
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 11);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) ==
|
||||
"a = 123, b = true, c.x = 0.000000, c.y = 0.500000, c.z = 1.000000, "
|
||||
"c.w = -1.000000");
|
||||
"a = 123, b = true, ##c.x = 0.000000, ##c.y = 0.500000, ##c.z = 1.000000, "
|
||||
"##c.w = -1.000000");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 12);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) ==
|
||||
"a = 123, b = true, c.x = 0.000000, c.y = 0.500000, c.z = 1.000000, "
|
||||
"c.w = -1.000000, d[0][0] = 2.000000, d[0][1] = 0.000000, d[0][2] = 0.000000, "
|
||||
"d[1][0] = 0.000000, d[1][1] = 2.000000, d[1][2] = 0.000000, "
|
||||
"d[2][0] = 0.000000, d[2][1] = 0.000000, d[2][2] = 2.000000");
|
||||
"c.w = -1.000000, ##d[0][0] = 2.000000, ##d[0][1] = 0.000000, "
|
||||
"##d[0][2] = 0.000000, ##d[1][0] = 0.000000, ##d[1][1] = 2.000000, "
|
||||
"##d[1][2] = 0.000000, ##d[2][0] = 0.000000, ##d[2][1] = 0.000000, "
|
||||
"##d[2][2] = 2.000000");
|
||||
|
||||
player.step();
|
||||
REPORTER_ASSERT(r, player.traceHasCompleted());
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "[main].result = 123");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "##[main].result = 123");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLTracePlayerIfStatement, r) {
|
||||
@ -367,7 +369,7 @@ int main() { // Line 2
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 4);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 0");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##val = 0");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 5);
|
||||
@ -376,7 +378,7 @@ int main() { // Line 2
|
||||
|
||||
// We skip over the false-branch.
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 9);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 1");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##val = 1");
|
||||
player.step();
|
||||
|
||||
// We skip over the true-branch.
|
||||
@ -385,11 +387,11 @@ int main() { // Line 2
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 14);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 4");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##val = 4");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.traceHasCompleted());
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "[main].result = 4");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "##[main].result = 4");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLTracePlayerForLoop, r) {
|
||||
@ -413,23 +415,23 @@ int main() { // Line 2
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 4);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 0");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##val = 0");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 5);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 0, x = 1");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 0, ##x = 1");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 4);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 1, x = 1");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##val = 1, x = 1");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 5);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 1, x = 2");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 1, ##x = 2");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 4);
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "val = 2, x = 2");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##val = 2, x = 2");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 7);
|
||||
@ -437,7 +439,7 @@ int main() { // Line 2
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.traceHasCompleted());
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "[main].result = 2");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "##[main].result = 2");
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLTracePlayerStepOut, r) {
|
||||
@ -471,20 +473,20 @@ int main() { // Line 9
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 4);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main() -> int fn()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "a = 11");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##a = 11");
|
||||
player.step();
|
||||
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 5);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main() -> int fn()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "a = 11, b = 22");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "a = 11, ##b = 22");
|
||||
player.stepOut();
|
||||
|
||||
// We should now be back inside main(), right where we left off.
|
||||
REPORTER_ASSERT(r, player.getCurrentLine() == 10);
|
||||
REPORTER_ASSERT(r, make_stack_string(*trace, player) == "int main()");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "[fn].result = 44");
|
||||
REPORTER_ASSERT(r, make_local_vars_string(*trace, player) == "##[fn].result = 44");
|
||||
player.stepOut();
|
||||
|
||||
REPORTER_ASSERT(r, player.traceHasCompleted());
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "[main].result = 44");
|
||||
REPORTER_ASSERT(r, make_global_vars_string(*trace, player) == "##[main].result = 44");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user