[vm, gc] Don't enqueue pre-marked Instructions.
Change-Id: Ic9a3b5f83fc45e363162c0531d474a663d243c6c
Reviewed-on: https://dart-review.googlesource.com/c/92666
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 5dc41bb..c246f43 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -368,12 +368,6 @@
}
static bool TryAcquireMarkBit(RawObject* raw_obj) {
- // While it might seem this is redundant with TryAcquireMarkBit, we must
- // do this check first to avoid attempting an atomic::fetch_and on the
- // read-only vm-isolate or image pages, which can fault even if there is no
- // change in the value.
- if (raw_obj->IsMarked()) return false;
-
if (!sync) {
raw_obj->SetMarkBitUnsynchronized();
return true;
@@ -383,17 +377,28 @@
}
void MarkObject(RawObject* raw_obj) {
- // Fast exit if the raw object is a Smi.
+ // Fast exit if the raw object is immediate or in new space. No memory
+ // access.
if (raw_obj->IsSmiOrNewObject()) {
return;
}
+ // While it might seem this is redundant with TryAcquireMarkBit, we must
+ // do this check first to avoid attempting an atomic::fetch_and on the
+ // read-only vm-isolate or image pages, which can fault even if there is no
+ // change in the value.
+ // Doing this before checking for an Instructions object avoids
+ // unnecessary queueing of pre-marked objects.
+ if (raw_obj->IsMarked()) {
+ return;
+ }
+
intptr_t class_id = raw_obj->GetClassId();
ASSERT(class_id != kFreeListElement);
if (sync && UNLIKELY(class_id == kInstructionsCid)) {
- // If this is the concurrent marker, instruction pages may be
- // non-writable.
+ // If this is the concurrent marker, this object may be non-writable due
+ // to W^X (--write-protect-code).
deferred_work_list_.Push(raw_obj);
return;
}