1// Copyright 2012 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/handles/local-handles.h" 6 7#include "src/api/api.h" 8#include "src/execution/isolate.h" 9#include "src/handles/handles-inl.h" 10#include "src/handles/handles.h" 11#include "src/heap/heap-inl.h" 12 13namespace v8 { 14namespace internal { 15 16Address* LocalHandleScope::GetMainThreadHandle(LocalHeap* local_heap, 17 Address value) { 18 Isolate* isolate = local_heap->heap()->isolate(); 19 return HandleScope::GetHandle(isolate, value); 20} 21 22void LocalHandleScope::OpenMainThreadScope(LocalHeap* local_heap) { 23 Isolate* isolate = local_heap->heap()->isolate(); 24 HandleScopeData* data = isolate->handle_scope_data(); 25 local_heap_ = local_heap; 26 prev_next_ = data->next; 27 prev_limit_ = data->limit; 28 data->level++; 29} 30 31void LocalHandleScope::CloseMainThreadScope(LocalHeap* local_heap, 32 Address* prev_next, 33 Address* prev_limit) { 34 Isolate* isolate = local_heap->heap()->isolate(); 35 HandleScope::CloseScope(isolate, prev_next, prev_limit); 36} 37 38LocalHandles::LocalHandles() { scope_.Initialize(); } 39LocalHandles::~LocalHandles() { 40 scope_.limit = nullptr; 41 RemoveUnusedBlocks(); 42 DCHECK(blocks_.empty()); 43} 44 45void LocalHandles::Iterate(RootVisitor* visitor) { 46 for (int i = 0; i < static_cast<int>(blocks_.size()) - 1; i++) { 47 Address* block = blocks_[i]; 48 visitor->VisitRootPointers(Root::kHandleScope, nullptr, 49 FullObjectSlot(block), 50 FullObjectSlot(&block[kHandleBlockSize])); 51 } 52 53 if (!blocks_.empty()) { 54 Address* block = blocks_.back(); 55 visitor->VisitRootPointers(Root::kHandleScope, nullptr, 56 FullObjectSlot(block), 57 FullObjectSlot(scope_.next)); 58 } 59} 60 61#ifdef DEBUG 62bool LocalHandles::Contains(Address* location) { 63 // We have to search in all blocks since they have no guarantee of order. 64 for (auto it = blocks_.begin(); it != blocks_.end(); ++it) { 65 Address* lower_bound = *it; 66 // The last block is a special case because it may have less than 67 // block_size_ handles. 68 Address* upper_bound = lower_bound != blocks_.back() 69 ? lower_bound + kHandleBlockSize 70 : scope_.next; 71 if (lower_bound <= location && location < upper_bound) { 72 return true; 73 } 74 } 75 return false; 76} 77#endif 78 79Address* LocalHandles::AddBlock() { 80 DCHECK_EQ(scope_.next, scope_.limit); 81 Address* block = NewArray<Address>(kHandleBlockSize); 82 blocks_.push_back(block); 83 scope_.next = block; 84 scope_.limit = block + kHandleBlockSize; 85 return block; 86} 87 88void LocalHandles::RemoveUnusedBlocks() { 89 while (!blocks_.empty()) { 90 Address* block_start = blocks_.back(); 91 Address* block_limit = block_start + kHandleBlockSize; 92 93 if (block_limit == scope_.limit) { 94 break; 95 } 96 97 blocks_.pop_back(); 98 99#ifdef ENABLE_HANDLE_ZAPPING 100 ZapRange(block_start, block_limit); 101#endif 102 103 DeleteArray(block_start); 104 } 105} 106 107#ifdef ENABLE_HANDLE_ZAPPING 108void LocalHandles::ZapRange(Address* start, Address* end) { 109 HandleScope::ZapRange(start, end); 110} 111#endif 112 113} // namespace internal 114} // namespace v8 115