Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b6dc4da

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/aot] Avoid using most Code objects in stack traces with --dwarf-stack-traces
The following changes are done in preparation for the removal of Code objects in AOT with --dwarf-stack-traces: * Stack trace objects are extended to hold uword PCs (which may not fit into Smi range). * Scanning stack frames in GC (StackFrame::VisitObjectPointers) now avoids using Code objects. In order to find CompressedStackMaps it now calls ReversePc::FindCompressedStackMaps. * Singleton Code object (StubCode::UnknownDartCode()) is prepared as a replacement for Code objects in stack traces. It has PayloadStart() == 0 and Size() == kUwordMax so it includes arbitrary PCs. * In --dwarf-stack-traces mode, most Code objects obtained from stack frames are replaced with StubCode::UnknownDartCode(). This simulates future behavior of ReversePc::Lookup when Code objects will be removed. Issue: dart-lang/sdk#44852 Change-Id: I7cec7b8b9396c9cfeca3c256a412ba4e82a7e0c4 TEST=ci Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182720 Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Tess Strickland <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent dfd52f6 commit b6dc4da

33 files changed

+343
-218
lines changed

runtime/lib/stacktrace.cc

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,35 @@ DECLARE_FLAG(bool, show_invisible_frames);
1818

1919
static const intptr_t kDefaultStackAllocation = 8;
2020

21+
static StackTracePtr CreateStackTraceObject(
22+
Zone* zone,
23+
const GrowableObjectArray& code_list,
24+
const GrowableArray<uword>& pc_offset_list) {
25+
const auto& code_array =
26+
Array::Handle(zone, Array::MakeFixedLength(code_list));
27+
const auto& pc_offset_array = TypedData::Handle(
28+
zone, TypedData::New(kUintPtrCid, pc_offset_list.length()));
29+
{
30+
NoSafepointScope no_safepoint;
31+
memmove(pc_offset_array.DataAddr(0), pc_offset_list.data(),
32+
pc_offset_list.length() * kWordSize);
33+
}
34+
return StackTrace::New(code_array, pc_offset_array);
35+
}
36+
2137
static StackTracePtr CurrentSyncStackTraceLazy(Thread* thread,
2238
intptr_t skip_frames = 1) {
2339
Zone* zone = thread->zone();
2440

2541
const auto& code_array = GrowableObjectArray::ZoneHandle(
2642
zone, GrowableObjectArray::New(kDefaultStackAllocation));
27-
const auto& pc_offset_array = GrowableObjectArray::ZoneHandle(
28-
zone, GrowableObjectArray::New(kDefaultStackAllocation));
43+
GrowableArray<uword> pc_offset_array;
2944

3045
// Collect the frames.
31-
StackTraceUtils::CollectFramesLazy(thread, code_array, pc_offset_array,
46+
StackTraceUtils::CollectFramesLazy(thread, code_array, &pc_offset_array,
3247
skip_frames);
3348

34-
const auto& code_array_fixed =
35-
Array::Handle(zone, Array::MakeFixedLength(code_array));
36-
const auto& pc_offset_array_fixed =
37-
Array::Handle(zone, Array::MakeFixedLength(pc_offset_array));
38-
39-
return StackTrace::New(code_array_fixed, pc_offset_array_fixed);
49+
return CreateStackTraceObject(zone, code_array, pc_offset_array);
4050
}
4151

4252
static StackTracePtr CurrentSyncStackTrace(Thread* thread,
@@ -51,8 +61,8 @@ static StackTracePtr CurrentSyncStackTrace(Thread* thread,
5161
// Allocate once.
5262
const Array& code_array =
5363
Array::ZoneHandle(zone, Array::New(stack_trace_length));
54-
const Array& pc_offset_array =
55-
Array::ZoneHandle(zone, Array::New(stack_trace_length));
64+
const TypedData& pc_offset_array = TypedData::ZoneHandle(
65+
zone, TypedData::New(kUintPtrCid, stack_trace_length));
5666

5767
// Collect the frames.
5868
const intptr_t collected_frames_count = StackTraceUtils::CollectFrames(
@@ -89,7 +99,7 @@ DEFINE_NATIVE_ENTRY(StackTrace_current, 0, 0) {
8999
}
90100

91101
static void AppendFrames(const GrowableObjectArray& code_list,
92-
const GrowableObjectArray& pc_offset_list,
102+
GrowableArray<uword>* pc_offset_list,
93103
int skip_frames) {
94104
Thread* thread = Thread::Current();
95105
Zone* zone = thread->zone();
@@ -98,7 +108,6 @@ static void AppendFrames(const GrowableObjectArray& code_list,
98108
StackFrame* frame = frames.NextFrame();
99109
ASSERT(frame != NULL); // We expect to find a dart invocation frame.
100110
Code& code = Code::Handle(zone);
101-
Smi& offset = Smi::Handle(zone);
102111
for (; frame != NULL; frame = frames.NextFrame()) {
103112
if (!frame->IsDartFrame()) {
104113
continue;
@@ -109,26 +118,24 @@ static void AppendFrames(const GrowableObjectArray& code_list,
109118
}
110119

111120
code = frame->LookupDartCode();
112-
offset = Smi::New(frame->pc() - code.PayloadStart());
121+
const intptr_t pc_offset = frame->pc() - code.PayloadStart();
113122
code_list.Add(code);
114-
pc_offset_list.Add(offset);
123+
pc_offset_list->Add(pc_offset);
115124
}
116125
}
117126

118127
// Creates a StackTrace object from the current stack.
119128
//
120129
// Skips the first skip_frames Dart frames.
121130
const StackTrace& GetCurrentStackTrace(int skip_frames) {
131+
Zone* zone = Thread::Current()->zone();
122132
const GrowableObjectArray& code_list =
123-
GrowableObjectArray::Handle(GrowableObjectArray::New());
124-
const GrowableObjectArray& pc_offset_list =
125-
GrowableObjectArray::Handle(GrowableObjectArray::New());
126-
AppendFrames(code_list, pc_offset_list, skip_frames);
127-
const Array& code_array = Array::Handle(Array::MakeFixedLength(code_list));
128-
const Array& pc_offset_array =
129-
Array::Handle(Array::MakeFixedLength(pc_offset_list));
130-
const StackTrace& stacktrace =
131-
StackTrace::Handle(StackTrace::New(code_array, pc_offset_array));
133+
GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
134+
GrowableArray<uword> pc_offset_list;
135+
AppendFrames(code_list, &pc_offset_list, skip_frames);
136+
137+
const StackTrace& stacktrace = StackTrace::Handle(
138+
zone, CreateStackTraceObject(zone, code_list, pc_offset_list));
132139
return stacktrace;
133140
}
134141

runtime/vm/code_patcher_arm.cc

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,8 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
9696
const Code& caller_code,
9797
const Object& data,
9898
const Code& target) {
99-
ASSERT(caller_code.ContainsInstructionAt(return_address));
10099
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
101-
BareSwitchableCallPattern call(return_address, caller_code);
100+
BareSwitchableCallPattern call(return_address);
102101
call.SetData(data);
103102
call.SetTarget(target);
104103
} else {
@@ -110,9 +109,8 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
110109

111110
uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
112111
const Code& caller_code) {
113-
ASSERT(caller_code.ContainsInstructionAt(return_address));
114112
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
115-
BareSwitchableCallPattern call(return_address, caller_code);
113+
BareSwitchableCallPattern call(return_address);
116114
return call.target_entry();
117115
} else {
118116
SwitchableCallPattern call(return_address, caller_code);
@@ -122,9 +120,8 @@ uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
122120

123121
ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
124122
const Code& caller_code) {
125-
ASSERT(caller_code.ContainsInstructionAt(return_address));
126123
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
127-
BareSwitchableCallPattern call(return_address, caller_code);
124+
BareSwitchableCallPattern call(return_address);
128125
return call.data();
129126
} else {
130127
SwitchableCallPattern call(return_address, caller_code);

runtime/vm/code_patcher_arm64.cc

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,8 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
132132
const Code& caller_code,
133133
const Object& data,
134134
const Code& target) {
135-
ASSERT(caller_code.ContainsInstructionAt(return_address));
136135
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
137-
BareSwitchableCallPattern call(return_address, caller_code);
136+
BareSwitchableCallPattern call(return_address);
138137
call.SetData(data);
139138
call.SetTarget(target);
140139
} else {
@@ -146,9 +145,8 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
146145

147146
uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
148147
const Code& caller_code) {
149-
ASSERT(caller_code.ContainsInstructionAt(return_address));
150148
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
151-
BareSwitchableCallPattern call(return_address, caller_code);
149+
BareSwitchableCallPattern call(return_address);
152150
return call.target_entry();
153151
} else {
154152
SwitchableCallPattern call(return_address, caller_code);
@@ -158,9 +156,8 @@ uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
158156

159157
ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
160158
const Code& caller_code) {
161-
ASSERT(caller_code.ContainsInstructionAt(return_address));
162159
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
163-
BareSwitchableCallPattern call(return_address, caller_code);
160+
BareSwitchableCallPattern call(return_address);
164161
return call.data();
165162
} else {
166163
SwitchableCallPattern call(return_address, caller_code);

runtime/vm/code_patcher_x64.cc

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,8 @@ class PoolPointerCall : public ValueObject {
220220
// call target.entry call stub.entry call stub.entry
221221
class SwitchableCallBase : public ValueObject {
222222
public:
223-
explicit SwitchableCallBase(const Code& code)
224-
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
225-
target_index_(-1),
226-
data_index_(-1) {}
223+
explicit SwitchableCallBase(const ObjectPool& object_pool)
224+
: object_pool_(object_pool), target_index_(-1), data_index_(-1) {}
227225

228226
intptr_t data_index() const { return data_index_; }
229227
intptr_t target_index() const { return target_index_; }
@@ -237,7 +235,7 @@ class SwitchableCallBase : public ValueObject {
237235
}
238236

239237
protected:
240-
ObjectPool& object_pool_;
238+
const ObjectPool& object_pool_;
241239
intptr_t target_index_;
242240
intptr_t data_index_;
243241

@@ -251,8 +249,9 @@ class SwitchableCallBase : public ValueObject {
251249
// monomorphic function or a stub code.
252250
class SwitchableCall : public SwitchableCallBase {
253251
public:
254-
SwitchableCall(uword return_address, const Code& code)
255-
: SwitchableCallBase(code) {
252+
SwitchableCall(uword return_address, const Code& caller_code)
253+
: SwitchableCallBase(ObjectPool::Handle(caller_code.GetObjectPool())) {
254+
ASSERT(caller_code.ContainsInstructionAt(return_address));
256255
uword pc = return_address;
257256

258257
// callq RCX
@@ -333,11 +332,9 @@ class SwitchableCall : public SwitchableCallBase {
333332
// of the monomorphic function or a stub entry point.
334333
class BareSwitchableCall : public SwitchableCallBase {
335334
public:
336-
BareSwitchableCall(uword return_address, const Code& code)
337-
: SwitchableCallBase(code) {
338-
object_pool_ = ObjectPool::RawCast(
339-
IsolateGroup::Current()->object_store()->global_object_pool());
340-
335+
explicit BareSwitchableCall(uword return_address)
336+
: SwitchableCallBase(ObjectPool::Handle(
337+
IsolateGroup::Current()->object_store()->global_object_pool())) {
341338
uword pc = return_address;
342339

343340
// callq RCX
@@ -489,9 +486,8 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
489486
const Code& caller_code,
490487
const Object& data,
491488
const Code& target) {
492-
ASSERT(caller_code.ContainsInstructionAt(return_address));
493489
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
494-
BareSwitchableCall call(return_address, caller_code);
490+
BareSwitchableCall call(return_address);
495491
call.SetData(data);
496492
call.SetTarget(target);
497493
} else {
@@ -503,9 +499,8 @@ void CodePatcher::PatchSwitchableCallAtWithMutatorsStopped(
503499

504500
uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
505501
const Code& caller_code) {
506-
ASSERT(caller_code.ContainsInstructionAt(return_address));
507502
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
508-
BareSwitchableCall call(return_address, caller_code);
503+
BareSwitchableCall call(return_address);
509504
return call.target_entry();
510505
} else {
511506
SwitchableCall call(return_address, caller_code);
@@ -515,9 +510,8 @@ uword CodePatcher::GetSwitchableCallTargetEntryAt(uword return_address,
515510

516511
ObjectPtr CodePatcher::GetSwitchableCallDataAt(uword return_address,
517512
const Code& caller_code) {
518-
ASSERT(caller_code.ContainsInstructionAt(return_address));
519513
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
520-
BareSwitchableCall call(return_address, caller_code);
514+
BareSwitchableCall call(return_address);
521515
return call.data();
522516
} else {
523517
SwitchableCall call(return_address, caller_code);

runtime/vm/compiler/assembler/disassembler.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,9 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
457457
void Disassembler::DisassembleCode(const Function& function,
458458
const Code& code,
459459
bool optimized) {
460+
if (code.IsUnknownDartCode()) {
461+
return;
462+
}
460463
TextBuffer buffer(128);
461464
const char* function_fullname = function.ToFullyQualifiedCString();
462465
buffer.Printf("%s", Function::KindToCString(function.kind()));

runtime/vm/compiler/stub_code_compiler.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,19 @@ void StubCodeCompiler::GenerateRangeErrorSharedWithFPURegsStub(
796796
GenerateRangeError(assembler, /*with_fpu_regs=*/true);
797797
}
798798

799+
void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
800+
Assembler* assembler) {
801+
__ Breakpoint(); // Marker stub.
802+
}
803+
804+
void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
805+
__ Breakpoint(); // Marker stub.
806+
}
807+
808+
void StubCodeCompiler::GenerateUnknownDartCodeStub(Assembler* assembler) {
809+
__ Breakpoint(); // Marker stub.
810+
}
811+
799812
} // namespace compiler
800813

801814
} // namespace dart

runtime/vm/compiler/stub_code_compiler_arm.cc

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3291,15 +3291,6 @@ void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
32913291
CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kMonomorphic)));
32923292
}
32933293

3294-
void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
3295-
Assembler* assembler) {
3296-
__ bkpt(0);
3297-
}
3298-
3299-
void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
3300-
__ bkpt(0);
3301-
}
3302-
33033294
void StubCodeCompiler::GenerateNotLoadedStub(Assembler* assembler) {
33043295
__ EnterStubFrame();
33053296
__ CallRuntime(kNotLoadedRuntimeEntry, 0);

runtime/vm/compiler/stub_code_compiler_arm64.cc

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3435,15 +3435,6 @@ void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
34353435
__ br(R1);
34363436
}
34373437

3438-
void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
3439-
Assembler* assembler) {
3440-
__ brk(0);
3441-
}
3442-
3443-
void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
3444-
__ brk(0);
3445-
}
3446-
34473438
void StubCodeCompiler::GenerateNotLoadedStub(Assembler* assembler) {
34483439
__ EnterStubFrame();
34493440
__ CallRuntime(kNotLoadedRuntimeEntry, 0);

runtime/vm/compiler/stub_code_compiler_ia32.cc

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2788,15 +2788,6 @@ void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
27882788
__ int3(); // AOT only.
27892789
}
27902790

2791-
void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
2792-
Assembler* assembler) {
2793-
__ int3(); // Marker stub.
2794-
}
2795-
2796-
void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
2797-
__ int3(); // Marker stub.
2798-
}
2799-
28002791
void StubCodeCompiler::GenerateNotLoadedStub(Assembler* assembler) {
28012792
__ EnterStubFrame();
28022793
__ CallRuntime(kNotLoadedRuntimeEntry, 0);

runtime/vm/compiler/stub_code_compiler_x64.cc

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3365,15 +3365,6 @@ void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
33653365
__ jmp(RCX);
33663366
}
33673367

3368-
void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
3369-
Assembler* assembler) {
3370-
__ int3();
3371-
}
3372-
3373-
void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
3374-
__ int3();
3375-
}
3376-
33773368
void StubCodeCompiler::GenerateNotLoadedStub(Assembler* assembler) {
33783369
__ EnterStubFrame();
33793370
__ CallRuntime(kNotLoadedRuntimeEntry, 0);

0 commit comments

Comments
 (0)