Files
sdk/runtime/vm/heap/weak_code.cc
T
Alexander Aprelev acc4ee0b1e Reapply "[vm/shared] Ensure to iterate over mutators, rather than only isolates during deopt."
This reverts commit ce9c2d3dd1 and as patchset 2 applies the fix to crash revealed on mac bots.

TEST=isolate_group_bound_lazy_deopt_test

Change-Id: I8aa05a482954dfbd4599d68637287f8b93716ce2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448641
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2025-09-05 12:13:14 -07:00

137 lines
4.0 KiB
C++

// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/heap/weak_code.h"
#include "platform/assert.h"
#include "vm/code_patcher.h"
#include "vm/hash_table.h"
#include "vm/object.h"
#include "vm/runtime_entry.h"
#include "vm/stack_frame.h"
#include "vm/thread_registry.h"
namespace dart {
class CodeTraits {
public:
static const char* Name() { return "CodeTraits"; }
static bool ReportStats() { return false; }
static bool IsMatch(const Object& a, const Object& b) {
return a.ptr() == b.ptr();
}
static uword Hash(const Object& key) { return Code::Cast(key).Hash(); }
};
typedef UnorderedHashSet<CodeTraits, WeakArrayStorageTraits> WeakCodeSet;
bool WeakCodeReferences::HasCodes() const {
return !array_.IsNull() && (array_.Length() > 0);
}
void WeakCodeReferences::Register(const Code& value) {
WeakCodeSet set(array_.IsNull() ? HashTables::New<WeakCodeSet>(4, Heap::kOld)
: array_.ptr());
set.Insert(value);
UpdateArrayTo(set.Release());
}
void WeakCodeReferences::DisableCode(bool are_mutators_stopped) {
#if defined(DART_PRECOMPILED_RUNTIME)
ASSERT(array_.IsNull());
return;
#else
// Ensure mutators see empty code_objects only after code was deoptimized.
DEBUG_ASSERT(
IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
if (array_.IsNull()) {
return;
}
WeakCodeSet set(array_.ptr());
auto isolate_group = IsolateGroup::Current();
auto disable_code_fun = [&]() {
Code& code = Code::Handle();
isolate_group->ForEachMutatorAtASafepoint([&](Thread* thread) {
DartFrameIterator iterator(
thread, StackFrameIterator::kAllowCrossThreadIteration);
StackFrame* frame = iterator.NextFrame();
while (frame != nullptr) {
if (!frame->is_interpreted()) {
code = frame->LookupDartCode();
if (set.ContainsKey(code)) {
ReportDeoptimization(code);
DeoptimizeAt(thread, code, frame);
}
}
frame = iterator.NextFrame();
}
});
// Switch functions that use dependent code to unoptimized code.
Object& owner = Object::Handle();
Function& function = Function::Handle();
WeakCodeSet::Iterator it(&set);
while (it.MoveNext()) {
code ^= set.GetKey(it.Current());
if (code.IsNull()) {
// Code was garbage collected already.
continue;
}
owner = code.owner();
if (owner.IsFunction()) {
function ^= owner.ptr();
} else if (owner.IsClass()) {
Class& cls = Class::Handle();
cls ^= owner.ptr();
cls.DisableAllocationStub();
continue;
} else if (owner.IsNull()) {
code.Print();
continue;
}
// Only optimized code can make dependencies (assumptions) about CHA /
// field guards and might need to be deoptimized if those assumptions no
// longer hold.
// See similar assertions when code gets registered in
// `Field::RegisterDependentCode` and `Class::RegisterCHACode`.
ASSERT(code.is_optimized());
ASSERT(function.unoptimized_code() != code.ptr());
// If function uses dependent code switch it to unoptimized.
if (function.CurrentCode() == code.ptr()) {
ReportSwitchingCode(code);
function.SwitchToUnoptimizedCode();
} else {
// Make non-OSR code non-entrant.
if (!code.IsDisabled()) {
ReportSwitchingCode(code);
code.DisableDartCode();
}
}
}
UpdateArrayTo(WeakArray::Handle());
};
// Deoptimize stacks and disable code (with mutators stopped if they are not
// stopped yet).
if (are_mutators_stopped) {
disable_code_fun();
} else {
isolate_group->RunWithStoppedMutators(disable_code_fun);
}
set.Release();
#endif // defined(DART_PRECOMPILED_RUNTIME)
}
} // namespace dart