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

Side by Side Diff: src/handles.h

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

Powered by Google App Engine
This is Rietveld 408576698