Skip to content

Commit 55b67e9

Browse files
creliercommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Ignore source positions not denoting a debug point in debugger.
The CheckStack bytecode does not denote a debug point anymore after the introduction of the DebugCheck bytecode. Fix caller/callee determination in mixed mode. Factorize some code. Change-Id: Ide1e0bbad022a83e6113243dc996396f9f5d2f3c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108565 Commit-Queue: Régis Crelier <[email protected]> Reviewed-by: Alexander Markov <[email protected]>
1 parent 9690693 commit 55b67e9

File tree

10 files changed

+245
-116
lines changed

10 files changed

+245
-116
lines changed

runtime/vm/constants_kbc.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,7 @@ class KernelBytecode {
959959
// The interpreter checks for a debug break at each instruction with listed
960960
// opcode and the bytecode generator emits a source position at each
961961
// instruction with listed opcode.
962-
DART_FORCE_INLINE static bool IsDebugBreakCheckedOpcode(
963-
const KBCInstr* instr) {
962+
DART_FORCE_INLINE static bool IsDebugCheckedOpcode(const KBCInstr* instr) {
964963
switch (DecodeOpcode(instr)) {
965964
case KernelBytecode::kAllocate:
966965
case KernelBytecode::kPopLocal:

runtime/vm/debugger.cc

Lines changed: 167 additions & 111 deletions
Large diffs are not rendered by default.

runtime/vm/debugger.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,14 @@ class ActivationFrame : public ZoneAllocated {
309309
}
310310
bool IsInterpreted() const { return !bytecode_.IsNull(); }
311311

312+
enum Relation {
313+
kCallee,
314+
kSelf,
315+
kCaller,
316+
};
317+
318+
Relation CompareTo(uword other_fp, bool other_is_interpreted) const;
319+
312320
RawString* QualifiedFunctionName();
313321
RawString* SourceUrl();
314322
RawScript* SourceScript();
@@ -821,8 +829,10 @@ class Debugger {
821829
// frame corresponds to this fp value, or if the top frame is
822830
// lower on the stack.
823831
uword stepping_fp_;
832+
bool interpreted_stepping_;
824833
// Used to track the current async/async* function.
825834
uword async_stepping_fp_;
835+
bool interpreted_async_stepping_;
826836
RawObject* top_frame_awaiter_;
827837

828838
// If we step while at a breakpoint, we would hit the same pc twice.

runtime/vm/interpreter.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ DART_FORCE_INLINE bool Interpreter::InstanceCall2(Thread* thread,
11461146
#define DEBUG_CHECK
11471147
#else
11481148
// The DEBUG_CHECK macro must only be called from bytecodes listed in
1149-
// KernelBytecode::IsDebugBreakCheckedOpcode.
1149+
// KernelBytecode::IsDebugCheckedOpcode.
11501150
#define DEBUG_CHECK \
11511151
if (is_debugging()) { \
11521152
/* Check for debug breakpoint or if single stepping. */ \

runtime/vm/object.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15395,6 +15395,26 @@ intptr_t Bytecode::GetTryIndexAtPc(uword return_address) const {
1539515395
#endif
1539615396
}
1539715397

15398+
uword Bytecode::GetDebugCheckedOpcodePc(uword from_offset,
15399+
uword to_offset) const {
15400+
#if defined(DART_PRECOMPILED_RUNTIME)
15401+
UNREACHABLE();
15402+
#else
15403+
uword pc = PayloadStart() + from_offset;
15404+
uword end_pc = pc + (to_offset - from_offset);
15405+
while (pc < end_pc) {
15406+
uword next_pc = KernelBytecode::Next(pc);
15407+
if (KernelBytecode::IsDebugCheckedOpcode(
15408+
reinterpret_cast<const KBCInstr*>(pc))) {
15409+
// Return the pc after the opcode, i.e. its 'return address'.
15410+
return next_pc;
15411+
}
15412+
pc = next_pc;
15413+
}
15414+
return 0;
15415+
#endif
15416+
}
15417+
1539815418
const char* Bytecode::ToCString() const {
1539915419
return Thread::Current()->zone()->PrintToString("Bytecode(%s)",
1540015420
QualifiedName());
@@ -15440,6 +15460,16 @@ const char* Bytecode::QualifiedName() const {
1544015460
return zone->PrintToString("[Bytecode] %s", function_name);
1544115461
}
1544215462

15463+
const char* Bytecode::FullyQualifiedName() const {
15464+
Zone* zone = Thread::Current()->zone();
15465+
const Function& fun = Function::Handle(zone, function());
15466+
if (fun.IsNull()) {
15467+
return BytecodeStubName(*this);
15468+
}
15469+
const char* function_name = fun.ToFullyQualifiedCString();
15470+
return zone->PrintToString("[Bytecode] %s", function_name);
15471+
}
15472+
1544315473
bool Bytecode::SlowFindRawBytecodeVisitor::FindObject(
1544415474
RawObject* raw_obj) const {
1544515475
return RawBytecode::ContainsPC(raw_obj, pc_);

runtime/vm/object.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5729,6 +5729,9 @@ class Bytecode : public Object {
57295729
TokenPosition GetTokenIndexOfPC(uword return_address) const;
57305730
intptr_t GetTryIndexAtPc(uword return_address) const;
57315731

5732+
// Return the pc after the first 'debug checked' opcode in the range.
5733+
uword GetDebugCheckedOpcodePc(uword from_offset, uword to_offset) const;
5734+
57325735
intptr_t instructions_binary_offset() const {
57335736
return raw_ptr()->instructions_binary_offset_;
57345737
}
@@ -5780,6 +5783,7 @@ class Bytecode : public Object {
57805783

57815784
const char* Name() const;
57825785
const char* QualifiedName() const;
5786+
const char* FullyQualifiedName() const;
57835787

57845788
class SlowFindRawBytecodeVisitor : public FindObjectVisitor {
57855789
public:

runtime/vm/source_report.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,29 @@ void SourceReport::PrintPossibleBreakpointsData(JSONObject* jsobj,
340340
const Bytecode& bytecode = Bytecode::Handle(func.bytecode());
341341
ASSERT(!bytecode.IsNull());
342342
kernel::BytecodeSourcePositionsIterator iter(zone(), bytecode);
343+
intptr_t token_offset = -1;
344+
uword pc_offset = kUwordMax;
345+
// TODO(regis): We should ignore all possible breakpoint positions until
346+
// the first DebugCheck opcode of the function.
343347
while (iter.MoveNext()) {
348+
if (pc_offset != kUwordMax) {
349+
// Check that there is at least one 'debug checked' opcode in the last
350+
// source position range.
351+
if (bytecode.GetDebugCheckedOpcodePc(pc_offset, iter.PcOffset()) != 0) {
352+
possible[token_offset] = true;
353+
}
354+
pc_offset = kUwordMax;
355+
}
344356
const TokenPosition token_pos = iter.TokenPos();
345357
if ((token_pos < begin_pos) || (token_pos > end_pos)) {
346358
// Does not correspond to a valid source position.
347359
continue;
348360
}
349-
intptr_t token_offset = token_pos.Pos() - begin_pos.Pos();
361+
pc_offset = iter.PcOffset();
362+
token_offset = token_pos.Pos() - begin_pos.Pos();
363+
}
364+
if (pc_offset != kUwordMax &&
365+
bytecode.GetDebugCheckedOpcodePc(pc_offset, bytecode.Size()) != 0) {
350366
possible[token_offset] = true;
351367
}
352368
} else {

runtime/vm/stack_frame.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ const char* StackFrame::ToCString() const {
184184
" offset:0x%" Px ") %s ]",
185185
GetName(), sp(), fp(), pc(),
186186
pc() - bytecode.PayloadStart(),
187-
bytecode.Name());
187+
bytecode.FullyQualifiedName());
188188
}
189189
const Code& code = Code::Handle(zone, LookupDartCode());
190190
ASSERT(!code.IsNull());

runtime/vm/stack_frame.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,18 @@ DART_FORCE_INLINE static uword ParamAddress(uword fp, intptr_t reverse_index) {
456456
return fp + (kParamEndSlotFromFp * kWordSize) + (reverse_index * kWordSize);
457457
}
458458

459+
// Both fp and other_fp are compiled code frame pointers.
460+
// See stack_frame_dbc.h for the DBC version.
459461
DART_FORCE_INLINE static bool IsCalleeFrameOf(uword fp, uword other_fp) {
460462
return other_fp < fp;
461463
}
462464

465+
// Both fp and other_fp are bytecode frame pointers.
466+
DART_FORCE_INLINE static bool IsBytecodeCalleeFrameOf(uword fp,
467+
uword other_fp) {
468+
return other_fp > fp;
469+
}
470+
463471
// Value for stack limit that is used to cause an interrupt.
464472
// Note that on DBC stack is growing upwards so interrupt limit is 0 unlike
465473
// on all other architectures.

runtime/vm/stack_frame_dbc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ DART_FORCE_INLINE static bool IsCalleeFrameOf(uword fp, uword other_fp) {
7474
return other_fp > fp;
7575
}
7676

77+
DART_FORCE_INLINE static bool IsBytecodeCalleeFrameOf(uword fp,
78+
uword other_fp) {
79+
UNREACHABLE();
80+
return false;
81+
}
82+
7783
static const int kExitLinkSlotFromEntryFp = 0;
7884

7985
// Value for stack limit that is used to cause an interrupt.

0 commit comments

Comments
 (0)