Index: src/handles.h |
diff --git a/src/handles.h b/src/handles.h |
index 36d10acaa776d1ffc0974fdae8e90ae3ee47284f..eb57f0e26089383c9d7fe9f57a8cba5f41a111e2 100644 |
--- a/src/handles.h |
+++ b/src/handles.h |
@@ -9,49 +9,45 @@ |
namespace v8 { |
namespace internal { |
- |
-// Forward declarations. |
-class DeferredHandles; |
-class HandleScopeImplementer; |
- |
// 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 { |
public: |
- V8_INLINE MaybeHandle() : location_(nullptr) {} |
+ INLINE(MaybeHandle()) : location_(NULL) { } |
// Constructor for handling automatic up casting from Handle. |
// Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected. |
template <class S> MaybeHandle(Handle<S> handle) { |
-#ifdef DEBUG |
- T* a = nullptr; |
- S* b = nullptr; |
- 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 <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); |
#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 <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); |
+#endif |
location_ = reinterpret_cast<T**>(maybe_handle.location_); |
} |
- V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); } |
- V8_INLINE void Check() const { CHECK_NOT_NULL(location_); } |
- |
- V8_INLINE Handle<T> ToHandleChecked() const { |
+ INLINE(void Assert() const) { DCHECK(location_ != NULL); } |
+ INLINE(void Check() const) { CHECK(location_ != NULL); } |
+ |
+ INLINE(Handle<T> ToHandleChecked()) const { |
Check(); |
return Handle<T>(location_); |
} |
@@ -78,114 +74,69 @@ |
template<class S> friend class MaybeHandle; |
}; |
- |
-// Base class for Handles. Don't use this directly. |
-class HandleBase { |
- public: |
- V8_INLINE explicit HandleBase(Object** location = nullptr) |
- : location_(location) {} |
- V8_INLINE explicit HandleBase(HandleBase const& other) |
- : location_(other.location_) {} |
- explicit HandleBase(HeapObject* object); |
- explicit HandleBase(Object* object, Isolate* isolate); |
- V8_INLINE ~HandleBase() {} |
- |
- // Check if this handle refers to the exact same object as the other handle. |
- V8_INLINE bool is_identical_to(HandleBase const& other) const { |
- // Dereferencing deferred handles to check object equality is safe. |
- SLOW_DCHECK(is_null() || IsDereferenceAllowed(NO_DEFERRED_CHECK)); |
- SLOW_DCHECK(other.is_null() || |
- other.IsDereferenceAllowed(NO_DEFERRED_CHECK)); |
- if (location_ == other.location_) return true; |
- if (location_ == nullptr || other.location_ == nullptr) return false; |
- return *location_ == *other.location_; |
- } |
- |
- // Check if this handle is a NULL handle. |
- V8_INLINE bool is_null() const { return location_ == nullptr; } |
- |
- protected: |
- // Provides the C++ deference 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_ == nullptr || |
- 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) 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) |
- : HandleBase(reinterpret_cast<Object**>(location)) {} |
- V8_INLINE explicit Handle(T* object) : HandleBase(object) {} |
- V8_INLINE Handle(T* object, Isolate* isolate) : HandleBase(object, isolate) {} |
+ |
+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. |
- V8_INLINE Handle() {} |
+ INLINE(Handle()) : location_(NULL) { } |
// Constructor for handling automatic up casting. |
// Ex. Handle<JSFunction> can be passed when Handle<Object> is expected. |
- template <class S> |
- V8_INLINE Handle(Handle<S> const& other) |
- : HandleBase(other) { |
- T* a = nullptr; |
- S* b = nullptr; |
+ 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); |
- } |
- |
- V8_INLINE T* operator->() const { return operator*(); } |
+#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. |
- V8_INLINE T* operator*() const { |
- return reinterpret_cast<T*>(HandleBase::operator*()); |
- } |
+ INLINE(T* operator*() const); |
// Returns the address to where the raw pointer is stored. |
- V8_INLINE T** location() const { |
- return reinterpret_cast<T**>(HandleBase::location()); |
- } |
- |
- template <class S> |
- V8_INLINE static Handle<T> cast(Handle<S> const& other) { |
- T::cast(*reinterpret_cast<T**>(other.location_)); |
- return Handle<T>(reinterpret_cast<T**>(other.location_)); |
+ 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); |
- private: |
+#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; |
}; |
@@ -199,9 +150,9 @@ |
// Convenience wrapper. |
-template <class T> |
+template<class T> |
inline Handle<T> handle(T* t) { |
- return Handle<T>(t); |
+ return Handle<T>(t, t->GetIsolate()); |
} |
@@ -210,6 +161,10 @@ |
// This is safe because maps don't move. |
return *lhs < *rhs; |
} |
+ |
+ |
+class DeferredHandles; |
+class HandleScopeImplementer; |
// A stack-allocated class that governs a number of local handles. |
@@ -224,21 +179,18 @@ |
// garbage collector will no longer track the object stored in the |
// handle and may deallocate it. The behavior of accessing a handle |
// for which the handle scope has been deleted is undefined. |
-class HandleScope final { |
- public: |
- explicit HandleScope(Isolate* isolate); |
- ~HandleScope(); |
+class HandleScope { |
+ public: |
+ explicit inline HandleScope(Isolate* isolate); |
+ |
+ inline ~HandleScope(); |
// Counts the number of allocated handles. |
static int NumberOfHandles(Isolate* isolate); |
// Creates a new handle with the given value. |
- static Object** CreateHandle(Isolate* isolate, Object* value); |
template <typename T> |
- static T** CreateHandle(Isolate* isolate, T* value) { |
- return reinterpret_cast<T**>( |
- CreateHandle(isolate, static_cast<Object*>(value))); |
- } |
+ static inline T** CreateHandle(Isolate* isolate, T* value); |
// Deallocates any extensions used by the current scope. |
static void DeleteExtensions(Isolate* isolate); |
@@ -251,42 +203,43 @@ |
// created in the scope of the HandleScope) and returns |
// a Handle backed by the parent scope holding the |
// value of the argument handle. |
- Handle<Object> CloseAndEscape(Handle<Object> handle); |
template <typename T> |
- Handle<T> CloseAndEscape(Handle<T> handle) { |
- return Handle<T>::cast(CloseAndEscape(Handle<Object>::cast(handle))); |
- } |
- |
- Isolate* isolate() const { return isolate_; } |
- |
- private: |
+ Handle<T> CloseAndEscape(Handle<T> handle_value); |
+ |
+ Isolate* isolate() { return isolate_; } |
+ |
+ private: |
+ // Prevent heap allocation or illegal handle scopes. |
+ HandleScope(const HandleScope&); |
+ void operator=(const HandleScope&); |
+ void* operator new(size_t size); |
+ void operator delete(void* size_t); |
+ |
+ Isolate* isolate_; |
+ Object** prev_next_; |
+ Object** prev_limit_; |
+ |
+ // Close the handle scope resetting limits to a previous state. |
+ static inline void CloseScope(Isolate* isolate, |
+ Object** prev_next, |
+ Object** prev_limit); |
+ |
+ // Extend the handle scope making room for more handles. |
+ static internal::Object** Extend(Isolate* isolate); |
+ |
+#ifdef ENABLE_HANDLE_ZAPPING |
+ // Zaps the handles in the half-open interval [start, end). |
+ static void ZapRange(Object** start, Object** end); |
+#endif |
+ |
friend class v8::HandleScope; |
friend class v8::internal::DeferredHandles; |
friend class v8::internal::HandleScopeImplementer; |
friend class v8::internal::Isolate; |
- |
- // Prevent heap allocation or illegal handle scopes. |
- void* operator new(size_t size) = delete; |
- void operator delete(void* size_t) = delete; |
- |
- // Close the handle scope resetting limits to a previous state. |
- static void CloseScope(Isolate* isolate, Object** prev_next, |
- Object** prev_limit); |
- |
- // Extend the handle scope making room for more handles. |
- static Object** Extend(Isolate* isolate); |
- |
-#ifdef ENABLE_HANDLE_ZAPPING |
- // Zaps the handles in the half-open interval [start, end). |
- static void ZapRange(Object** start, Object** end); |
-#endif |
- |
- Isolate* const isolate_; |
- Object** prev_next_; |
- Object** prev_limit_; |
- |
- DISALLOW_COPY_AND_ASSIGN(HandleScope); |
-}; |
+}; |
+ |
+ |
+class DeferredHandles; |
class DeferredHandleScope { |
@@ -314,25 +267,20 @@ |
// 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) {} |
~SealHandleScope() {} |
#else |
- explicit SealHandleScope(Isolate* isolate); |
- ~SealHandleScope(); |
- |
- private: |
- Isolate* const isolate_; |
+ explicit inline SealHandleScope(Isolate* isolate); |
+ inline ~SealHandleScope(); |
+ private: |
+ Isolate* isolate_; |
Object** limit_; |
int level_; |
-#endif // DEBUG |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(SealHandleScope); |
-}; |
- |
+#endif |
+}; |
struct HandleScopeData { |
internal::Object** next; |
@@ -340,12 +288,11 @@ |
int level; |
void Initialize() { |
- next = limit = nullptr; |
+ next = limit = NULL; |
level = 0; |
} |
}; |
-} // namespace internal |
-} // namespace v8 |
+} } // namespace v8::internal |
#endif // V8_HANDLES_H_ |