// Copyright 2012 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/handles/local-handles.h" #include "src/api/api.h" #include "src/handles/handles.h" namespace v8 { namespace internal { LocalHandles::LocalHandles() { scope_.Initialize(); } LocalHandles::~LocalHandles() { scope_.limit = nullptr; RemoveUnusedBlocks(); DCHECK(blocks_.empty()); } void LocalHandles::Iterate(RootVisitor* visitor) { for (int i = 0; i < static_cast<int>(blocks_.size()) - 1; i++) { Address* block = blocks_[i]; visitor->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block), FullObjectSlot(&block[kHandleBlockSize])); } if (!blocks_.empty()) { Address* block = blocks_.back(); visitor->VisitRootPointers(Root::kHandleScope, nullptr, FullObjectSlot(block), FullObjectSlot(scope_.next)); } } #ifdef DEBUG bool LocalHandles::Contains(Address* location) { // We have to search in all blocks since they have no guarantee of order. for (auto it = blocks_.begin(); it != blocks_.end(); ++it) { Address* lower_bound = *it; // The last block is a special case because it may have less than // block_size_ handles. Address* upper_bound = lower_bound != blocks_.back() ? lower_bound + kHandleBlockSize : scope_.next; if (lower_bound <= location && location < upper_bound) { return true; } } return false; } #endif Address* LocalHandles::AddBlock() { DCHECK_EQ(scope_.next, scope_.limit); Address* block = NewArray<Address>(kHandleBlockSize); blocks_.push_back(block); scope_.next = block; scope_.limit = block + kHandleBlockSize; return block; } void LocalHandles::RemoveUnusedBlocks() { while (!blocks_.empty()) { Address* block_start = blocks_.back(); Address* block_limit = block_start + kHandleBlockSize; if (block_limit == scope_.limit) { break; } blocks_.pop_back(); #ifdef ENABLE_HANDLE_ZAPPING ZapRange(block_start, block_limit); #endif DeleteArray(block_start); } } #ifdef ENABLE_HANDLE_ZAPPING void LocalHandles::ZapRange(Address* start, Address* end) { HandleScope::ZapRange(start, end); } #endif } // namespace internal } // namespace v8