Line data Source code
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 222251660 : : location_(HandleScope::GetHandle(isolate, object)) {}
17 :
18 : // Allocate a new handle for the object, do not canonicalize.
19 :
20 : template <typename T>
21 : Handle<T> Handle<T>::New(T object, Isolate* isolate) {
22 : return Handle(HandleScope::CreateHandle(isolate, object.ptr()));
23 : }
24 :
25 : template <typename T>
26 : template <typename S>
27 8675716 : const Handle<T> Handle<T>::cast(Handle<S> that) {
28 : T::cast(*FullObjectSlot(that.location()));
29 8675716 : return Handle<T>(that.location_);
30 : }
31 :
32 134583 : HandleScope::HandleScope(Isolate* isolate) {
33 : HandleScopeData* data = isolate->handle_scope_data();
34 18333877 : isolate_ = isolate;
35 231573203 : prev_next_ = data->next;
36 275203593 : prev_limit_ = data->limit;
37 275203593 : data->level++;
38 134583 : }
39 :
40 : template <typename T>
41 : Handle<T>::Handle(T object, Isolate* isolate)
42 : : HandleBase(object.ptr(), isolate) {}
43 :
44 : template <typename T>
45 : V8_INLINE Handle<T> handle(T object, Isolate* isolate) {
46 : return Handle<T>(object, isolate);
47 : }
48 :
49 : template <typename T>
50 179 : inline std::ostream& operator<<(std::ostream& os, Handle<T> handle) {
51 179 : return os << Brief(*handle);
52 : }
53 :
54 18736956 : HandleScope::~HandleScope() {
55 : #ifdef DEBUG
56 : if (FLAG_check_handle_count) {
57 : int before = NumberOfHandles(isolate_);
58 : CloseScope(isolate_, prev_next_, prev_limit_);
59 : int after = NumberOfHandles(isolate_);
60 : DCHECK_LT(after - before, kCheckHandleThreshold);
61 : DCHECK_LT(before, kCheckHandleThreshold);
62 : } else {
63 : #endif // DEBUG
64 266825793 : CloseScope(isolate_, prev_next_, prev_limit_);
65 : #ifdef DEBUG
66 : }
67 : #endif // DEBUG
68 403078 : }
69 :
70 765685655 : void HandleScope::CloseScope(Isolate* isolate, Address* prev_next,
71 : Address* prev_limit) {
72 : HandleScopeData* current = isolate->handle_scope_data();
73 :
74 : std::swap(current->next, prev_next);
75 765685655 : current->level--;
76 : Address* limit = prev_next;
77 765685655 : if (current->limit != prev_limit) {
78 2923378 : current->limit = prev_limit;
79 : limit = prev_limit;
80 2923378 : DeleteExtensions(isolate);
81 : }
82 : #ifdef ENABLE_HANDLE_ZAPPING
83 765685673 : ZapRange(current->next, limit);
84 : #endif
85 : MSAN_ALLOCATED_UNINITIALIZED_MEMORY(
86 : current->next,
87 : static_cast<size_t>(reinterpret_cast<Address>(limit) -
88 : reinterpret_cast<Address>(current->next)));
89 765685538 : }
90 :
91 : template <typename T>
92 15347461 : Handle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) {
93 15347461 : HandleScopeData* current = isolate_->handle_scope_data();
94 : T value = *handle_value;
95 : // Throw away all handles in the current scope.
96 15347461 : CloseScope(isolate_, prev_next_, prev_limit_);
97 : // Allocate one handle in the parent scope.
98 : DCHECK(current->level > current->sealed_level);
99 15347461 : Handle<T> result(value, isolate_);
100 : // Reinitialize the current scope (so that it's ready
101 : // to be used or closed again).
102 15347461 : prev_next_ = current->next;
103 15347461 : prev_limit_ = current->limit;
104 15347461 : current->level++;
105 15347461 : return result;
106 : }
107 :
108 : Address* HandleScope::CreateHandle(Isolate* isolate, Address value) {
109 : DCHECK(AllowHandleAllocation::IsAllowed());
110 : HandleScopeData* data = isolate->handle_scope_data();
111 1866170523 : Address* result = data->next;
112 1868692298 : if (result == data->limit) {
113 3199262 : result = Extend(isolate);
114 : }
115 : // Update the current next field, set the value in the created handle,
116 : // and return the result.
117 : DCHECK_LT(reinterpret_cast<Address>(result),
118 : reinterpret_cast<Address>(data->limit));
119 1868692373 : data->next = reinterpret_cast<Address*>(reinterpret_cast<Address>(result) +
120 1868692373 : sizeof(Address));
121 1868692373 : *result = value;
122 : return result;
123 : }
124 :
125 : Address* HandleScope::GetHandle(Isolate* isolate, Address value) {
126 : DCHECK(AllowHandleAllocation::IsAllowed());
127 : HandleScopeData* data = isolate->handle_scope_data();
128 2031480250 : CanonicalHandleScope* canonical = data->canonical_scope;
129 2031480250 : return canonical ? canonical->Lookup(value) : CreateHandle(isolate, value);
130 : }
131 :
132 :
133 : #ifdef DEBUG
134 : inline SealHandleScope::SealHandleScope(Isolate* isolate) : isolate_(isolate) {
135 : // Make sure the current thread is allowed to create handles to begin with.
136 : DCHECK(AllowHandleAllocation::IsAllowed());
137 : HandleScopeData* current = isolate_->handle_scope_data();
138 : // Shrink the current handle scope to make it impossible to do
139 : // handle allocations without an explicit handle scope.
140 : prev_limit_ = current->limit;
141 : current->limit = current->next;
142 : prev_sealed_level_ = current->sealed_level;
143 : current->sealed_level = current->level;
144 : }
145 :
146 :
147 : inline SealHandleScope::~SealHandleScope() {
148 : // Restore state in current handle scope to re-enable handle
149 : // allocations.
150 : HandleScopeData* current = isolate_->handle_scope_data();
151 : DCHECK_EQ(current->next, current->limit);
152 : current->limit = prev_limit_;
153 : DCHECK_EQ(current->level, current->sealed_level);
154 : current->sealed_level = prev_sealed_level_;
155 : }
156 :
157 : #endif
158 :
159 : } // namespace internal
160 : } // namespace v8
161 :
162 : #endif // V8_HANDLES_INL_H_
|