[vm, gc] The GC cares about immediate-ness not Smi-ness.

TEST=ci
Change-Id: Ib7bae6df6becf0ed696a4c00257cedaf46f750aa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311148
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2023-06-27 19:47:04 +00:00 committed by Commit Queue
parent dc30f815f1
commit 4949f6185e
10 changed files with 56 additions and 51 deletions

View file

@ -358,7 +358,7 @@ class FinalizablePersistentHandle {
// Returns the space to charge for the external size.
Heap::Space SpaceForExternal() const {
// Non-heap and VM-heap objects count as old space here.
return ptr_->IsSmiOrOldObject() ? Heap::kOld : Heap::kNew;
return ptr_->IsImmediateOrOldObject() ? Heap::kOld : Heap::kNew;
}
ObjectPtr ptr_;

View file

@ -288,10 +288,10 @@ void Become::Forward() {
if (before == after) {
InvalidForwarding(before, after, "Cannot self-forward");
}
if (!before->IsHeapObject()) {
if (before->IsImmediateObject()) {
InvalidForwarding(before, after, "Cannot forward immediates");
}
if (!after->IsHeapObject()) {
if (after->IsImmediateObject()) {
InvalidForwarding(before, after, "Cannot target immediates");
}
if (before->untag()->InVMIsolateHeap()) {

View file

@ -642,7 +642,7 @@ void GCCompactor::SetupImagePageBoundaries() {
DART_FORCE_INLINE
void GCCompactor::ForwardPointer(ObjectPtr* ptr) {
ObjectPtr old_target = *ptr;
if (old_target->IsSmiOrNewObject()) {
if (old_target->IsImmediateOrNewObject()) {
return; // Not moved.
}
@ -670,7 +670,7 @@ void GCCompactor::ForwardPointer(ObjectPtr* ptr) {
ObjectPtr new_target =
UntaggedObject::FromAddr(forwarding_page->Lookup(old_addr));
ASSERT(!new_target->IsSmiOrNewObject());
ASSERT(!new_target->IsImmediateOrNewObject());
*ptr = new_target;
}
@ -678,7 +678,7 @@ DART_FORCE_INLINE
void GCCompactor::ForwardCompressedPointer(uword heap_base,
CompressedObjectPtr* ptr) {
ObjectPtr old_target = ptr->Decompress(heap_base);
if (old_target->IsSmiOrNewObject()) {
if (old_target->IsImmediateOrNewObject()) {
return; // Not moved.
}
@ -706,7 +706,7 @@ void GCCompactor::ForwardCompressedPointer(uword heap_base,
ObjectPtr new_target =
UntaggedObject::FromAddr(forwarding_page->Lookup(old_addr));
ASSERT(!new_target->IsSmiOrNewObject());
ASSERT(!new_target->IsImmediateOrNewObject());
*ptr = new_target;
}

View file

@ -38,8 +38,8 @@ void GCLinkedLists::FlushInto(GCLinkedLists* to) {
Heap::Space SpaceForExternal(FinalizerEntryPtr raw_entry) {
// As with WeakTables, Smis are "old".
return raw_entry->untag()->value()->IsSmiOrOldObject() ? Heap::kOld
: Heap::kNew;
return raw_entry->untag()->value()->IsImmediateOrOldObject() ? Heap::kOld
: Heap::kNew;
}
} // namespace dart

View file

@ -909,38 +909,36 @@ void Heap::ResetObjectIdTable() {
}
intptr_t Heap::GetWeakEntry(ObjectPtr raw_obj, WeakSelector sel) const {
if (!raw_obj->IsSmiOrOldObject()) {
if (raw_obj->IsImmediateOrOldObject()) {
return old_weak_tables_[sel]->GetValue(raw_obj);
} else {
return new_weak_tables_[sel]->GetValue(raw_obj);
}
ASSERT(raw_obj->IsSmiOrOldObject());
return old_weak_tables_[sel]->GetValue(raw_obj);
}
void Heap::SetWeakEntry(ObjectPtr raw_obj, WeakSelector sel, intptr_t val) {
if (!raw_obj->IsSmiOrOldObject()) {
new_weak_tables_[sel]->SetValue(raw_obj, val);
} else {
ASSERT(raw_obj->IsSmiOrOldObject());
if (raw_obj->IsImmediateOrOldObject()) {
old_weak_tables_[sel]->SetValue(raw_obj, val);
} else {
new_weak_tables_[sel]->SetValue(raw_obj, val);
}
}
intptr_t Heap::SetWeakEntryIfNonExistent(ObjectPtr raw_obj,
WeakSelector sel,
intptr_t val) {
if (!raw_obj->IsSmiOrOldObject()) {
return new_weak_tables_[sel]->SetValueIfNonExistent(raw_obj, val);
} else {
ASSERT(raw_obj->IsSmiOrOldObject());
if (raw_obj->IsImmediateOrOldObject()) {
return old_weak_tables_[sel]->SetValueIfNonExistent(raw_obj, val);
} else {
return new_weak_tables_[sel]->SetValueIfNonExistent(raw_obj, val);
}
}
void Heap::ForwardWeakEntries(ObjectPtr before_object, ObjectPtr after_object) {
const auto before_space =
!before_object->IsSmiOrOldObject() ? Heap::kNew : Heap::kOld;
before_object->IsImmediateOrOldObject() ? Heap::kOld : Heap::kNew;
const auto after_space =
!after_object->IsSmiOrOldObject() ? Heap::kNew : Heap::kOld;
after_object->IsImmediateOrOldObject() ? Heap::kOld : Heap::kNew;
for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) {
const auto selector = static_cast<Heap::WeakSelector>(sel);
@ -954,15 +952,15 @@ void Heap::ForwardWeakEntries(ObjectPtr before_object, ObjectPtr after_object) {
isolate_group()->ForEachIsolate(
[&](Isolate* isolate) {
auto before_table = !before_object->IsSmiOrOldObject()
? isolate->forward_table_new()
: isolate->forward_table_old();
auto before_table = before_object->IsImmediateOrOldObject()
? isolate->forward_table_old()
: isolate->forward_table_new();
if (before_table != nullptr) {
intptr_t entry = before_table->RemoveValueExclusive(before_object);
if (entry != 0) {
auto after_table = !after_object->IsSmiOrOldObject()
? isolate->forward_table_new()
: isolate->forward_table_old();
auto after_table = after_object->IsImmediateOrOldObject()
? isolate->forward_table_old()
: isolate->forward_table_new();
ASSERT(after_table != nullptr);
after_table->SetValueExclusive(after_object, entry);
}

View file

@ -62,9 +62,10 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
ObjectPtr raw_key = cur_weak->untag()->key();
// Reset the next pointer in the weak property.
cur_weak->untag()->next_seen_by_gc_ = WeakProperty::null();
if (raw_key->IsSmiOrNewObject() || raw_key->untag()->IsMarked()) {
if (raw_key->IsImmediateOrNewObject() || raw_key->untag()->IsMarked()) {
ObjectPtr raw_val = cur_weak->untag()->value();
if (!raw_val->IsSmiOrNewObject() && !raw_val->untag()->IsMarked()) {
if (!raw_val->IsImmediateOrNewObject() &&
!raw_val->untag()->IsMarked()) {
more_to_mark = true;
}
@ -325,7 +326,7 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
static bool ForwardOrSetNullIfCollected(uword heap_base,
CompressedObjectPtr* ptr_address) {
ObjectPtr raw = ptr_address->Decompress(heap_base);
if (raw->IsSmiOrNewObject()) {
if (raw->IsImmediateOrNewObject()) {
// Object not touched during this GC.
return false;
}
@ -394,7 +395,7 @@ class MarkingVisitorBase : public ObjectPointerVisitor {
void MarkObject(ObjectPtr raw_obj) {
// Fast exit if the raw object is immediate or in new space. No memory
// access.
if (raw_obj->IsSmiOrNewObject()) {
if (raw_obj->IsImmediateOrNewObject()) {
return;
}
@ -447,7 +448,7 @@ typedef MarkingVisitorBase<false> UnsyncMarkingVisitor;
typedef MarkingVisitorBase<true> SyncMarkingVisitor;
static bool IsUnreachable(const ObjectPtr raw_obj) {
if (raw_obj->IsSmiOrNewObject()) {
if (raw_obj->IsImmediateOrNewObject()) {
return false;
}
return !raw_obj->untag()->IsMarked();

View file

@ -352,7 +352,7 @@ class ScavengerVisitorBase : public ObjectPointerVisitor {
// ScavengePointer cannot be called recursively.
ObjectPtr raw_obj = *p;
if (raw_obj->IsSmiOrOldObject()) {
if (raw_obj->IsImmediateOrOldObject()) {
return;
}
@ -382,7 +382,8 @@ class ScavengerVisitorBase : public ObjectPointerVisitor {
// ScavengePointer cannot be called recursively.
ObjectPtr raw_obj = p->Decompress(heap_base);
if (raw_obj->IsSmiOrOldObject()) { // Could be tested without decompression
// Could be tested without decompression.
if (raw_obj->IsImmediateOrOldObject()) {
return;
}
@ -583,7 +584,7 @@ typedef ScavengerVisitorBase<true> ParallelScavengerVisitor;
static bool IsUnreachable(ObjectPtr* ptr) {
ObjectPtr raw_obj = *ptr;
if (raw_obj->IsSmiOrOldObject()) {
if (raw_obj->IsImmediateOrOldObject()) {
return false;
}
uword raw_addr = UntaggedObject::ToAddr(raw_obj);
@ -1349,7 +1350,7 @@ intptr_t ScavengerVisitorBase<parallel>::ProcessCopied(ObjectPtr raw_obj) {
WeakPropertyPtr raw_weak = static_cast<WeakPropertyPtr>(raw_obj);
// The fate of the weak property is determined by its key.
ObjectPtr raw_key = raw_weak->untag()->key();
if (!raw_key->IsSmiOrOldObject()) {
if (!raw_key->IsImmediateOrOldObject()) {
uword header = ReadHeaderRelaxed(raw_key);
if (!IsForwarding(header)) {
// Key is white. Enqueue the weak property.
@ -1363,7 +1364,7 @@ intptr_t ScavengerVisitorBase<parallel>::ProcessCopied(ObjectPtr raw_obj) {
WeakReferencePtr raw_weak = static_cast<WeakReferencePtr>(raw_obj);
// The fate of the weak reference target is determined by its target.
ObjectPtr raw_target = raw_weak->untag()->target();
if (!raw_target->IsSmiOrOldObject()) {
if (!raw_target->IsImmediateOrOldObject()) {
uword header = ReadHeaderRelaxed(raw_target);
if (!IsForwarding(header)) {
// Target is white. Enqueue the weak reference. Always visit type
@ -1579,7 +1580,7 @@ bool ScavengerVisitorBase<parallel>::ForwardOrSetNullIfCollected(
uword heap_base,
CompressedObjectPtr* ptr_address) {
ObjectPtr raw = ptr_address->Decompress(heap_base);
if (raw->IsSmiOrOldObject()) {
if (raw->IsImmediateOrOldObject()) {
// Object already null (which is old) or not touched during this GC.
return false;
}

View file

@ -209,10 +209,10 @@ class MessageSerializer : public BaseSerializer {
bool MarkObjectId(ObjectPtr object, intptr_t id) {
ASSERT(id != WeakTable::kNoValue);
WeakTable* table;
if (!object->IsSmiOrOldObject()) {
table = isolate()->forward_table_new();
} else {
if (object->IsImmediateOrOldObject()) {
table = isolate()->forward_table_old();
} else {
table = isolate()->forward_table_new();
}
return table->MarkValueExclusive(object, id);
}
@ -220,20 +220,20 @@ class MessageSerializer : public BaseSerializer {
void SetObjectId(ObjectPtr object, intptr_t id) {
ASSERT(id != WeakTable::kNoValue);
WeakTable* table;
if (!object->IsSmiOrOldObject()) {
table = isolate()->forward_table_new();
} else {
if (object->IsImmediateOrOldObject()) {
table = isolate()->forward_table_old();
} else {
table = isolate()->forward_table_new();
}
table->SetValueExclusive(object, id);
}
intptr_t GetObjectId(ObjectPtr object) const {
const WeakTable* table;
if (!object->IsSmiOrOldObject()) {
table = isolate()->forward_table_new();
} else {
if (object->IsImmediateOrOldObject()) {
table = isolate()->forward_table_old();
} else {
table = isolate()->forward_table_new();
}
return table->GetValueExclusive(object);
}

View file

@ -29,6 +29,11 @@ class UntaggedObject;
return (value & kSmiTagMask) == 0 || \
Utils::IsAligned(value - kHeapObjectTag, kWordSize); \
} \
bool IsImmediateObject() const { \
ASSERT(IsWellFormed()); \
const uword value = ptr; \
return (value & kSmiTagMask) != kHeapObjectTag; \
} \
bool IsHeapObject() const { \
ASSERT(IsWellFormed()); \
const uword value = ptr; \
@ -53,7 +58,7 @@ class UntaggedObject;
} \
\
/* Like !IsHeapObject() || IsOldObject() but compiles to a single branch. */ \
bool IsSmiOrOldObject() const { \
bool IsImmediateOrOldObject() const { \
ASSERT(IsWellFormed()); \
const uword kNewObjectBits = (kNewObjectAlignmentOffset | kHeapObjectTag); \
const uword addr = ptr; \
@ -61,7 +66,7 @@ class UntaggedObject;
} \
\
/* Like !IsHeapObject() || IsNewObject() but compiles to a single branch. */ \
bool IsSmiOrNewObject() const { \
bool IsImmediateOrNewObject() const { \
ASSERT(IsWellFormed()); \
const uword kOldObjectBits = (kOldObjectAlignmentOffset | kHeapObjectTag); \
const uword addr = ptr; \

View file

@ -935,7 +935,7 @@ class RestoreWriteBarrierInvariantVisitor : public ObjectPointerVisitor {
for (; first != last + 1; first++) {
ObjectPtr obj = *first;
// Stores into new-space objects don't need a write barrier.
if (obj->IsSmiOrNewObject()) continue;
if (obj->IsImmediateOrNewObject()) continue;
// To avoid adding too much work into the remembered set, skip large
// arrays. Write barrier elimination will not remove the barrier