// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_HEAP_INVALIDATED_SLOTS_INL_H_ #define V8_HEAP_INVALIDATED_SLOTS_INL_H_ #include "src/heap/invalidated-slots.h" #include "src/heap/spaces.h" #include "src/objects/objects-inl.h" #include "src/utils/allocation.h" namespace v8 { namespace internal { bool InvalidatedSlotsFilter::IsValid(Address slot) { #ifdef DEBUG DCHECK_LT(slot, sentinel_); // Slots must come in non-decreasing order. DCHECK_LE(last_slot_, slot); last_slot_ = slot; #endif if (slot < invalidated_start_) { return true; } while (slot >= next_invalidated_start_) { NextInvalidatedObject(); } HeapObject invalidated_object = HeapObject::FromAddress(invalidated_start_); if (invalidated_size_ == 0) { DCHECK(MarkCompactCollector::IsMapOrForwardedMap(invalidated_object.map())); invalidated_size_ = invalidated_object.Size(); } int offset = static_cast(slot - invalidated_start_); // OLD_TO_OLD can have slots in map word unlike other remembered sets. DCHECK_GE(offset, 0); DCHECK_IMPLIES(remembered_set_type_ != OLD_TO_OLD, offset > 0); if (offset < invalidated_size_) return offset == 0 || invalidated_object.IsValidSlot(invalidated_object.map(), offset); NextInvalidatedObject(); return true; } void InvalidatedSlotsFilter::NextInvalidatedObject() { invalidated_start_ = next_invalidated_start_; invalidated_size_ = 0; if (iterator_ == iterator_end_) { next_invalidated_start_ = sentinel_; } else { next_invalidated_start_ = iterator_->address(); iterator_++; } } void InvalidatedSlotsCleanup::Free(Address free_start, Address free_end) { #ifdef DEBUG DCHECK_LT(free_start, free_end); // Free regions should come in increasing order and do not overlap DCHECK_LE(last_free_, free_start); last_free_ = free_start; #endif if (iterator_ == iterator_end_) return; // Ignore invalidated objects that start before free region while (invalidated_start_ < free_start) { ++iterator_; NextInvalidatedObject(); } // Remove all invalidated objects that start within // free region. while (invalidated_start_ < free_end) { iterator_ = invalidated_slots_->erase(iterator_); NextInvalidatedObject(); } } void InvalidatedSlotsCleanup::NextInvalidatedObject() { if (iterator_ != iterator_end_) { invalidated_start_ = iterator_->address(); } else { invalidated_start_ = sentinel_; } } } // namespace internal } // namespace v8 #endif // V8_HEAP_INVALIDATED_SLOTS_INL_H_