11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/heap/slot-set.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/base/logging.h" 81cb0ef41Sopenharmony_ci#include "src/heap/memory-chunk-layout.h" 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cinamespace v8 { 111cb0ef41Sopenharmony_cinamespace internal { 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciTypedSlots::~TypedSlots() { 141cb0ef41Sopenharmony_ci Chunk* chunk = head_; 151cb0ef41Sopenharmony_ci while (chunk != nullptr) { 161cb0ef41Sopenharmony_ci Chunk* next = chunk->next; 171cb0ef41Sopenharmony_ci delete chunk; 181cb0ef41Sopenharmony_ci chunk = next; 191cb0ef41Sopenharmony_ci } 201cb0ef41Sopenharmony_ci head_ = nullptr; 211cb0ef41Sopenharmony_ci tail_ = nullptr; 221cb0ef41Sopenharmony_ci} 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_civoid TypedSlots::Insert(SlotType type, uint32_t offset) { 251cb0ef41Sopenharmony_ci TypedSlot slot = {TypeField::encode(type) | OffsetField::encode(offset)}; 261cb0ef41Sopenharmony_ci Chunk* chunk = EnsureChunk(); 271cb0ef41Sopenharmony_ci DCHECK_LT(chunk->buffer.size(), chunk->buffer.capacity()); 281cb0ef41Sopenharmony_ci chunk->buffer.push_back(slot); 291cb0ef41Sopenharmony_ci} 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_civoid TypedSlots::Merge(TypedSlots* other) { 321cb0ef41Sopenharmony_ci if (other->head_ == nullptr) { 331cb0ef41Sopenharmony_ci return; 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci if (head_ == nullptr) { 361cb0ef41Sopenharmony_ci head_ = other->head_; 371cb0ef41Sopenharmony_ci tail_ = other->tail_; 381cb0ef41Sopenharmony_ci } else { 391cb0ef41Sopenharmony_ci tail_->next = other->head_; 401cb0ef41Sopenharmony_ci tail_ = other->tail_; 411cb0ef41Sopenharmony_ci } 421cb0ef41Sopenharmony_ci other->head_ = nullptr; 431cb0ef41Sopenharmony_ci other->tail_ = nullptr; 441cb0ef41Sopenharmony_ci} 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ciTypedSlots::Chunk* TypedSlots::EnsureChunk() { 471cb0ef41Sopenharmony_ci if (!head_) { 481cb0ef41Sopenharmony_ci head_ = tail_ = NewChunk(nullptr, kInitialBufferSize); 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci if (head_->buffer.size() == head_->buffer.capacity()) { 511cb0ef41Sopenharmony_ci head_ = NewChunk(head_, NextCapacity(head_->buffer.capacity())); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci return head_; 541cb0ef41Sopenharmony_ci} 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ciTypedSlots::Chunk* TypedSlots::NewChunk(Chunk* next, size_t capacity) { 571cb0ef41Sopenharmony_ci Chunk* chunk = new Chunk; 581cb0ef41Sopenharmony_ci chunk->next = next; 591cb0ef41Sopenharmony_ci chunk->buffer.reserve(capacity); 601cb0ef41Sopenharmony_ci DCHECK_EQ(chunk->buffer.capacity(), capacity); 611cb0ef41Sopenharmony_ci return chunk; 621cb0ef41Sopenharmony_ci} 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_civoid TypedSlotSet::ClearInvalidSlots(const FreeRangesMap& invalid_ranges) { 651cb0ef41Sopenharmony_ci IterateSlotsInRanges([](TypedSlot* slot) { *slot = ClearedTypedSlot(); }, 661cb0ef41Sopenharmony_ci invalid_ranges); 671cb0ef41Sopenharmony_ci} 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_civoid TypedSlotSet::AssertNoInvalidSlots(const FreeRangesMap& invalid_ranges) { 701cb0ef41Sopenharmony_ci IterateSlotsInRanges( 711cb0ef41Sopenharmony_ci [](TypedSlot* slot) { 721cb0ef41Sopenharmony_ci CHECK_WITH_MSG(false, "No slot in ranges expected."); 731cb0ef41Sopenharmony_ci }, 741cb0ef41Sopenharmony_ci invalid_ranges); 751cb0ef41Sopenharmony_ci} 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_citemplate <typename Callback> 781cb0ef41Sopenharmony_civoid TypedSlotSet::IterateSlotsInRanges(Callback callback, 791cb0ef41Sopenharmony_ci const FreeRangesMap& ranges) { 801cb0ef41Sopenharmony_ci if (ranges.empty()) return; 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci Chunk* chunk = LoadHead(); 831cb0ef41Sopenharmony_ci while (chunk != nullptr) { 841cb0ef41Sopenharmony_ci for (TypedSlot& slot : chunk->buffer) { 851cb0ef41Sopenharmony_ci SlotType type = TypeField::decode(slot.type_and_offset); 861cb0ef41Sopenharmony_ci if (type == SlotType::kCleared) continue; 871cb0ef41Sopenharmony_ci uint32_t offset = OffsetField::decode(slot.type_and_offset); 881cb0ef41Sopenharmony_ci FreeRangesMap::const_iterator upper_bound = ranges.upper_bound(offset); 891cb0ef41Sopenharmony_ci if (upper_bound == ranges.begin()) continue; 901cb0ef41Sopenharmony_ci // upper_bounds points to the invalid range after the given slot. Hence, 911cb0ef41Sopenharmony_ci // we have to go to the previous element. 921cb0ef41Sopenharmony_ci upper_bound--; 931cb0ef41Sopenharmony_ci DCHECK_LE(upper_bound->first, offset); 941cb0ef41Sopenharmony_ci if (upper_bound->second > offset) { 951cb0ef41Sopenharmony_ci callback(&slot); 961cb0ef41Sopenharmony_ci } 971cb0ef41Sopenharmony_ci } 981cb0ef41Sopenharmony_ci chunk = LoadNext(chunk); 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci} 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci} // namespace internal 1031cb0ef41Sopenharmony_ci} // namespace v8 104