Index: src/handles.h |
diff --git a/src/handles.h b/src/handles.h |
index 841a83ba6044f81a7bc418792fcf3465b0eab38b..162b6d282f2cdae48f3f3141a17f5f6e5a124e57 100644 |
--- a/src/handles.h |
+++ b/src/handles.h |
@@ -10,174 +10,52 @@ |
namespace v8 { |
namespace internal { |
-// Forward declarations. |
-class DeferredHandles; |
-class HandleScopeImplementer; |
- |
- |
-// ---------------------------------------------------------------------------- |
-// Base class for Handle instantiations. Don't use directly. |
-class HandleBase { |
- public: |
- V8_INLINE explicit HandleBase(Object** location) : location_(location) {} |
- V8_INLINE explicit HandleBase(Object* object, Isolate* isolate); |
- |
- // Check if this handle refers to the exact same object as the other handle. |
- V8_INLINE bool is_identical_to(const HandleBase that) const { |
- // Dereferencing deferred handles to check object equality is safe. |
- SLOW_DCHECK((this->location_ == NULL || |
- this->IsDereferenceAllowed(NO_DEFERRED_CHECK)) && |
- (that.location_ == NULL || |
- that.IsDereferenceAllowed(NO_DEFERRED_CHECK))); |
- if (this->location_ == that.location_) return true; |
- if (this->location_ == NULL || that.location_ == NULL) return false; |
- return *this->location_ == *that.location_; |
- } |
- |
- V8_INLINE bool is_null() const { return location_ == nullptr; } |
- |
- protected: |
- // Provides the C++ dereference operator. |
- V8_INLINE Object* operator*() const { |
- SLOW_DCHECK(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK)); |
- return *location_; |
- } |
- |
- // Returns the address to where the raw pointer is stored. |
- V8_INLINE Object** location() const { |
- SLOW_DCHECK(location_ == NULL || |
- IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK)); |
- return location_; |
- } |
- |
- enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK }; |
-#ifdef DEBUG |
- bool IsDereferenceAllowed(DereferenceCheckMode mode) const; |
-#else |
- V8_INLINE |
- bool IsDereferenceAllowed(DereferenceCheckMode mode) const { return true; } |
-#endif // DEBUG |
- |
- Object** location_; |
-}; |
- |
- |
-// ---------------------------------------------------------------------------- |
-// A Handle provides a reference to an object that survives relocation by |
-// the garbage collector. |
-// Handles are only valid within a HandleScope. |
-// When a handle is created for an object a cell is allocated in the heap. |
-template <typename T> |
-class Handle final : public HandleBase { |
- public: |
- V8_INLINE explicit Handle(T** location = nullptr) |
- : HandleBase(reinterpret_cast<Object**>(location)) { |
- Object* a = nullptr; |
- T* b = nullptr; |
- a = b; // Fake assignment to enforce type checks. |
- USE(a); |
- } |
- V8_INLINE explicit Handle(T* object) : Handle(object, object->GetIsolate()) {} |
- V8_INLINE Handle(T* object, Isolate* isolate) : HandleBase(object, isolate) {} |
- |
- // Constructor for handling automatic up casting. |
- // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected. |
- template <typename S> |
- V8_INLINE Handle(Handle<S> handle) |
- : HandleBase(handle) { |
- T* a = nullptr; |
- S* b = nullptr; |
- a = b; // Fake assignment to enforce type checks. |
- USE(a); |
- } |
- |
- V8_INLINE T* operator->() const { return operator*(); } |
- |
- // Provides the C++ dereference operator. |
- V8_INLINE T* operator*() const { |
- return reinterpret_cast<T*>(HandleBase::operator*()); |
- } |
- |
- // Returns the address to where the raw pointer is stored. |
- V8_INLINE T** location() const { |
- return reinterpret_cast<T**>(HandleBase::location()); |
- } |
- |
- template <typename S> |
- static const Handle<T> cast(Handle<S> that) { |
- T::cast(*reinterpret_cast<T**>(that.location_)); |
- return Handle<T>(reinterpret_cast<T**>(that.location_)); |
- } |
- |
- // TODO(yangguo): Values that contain empty handles should be declared as |
- // MaybeHandle to force validation before being used as handles. |
- static const Handle<T> null() { return Handle<T>(); } |
- |
- private: |
- // Handles of different classes are allowed to access each other's location_. |
- template <typename> |
- friend class Handle; |
- // MaybeHandle is allowed to access location_. |
- template <typename> |
- friend class MaybeHandle; |
-}; |
- |
-template <typename T> |
-V8_INLINE Handle<T> handle(T* object, Isolate* isolate) { |
- return Handle<T>(object, isolate); |
-} |
- |
-template <typename T> |
-V8_INLINE Handle<T> handle(T* object) { |
- return Handle<T>(object); |
-} |
- |
- |
-// ---------------------------------------------------------------------------- |
// A Handle can be converted into a MaybeHandle. Converting a MaybeHandle |
// into a Handle requires checking that it does not point to NULL. This |
// ensures NULL checks before use. |
// Do not use MaybeHandle as argument type. |
-template <typename T> |
-class MaybeHandle final { |
- public: |
- V8_INLINE MaybeHandle() {} |
- V8_INLINE ~MaybeHandle() {} |
+ |
+template<typename T> |
+class MaybeHandle { |
+ public: |
+ INLINE(MaybeHandle()) : location_(NULL) { } |
// Constructor for handling automatic up casting from Handle. |
// Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected. |
- template <typename S> |
- V8_INLINE MaybeHandle(Handle<S> handle) |
- : location_(reinterpret_cast<T**>(handle.location_)) { |
- T* a = nullptr; |
- S* b = nullptr; |
+ template <class S> MaybeHandle(Handle<S> handle) { |
+#ifdef DEBUG |
+ T* a = NULL; |
+ S* b = NULL; |
a = b; // Fake assignment to enforce type checks. |
USE(a); |
+#endif |
+ this->location_ = reinterpret_cast<T**>(handle.location()); |
} |
// Constructor for handling automatic up casting. |
// Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected. |
- template <typename S> |
- V8_INLINE MaybeHandle(MaybeHandle<S> maybe_handle) |
- : location_(reinterpret_cast<T**>(maybe_handle.location_)) { |
- T* a = nullptr; |
- S* b = nullptr; |
+ template <class S> MaybeHandle(MaybeHandle<S> maybe_handle) { |
+#ifdef DEBUG |
+ T* a = NULL; |
+ S* b = NULL; |
a = b; // Fake assignment to enforce type checks. |
USE(a); |
- } |
- |
- V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); } |
- V8_INLINE void Check() const { CHECK_NOT_NULL(location_); } |
- |
- V8_INLINE Handle<T> ToHandleChecked() const { |
+#endif |
+ location_ = reinterpret_cast<T**>(maybe_handle.location_); |
+ } |
+ |
+ INLINE(void Assert() const) { DCHECK(location_ != NULL); } |
+ INLINE(void Check() const) { CHECK(location_ != NULL); } |
+ |
+ INLINE(Handle<T> ToHandleChecked()) const { |
Check(); |
return Handle<T>(location_); |
} |
// Convert to a Handle with a type that can be upcasted to. |
- template <typename S> |
+ template <class S> |
V8_INLINE bool ToHandle(Handle<S>* out) const { |
- if (location_ == nullptr) { |
+ if (location_ == NULL) { |
*out = Handle<T>::null(); |
return false; |
} else { |
@@ -186,35 +64,118 @@ |
} |
} |
- bool is_null() const { return location_ == nullptr; } |
+ bool is_null() const { return location_ == NULL; } |
template <typename S> |
- V8_INLINE bool operator==(MaybeHandle<S> that) const { |
+ bool operator==(MaybeHandle<S> that) const { |
return this->location_ == that.location_; |
} |
template <typename S> |
- V8_INLINE bool operator!=(MaybeHandle<S> that) const { |
- return this->location_ != that.location_; |
- } |
+ bool operator!=(MaybeHandle<S> that) const { |
+ return !(*this == that); |
+ } |
+ |
protected: |
- T** location_ = nullptr; |
+ T** location_; |
// MaybeHandles of different classes are allowed to access each |
// other's location_. |
- template <typename> |
- friend class MaybeHandle; |
- // Utility functions are allowed to access location_. |
+ template<class S> friend class MaybeHandle; |
template <typename S> |
friend size_t hash_value(MaybeHandle<S>); |
}; |
-template <typename T> |
-V8_INLINE size_t hash_value(MaybeHandle<T> maybe_handle) { |
- uintptr_t v = bit_cast<uintptr_t>(maybe_handle.location_); |
- DCHECK_EQ(0u, v & ((1u << kPointerSizeLog2) - 1)); |
- return v >> kPointerSizeLog2; |
+template <typename S> |
+inline size_t hash_value(MaybeHandle<S> maybe_handle) { |
+ return bit_cast<size_t>(maybe_handle.location_); |
} |
+ |
+ |
+// ---------------------------------------------------------------------------- |
+// A Handle provides a reference to an object that survives relocation by |
+// the garbage collector. |
+// Handles are only valid within a HandleScope. |
+// When a handle is created for an object a cell is allocated in the heap. |
+ |
+template<typename T> |
+class Handle { |
+ public: |
+ INLINE(explicit Handle(T** location)) { location_ = location; } |
+ INLINE(explicit Handle(T* obj)); |
+ INLINE(Handle(T* obj, Isolate* isolate)); |
+ |
+ // TODO(yangguo): Values that contain empty handles should be declared as |
+ // MaybeHandle to force validation before being used as handles. |
+ INLINE(Handle()) : location_(NULL) { } |
+ |
+ // Constructor for handling automatic up casting. |
+ // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected. |
+ template <class S> Handle(Handle<S> handle) { |
+#ifdef DEBUG |
+ T* a = NULL; |
+ S* b = NULL; |
+ a = b; // Fake assignment to enforce type checks. |
+ USE(a); |
+#endif |
+ location_ = reinterpret_cast<T**>(handle.location_); |
+ } |
+ |
+ INLINE(T* operator->() const) { return operator*(); } |
+ |
+ // Check if this handle refers to the exact same object as the other handle. |
+ INLINE(bool is_identical_to(const Handle<T> other) const); |
+ |
+ // Provides the C++ dereference operator. |
+ INLINE(T* operator*() const); |
+ |
+ // Returns the address to where the raw pointer is stored. |
+ INLINE(T** location() const); |
+ |
+ template <class S> static Handle<T> cast(Handle<S> that) { |
+ T::cast(*reinterpret_cast<T**>(that.location_)); |
+ return Handle<T>(reinterpret_cast<T**>(that.location_)); |
+ } |
+ |
+ // TODO(yangguo): Values that contain empty handles should be declared as |
+ // MaybeHandle to force validation before being used as handles. |
+ static Handle<T> null() { return Handle<T>(); } |
+ bool is_null() const { return location_ == NULL; } |
+ |
+ // Closes the given scope, but lets this handle escape. See |
+ // implementation in api.h. |
+ inline Handle<T> EscapeFrom(v8::EscapableHandleScope* scope); |
+ |
+#ifdef DEBUG |
+ enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK }; |
+ |
+ bool IsDereferenceAllowed(DereferenceCheckMode mode) const; |
+#endif // DEBUG |
+ |
+ private: |
+ T** location_; |
+ |
+ // Handles of different classes are allowed to access each other's location_. |
+ template<class S> friend class Handle; |
+}; |
+ |
+ |
+// Convenience wrapper. |
+template<class T> |
+inline Handle<T> handle(T* t, Isolate* isolate) { |
+ return Handle<T>(t, isolate); |
+} |
+ |
+ |
+// Convenience wrapper. |
+template<class T> |
+inline Handle<T> handle(T* t) { |
+ return Handle<T>(t, t->GetIsolate()); |
+} |
+ |
+ |
+class DeferredHandles; |
+class HandleScopeImplementer; |
// A stack-allocated class that governs a number of local handles. |
@@ -280,7 +241,7 @@ |
Object** prev_limit); |
// Extend the handle scope making room for more handles. |
- static Object** Extend(Isolate* isolate); |
+ static internal::Object** Extend(Isolate* isolate); |
#ifdef ENABLE_HANDLE_ZAPPING |
// Zaps the handles in the half-open interval [start, end). |
@@ -288,13 +249,16 @@ |
#endif |
friend class v8::HandleScope; |
- friend class DeferredHandles; |
- friend class HandleScopeImplementer; |
- friend class Isolate; |
-}; |
- |
- |
-class DeferredHandleScope final { |
+ friend class v8::internal::DeferredHandles; |
+ friend class v8::internal::HandleScopeImplementer; |
+ friend class v8::internal::Isolate; |
+}; |
+ |
+ |
+class DeferredHandles; |
+ |
+ |
+class DeferredHandleScope { |
public: |
explicit DeferredHandleScope(Isolate* isolate); |
// The DeferredHandles object returned stores the Handles created |
@@ -319,7 +283,7 @@ |
// Seal off the current HandleScope so that new handles can only be created |
// if a new HandleScope is entered. |
-class SealHandleScope final { |
+class SealHandleScope BASE_EMBEDDED { |
public: |
#ifndef DEBUG |
explicit SealHandleScope(Isolate* isolate) {} |
@@ -334,10 +298,9 @@ |
#endif |
}; |
- |
-struct HandleScopeData final { |
- Object** next; |
- Object** limit; |
+struct HandleScopeData { |
+ internal::Object** next; |
+ internal::Object** limit; |
int level; |
void Initialize() { |
@@ -346,7 +309,6 @@ |
} |
}; |
-} // namespace internal |
-} // namespace v8 |
+} } // namespace v8::internal |
#endif // V8_HANDLES_H_ |