Skip to content

Commit 0bbb2ae

Browse files
sstricklCommit Queue
authored andcommitted
[vm,dyn_modules] Fix/skip vm/cc tests that crash for dynamic modules.
Skip IR or snapshot-related tests when running from bytecode. TEST=vm/cc/DartAPI_DeepStackTraceInfo vm/cc/DartAPI_HeapSampling_UserDefinedClass vm/cc/DartAPI_StackTraceInfo vm/cc/DartAPI_StackOverflowStackTraceInfoArrowFunction vm/cc/DartAPI_StackOverflowStackTraceInfoBraceFunction1 vm/cc/DartAPI_StackOverflowStackTraceInfoBraceFunction2 vm/cc/FrameLookup vm/cc/Service_LocalVarDescriptors Cq-Include-Trybots: luci.dart.try:vm-dyn-linux-debug-x64-try Change-Id: I396a4e8ddacdbb88b3844e4113dc5c4ff6287e30 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/490083 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
1 parent f92673c commit 0bbb2ae

9 files changed

Lines changed: 77 additions & 59 deletions

File tree

pkg/dart2bytecode/lib/bytecode_generator.dart

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,12 +2282,12 @@ class BytecodeGenerator extends RecursiveVisitor {
22822282
}
22832283
}
22842284

2285-
// The CheckStack below is the instruction which should be used for function
2286-
// entry breakpoints.
2287-
_recordInitialSourcePositionForFunction(node, function);
22882285
// CheckStack must see a properly initialized context when stress-testing
22892286
// stack trace collection.
22902287
asm.emitCheckStack(0);
2288+
// After checking the stack, the next instruction is safe for setting
2289+
// the entry breakpoint for a function.
2290+
_emitSourcePositionForFunctionEntryBreakpoint(node, function);
22912291

22922292
if (locals.hasFunctionTypeArgsVar && isClosure) {
22932293
if (function!.typeParameters.isNotEmpty) {
@@ -2386,26 +2386,25 @@ class BytecodeGenerator extends RecursiveVisitor {
23862386
}
23872387
}
23882388

2389-
int _initialSourcePositionForFunction(TreeNode node, FunctionNode? function) {
2390-
// The debugger expects the initial source position to correspond to the
2391-
// declaration position of the last parameter, if any, or of the function.
2389+
void _emitSourcePositionForFunctionEntryBreakpoint(
2390+
TreeNode node,
2391+
FunctionNode? function,
2392+
) {
2393+
// The debugger expects the source position for function entry to correspond
2394+
// to the declaration position of the last parameter, if any, otherwise
2395+
// the file offset of the function.
2396+
final int startOffset;
23922397
if (function?.namedParameters.isNotEmpty ?? false) {
2393-
return function!.namedParameters.last.fileOffset;
2398+
startOffset = function!.namedParameters.last.fileOffset;
23942399
} else if (function?.positionalParameters.isNotEmpty ?? false) {
2395-
return function!.positionalParameters.last.fileOffset;
2400+
startOffset = function!.positionalParameters.last.fileOffset;
23962401
} else if (function != null) {
2397-
return function.fileOffset;
2402+
startOffset = function.fileOffset;
23982403
} else {
2399-
return node.fileOffset;
2404+
startOffset = node.fileOffset;
24002405
}
2401-
}
2402-
2403-
void _recordInitialSourcePositionForFunction(
2404-
TreeNode node,
2405-
FunctionNode? function,
2406-
) {
2407-
final position = _initialSourcePositionForFunction(node, function);
2408-
_recordSourcePosition(position, 0);
2406+
_recordSourcePosition(startOffset, 0);
2407+
asm.emitSourcePosition();
24092408
}
24102409

24112410
void _copyParamIfCaptured(VariableDeclaration variable) {

runtime/tests/vm/vm.status

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ cc/DeoptimizeFramesWhenSettingBreakpoint: SkipByDesign # JIT compilation is not
9191
cc/DerivedInduction: SkipByDesign # Building flow graph is not supported from bytecode.
9292
cc/Ffi_StructSinking: SkipByDesign # Building flow graph is not supported from bytecode.
9393
cc/FlowGraph_PhiUnboxingHeuristic_*: SkipByDesign # Building flow graph is not supported from bytecode.
94+
cc/FullSnapshot: SkipByDesign # JIT compilation is not supported from bytecode.
9495
cc/IRTest_*: SkipByDesign # Building flow graph is not supported from bytecode.
9596
cc/Inliner_*: SkipByDesign # Building flow graph is not supported from bytecode.
9697
cc/IsolateReload_EnumWithSet: SkipByDesign # Bytecode doesn't support KernelProgramInfo.
@@ -103,6 +104,7 @@ cc/NotEqualCondition*: SkipByDesign # Building flow graph is not supported from
103104
cc/OptimizeCompileFunctionOnHelperThread: SkipByDesign # JIT compilation is not supported from bytecode.
104105
cc/PeriodicAndDerived: SkipByDesign # Building flow graph is not supported from bytecode.
105106
cc/RangeAnalysis_*: SkipByDesign # Building flow graph is not supported from bytecode.
107+
cc/ReachabilityFence_*: SkipByDesign # Building flow graph is not supported from bytecode.
106108
cc/SecondExit*: SkipByDesign # Building flow graph is not supported from bytecode.
107109
cc/StackMapGC: SkipByDesign # JIT compilation is not supported from bytecode.
108110
cc/StreamingFlowGraphBuilder_*: SkipByDesign # Building flow graph is not supported from bytecode.

runtime/vm/benchmark_test.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,15 @@ static void StackFrame_accessFrame(Dart_NativeArguments args) {
272272
Thread* thread = Thread::Current();
273273
TransitionNativeToVM transition(thread);
274274
const int kNumIterations = 100;
275-
Code& code = Code::Handle(thread->zone());
276275
for (int i = 0; i < kNumIterations; i++) {
277276
StackFrameIterator frames(ValidationPolicy::kDontValidateFrames, thread,
278277
StackFrameIterator::kNoCrossThreadIteration);
279278
StackFrame* frame = frames.NextFrame();
280279
while (frame != nullptr) {
281280
if (frame->IsStubFrame()) {
282-
code = frame->LookupDartCode();
283-
EXPECT(code.function() == Function::null());
281+
EXPECT(frame->LookupDartFunction() == Function::null());
284282
} else if (frame->IsDartFrame()) {
285-
code = frame->LookupDartCode();
286-
EXPECT(code.function() != Function::null());
283+
EXPECT(frame->LookupDartFunction() != Function::null());
287284
}
288285
frame = frames.NextFrame();
289286
}

runtime/vm/bytecode_reader.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,6 +2425,10 @@ void BytecodeReaderHelper::ReadClassDeclaration(const Class& cls) {
24252425
if (!cls.is_type_finalized()) {
24262426
ClassFinalizer::FinalizeTypesInClass(cls);
24272427
}
2428+
2429+
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
2430+
cls.SetUserVisibleNameInClassTable();
2431+
#endif
24282432
}
24292433

24302434
void BytecodeReaderHelper::ReadLibraryDeclaration(const Library& library,

runtime/vm/compiler/assembler/disassembler_kbc.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,6 @@ void KernelBytecodeDisassembler::Disassemble(uword start,
365365
char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form.
366366
char human_buffer[kUserReadableBufferSize]; // Human-readable instruction.
367367
uword pc = start;
368-
GrowableArray<const Function*> inlined_functions;
369-
GrowableArray<TokenPosition> token_positions;
370368
while (pc < end) {
371369
int instruction_length;
372370
Object* object;

runtime/vm/debugger.cc

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ intptr_t ActivationFrame::DeoptId() {
578578

579579
intptr_t ActivationFrame::LineNumber() {
580580
// Compute line number lazily since it causes scanning of the script.
581-
const TokenPosition& token_pos = TokenPos();
581+
const TokenPosition& token_pos = TokenPos().ToRealIfSynthetic();
582582
if ((line_number_ < 0) && token_pos.IsReal()) {
583583
const Script& script = Script::Handle(SourceScript());
584584
script.GetTokenLocation(token_pos, &line_number_, &column_number_);
@@ -588,7 +588,7 @@ intptr_t ActivationFrame::LineNumber() {
588588

589589
intptr_t ActivationFrame::ColumnNumber() {
590590
// Compute column number lazily since it causes scanning of the script.
591-
const TokenPosition& token_pos = TokenPos();
591+
const TokenPosition& token_pos = TokenPos().ToRealIfSynthetic();
592592
if ((column_number_ < 0) && token_pos.IsReal()) {
593593
const Script& script = Script::Handle(SourceScript());
594594
script.GetTokenLocation(token_pos, &line_number_, &column_number_);
@@ -2063,36 +2063,42 @@ DebuggerStackTrace* DebuggerStackTrace::From(const class StackTrace& ex_trace) {
20632063
// pre-allocated trace (such as a stack overflow) or (b) because a stack has
20642064
// fewer frames that the pre-allocated trace (such as memory exhaustion with
20652065
// a shallow stack).
2066-
if (!code_object.IsNull()) {
2067-
code ^= code_object.ptr();
2066+
function = Function::null();
2067+
uword start = 0;
2068+
bool is_optimized_code = false;
2069+
if (code_object.IsCode()) {
2070+
const auto& code = Code::Cast(code_object);
20682071
ASSERT(code.IsFunctionCode());
20692072
function = code.function();
2070-
if (function.is_visible()) {
2073+
start = code.PayloadStart();
2074+
is_optimized_code = code.is_optimized();
2075+
} else if (code_object.IsBytecode()) {
2076+
const auto& bytecode = Bytecode::Cast(code_object);
2077+
function = bytecode.function();
2078+
start = bytecode.PayloadStart();
2079+
}
2080+
if (function.IsNull() || !function.is_visible()) continue;
2081+
const uword pc = start + ex_trace.PcOffsetAtFrame(i);
2082+
if (is_optimized_code && ex_trace.expand_inlined()) {
2083+
// Traverse inlined frames.
2084+
code ^= code_object.ptr();
2085+
for (InlinedFunctionsIterator it(code, pc); !it.Done(); it.Advance()) {
2086+
function = it.function();
2087+
code = it.code();
20712088
ASSERT(function.ptr() == code.function());
2072-
uword pc = code.PayloadStart() + ex_trace.PcOffsetAtFrame(i);
2073-
if (code.is_optimized() && ex_trace.expand_inlined()) {
2074-
// Traverse inlined frames.
2075-
for (InlinedFunctionsIterator it(code, pc); !it.Done();
2076-
it.Advance()) {
2077-
function = it.function();
2078-
code = it.code();
2079-
ASSERT(function.ptr() == code.function());
2080-
uword pc = it.pc();
2081-
ASSERT(pc != 0);
2082-
ASSERT(code.PayloadStart() <= pc);
2083-
ASSERT(pc < (code.PayloadStart() + code.Size()));
2084-
2085-
ActivationFrame* activation = new ActivationFrame(
2086-
pc, fp, sp, function, code, deopt_frame, deopt_frame_offset);
2087-
stack_trace->AddActivation(activation);
2088-
}
2089-
} else {
2090-
ActivationFrame* activation = new ActivationFrame(
2091-
pc, fp, sp, function, code, deopt_frame, deopt_frame_offset);
2092-
stack_trace->AddActivation(activation);
2093-
}
2089+
uword pc = it.pc();
2090+
ASSERT(pc != 0);
2091+
ASSERT(code.PayloadStart() <= pc);
2092+
ASSERT(pc < (code.PayloadStart() + code.Size()));
2093+
2094+
auto* const activation = new ActivationFrame(
2095+
pc, fp, sp, function, code, deopt_frame, deopt_frame_offset);
2096+
stack_trace->AddActivation(activation);
20942097
}
20952098
}
2099+
auto* const activation = new ActivationFrame(
2100+
pc, fp, sp, function, code_object, deopt_frame, deopt_frame_offset);
2101+
stack_trace->AddActivation(activation);
20962102
}
20972103
return stack_trace;
20982104
}

runtime/vm/object.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6010,7 +6010,9 @@ void Class::set_user_name(const String& value) const {
60106010
#endif // !defined(PRODUCT)
60116011

60126012
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
6013-
void Class::SetUserVisibleNameInClassTable() {
6013+
void Class::SetUserVisibleNameInClassTable() const {
6014+
// Top level classes don't record a user visible name in the class table.
6015+
if (IsTopLevel()) return;
60146016
IsolateGroup* isolate_group = IsolateGroup::Current();
60156017
auto class_table = isolate_group->class_table();
60166018
if (class_table->UserVisibleNameFor(id()) == nullptr) {

runtime/vm/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2098,7 +2098,7 @@ class Class : public Object {
20982098
const Field& field) const;
20992099

21002100
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
2101-
void SetUserVisibleNameInClassTable();
2101+
void SetUserVisibleNameInClassTable() const;
21022102
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
21032103

21042104
private:

runtime/vm/service_test.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -454,11 +454,21 @@ ISOLATE_UNIT_TEST_CASE(Service_LocalVarDescriptors) {
454454
EXPECT(!class_a.IsNull());
455455
const Function& function_c = Function::Handle(GetFunction(class_a, "c"));
456456
EXPECT(!function_c.IsNull());
457-
const Code& code_c = Code::Handle(function_c.CurrentCode());
458-
EXPECT(!code_c.IsNull());
459-
460-
const LocalVarDescriptors& descriptors =
461-
LocalVarDescriptors::Handle(code_c.GetLocalVarDescriptors());
457+
LocalVarDescriptors& descriptors = LocalVarDescriptors::Handle();
458+
if (function_c.IsInterpreted()) {
459+
#if defined(DART_DYNAMIC_MODULES)
460+
const Bytecode& bytecode_c = Bytecode::Handle(function_c.GetBytecode());
461+
EXPECT(!bytecode_c.IsNull());
462+
descriptors = bytecode_c.var_descriptors();
463+
#else
464+
UNREACHABLE();
465+
#endif
466+
} else {
467+
const Code& code_c = Code::Handle(function_c.CurrentCode());
468+
EXPECT(!code_c.IsNull());
469+
descriptors = code_c.GetLocalVarDescriptors();
470+
}
471+
EXPECT(!descriptors.IsNull());
462472
// Generate an ID for this object.
463473
ServiceIdZone& default_id_zone = isolate->EnsureDefaultServiceIdZone();
464474
const char* id = default_id_zone.GetServiceId(descriptors);

0 commit comments

Comments
 (0)