• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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