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

Side by Side Diff: src/handles.h

Issue 1235253007: Revert of [handles] Sanitize Handle and friends. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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
« no previous file with comments | « src/api.cc ('k') | src/handles.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 #ifndef V8_HANDLES_H_ 5 #ifndef V8_HANDLES_H_
6 #define V8_HANDLES_H_ 6 #define V8_HANDLES_H_
7 7
8 #include "src/objects.h" 8 #include "src/objects.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 // Forward declarations.
14 class DeferredHandles;
15 class HandleScopeImplementer;
16
17
18 // ----------------------------------------------------------------------------
19 // Base class for Handle instantiations. Don't use directly.
20 class HandleBase {
21 public:
22 V8_INLINE explicit HandleBase(Object** location) : location_(location) {}
23 V8_INLINE explicit HandleBase(Object* object, Isolate* isolate);
24
25 // Check if this handle refers to the exact same object as the other handle.
26 V8_INLINE bool is_identical_to(const HandleBase that) const {
27 // Dereferencing deferred handles to check object equality is safe.
28 SLOW_DCHECK((this->location_ == NULL ||
29 this->IsDereferenceAllowed(NO_DEFERRED_CHECK)) &&
30 (that.location_ == NULL ||
31 that.IsDereferenceAllowed(NO_DEFERRED_CHECK)));
32 if (this->location_ == that.location_) return true;
33 if (this->location_ == NULL || that.location_ == NULL) return false;
34 return *this->location_ == *that.location_;
35 }
36
37 V8_INLINE bool is_null() const { return location_ == nullptr; }
38
39 protected:
40 // Provides the C++ dereference operator.
41 V8_INLINE Object* operator*() const {
42 SLOW_DCHECK(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
43 return *location_;
44 }
45
46 // Returns the address to where the raw pointer is stored.
47 V8_INLINE Object** location() const {
48 SLOW_DCHECK(location_ == NULL ||
49 IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
50 return location_;
51 }
52
53 enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK };
54 #ifdef DEBUG
55 bool IsDereferenceAllowed(DereferenceCheckMode mode) const;
56 #else
57 V8_INLINE
58 bool IsDereferenceAllowed(DereferenceCheckMode mode) const { return true; }
59 #endif // DEBUG
60
61 Object** location_;
62 };
63
64
65 // ----------------------------------------------------------------------------
66 // A Handle provides a reference to an object that survives relocation by
67 // the garbage collector.
68 // Handles are only valid within a HandleScope.
69 // When a handle is created for an object a cell is allocated in the heap.
70 template <typename T>
71 class Handle final : public HandleBase {
72 public:
73 V8_INLINE explicit Handle(T** location = nullptr)
74 : HandleBase(reinterpret_cast<Object**>(location)) {
75 Object* a = nullptr;
76 T* b = nullptr;
77 a = b; // Fake assignment to enforce type checks.
78 USE(a);
79 }
80 V8_INLINE explicit Handle(T* object) : Handle(object, object->GetIsolate()) {}
81 V8_INLINE Handle(T* object, Isolate* isolate) : HandleBase(object, isolate) {}
82
83 // Constructor for handling automatic up casting.
84 // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
85 template <typename S>
86 V8_INLINE Handle(Handle<S> handle)
87 : HandleBase(handle) {
88 T* a = nullptr;
89 S* b = nullptr;
90 a = b; // Fake assignment to enforce type checks.
91 USE(a);
92 }
93
94 V8_INLINE T* operator->() const { return operator*(); }
95
96 // Provides the C++ dereference operator.
97 V8_INLINE T* operator*() const {
98 return reinterpret_cast<T*>(HandleBase::operator*());
99 }
100
101 // Returns the address to where the raw pointer is stored.
102 V8_INLINE T** location() const {
103 return reinterpret_cast<T**>(HandleBase::location());
104 }
105
106 template <typename S>
107 static const Handle<T> cast(Handle<S> that) {
108 T::cast(*reinterpret_cast<T**>(that.location_));
109 return Handle<T>(reinterpret_cast<T**>(that.location_));
110 }
111
112 // TODO(yangguo): Values that contain empty handles should be declared as
113 // MaybeHandle to force validation before being used as handles.
114 static const Handle<T> null() { return Handle<T>(); }
115
116 private:
117 // Handles of different classes are allowed to access each other's location_.
118 template <typename>
119 friend class Handle;
120 // MaybeHandle is allowed to access location_.
121 template <typename>
122 friend class MaybeHandle;
123 };
124
125 template <typename T>
126 V8_INLINE Handle<T> handle(T* object, Isolate* isolate) {
127 return Handle<T>(object, isolate);
128 }
129
130 template <typename T>
131 V8_INLINE Handle<T> handle(T* object) {
132 return Handle<T>(object);
133 }
134
135
136 // ----------------------------------------------------------------------------
137 // A Handle can be converted into a MaybeHandle. Converting a MaybeHandle 13 // A Handle can be converted into a MaybeHandle. Converting a MaybeHandle
138 // into a Handle requires checking that it does not point to NULL. This 14 // into a Handle requires checking that it does not point to NULL. This
139 // ensures NULL checks before use. 15 // ensures NULL checks before use.
140 // Do not use MaybeHandle as argument type. 16 // Do not use MaybeHandle as argument type.
141 template <typename T> 17
142 class MaybeHandle final { 18 template<typename T>
19 class MaybeHandle {
143 public: 20 public:
144 V8_INLINE MaybeHandle() {} 21 INLINE(MaybeHandle()) : location_(NULL) { }
145 V8_INLINE ~MaybeHandle() {}
146 22
147 // Constructor for handling automatic up casting from Handle. 23 // Constructor for handling automatic up casting from Handle.
148 // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected. 24 // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected.
149 template <typename S> 25 template <class S> MaybeHandle(Handle<S> handle) {
150 V8_INLINE MaybeHandle(Handle<S> handle) 26 #ifdef DEBUG
151 : location_(reinterpret_cast<T**>(handle.location_)) { 27 T* a = NULL;
152 T* a = nullptr; 28 S* b = NULL;
153 S* b = nullptr;
154 a = b; // Fake assignment to enforce type checks. 29 a = b; // Fake assignment to enforce type checks.
155 USE(a); 30 USE(a);
31 #endif
32 this->location_ = reinterpret_cast<T**>(handle.location());
156 } 33 }
157 34
158 // Constructor for handling automatic up casting. 35 // Constructor for handling automatic up casting.
159 // Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected. 36 // Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected.
160 template <typename S> 37 template <class S> MaybeHandle(MaybeHandle<S> maybe_handle) {
161 V8_INLINE MaybeHandle(MaybeHandle<S> maybe_handle) 38 #ifdef DEBUG
162 : location_(reinterpret_cast<T**>(maybe_handle.location_)) { 39 T* a = NULL;
163 T* a = nullptr; 40 S* b = NULL;
164 S* b = nullptr;
165 a = b; // Fake assignment to enforce type checks. 41 a = b; // Fake assignment to enforce type checks.
166 USE(a); 42 USE(a);
43 #endif
44 location_ = reinterpret_cast<T**>(maybe_handle.location_);
167 } 45 }
168 46
169 V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); } 47 INLINE(void Assert() const) { DCHECK(location_ != NULL); }
170 V8_INLINE void Check() const { CHECK_NOT_NULL(location_); } 48 INLINE(void Check() const) { CHECK(location_ != NULL); }
171 49
172 V8_INLINE Handle<T> ToHandleChecked() const { 50 INLINE(Handle<T> ToHandleChecked()) const {
173 Check(); 51 Check();
174 return Handle<T>(location_); 52 return Handle<T>(location_);
175 } 53 }
176 54
177 // Convert to a Handle with a type that can be upcasted to. 55 // Convert to a Handle with a type that can be upcasted to.
178 template <typename S> 56 template <class S>
179 V8_INLINE bool ToHandle(Handle<S>* out) const { 57 V8_INLINE bool ToHandle(Handle<S>* out) const {
180 if (location_ == nullptr) { 58 if (location_ == NULL) {
181 *out = Handle<T>::null(); 59 *out = Handle<T>::null();
182 return false; 60 return false;
183 } else { 61 } else {
184 *out = Handle<T>(location_); 62 *out = Handle<T>(location_);
185 return true; 63 return true;
186 } 64 }
187 } 65 }
188 66
189 bool is_null() const { return location_ == nullptr; } 67 bool is_null() const { return location_ == NULL; }
190 68
191 template <typename S> 69 template <typename S>
192 V8_INLINE bool operator==(MaybeHandle<S> that) const { 70 bool operator==(MaybeHandle<S> that) const {
193 return this->location_ == that.location_; 71 return this->location_ == that.location_;
194 } 72 }
195 template <typename S> 73 template <typename S>
196 V8_INLINE bool operator!=(MaybeHandle<S> that) const { 74 bool operator!=(MaybeHandle<S> that) const {
197 return this->location_ != that.location_; 75 return !(*this == that);
198 } 76 }
199 77
78
200 protected: 79 protected:
201 T** location_ = nullptr; 80 T** location_;
202 81
203 // MaybeHandles of different classes are allowed to access each 82 // MaybeHandles of different classes are allowed to access each
204 // other's location_. 83 // other's location_.
205 template <typename> 84 template<class S> friend class MaybeHandle;
206 friend class MaybeHandle;
207 // Utility functions are allowed to access location_.
208 template <typename S> 85 template <typename S>
209 friend size_t hash_value(MaybeHandle<S>); 86 friend size_t hash_value(MaybeHandle<S>);
210 }; 87 };
211 88
212 template <typename T> 89 template <typename S>
213 V8_INLINE size_t hash_value(MaybeHandle<T> maybe_handle) { 90 inline size_t hash_value(MaybeHandle<S> maybe_handle) {
214 uintptr_t v = bit_cast<uintptr_t>(maybe_handle.location_); 91 return bit_cast<size_t>(maybe_handle.location_);
215 DCHECK_EQ(0u, v & ((1u << kPointerSizeLog2) - 1));
216 return v >> kPointerSizeLog2;
217 } 92 }
218 93
219 94
95 // ----------------------------------------------------------------------------
96 // A Handle provides a reference to an object that survives relocation by
97 // the garbage collector.
98 // Handles are only valid within a HandleScope.
99 // When a handle is created for an object a cell is allocated in the heap.
100
101 template<typename T>
102 class Handle {
103 public:
104 INLINE(explicit Handle(T** location)) { location_ = location; }
105 INLINE(explicit Handle(T* obj));
106 INLINE(Handle(T* obj, Isolate* isolate));
107
108 // TODO(yangguo): Values that contain empty handles should be declared as
109 // MaybeHandle to force validation before being used as handles.
110 INLINE(Handle()) : location_(NULL) { }
111
112 // Constructor for handling automatic up casting.
113 // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
114 template <class S> Handle(Handle<S> handle) {
115 #ifdef DEBUG
116 T* a = NULL;
117 S* b = NULL;
118 a = b; // Fake assignment to enforce type checks.
119 USE(a);
120 #endif
121 location_ = reinterpret_cast<T**>(handle.location_);
122 }
123
124 INLINE(T* operator->() const) { return operator*(); }
125
126 // Check if this handle refers to the exact same object as the other handle.
127 INLINE(bool is_identical_to(const Handle<T> other) const);
128
129 // Provides the C++ dereference operator.
130 INLINE(T* operator*() const);
131
132 // Returns the address to where the raw pointer is stored.
133 INLINE(T** location() const);
134
135 template <class S> static Handle<T> cast(Handle<S> that) {
136 T::cast(*reinterpret_cast<T**>(that.location_));
137 return Handle<T>(reinterpret_cast<T**>(that.location_));
138 }
139
140 // TODO(yangguo): Values that contain empty handles should be declared as
141 // MaybeHandle to force validation before being used as handles.
142 static Handle<T> null() { return Handle<T>(); }
143 bool is_null() const { return location_ == NULL; }
144
145 // Closes the given scope, but lets this handle escape. See
146 // implementation in api.h.
147 inline Handle<T> EscapeFrom(v8::EscapableHandleScope* scope);
148
149 #ifdef DEBUG
150 enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK };
151
152 bool IsDereferenceAllowed(DereferenceCheckMode mode) const;
153 #endif // DEBUG
154
155 private:
156 T** location_;
157
158 // Handles of different classes are allowed to access each other's location_.
159 template<class S> friend class Handle;
160 };
161
162
163 // Convenience wrapper.
164 template<class T>
165 inline Handle<T> handle(T* t, Isolate* isolate) {
166 return Handle<T>(t, isolate);
167 }
168
169
170 // Convenience wrapper.
171 template<class T>
172 inline Handle<T> handle(T* t) {
173 return Handle<T>(t, t->GetIsolate());
174 }
175
176
177 class DeferredHandles;
178 class HandleScopeImplementer;
179
180
220 // A stack-allocated class that governs a number of local handles. 181 // A stack-allocated class that governs a number of local handles.
221 // After a handle scope has been created, all local handles will be 182 // After a handle scope has been created, all local handles will be
222 // allocated within that handle scope until either the handle scope is 183 // allocated within that handle scope until either the handle scope is
223 // deleted or another handle scope is created. If there is already a 184 // deleted or another handle scope is created. If there is already a
224 // handle scope and a new one is created, all allocations will take 185 // handle scope and a new one is created, all allocations will take
225 // place in the new handle scope until it is deleted. After that, 186 // place in the new handle scope until it is deleted. After that,
226 // new handles will again be allocated in the original handle scope. 187 // new handles will again be allocated in the original handle scope.
227 // 188 //
228 // After the handle scope of a local handle has been deleted the 189 // After the handle scope of a local handle has been deleted the
229 // garbage collector will no longer track the object stored in the 190 // garbage collector will no longer track the object stored in the
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 Isolate* isolate_; 234 Isolate* isolate_;
274 Object** prev_next_; 235 Object** prev_next_;
275 Object** prev_limit_; 236 Object** prev_limit_;
276 237
277 // Close the handle scope resetting limits to a previous state. 238 // Close the handle scope resetting limits to a previous state.
278 static inline void CloseScope(Isolate* isolate, 239 static inline void CloseScope(Isolate* isolate,
279 Object** prev_next, 240 Object** prev_next,
280 Object** prev_limit); 241 Object** prev_limit);
281 242
282 // Extend the handle scope making room for more handles. 243 // Extend the handle scope making room for more handles.
283 static Object** Extend(Isolate* isolate); 244 static internal::Object** Extend(Isolate* isolate);
284 245
285 #ifdef ENABLE_HANDLE_ZAPPING 246 #ifdef ENABLE_HANDLE_ZAPPING
286 // Zaps the handles in the half-open interval [start, end). 247 // Zaps the handles in the half-open interval [start, end).
287 static void ZapRange(Object** start, Object** end); 248 static void ZapRange(Object** start, Object** end);
288 #endif 249 #endif
289 250
290 friend class v8::HandleScope; 251 friend class v8::HandleScope;
291 friend class DeferredHandles; 252 friend class v8::internal::DeferredHandles;
292 friend class HandleScopeImplementer; 253 friend class v8::internal::HandleScopeImplementer;
293 friend class Isolate; 254 friend class v8::internal::Isolate;
294 }; 255 };
295 256
296 257
297 class DeferredHandleScope final { 258 class DeferredHandles;
259
260
261 class DeferredHandleScope {
298 public: 262 public:
299 explicit DeferredHandleScope(Isolate* isolate); 263 explicit DeferredHandleScope(Isolate* isolate);
300 // The DeferredHandles object returned stores the Handles created 264 // The DeferredHandles object returned stores the Handles created
301 // since the creation of this DeferredHandleScope. The Handles are 265 // since the creation of this DeferredHandleScope. The Handles are
302 // alive as long as the DeferredHandles object is alive. 266 // alive as long as the DeferredHandles object is alive.
303 DeferredHandles* Detach(); 267 DeferredHandles* Detach();
304 ~DeferredHandleScope(); 268 ~DeferredHandleScope();
305 269
306 private: 270 private:
307 Object** prev_limit_; 271 Object** prev_limit_;
308 Object** prev_next_; 272 Object** prev_next_;
309 HandleScopeImplementer* impl_; 273 HandleScopeImplementer* impl_;
310 274
311 #ifdef DEBUG 275 #ifdef DEBUG
312 bool handles_detached_; 276 bool handles_detached_;
313 int prev_level_; 277 int prev_level_;
314 #endif 278 #endif
315 279
316 friend class HandleScopeImplementer; 280 friend class HandleScopeImplementer;
317 }; 281 };
318 282
319 283
320 // Seal off the current HandleScope so that new handles can only be created 284 // Seal off the current HandleScope so that new handles can only be created
321 // if a new HandleScope is entered. 285 // if a new HandleScope is entered.
322 class SealHandleScope final { 286 class SealHandleScope BASE_EMBEDDED {
323 public: 287 public:
324 #ifndef DEBUG 288 #ifndef DEBUG
325 explicit SealHandleScope(Isolate* isolate) {} 289 explicit SealHandleScope(Isolate* isolate) {}
326 ~SealHandleScope() {} 290 ~SealHandleScope() {}
327 #else 291 #else
328 explicit inline SealHandleScope(Isolate* isolate); 292 explicit inline SealHandleScope(Isolate* isolate);
329 inline ~SealHandleScope(); 293 inline ~SealHandleScope();
330 private: 294 private:
331 Isolate* isolate_; 295 Isolate* isolate_;
332 Object** limit_; 296 Object** limit_;
333 int level_; 297 int level_;
334 #endif 298 #endif
335 }; 299 };
336 300
337 301 struct HandleScopeData {
338 struct HandleScopeData final { 302 internal::Object** next;
339 Object** next; 303 internal::Object** limit;
340 Object** limit;
341 int level; 304 int level;
342 305
343 void Initialize() { 306 void Initialize() {
344 next = limit = NULL; 307 next = limit = NULL;
345 level = 0; 308 level = 0;
346 } 309 }
347 }; 310 };
348 311
349 } // namespace internal 312 } } // namespace v8::internal
350 } // namespace v8
351 313
352 #endif // V8_HANDLES_H_ 314 #endif // V8_HANDLES_H_
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/handles.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698