[vm/concurrency] Ensure field unboxed->boxed deoptimization runs with stopped mutators.

In lightweight isolate mode if some isolate or background compiler decides
to deopt unboxed field, we need to bring to stop all other isolates
to prevent to-be-deoptimized code from running.

If isolates are not stopped they might continue running the code that
still assumes the field is unboxed(reusable mutable box), overwriting
(now immutable) boxed value.

Issue https://github.com/dart-lang/sdk/issues/36097

TEST=ci

Change-Id: I5d2492650b8aa00491a1bd6ba2a7fb4817460f14
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195662
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Alexander Aprelev
2021-04-19 16:03:18 +00:00
committed by commit-bot@chromium.org
parent 54fc28ec25
commit f3520ff11b
+10 -4
View File
@@ -10148,19 +10148,25 @@ const Object* Field::CloneForUnboxed(const Object& value) const {
}
void Field::DisableFieldUnboxing() const {
Thread* thread = Thread::Current();
ASSERT(!IsOriginal());
const Field& original = Field::Handle(Original());
if (!original.is_unboxing_candidate()) {
return;
}
auto thread = Thread::Current();
SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
if (!original.is_unboxing_candidate()) {
return;
}
original.set_is_unboxing_candidate(false);
set_is_unboxing_candidate(false);
original.DeoptimizeDependentCode();
// Ensures that to-be-disabled existing code won't continue running as we
// update field properties as it might write into now boxed field thinking
// it still holds unboxed(reusable box) value.
thread->isolate_group()->RunWithStoppedMutators([&]() {
original.set_is_unboxing_candidate(false);
set_is_unboxing_candidate(false);
original.DeoptimizeDependentCode();
});
}
intptr_t Field::guarded_cid() const {