Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: src/handles.cc

Issue 1128533002: [handles] Sanitize Handle and friends. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/handles.h"
6 6
7 #include "src/handles.h" 7 #include "src/api.h"
8 #include "src/isolate.h"
8 9
9 namespace v8 { 10 namespace v8 {
10 namespace internal { 11 namespace internal {
11 12
13 HandleBase::HandleBase(HeapObject* object)
14 : HandleBase(object, object->GetIsolate()) {}
12 15
16
17 HandleBase::HandleBase(Object* object, Isolate* isolate)
18 : HandleBase(HandleScope::CreateHandle(isolate, object)) {}
19
20
21 #ifdef DEBUG
22
23 bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const {
24 DCHECK_NOT_NULL(location_);
25 Object* const object = *location_;
26 if (object->IsSmi()) return true;
27 HeapObject* const heap_object = HeapObject::cast(object);
28 Heap* const heap = heap_object->GetHeap();
29 Object** roots_array_start = heap->roots_array_start();
30 if (roots_array_start <= location_ &&
31 location_ < roots_array_start + Heap::kStrongRootListLength &&
32 heap->RootCanBeTreatedAsConstant(
33 static_cast<Heap::RootListIndex>(location_ - roots_array_start))) {
34 return true;
35 }
36 if (!AllowHandleDereference::IsAllowed()) return false;
37 if (mode == INCLUDE_DEFERRED_CHECK &&
38 !AllowDeferredHandleDereference::IsAllowed()) {
39 // Accessing cells, maps and internalized strings is safe.
40 if (heap_object->IsCell()) return true;
41 if (heap_object->IsMap()) return true;
42 if (heap_object->IsInternalizedString()) return true;
43 return !heap->isolate()->IsDeferredHandle(location_);
44 }
45 return true;
46 }
47
48 #endif // DEBUG
49
50
51 HandleScope::HandleScope(Isolate* isolate) : isolate_(isolate) {
52 HandleScopeData* const current = isolate->handle_scope_data();
53 prev_next_ = current->next;
54 prev_limit_ = current->limit;
55 current->level++;
56 }
57
58
59 HandleScope::~HandleScope() { CloseScope(isolate_, prev_next_, prev_limit_); }
60
61
62 // static
13 int HandleScope::NumberOfHandles(Isolate* isolate) { 63 int HandleScope::NumberOfHandles(Isolate* isolate) {
14 HandleScopeImplementer* impl = isolate->handle_scope_implementer(); 64 HandleScopeImplementer* impl = isolate->handle_scope_implementer();
15 int n = impl->blocks()->length(); 65 int n = impl->blocks()->length();
16 if (n == 0) return 0; 66 if (n == 0) return 0;
17 return ((n - 1) * kHandleBlockSize) + static_cast<int>( 67 return ((n - 1) * kHandleBlockSize) + static_cast<int>(
18 (isolate->handle_scope_data()->next - impl->blocks()->last())); 68 (isolate->handle_scope_data()->next - impl->blocks()->last()));
19 } 69 }
20 70
21 71
72 // static
73 Object** HandleScope::CreateHandle(Isolate* isolate, Object* value) {
74 DCHECK(AllowHandleAllocation::IsAllowed());
75 HandleScopeData* const current = isolate->handle_scope_data();
76
77 Object** result = current->next;
78 if (result == current->limit) result = Extend(isolate);
79 // Update the current next field, set the value in the created
80 // handle, and return the result.
81 DCHECK_LT(result, current->limit);
82 current->next = result + 1;
83
84 *result = value;
85 return result;
86 }
87
88
89 // static
90 void HandleScope::DeleteExtensions(Isolate* isolate) {
91 HandleScopeData* const current = isolate->handle_scope_data();
92 isolate->handle_scope_implementer()->DeleteExtensions(current->limit);
93 }
94
95
96 Handle<Object> HandleScope::CloseAndEscape(Handle<Object> handle) {
97 HandleScopeData* const current = isolate_->handle_scope_data();
98
99 Object* value = *handle;
100 // Throw away all handles in the current scope.
101 CloseScope(isolate_, prev_next_, prev_limit_);
102 // Allocate one handle in the parent scope.
103 DCHECK_LT(0, current->level);
104 Handle<Object> result(CreateHandle(isolate_, value));
105 // Reinitialize the current scope (so that it's ready
106 // to be used or closed again).
107 prev_next_ = current->next;
108 prev_limit_ = current->limit;
109 current->level++;
110 return result;
111 }
112
113
114 // static
115 void HandleScope::CloseScope(Isolate* isolate, Object** prev_next,
116 Object** prev_limit) {
117 HandleScopeData* const current = isolate->handle_scope_data();
118
119 std::swap(current->next, prev_next);
120 current->level--;
121 if (current->limit != prev_limit) {
122 current->limit = prev_limit;
123 DeleteExtensions(isolate);
124 #ifdef ENABLE_HANDLE_ZAPPING
125 ZapRange(current->next, prev_limit);
126 } else {
127 ZapRange(current->next, prev_next);
128 #endif
129 }
130 }
131
132
133 // static
22 Object** HandleScope::Extend(Isolate* isolate) { 134 Object** HandleScope::Extend(Isolate* isolate) {
23 HandleScopeData* current = isolate->handle_scope_data(); 135 HandleScopeData* current = isolate->handle_scope_data();
24 136
25 Object** result = current->next; 137 Object** result = current->next;
26 138 DCHECK_EQ(result, current->limit);
27 DCHECK(result == current->limit);
28 // Make sure there's at least one scope on the stack and that the 139 // Make sure there's at least one scope on the stack and that the
29 // top of the scope stack isn't a barrier. 140 // top of the scope stack isn't a barrier.
30 if (!Utils::ApiCheck(current->level != 0, 141 if (!Utils::ApiCheck(current->level != 0,
31 "v8::HandleScope::CreateHandle()", 142 "v8::HandleScope::CreateHandle()",
32 "Cannot create a handle without a HandleScope")) { 143 "Cannot create a handle without a HandleScope")) {
33 return NULL; 144 return NULL;
34 } 145 }
35 HandleScopeImplementer* impl = isolate->handle_scope_implementer(); 146 HandleScopeImplementer* impl = isolate->handle_scope_implementer();
36 // If there's more room in the last block, we use that. This is used 147 // If there's more room in the last block, we use that. This is used
37 // for fast creation of scopes after scope barriers. 148 // for fast creation of scopes after scope barriers.
(...skipping 13 matching lines...) Expand all
51 // Add the extension to the global list of blocks, but count the 162 // Add the extension to the global list of blocks, but count the
52 // extension as part of the current scope. 163 // extension as part of the current scope.
53 impl->blocks()->Add(result); 164 impl->blocks()->Add(result);
54 current->limit = &result[kHandleBlockSize]; 165 current->limit = &result[kHandleBlockSize];
55 } 166 }
56 167
57 return result; 168 return result;
58 } 169 }
59 170
60 171
61 void HandleScope::DeleteExtensions(Isolate* isolate) {
62 HandleScopeData* current = isolate->handle_scope_data();
63 isolate->handle_scope_implementer()->DeleteExtensions(current->limit);
64 }
65
66
67 #ifdef ENABLE_HANDLE_ZAPPING 172 #ifdef ENABLE_HANDLE_ZAPPING
68 void HandleScope::ZapRange(Object** start, Object** end) { 173 void HandleScope::ZapRange(Object** start, Object** end) {
69 DCHECK(end - start <= kHandleBlockSize); 174 DCHECK(end - start <= kHandleBlockSize);
70 for (Object** p = start; p != end; p++) { 175 for (Object** p = start; p != end; p++) {
71 *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue; 176 *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue;
72 } 177 }
73 } 178 }
74 #endif 179 #endif
75 180
76 181
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 DeferredHandles* deferred = impl_->Detach(prev_limit_); 225 DeferredHandles* deferred = impl_->Detach(prev_limit_);
121 HandleScopeData* data = impl_->isolate()->handle_scope_data(); 226 HandleScopeData* data = impl_->isolate()->handle_scope_data();
122 data->next = prev_next_; 227 data->next = prev_next_;
123 data->limit = prev_limit_; 228 data->limit = prev_limit_;
124 #ifdef DEBUG 229 #ifdef DEBUG
125 handles_detached_ = true; 230 handles_detached_ = true;
126 #endif 231 #endif
127 return deferred; 232 return deferred;
128 } 233 }
129 234
130 } } // namespace v8::internal 235
236 #ifdef DEBUG
237
238 SealHandleScope::SealHandleScope(Isolate* isolate) : isolate_(isolate) {
239 // Make sure the current thread is allowed to create handles to begin with.
240 CHECK(AllowHandleAllocation::IsAllowed());
241 HandleScopeData* const current = isolate_->handle_scope_data();
242 // Shrink the current handle scope to make it impossible to do
243 // handle allocations without an explicit handle scope.
244 limit_ = current->limit;
245 current->limit = current->next;
246 level_ = current->level;
247 current->level = 0;
248 }
249
250
251 SealHandleScope::~SealHandleScope() {
252 // Restore state in current handle scope to re-enable handle
253 // allocations.
254 HandleScopeData* const current = isolate_->handle_scope_data();
255 DCHECK_EQ(0, current->level);
256 current->level = level_;
257 DCHECK_EQ(current->next, current->limit);
258 current->limit = limit_;
259 }
260
261 #endif // DEBUG
262
263 } // namespace internal
264 } // namespace v8
OLDNEW
« src/handles.h ('K') | « src/handles.h ('k') | src/handles-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698