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
13 namespace v8 {
14 namespace internal {
15
GetMainThreadHandle(LocalHeap * local_heap,Address value)16 Address* LocalHandleScope::GetMainThreadHandle(LocalHeap* local_heap,
17 Address value) {
18 Isolate* isolate = local_heap->heap()->isolate();
19 return HandleScope::GetHandle(isolate, value);
20 }
21
OpenMainThreadScope(LocalHeap * local_heap)22 void 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
CloseMainThreadScope(LocalHeap * local_heap,Address * prev_next,Address * prev_limit)31 void 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
LocalHandles()38 LocalHandles::LocalHandles() { scope_.Initialize(); }
~LocalHandles()39 LocalHandles::~LocalHandles() {
40 scope_.limit = nullptr;
41 RemoveUnusedBlocks();
42 DCHECK(blocks_.empty());
43 }
44
Iterate(RootVisitor * visitor)45 void 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
Contains(Address * location)62 bool 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
AddBlock()79 Address* 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
RemoveUnusedBlocks()88 void 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
ZapRange(Address * start,Address * end)108 void LocalHandles::ZapRange(Address* start, Address* end) {
109 HandleScope::ZapRange(start, end);
110 }
111 #endif
112
113 } // namespace internal
114 } // namespace v8
115