Skip to content

Commit 0aaa86c

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm,dyn_modules] Initial support for interpreter frames in debugger
Also, support reading local variables information from bytecode. TEST=pkg/vm_service Change-Id: Iab482316891f0e474af0011e9b1765c4e8312bc9 Cq-Include-Trybots: luci.dart.try:vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try,vm-dyn-linux-debug-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/437281 Reviewed-by: Slava Egorov <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 113df82 commit 0aaa86c

File tree

9 files changed

+456
-63
lines changed

9 files changed

+456
-63
lines changed

pkg/dart2bytecode/bin/kernel_service.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ Uint8List _generateBytecode(
2929
hierarchy: hierarchy,
3030
target: target,
3131
options: BytecodeOptions(
32-
enableAsserts: enableAsserts, emitSourcePositions: true));
32+
enableAsserts: enableAsserts,
33+
emitSourcePositions: true,
34+
emitLocalVarInfo: true));
3335
return byteSink.builder.takeBytes();
3436
}
3537

runtime/vm/bytecode_reader.cc

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "vm/object_store.h"
2525
#include "vm/resolver.h"
2626
#include "vm/reusable_handles.h"
27+
#include "vm/scopes.h"
2728
#include "vm/stack_frame_kbc.h"
2829
#include "vm/symbols.h"
2930
#include "vm/timeline.h"
@@ -728,7 +729,13 @@ void BytecodeReaderHelper::ReadLocalVariables(const Bytecode& bytecode,
728729
return;
729730
}
730731

731-
reader_.ReadUInt(); // Skip local variables offset.
732+
const intptr_t offset = reader_.ReadUInt();
733+
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
734+
bytecode.set_local_variables_binary_offset(
735+
bytecode_component_->GetLocalVariablesOffset() + offset);
736+
#else
737+
USE(offset);
738+
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
732739
}
733740

734741
ArrayPtr BytecodeReaderHelper::ReadBytecodeComponent() {
@@ -2664,6 +2671,99 @@ void BytecodeReader::CollectScriptTokenPositionsFromBytecode(
26642671
}
26652672
}
26662673

2674+
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2675+
2676+
LocalVarDescriptorsPtr BytecodeReader::ComputeLocalVarDescriptors(
2677+
Zone* zone,
2678+
const Function& function,
2679+
const Bytecode& bytecode) {
2680+
ASSERT(function.is_declared_in_bytecode());
2681+
ASSERT(function.HasBytecode());
2682+
ASSERT(!bytecode.IsNull());
2683+
ASSERT(function.GetBytecode() == bytecode.ptr());
2684+
2685+
LocalVarDescriptorsBuilder vars;
2686+
2687+
if (function.IsLocalFunction()) {
2688+
const auto& parent = Function::Handle(zone, function.parent_function());
2689+
ASSERT(parent.is_declared_in_bytecode() && parent.HasBytecode());
2690+
const auto& parent_bytecode = Bytecode::Handle(zone, parent.GetBytecode());
2691+
const auto& parent_vars = LocalVarDescriptors::Handle(
2692+
zone, parent_bytecode.GetLocalVarDescriptors());
2693+
for (intptr_t i = 0; i < parent_vars.Length(); ++i) {
2694+
UntaggedLocalVarDescriptors::VarInfo var_info;
2695+
parent_vars.GetInfo(i, &var_info);
2696+
// Include parent's context variable if variable's scope
2697+
// intersects with the local function range.
2698+
// It is not enough to check if local function is declared within the
2699+
// scope of variable, because in case of async functions closure has
2700+
// the same range as original function.
2701+
if (var_info.kind() == UntaggedLocalVarDescriptors::kContextVar &&
2702+
((var_info.begin_pos <= function.token_pos() &&
2703+
function.token_pos() <= var_info.end_pos) ||
2704+
(function.token_pos() <= var_info.begin_pos &&
2705+
var_info.begin_pos <= function.end_token_pos()))) {
2706+
vars.Add(LocalVarDescriptorsBuilder::VarDesc{
2707+
&String::Handle(zone, parent_vars.GetName(i)), var_info});
2708+
}
2709+
}
2710+
}
2711+
2712+
if (bytecode.HasLocalVariablesInfo()) {
2713+
intptr_t scope_id = 0;
2714+
intptr_t context_level = -1;
2715+
BytecodeLocalVariablesIterator local_vars(zone, bytecode);
2716+
while (local_vars.MoveNext()) {
2717+
switch (local_vars.Kind()) {
2718+
case BytecodeLocalVariablesIterator::kScope: {
2719+
++scope_id;
2720+
context_level = local_vars.ContextLevel();
2721+
} break;
2722+
case BytecodeLocalVariablesIterator::kVariableDeclaration: {
2723+
LocalVarDescriptorsBuilder::VarDesc desc;
2724+
desc.name = &String::Handle(zone, local_vars.Name());
2725+
if (local_vars.IsCaptured()) {
2726+
desc.info.set_kind(UntaggedLocalVarDescriptors::kContextVar);
2727+
desc.info.scope_id = context_level;
2728+
desc.info.set_index(local_vars.Index());
2729+
} else {
2730+
desc.info.set_kind(UntaggedLocalVarDescriptors::kStackVar);
2731+
desc.info.scope_id = scope_id;
2732+
if (local_vars.Index() < 0) {
2733+
// Parameter
2734+
ASSERT(local_vars.Index() < -kKBCParamEndSlotFromFp);
2735+
desc.info.set_index(-local_vars.Index() - kKBCParamEndSlotFromFp);
2736+
} else {
2737+
desc.info.set_index(-local_vars.Index());
2738+
}
2739+
}
2740+
desc.info.declaration_pos = local_vars.DeclarationTokenPos();
2741+
desc.info.begin_pos = local_vars.StartTokenPos();
2742+
desc.info.end_pos = local_vars.EndTokenPos();
2743+
vars.Add(desc);
2744+
} break;
2745+
case BytecodeLocalVariablesIterator::kContextVariable: {
2746+
ASSERT(local_vars.Index() >= 0);
2747+
const intptr_t context_variable_index = -local_vars.Index();
2748+
LocalVarDescriptorsBuilder::VarDesc desc;
2749+
desc.name = &Symbols::CurrentContextVar();
2750+
desc.info.set_kind(UntaggedLocalVarDescriptors::kSavedCurrentContext);
2751+
desc.info.scope_id = 0;
2752+
desc.info.declaration_pos = TokenPosition::kMinSource;
2753+
desc.info.begin_pos = TokenPosition::kMinSource;
2754+
desc.info.end_pos = TokenPosition::kMinSource;
2755+
desc.info.set_index(context_variable_index);
2756+
vars.Add(desc);
2757+
} break;
2758+
}
2759+
}
2760+
}
2761+
2762+
return vars.Done();
2763+
}
2764+
2765+
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
2766+
26672767
} // namespace bytecode
26682768
} // namespace dart
26692769

runtime/vm/bytecode_reader.h

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,14 @@ class BytecodeReader : public AllStatic {
475475
static void CollectScriptTokenPositionsFromBytecode(
476476
const Script& interesting_script,
477477
GrowableArray<intptr_t>* token_positions);
478+
479+
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
480+
// Compute local variable descriptors for [function] with [bytecode].
481+
static LocalVarDescriptorsPtr ComputeLocalVarDescriptors(
482+
Zone* zone,
483+
const Function& function,
484+
const Bytecode& bytecode);
485+
#endif
478486
};
479487

480488
class BytecodeSourcePositionsIterator : ValueObject {
@@ -526,6 +534,125 @@ class BytecodeSourcePositionsIterator : ValueObject {
526534
bool is_yield_point_ = false;
527535
};
528536

537+
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
538+
539+
class BytecodeLocalVariablesIterator : ValueObject {
540+
public:
541+
// These constants should match corresponding constants in
542+
// pkg/dart2bytecode/lib/local_variable_table.dart.
543+
enum {
544+
kInvalid,
545+
kScope,
546+
kVariableDeclaration,
547+
kContextVariable,
548+
};
549+
550+
static const intptr_t kKindMask = 0xF;
551+
static const intptr_t kIsCapturedFlag = 1 << 4;
552+
553+
BytecodeLocalVariablesIterator(Zone* zone, const Bytecode& bytecode)
554+
: reader_(TypedDataBase::Handle(zone, bytecode.binary())),
555+
object_pool_(ObjectPool::Handle(zone, bytecode.object_pool())) {
556+
if (bytecode.HasLocalVariablesInfo()) {
557+
reader_.set_offset(bytecode.local_variables_binary_offset());
558+
entries_remaining_ = reader_.ReadUInt();
559+
}
560+
}
561+
562+
bool MoveNext() {
563+
if (entries_remaining_ <= 0) {
564+
// Finished looking at the last entry, now we're done.
565+
entries_remaining_ = -1;
566+
return false;
567+
}
568+
--entries_remaining_;
569+
cur_kind_and_flags_ = reader_.ReadByte();
570+
cur_start_pc_ += reader_.ReadSLEB128();
571+
switch (Kind()) {
572+
case kScope:
573+
cur_end_pc_ = cur_start_pc_ + reader_.ReadUInt();
574+
cur_index_ = reader_.ReadSLEB128();
575+
cur_token_pos_ = reader_.ReadPosition();
576+
cur_end_token_pos_ = reader_.ReadPosition();
577+
break;
578+
case kVariableDeclaration:
579+
cur_index_ = reader_.ReadSLEB128();
580+
cur_name_ = reader_.ReadUInt();
581+
cur_type_ = reader_.ReadUInt();
582+
cur_declaration_token_pos_ = reader_.ReadPosition();
583+
cur_token_pos_ = reader_.ReadPosition();
584+
break;
585+
case kContextVariable:
586+
cur_index_ = reader_.ReadSLEB128();
587+
break;
588+
}
589+
return true;
590+
}
591+
592+
// Returns true after iterator moved past the last entry and
593+
// MoveNext() returned false.
594+
bool IsDone() const { return entries_remaining_ < 0; }
595+
596+
intptr_t Kind() const { return cur_kind_and_flags_ & kKindMask; }
597+
bool IsScope() const { return Kind() == kScope; }
598+
bool IsVariableDeclaration() const { return Kind() == kVariableDeclaration; }
599+
bool IsContextVariable() const { return Kind() == kContextVariable; }
600+
601+
intptr_t StartPC() const { return cur_start_pc_; }
602+
intptr_t EndPC() const {
603+
ASSERT(IsScope() || IsVariableDeclaration());
604+
return cur_end_pc_;
605+
}
606+
intptr_t ContextLevel() const {
607+
ASSERT(IsScope());
608+
return cur_index_;
609+
}
610+
TokenPosition StartTokenPos() const {
611+
ASSERT(IsScope() || IsVariableDeclaration());
612+
return cur_token_pos_;
613+
}
614+
TokenPosition EndTokenPos() const {
615+
ASSERT(IsScope() || IsVariableDeclaration());
616+
return cur_end_token_pos_;
617+
}
618+
intptr_t Index() const {
619+
ASSERT(IsVariableDeclaration() || IsContextVariable());
620+
return cur_index_;
621+
}
622+
StringPtr Name() const {
623+
ASSERT(IsVariableDeclaration());
624+
return String::RawCast(object_pool_.ObjectAt(cur_name_));
625+
}
626+
AbstractTypePtr Type() const {
627+
ASSERT(IsVariableDeclaration());
628+
return AbstractType::RawCast(object_pool_.ObjectAt(cur_type_));
629+
}
630+
TokenPosition DeclarationTokenPos() const {
631+
ASSERT(IsVariableDeclaration());
632+
return cur_declaration_token_pos_;
633+
}
634+
bool IsCaptured() const {
635+
ASSERT(IsVariableDeclaration());
636+
return (cur_kind_and_flags_ & kIsCapturedFlag) != 0;
637+
}
638+
639+
private:
640+
Reader reader_;
641+
const ObjectPool& object_pool_;
642+
intptr_t entries_remaining_ = 0;
643+
intptr_t cur_kind_and_flags_ = 0;
644+
intptr_t cur_start_pc_ = 0;
645+
intptr_t cur_end_pc_ = 0;
646+
intptr_t cur_index_ = -1;
647+
intptr_t cur_name_ = -1;
648+
intptr_t cur_type_ = -1;
649+
TokenPosition cur_token_pos_ = TokenPosition::kNoSource;
650+
TokenPosition cur_declaration_token_pos_ = TokenPosition::kNoSource;
651+
TokenPosition cur_end_token_pos_ = TokenPosition::kNoSource;
652+
};
653+
654+
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
655+
529656
} // namespace bytecode
530657
} // namespace dart
531658

runtime/vm/compiler/runtime_offsets_extracted.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x14;
634634
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x8;
635635
static constexpr dart::compiler::target::word Array_header_size = 0xc;
636636
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x8;
637-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x30;
637+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x38;
638638
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
639639
static constexpr dart::compiler::target::word Class_InstanceSize = 0x78;
640640
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x1c;
@@ -1362,7 +1362,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x28;
13621362
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x10;
13631363
static constexpr dart::compiler::target::word Array_header_size = 0x18;
13641364
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x10;
1365-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x58;
1365+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x60;
13661366
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
13671367
static constexpr dart::compiler::target::word Class_InstanceSize = 0xc8;
13681368
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x38;
@@ -2081,7 +2081,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x14;
20812081
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x8;
20822082
static constexpr dart::compiler::target::word Array_header_size = 0xc;
20832083
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x8;
2084-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x30;
2084+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x38;
20852085
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
20862086
static constexpr dart::compiler::target::word Class_InstanceSize = 0x78;
20872087
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x1c;
@@ -2811,7 +2811,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x28;
28112811
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x10;
28122812
static constexpr dart::compiler::target::word Array_header_size = 0x18;
28132813
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x10;
2814-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x58;
2814+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x60;
28152815
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
28162816
static constexpr dart::compiler::target::word Class_InstanceSize = 0xc8;
28172817
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x38;
@@ -3536,7 +3536,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x20;
35363536
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x10;
35373537
static constexpr dart::compiler::target::word Array_header_size = 0x10;
35383538
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x10;
3539-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x40;
3539+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x48;
35403540
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
35413541
static constexpr dart::compiler::target::word Class_InstanceSize = 0x80;
35423542
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x20;
@@ -4263,7 +4263,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x20;
42634263
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x10;
42644264
static constexpr dart::compiler::target::word Array_header_size = 0x10;
42654265
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x10;
4266-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x40;
4266+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x48;
42674267
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
42684268
static constexpr dart::compiler::target::word Class_InstanceSize = 0x80;
42694269
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x20;
@@ -4984,7 +4984,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x14;
49844984
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x8;
49854985
static constexpr dart::compiler::target::word Array_header_size = 0xc;
49864986
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x8;
4987-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x30;
4987+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x38;
49884988
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
49894989
static constexpr dart::compiler::target::word Class_InstanceSize = 0x78;
49904990
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x1c;
@@ -5713,7 +5713,7 @@ static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x28;
57135713
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x10;
57145714
static constexpr dart::compiler::target::word Array_header_size = 0x18;
57155715
static constexpr dart::compiler::target::word Bool_InstanceSize = 0x10;
5716-
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x58;
5716+
static constexpr dart::compiler::target::word Bytecode_InstanceSize = 0x60;
57175717
static constexpr dart::compiler::target::word Capability_InstanceSize = 0x10;
57185718
static constexpr dart::compiler::target::word Class_InstanceSize = 0xc8;
57195719
static constexpr dart::compiler::target::word Closure_InstanceSize = 0x38;

0 commit comments

Comments
 (0)