blob: fd6cb6346bab98a15008af19841376cd29c9b23a [file] [log] [blame]
// 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