// Copyright 2018 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. #include "src/heap/slot-set.h" namespace v8 { namespace internal { TypedSlots::~TypedSlots() { Chunk* chunk = head_; while (chunk != nullptr) { Chunk* next = chunk->next; delete chunk; chunk = next; } head_ = nullptr; tail_ = nullptr; } void TypedSlots::Insert(SlotType type, uint32_t offset) { TypedSlot slot = {TypeField::encode(type) | OffsetField::encode(offset)}; Chunk* chunk = EnsureChunk(); DCHECK_LT(chunk->buffer.size(), chunk->buffer.capacity()); chunk->buffer.push_back(slot); } void TypedSlots::Merge(TypedSlots* other) { if (other->head_ == nullptr) { return; } if (head_ == nullptr) { head_ = other->head_; tail_ = other->tail_; } else { tail_->next = other->head_; tail_ = other->tail_; } other->head_ = nullptr; other->tail_ = nullptr; } TypedSlots::Chunk* TypedSlots::EnsureChunk() { if (!head_) { head_ = tail_ = NewChunk(nullptr, kInitialBufferSize); } if (head_->buffer.size() == head_->buffer.capacity()) { head_ = NewChunk(head_, NextCapacity(head_->buffer.capacity())); } return head_; } TypedSlots::Chunk* TypedSlots::NewChunk(Chunk* next, size_t capacity) { Chunk* chunk = new Chunk; chunk->next = next; chunk->buffer.reserve(capacity); DCHECK_EQ(chunk->buffer.capacity(), capacity); return chunk; } void TypedSlotSet::ClearInvalidSlots( const std::map& invalid_ranges) { Chunk* chunk = LoadHead(); while (chunk != nullptr) { for (TypedSlot& slot : chunk->buffer) { SlotType type = TypeField::decode(slot.type_and_offset); if (type == CLEARED_SLOT) continue; uint32_t offset = OffsetField::decode(slot.type_and_offset); std::map::const_iterator upper_bound = invalid_ranges.upper_bound(offset); if (upper_bound == invalid_ranges.begin()) continue; // upper_bounds points to the invalid range after the given slot. Hence, // we have to go to the previous element. upper_bound--; DCHECK_LE(upper_bound->first, offset); if (upper_bound->second > offset) { slot = ClearedTypedSlot(); } } chunk = LoadNext(chunk); } } } // namespace internal } // namespace v8