V8 Project
handles.h
Go to the documentation of this file.
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
3 // found in the LICENSE file.
4 
5 #ifndef V8_HANDLES_H_
6 #define V8_HANDLES_H_
7 
8 #include "src/objects.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 // A Handle can be converted into a MaybeHandle. Converting a MaybeHandle
14 // into a Handle requires checking that it does not point to NULL. This
15 // ensures NULL checks before use.
16 // Do not use MaybeHandle as argument type.
17 
18 template<typename T>
19 class MaybeHandle {
20  public:
22 
23  // Constructor for handling automatic up casting from Handle.
24  // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected.
25  template <class S> MaybeHandle(Handle<S> handle) {
26 #ifdef DEBUG
27  T* a = NULL;
28  S* b = NULL;
29  a = b; // Fake assignment to enforce type checks.
30  USE(a);
31 #endif
32  this->location_ = reinterpret_cast<T**>(handle.location());
33  }
34 
35  // Constructor for handling automatic up casting.
36  // Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected.
37  template <class S> MaybeHandle(MaybeHandle<S> maybe_handle) {
38 #ifdef DEBUG
39  T* a = NULL;
40  S* b = NULL;
41  a = b; // Fake assignment to enforce type checks.
42  USE(a);
43 #endif
44  location_ = reinterpret_cast<T**>(maybe_handle.location_);
45  }
46 
47  INLINE(void Assert() const) { DCHECK(location_ != NULL); }
48  INLINE(void Check() const) { CHECK(location_ != NULL); }
49 
50  INLINE(Handle<T> ToHandleChecked()) const {
51  Check();
52  return Handle<T>(location_);
53  }
54 
55  // Convert to a Handle with a type that can be upcasted to.
56  template <class S> INLINE(bool ToHandle(Handle<S>* out)) {
57  if (location_ == NULL) {
58  *out = Handle<T>::null();
59  return false;
60  } else {
61  *out = Handle<T>(location_);
62  return true;
63  }
64  }
65 
66  bool is_null() const { return location_ == NULL; }
67 
68  protected:
70 
71  // MaybeHandles of different classes are allowed to access each
72  // other's location_.
73  template<class S> friend class MaybeHandle;
74 };
75 
76 // ----------------------------------------------------------------------------
77 // A Handle provides a reference to an object that survives relocation by
78 // the garbage collector.
79 // Handles are only valid within a HandleScope.
80 // When a handle is created for an object a cell is allocated in the heap.
81 
82 template<typename T>
83 class Handle {
84  public:
85  INLINE(explicit Handle(T** location)) { location_ = location; }
86  INLINE(explicit Handle(T* obj));
87  INLINE(Handle(T* obj, Isolate* isolate));
88 
89  // TODO(yangguo): Values that contain empty handles should be declared as
90  // MaybeHandle to force validation before being used as handles.
92 
93  // Constructor for handling automatic up casting.
94  // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
95  template <class S> Handle(Handle<S> handle) {
96 #ifdef DEBUG
97  T* a = NULL;
98  S* b = NULL;
99  a = b; // Fake assignment to enforce type checks.
100  USE(a);
101 #endif
102  location_ = reinterpret_cast<T**>(handle.location_);
103  }
104 
105  INLINE(T* operator->() const) { return operator*(); }
106 
107  // Check if this handle refers to the exact same object as the other handle.
108  INLINE(bool is_identical_to(const Handle<T> other) const);
109 
110  // Provides the C++ dereference operator.
111  INLINE(T* operator*() const);
112 
113  // Returns the address to where the raw pointer is stored.
114  INLINE(T** location() const);
115 
116  template <class S> static Handle<T> cast(Handle<S> that) {
117  T::cast(*reinterpret_cast<T**>(that.location_));
118  return Handle<T>(reinterpret_cast<T**>(that.location_));
119  }
120 
121  // TODO(yangguo): Values that contain empty handles should be declared as
122  // MaybeHandle to force validation before being used as handles.
123  static Handle<T> null() { return Handle<T>(); }
124  bool is_null() const { return location_ == NULL; }
125 
126  // Closes the given scope, but lets this handle escape. See
127  // implementation in api.h.
129 
130 #ifdef DEBUG
131  enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK };
132 
133  bool IsDereferenceAllowed(DereferenceCheckMode mode) const;
134 #endif // DEBUG
135 
136  private:
138 
139  // Handles of different classes are allowed to access each other's location_.
140  template<class S> friend class Handle;
141 };
142 
143 
144 // Convenience wrapper.
145 template<class T>
146 inline Handle<T> handle(T* t, Isolate* isolate) {
147  return Handle<T>(t, isolate);
148 }
149 
150 
151 // Convenience wrapper.
152 template<class T>
153 inline Handle<T> handle(T* t) {
154  return Handle<T>(t, t->GetIsolate());
155 }
156 
157 
158 // Key comparison function for Map handles.
159 inline bool operator<(const Handle<Map>& lhs, const Handle<Map>& rhs) {
160  // This is safe because maps don't move.
161  return *lhs < *rhs;
162 }
163 
164 
165 class DeferredHandles;
166 class HandleScopeImplementer;
167 
168 
169 // A stack-allocated class that governs a number of local handles.
170 // After a handle scope has been created, all local handles will be
171 // allocated within that handle scope until either the handle scope is
172 // deleted or another handle scope is created. If there is already a
173 // handle scope and a new one is created, all allocations will take
174 // place in the new handle scope until it is deleted. After that,
175 // new handles will again be allocated in the original handle scope.
176 //
177 // After the handle scope of a local handle has been deleted the
178 // garbage collector will no longer track the object stored in the
179 // handle and may deallocate it. The behavior of accessing a handle
180 // for which the handle scope has been deleted is undefined.
181 class HandleScope {
182  public:
183  explicit inline HandleScope(Isolate* isolate);
184 
185  inline ~HandleScope();
186 
187  // Counts the number of allocated handles.
188  static int NumberOfHandles(Isolate* isolate);
189 
190  // Creates a new handle with the given value.
191  template <typename T>
192  static inline T** CreateHandle(Isolate* isolate, T* value);
193 
194  // Deallocates any extensions used by the current scope.
195  static void DeleteExtensions(Isolate* isolate);
196 
200 
201  // Closes the HandleScope (invalidating all handles
202  // created in the scope of the HandleScope) and returns
203  // a Handle backed by the parent scope holding the
204  // value of the argument handle.
205  template <typename T>
206  Handle<T> CloseAndEscape(Handle<T> handle_value);
207 
208  Isolate* isolate() { return isolate_; }
209 
210  private:
211  // Prevent heap allocation or illegal handle scopes.
213  void operator=(const HandleScope&);
214  void* operator new(size_t size);
215  void operator delete(void* size_t);
216 
220 
221  // Close the handle scope resetting limits to a previous state.
222  static inline void CloseScope(Isolate* isolate,
223  Object** prev_next,
224  Object** prev_limit);
225 
226  // Extend the handle scope making room for more handles.
228 
229 #ifdef ENABLE_HANDLE_ZAPPING
230  // Zaps the handles in the half-open interval [start, end).
231  static void ZapRange(Object** start, Object** end);
232 #endif
233 
234  friend class v8::HandleScope;
237  friend class v8::internal::Isolate;
238 };
239 
240 
241 class DeferredHandles;
242 
243 
245  public:
246  explicit DeferredHandleScope(Isolate* isolate);
247  // The DeferredHandles object returned stores the Handles created
248  // since the creation of this DeferredHandleScope. The Handles are
249  // alive as long as the DeferredHandles object is alive.
252 
253  private:
257 
258 #ifdef DEBUG
259  bool handles_detached_;
260  int prev_level_;
261 #endif
262 
264 };
265 
266 
267 // Seal off the current HandleScope so that new handles can only be created
268 // if a new HandleScope is entered.
269 class SealHandleScope BASE_EMBEDDED {
270  public:
271 #ifndef DEBUG
272  explicit SealHandleScope(Isolate* isolate) {}
274 #else
275  explicit inline SealHandleScope(Isolate* isolate);
276  inline ~SealHandleScope();
277  private:
278  Isolate* isolate_;
279  Object** limit_;
280  int level_;
281 #endif
282 };
283 
287  int level;
288 
289  void Initialize() {
290  next = limit = NULL;
291  level = 0;
292  }
293 };
294 
295 } } // namespace v8::internal
296 
297 #endif // V8_HANDLES_H_
A HandleScope which first allocates a handle in the current scope which will be later filled with the...
Definition: v8.h:855
A stack-allocated class that governs a number of local handles.
Definition: v8.h:802
SealHandleScope(Isolate *isolate)
Definition: handles.h:272
DeferredHandleScope(Isolate *isolate)
Definition: handles.cc:92
HandleScopeImplementer * impl_
Definition: handles.h:256
DeferredHandles * Detach()
Definition: handles.cc:119
static int NumberOfHandles(Isolate *isolate)
Definition: handles.cc:13
HandleScope(Isolate *isolate)
Definition: handles-inl.h:85
Handle< T > CloseAndEscape(Handle< T > handle_value)
Definition: handles-inl.h:119
static Address current_limit_address(Isolate *isolate)
Definition: handles.cc:87
static void DeleteExtensions(Isolate *isolate)
Definition: handles.cc:61
static Address current_next_address(Isolate *isolate)
Definition: handles.cc:82
void operator=(const HandleScope &)
static void CloseScope(Isolate *isolate, Object **prev_next, Object **prev_limit)
Definition: handles-inl.h:99
static T ** CreateHandle(Isolate *isolate, T *value)
Definition: handles-inl.h:138
HandleScope(const HandleScope &)
static Address current_level_address(Isolate *isolate)
Definition: handles.cc:77
static internal::Object ** Extend(Isolate *isolate)
Definition: handles.cc:22
INLINE(T **location() const)
static Handle< T > cast(Handle< S > that)
Definition: handles.h:116
bool is_null() const
Definition: handles.h:124
INLINE(Handle(T *obj, Isolate *isolate))
INLINE(explicit Handle(T **location))
Definition: handles.h:85
Handle< T > EscapeFrom(v8::EscapableHandleScope *scope)
Definition: api.h:298
friend class Handle
Definition: handles.h:140
INLINE(bool is_identical_to(const Handle< T > other) const)
Handle(Handle< S > handle)
Definition: handles.h:95
INLINE(T *operator*() const)
INLINE(T *operator->() const)
Definition: handles.h:105
INLINE(explicit Handle(T *obj))
static Handle< T > null()
Definition: handles.h:123
INLINE(Handle())
Definition: handles.h:91
INLINE(Handle< T > ToHandleChecked()) const
Definition: handles.h:50
MaybeHandle(MaybeHandle< S > maybe_handle)
Definition: handles.h:37
friend class MaybeHandle
Definition: handles.h:73
INLINE(void Assert() const)
Definition: handles.h:47
INLINE(void Check() const)
Definition: handles.h:48
bool is_null() const
Definition: handles.h:66
INLINE(bool ToHandle(Handle< S > *out))
Definition: handles.h:56
MaybeHandle(Handle< S > handle)
Definition: handles.h:25
INLINE(MaybeHandle())
Definition: handles.h:21
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define CHECK(condition)
Definition: logging.h:36
#define DCHECK(condition)
Definition: logging.h:205
void USE(T)
Definition: macros.h:322
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:146
bool operator<(const Handle< Map > &lhs, const Handle< Map > &rhs)
Definition: handles.h:159
byte * Address
Definition: globals.h:101
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
internal::Object ** next
Definition: handles.h:285
internal::Object ** limit
Definition: handles.h:286
#define T(name, string, precedence)
Definition: token.cc:25