mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:00:09 +00:00
[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:
parent
dc30f815f1
commit
4949f6185e
|
@ -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_;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue