mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 05:26:57 +00:00
[vm, gc] Interrupt to finalize concurrent marking.
STW marking is no longer O(new-space), so there's no longer a reason to delay finalizing marking hoping for a scavenge to make new-space mostly empty. TEST=ci Change-Id: Ie782e88852714d30e0c75aa9aecac62e56c434ce Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319880 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
da0b9aa8b3
commit
2d01bf3779
|
@ -613,6 +613,20 @@ void Heap::CheckConcurrentMarking(Thread* thread,
|
|||
}
|
||||
}
|
||||
|
||||
void Heap::CheckFinalizeMarking(Thread* thread) {
|
||||
ASSERT(!thread->force_growth());
|
||||
|
||||
PageSpace::Phase phase;
|
||||
{
|
||||
MonitorLocker ml(old_space_.tasks_lock());
|
||||
phase = old_space_.phase();
|
||||
}
|
||||
|
||||
if (phase == PageSpace::kAwaitingFinalization) {
|
||||
CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kFinalize);
|
||||
}
|
||||
}
|
||||
|
||||
void Heap::StartConcurrentMarking(Thread* thread, GCReason reason) {
|
||||
GcSafepointOperationScope safepoint_operation(thread);
|
||||
RecordBeforeGC(GCType::kStartConcurrentMark, reason);
|
||||
|
|
|
@ -115,6 +115,7 @@ class Heap {
|
|||
|
||||
void CheckCatchUp(Thread* thread);
|
||||
void CheckConcurrentMarking(Thread* thread, GCReason reason, intptr_t size);
|
||||
void CheckFinalizeMarking(Thread* thread);
|
||||
void StartConcurrentMarking(Thread* thread, GCReason reason);
|
||||
void WaitForMarkerTasks(Thread* thread);
|
||||
void WaitForSweeperTasks(Thread* thread);
|
||||
|
|
|
@ -920,6 +920,7 @@ class ConcurrentMarkTask : public ThreadPool::Task {
|
|||
ASSERT(page_space_->phase() == PageSpace::kMarking);
|
||||
if (page_space_->concurrent_marker_tasks() == 0) {
|
||||
page_space_->set_phase(PageSpace::kAwaitingFinalization);
|
||||
isolate_group_->ScheduleInterrupts(Thread::kVMInterrupt);
|
||||
}
|
||||
ml.NotifyAll();
|
||||
}
|
||||
|
|
|
@ -1886,6 +1886,13 @@ void IsolateGroup::SetupImagePage(const uint8_t* image_buffer,
|
|||
is_executable);
|
||||
}
|
||||
|
||||
void IsolateGroup::ScheduleInterrupts(uword interrupt_bits) {
|
||||
SafepointReadRwLocker ml(Thread::Current(), isolates_lock_.get());
|
||||
for (Isolate* isolate : isolates_) {
|
||||
isolate->ScheduleInterrupts(interrupt_bits);
|
||||
}
|
||||
}
|
||||
|
||||
void Isolate::ScheduleInterrupts(uword interrupt_bits) {
|
||||
// We take the threads lock here to ensure that the mutator thread does not
|
||||
// exit the isolate while we are trying to schedule interrupts on it.
|
||||
|
|
|
@ -335,6 +335,8 @@ class IsolateGroup : public IntrusiveDListEntry<IsolateGroup> {
|
|||
|
||||
void RunWithLockedGroup(std::function<void()> fun);
|
||||
|
||||
void ScheduleInterrupts(uword interrupt_bits);
|
||||
|
||||
ThreadRegistry* thread_registry() const { return thread_registry_.get(); }
|
||||
SafepointHandler* safepoint_handler() { return safepoint_handler_.get(); }
|
||||
|
||||
|
|
|
@ -3152,6 +3152,7 @@ DEFINE_RUNTIME_ENTRY(InterruptOrStackOverflow, 0) {
|
|||
// Handle interrupts:
|
||||
// - store buffer overflow
|
||||
// - OOB message (vm-service or dart:isolate)
|
||||
// - marking ready for finalization
|
||||
const Error& error = Error::Handle(thread->HandleInterrupts());
|
||||
ThrowIfError(error);
|
||||
|
||||
|
|
|
@ -741,6 +741,7 @@ ErrorPtr Thread::HandleInterrupts() {
|
|||
// occur that does promote them.
|
||||
heap()->CollectGarbage(this, GCType::kEvacuate, GCReason::kStoreBuffer);
|
||||
}
|
||||
heap()->CheckFinalizeMarking(this);
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
if (isolate()->TakeHasCompletedBlocks()) {
|
||||
|
|
Loading…
Reference in a new issue