[vm, gc] Check for pause requests when marking large arrays.

This was sometimes responsible for the largest GC pause in IsolateSendExitLatency, with a scavenge waiting for a concurrent marker to finish a whole array and pause.

TEST=ci
Change-Id: Ib2d8417ffe6cee3e8436a8c382d2db660e1eef41
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371180
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
This commit is contained in:
Ryan Macnak 2024-06-12 20:53:18 +00:00 committed by Commit Queue
parent 418858b725
commit 0713bce1fe
5 changed files with 18 additions and 8 deletions

View file

@ -225,11 +225,10 @@ static ObjectPtr ValidateMessageObject(Zone* zone,
case kArrayCid: {
array ^= Array::RawCast(raw);
visitor.VisitObject(array.GetTypeArguments());
const intptr_t batch_size = (2 << 14) - 1;
for (intptr_t i = 0; i < array.Length(); ++i) {
ObjectPtr ptr = array.At(i);
visitor.VisitObject(ptr);
if ((i & batch_size) == batch_size) {
if (((i + 1) % kSlotsPerInterruptCheck) == 0) {
thread->CheckForSafepoint();
}
}

View file

@ -213,6 +213,12 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
has_evacuation_candidate_ = false;
page->RememberCard(card_from);
}
if (((i + 1) % kCardsPerInterruptCheck) == 0) {
if (UNLIKELY(page_space_->pause_concurrent_marking())) {
YieldConcurrentMarking();
}
}
}
return obj->untag()->HeapSize();

View file

@ -172,6 +172,7 @@ class Page {
// 1 card = 32 slots.
static constexpr intptr_t kSlotsPerCardLog2 = 5;
static constexpr intptr_t kSlotsPerCard = 1 << kSlotsPerCardLog2;
static constexpr intptr_t kBytesPerCardLog2 =
kCompressedWordSizeLog2 + kSlotsPerCardLog2;
@ -355,6 +356,10 @@ class Page {
DISALLOW_IMPLICIT_CONSTRUCTORS(Page);
};
static constexpr intptr_t kSlotsPerInterruptCheck = KB;
static constexpr intptr_t kCardsPerInterruptCheck =
kSlotsPerInterruptCheck / Page::kSlotsPerCard;
} // namespace dart
#endif // RUNTIME_VM_HEAP_PAGE_H_

View file

@ -24778,7 +24778,7 @@ ArrayPtr Array::New(intptr_t class_id, intptr_t len, Heap::Space space) {
result.SetTypeArguments(Object::null_type_arguments());
for (intptr_t i = 0; i < len; i++) {
result.SetAt(i, Object::null_object(), thread);
if (((i + 1) % KB) == 0) {
if (((i + 1) % kSlotsPerInterruptCheck) == 0) {
thread->CheckForSafepoint();
}
}
@ -24804,7 +24804,7 @@ ArrayPtr Array::Slice(intptr_t start,
} else {
for (int i = 0; i < count; i++) {
dest.untag()->set_element(i, untag()->element(i + start), thread);
if (((i + 1) % KB) == 0) {
if (((i + 1) % kSlotsPerInterruptCheck) == 0) {
thread->CheckForSafepoint();
}
}
@ -24855,13 +24855,13 @@ ArrayPtr Array::Grow(const Array& source,
} else {
for (intptr_t i = 0; i < old_length; i++) {
result.untag()->set_element(i, source.untag()->element(i), thread);
if (((i + 1) % KB) == 0) {
if (((i + 1) % kSlotsPerInterruptCheck) == 0) {
thread->CheckForSafepoint();
}
}
for (intptr_t i = old_length; i < new_length; i++) {
result.untag()->set_element(i, Object::null(), thread);
if (((i + 1) % KB) == 0) {
if (((i + 1) % kSlotsPerInterruptCheck) == 0) {
thread->CheckForSafepoint();
}
}

View file

@ -497,7 +497,7 @@ class IdentityMap {
malloc(hash_table_capacity_ * sizeof(uint32_t)));
for (intptr_t i = 0; i < hash_table_capacity_; i++) {
hash_table_[i] = 0;
if (check_for_safepoint && (((i + 1) % KB) == 0)) {
if (check_for_safepoint && (((i + 1) % kSlotsPerInterruptCheck) == 0)) {
thread_->CheckForSafepoint();
}
}
@ -513,7 +513,7 @@ class IdentityMap {
}
probe = (probe + 1) & mask;
}
if (check_for_safepoint && (((id + 2) % KB) == 0)) {
if (check_for_safepoint && (((id + 2) % kSlotsPerInterruptCheck) == 0)) {
thread_->CheckForSafepoint();
}
}