• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 #ifndef V8_HANDLES_LOCAL_HANDLES_INL_H_
6 #define V8_HANDLES_LOCAL_HANDLES_INL_H_
7 
8 #include "src/base/sanitizer/msan.h"
9 #include "src/execution/isolate.h"
10 #include "src/execution/local-isolate.h"
11 #include "src/handles/local-handles.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // static
GetHandle(LocalHeap * local_heap,Address value)17 V8_INLINE Address* LocalHandleScope::GetHandle(LocalHeap* local_heap,
18                                                Address value) {
19   DCHECK(local_heap->IsRunning());
20   if (local_heap->is_main_thread())
21     return LocalHandleScope::GetMainThreadHandle(local_heap, value);
22 
23   LocalHandles* handles = local_heap->handles();
24   Address* result = handles->scope_.next;
25   if (result == handles->scope_.limit) {
26     result = handles->AddBlock();
27   }
28   DCHECK_LT(result, handles->scope_.limit);
29   handles->scope_.next++;
30   *result = value;
31   return result;
32 }
33 
LocalHandleScope(LocalIsolate * local_isolate)34 LocalHandleScope::LocalHandleScope(LocalIsolate* local_isolate)
35     : LocalHandleScope(local_isolate->heap()) {}
36 
LocalHandleScope(LocalHeap * local_heap)37 LocalHandleScope::LocalHandleScope(LocalHeap* local_heap) {
38   DCHECK(local_heap->IsRunning());
39 
40   if (local_heap->is_main_thread()) {
41     OpenMainThreadScope(local_heap);
42   } else {
43     LocalHandles* handles = local_heap->handles();
44     local_heap_ = local_heap;
45     prev_next_ = handles->scope_.next;
46     prev_limit_ = handles->scope_.limit;
47     handles->scope_.level++;
48   }
49 }
50 
~LocalHandleScope()51 LocalHandleScope::~LocalHandleScope() {
52   if (local_heap_->is_main_thread()) {
53     CloseMainThreadScope(local_heap_, prev_next_, prev_limit_);
54   } else {
55     CloseScope(local_heap_, prev_next_, prev_limit_);
56   }
57 }
58 
59 template <typename T>
CloseAndEscape(Handle<T> handle_value)60 Handle<T> LocalHandleScope::CloseAndEscape(Handle<T> handle_value) {
61   HandleScopeData* current;
62   T value = *handle_value;
63   // Throw away all handles in the current scope.
64   if (local_heap_->is_main_thread()) {
65     current = local_heap_->heap()->isolate()->handle_scope_data();
66     CloseMainThreadScope(local_heap_, prev_next_, prev_limit_);
67   } else {
68     current = &local_heap_->handles()->scope_;
69     CloseScope(local_heap_, prev_next_, prev_limit_);
70   }
71   // Allocate one handle in the parent scope.
72   DCHECK(current->level > current->sealed_level);
73   Handle<T> result(value, local_heap_);
74   // Reinitialize the current scope (so that it's ready
75   // to be used or closed again).
76   prev_next_ = current->next;
77   prev_limit_ = current->limit;
78   current->level++;
79   return result;
80 }
81 
CloseScope(LocalHeap * local_heap,Address * prev_next,Address * prev_limit)82 void LocalHandleScope::CloseScope(LocalHeap* local_heap, Address* prev_next,
83                                   Address* prev_limit) {
84   LocalHandles* handles = local_heap->handles();
85   Address* old_limit = handles->scope_.limit;
86 
87   handles->scope_.next = prev_next;
88   handles->scope_.limit = prev_limit;
89   handles->scope_.level--;
90 
91   if (old_limit != handles->scope_.limit) {
92     handles->RemoveUnusedBlocks();
93     old_limit = handles->scope_.limit;
94   }
95 
96 #ifdef ENABLE_HANDLE_ZAPPING
97   LocalHandles::ZapRange(handles->scope_.next, old_limit);
98 #endif
99 
100   MSAN_ALLOCATED_UNINITIALIZED_MEMORY(
101       handles->scope_.next,
102       static_cast<size_t>(reinterpret_cast<Address>(old_limit) -
103                           reinterpret_cast<Address>(handles->scope_.next)));
104 }
105 
106 }  // namespace internal
107 }  // namespace v8
108 
109 #endif  // V8_HANDLES_LOCAL_HANDLES_INL_H_
110