V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
handles-inl.h
1 // Copyright 2006-2008 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_INL_H_
6 #define V8_HANDLES_INL_H_
7 
8 #include "src/handles.h"
9 #include "src/isolate.h"
10 #include "src/msan.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 HandleBase::HandleBase(Address object, Isolate* isolate)
16  : location_(HandleScope::GetHandle(isolate, object)) {}
17 
18 // Allocate a new handle for the object, do not canonicalize.
19 template <typename T>
20 template <typename T1, typename>
21 Handle<T> Handle<T>::New(T* object, Isolate* isolate) {
22  return Handle(reinterpret_cast<T**>(
23  HandleScope::CreateHandle(isolate, reinterpret_cast<Address>(object))));
24 }
25 template <typename T>
26 template <typename T1, typename>
27 Handle<T> Handle<T>::New(T object, Isolate* isolate) {
28  return Handle(HandleScope::CreateHandle(isolate, object.ptr()));
29 }
30 
31 template <typename T>
32 template <typename S>
33 const Handle<T> Handle<T>::cast(Handle<S> that) {
34  T::cast(*reinterpret_cast<Object**>(that.location()));
35  return Handle<T>(that.location_);
36 }
37 
38 HandleScope::HandleScope(Isolate* isolate) {
39  HandleScopeData* data = isolate->handle_scope_data();
40  isolate_ = isolate;
41  prev_next_ = data->next;
42  prev_limit_ = data->limit;
43  data->level++;
44 }
45 
46 template <typename T>
47 template <typename T1, typename>
48 Handle<T>::Handle(T* object, Isolate* isolate)
49  : HandleBase(reinterpret_cast<Address>(object), isolate) {}
50 
51 template <typename T>
52 template <typename T1, typename>
53 Handle<T>::Handle(T object, Isolate* isolate)
54  : HandleBase(object.ptr(), isolate) {}
55 
56 template <typename T, typename = typename std::enable_if<
57  std::is_base_of<Object, T>::value>::type>
58 V8_INLINE Handle<T> handle(T* object, Isolate* isolate) {
59  return Handle<T>(object, isolate);
60 }
61 
62 template <typename T, typename = typename std::enable_if<
63  std::is_base_of<ObjectPtr, T>::value>::type>
64 V8_INLINE Handle<T> handle(T object, Isolate* isolate) {
65  return Handle<T>(object, isolate);
66 }
67 
68 template <typename T>
69 inline std::ostream& operator<<(std::ostream& os, Handle<T> handle) {
70  return os << Brief(*handle);
71 }
72 
73 HandleScope::~HandleScope() {
74 #ifdef DEBUG
75  if (FLAG_check_handle_count) {
76  int before = NumberOfHandles(isolate_);
77  CloseScope(isolate_, prev_next_, prev_limit_);
78  int after = NumberOfHandles(isolate_);
79  DCHECK_LT(after - before, kCheckHandleThreshold);
80  DCHECK_LT(before, kCheckHandleThreshold);
81  } else {
82 #endif // DEBUG
83  CloseScope(isolate_, prev_next_, prev_limit_);
84 #ifdef DEBUG
85  }
86 #endif // DEBUG
87 }
88 
89 void HandleScope::CloseScope(Isolate* isolate, Address* prev_next,
90  Address* prev_limit) {
91  HandleScopeData* current = isolate->handle_scope_data();
92 
93  std::swap(current->next, prev_next);
94  current->level--;
95  Address* limit = prev_next;
96  if (current->limit != prev_limit) {
97  current->limit = prev_limit;
98  limit = prev_limit;
99  DeleteExtensions(isolate);
100  }
101 #ifdef ENABLE_HANDLE_ZAPPING
102  ZapRange(current->next, limit);
103 #endif
104  MSAN_ALLOCATED_UNINITIALIZED_MEMORY(
105  current->next,
106  static_cast<size_t>(reinterpret_cast<Address>(limit) -
107  reinterpret_cast<Address>(current->next)));
108 }
109 
110 template <typename T>
111 Handle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) {
112  HandleScopeData* current = isolate_->handle_scope_data();
113 
114  typedef
115  typename std::conditional<std::is_base_of<Object, T>::value, T*, T>::type
116  ValueType;
117 
118  ValueType value = *handle_value;
119  // Throw away all handles in the current scope.
120  CloseScope(isolate_, prev_next_, prev_limit_);
121  // Allocate one handle in the parent scope.
122  DCHECK(current->level > current->sealed_level);
123  Handle<T> result(value, isolate_);
124  // Reinitialize the current scope (so that it's ready
125  // to be used or closed again).
126  prev_next_ = current->next;
127  prev_limit_ = current->limit;
128  current->level++;
129  return result;
130 }
131 
132 Address* HandleScope::CreateHandle(Isolate* isolate, Address value) {
133  DCHECK(AllowHandleAllocation::IsAllowed());
134  HandleScopeData* data = isolate->handle_scope_data();
135  Address* result = data->next;
136  if (result == data->limit) {
137  result = Extend(isolate);
138  }
139  // Update the current next field, set the value in the created handle,
140  // and return the result.
141  DCHECK_LT(reinterpret_cast<Address>(result),
142  reinterpret_cast<Address>(data->limit));
143  data->next = reinterpret_cast<Address*>(reinterpret_cast<Address>(result) +
144  sizeof(Address));
145  *result = value;
146  return result;
147 }
148 
149 Address* HandleScope::GetHandle(Isolate* isolate, Address value) {
150  DCHECK(AllowHandleAllocation::IsAllowed());
151  HandleScopeData* data = isolate->handle_scope_data();
152  CanonicalHandleScope* canonical = data->canonical_scope;
153  return canonical ? canonical->Lookup(value) : CreateHandle(isolate, value);
154 }
155 
156 
157 #ifdef DEBUG
158 inline SealHandleScope::SealHandleScope(Isolate* isolate) : isolate_(isolate) {
159  // Make sure the current thread is allowed to create handles to begin with.
160  DCHECK(AllowHandleAllocation::IsAllowed());
161  HandleScopeData* current = isolate_->handle_scope_data();
162  // Shrink the current handle scope to make it impossible to do
163  // handle allocations without an explicit handle scope.
164  prev_limit_ = current->limit;
165  current->limit = current->next;
166  prev_sealed_level_ = current->sealed_level;
167  current->sealed_level = current->level;
168 }
169 
170 
171 inline SealHandleScope::~SealHandleScope() {
172  // Restore state in current handle scope to re-enable handle
173  // allocations.
174  HandleScopeData* current = isolate_->handle_scope_data();
175  DCHECK_EQ(current->next, current->limit);
176  current->limit = prev_limit_;
177  DCHECK_EQ(current->level, current->sealed_level);
178  current->sealed_level = prev_sealed_level_;
179 }
180 
181 #endif
182 
183 } // namespace internal
184 } // namespace v8
185 
186 #endif // V8_HANDLES_INL_H_
Definition: libplatform.h:13