mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[vm/concurrency] Avoid relying on Isolate::Current() when deoptimizing code.
The background compiler can cause finalization of classes which can cause deoptimization of code. Any deoptimization will iterate over all mutator threads and marks frames on the stack to be deoptimized. This requires saving old (fp, pc) state. This state is currently saved on the current isolate's pending deopt array (via `Thread::Current()->isolate()->AddPendingDeopt()`) instead of the isolate whose stack got walked. As part of making the compiler independent of `Isolate::Current()` we pass the isolate explicitly. Issue https://github.com/dart-lang/sdk/issues/36097 TEST=Refactoring of existing code. Change-Id: I9327f3b76981fc16c1879a873edf37df1cbdd8bf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182380 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Alexander Aprelev <aam@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
59aa375d22
commit
d604461fc5
|
@ -76,24 +76,20 @@ void WeakCodeReferences::DisableCode() {
|
|||
// Deoptimize stacks and disable code with mutators stopped.
|
||||
isolate_group->RunWithStoppedMutators([&]() {
|
||||
Code& code = Code::Handle();
|
||||
Thread* current = isolate_group->thread_registry()->active_list();
|
||||
while (current != NULL) {
|
||||
// Disable all code on stack.
|
||||
{
|
||||
DartFrameIterator iterator(
|
||||
current, StackFrameIterator::kAllowCrossThreadIteration);
|
||||
StackFrame* frame = iterator.NextFrame();
|
||||
while (frame != NULL) {
|
||||
code = frame->LookupDartCode();
|
||||
if (IsOptimizedCode(code_objects, code)) {
|
||||
ReportDeoptimization(code);
|
||||
DeoptimizeAt(code, frame);
|
||||
}
|
||||
frame = iterator.NextFrame();
|
||||
isolate_group->ForEachIsolate([&](Isolate* isolate) {
|
||||
DartFrameIterator iterator(
|
||||
isolate->mutator_thread(),
|
||||
StackFrameIterator::kAllowCrossThreadIteration);
|
||||
StackFrame* frame = iterator.NextFrame();
|
||||
while (frame != nullptr) {
|
||||
code = frame->LookupDartCode();
|
||||
if (IsOptimizedCode(code_objects, code)) {
|
||||
ReportDeoptimization(code);
|
||||
DeoptimizeAt(isolate, code, frame);
|
||||
}
|
||||
frame = iterator.NextFrame();
|
||||
}
|
||||
current = current->next();
|
||||
}
|
||||
});
|
||||
|
||||
// Switch functions that use dependent code to unoptimized code.
|
||||
WeakProperty& weak_property = WeakProperty::Handle();
|
||||
|
|
|
@ -2952,7 +2952,9 @@ const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason) {
|
|||
}
|
||||
}
|
||||
|
||||
void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
|
||||
void DeoptimizeAt(Isolate* isolate,
|
||||
const Code& optimized_code,
|
||||
StackFrame* frame) {
|
||||
ASSERT(optimized_code.is_optimized());
|
||||
|
||||
// Force-optimized code is optimized code which cannot deoptimize and doesn't
|
||||
|
@ -2993,7 +2995,7 @@ void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
|
|||
|
||||
// N.B.: Update the pending deopt table before updating the frame. The
|
||||
// profiler may attempt a stack walk in between.
|
||||
thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc);
|
||||
isolate->AddPendingDeopt(frame->fp(), deopt_pc);
|
||||
frame->MarkForLazyDeopt();
|
||||
|
||||
if (FLAG_trace_deoptimization) {
|
||||
|
@ -3011,22 +3013,21 @@ void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
|
|||
void DeoptimizeFunctionsOnStack() {
|
||||
auto isolate_group = IsolateGroup::Current();
|
||||
isolate_group->RunWithStoppedMutators([&]() {
|
||||
auto current = isolate_group->thread_registry()->active_list();
|
||||
Code& optimized_code = Code::Handle();
|
||||
while (current != nullptr) {
|
||||
isolate_group->ForEachIsolate([&](Isolate* isolate) {
|
||||
DartFrameIterator iterator(
|
||||
current, StackFrameIterator::kAllowCrossThreadIteration);
|
||||
isolate->mutator_thread(),
|
||||
StackFrameIterator::kAllowCrossThreadIteration);
|
||||
StackFrame* frame = iterator.NextFrame();
|
||||
while (frame != NULL) {
|
||||
while (frame != nullptr) {
|
||||
optimized_code = frame->LookupDartCode();
|
||||
if (optimized_code.is_optimized() &&
|
||||
!optimized_code.is_force_optimized()) {
|
||||
DeoptimizeAt(optimized_code, frame);
|
||||
DeoptimizeAt(isolate, optimized_code, frame);
|
||||
}
|
||||
frame = iterator.NextFrame();
|
||||
}
|
||||
current = current->next();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,9 @@ extern "C" LocalHandle* DLRT_AllocateHandle(ApiLocalScope* scope);
|
|||
|
||||
const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason);
|
||||
|
||||
void DeoptimizeAt(const Code& optimized_code, StackFrame* frame);
|
||||
void DeoptimizeAt(Isolate* isolate,
|
||||
const Code& optimized_code,
|
||||
StackFrame* frame);
|
||||
void DeoptimizeFunctionsOnStack();
|
||||
|
||||
double DartModulo(double a, double b);
|
||||
|
|
|
@ -58,8 +58,6 @@ class ThreadRegistry {
|
|||
friend class IsolateGroup;
|
||||
friend class SafepointHandler;
|
||||
friend class Scavenger;
|
||||
friend class WeakCodeReferences;
|
||||
friend void DeoptimizeFunctionsOnStack();
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadRegistry);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue