Index: third_party/WebKit/Source/platform/heap/Handle.h |
diff --git a/third_party/WebKit/Source/platform/heap/Handle.h b/third_party/WebKit/Source/platform/heap/Handle.h |
index fd9415a02382af0ad0f35457dd7285cb41c122fa..6d58177b444f147111a8b575fca889e9af51f75c 100644 |
--- a/third_party/WebKit/Source/platform/heap/Handle.h |
+++ b/third_party/WebKit/Source/platform/heap/Handle.h |
@@ -869,6 +869,109 @@ private: |
template<typename Derived> friend class VisitorHelper; |
}; |
+// UnsafePtr is actually a raw pointer. |
+// It is allowed to store a pointer to an object on oilpan heap, |
+// and it is also allowed to store UnsafePtr in off heap collections. |
+// UnsafePtr does not keep the pointee object alive, so if you use |
+// UnsafePtr, you must guarantee that the pointee object is alive in |
+// some reason. |
+template<typename T> |
+class UnsafePtr { |
haraken
2015/10/14 06:00:21
I'd rename UnsafePtr to UnsafeMember or UntracedMe
haraken
2015/10/14 06:00:21
Add conversions between UnsafePtr <=> Member, Pers
peria
2015/10/14 09:36:28
OK. Both names look better than UnsafePtr.
peria
2015/10/14 09:36:28
Done.
|
+public: |
+ UnsafePtr() : m_raw(nullptr) |
+ { |
+ } |
+ |
+ UnsafePtr(std::nullptr_t) : m_raw(nullptr) |
+ { |
+ } |
+ |
+ UnsafePtr(T* raw) : m_raw(raw) |
+ { |
+ checkPointer(); |
+ } |
+ |
+ template<typename U> |
+ UnsafePtr(const RawPtr<U>& other) : m_raw(other.get()) |
+ { |
+ checkPointer(); |
+ } |
+ |
+ bool operator!() const { return !m_raw; } |
+ |
+ operator T*() const { return m_raw; } |
+ |
+ T* operator->() const { return m_raw; } |
+ T& operator*() const { return *m_raw; } |
+ template<typename U> |
+ operator RawPtr<U>() const { return m_raw; } |
+ |
+ template<typename U> |
+ UnsafePtr& operator=(const UnsafePtr<U>& other) |
+ { |
+ m_raw = other; |
+ checkPointer(); |
+ return *this; |
+ } |
+ |
+ template<typename U> |
+ UnsafePtr& operator=(U* other) |
+ { |
+ m_raw = other; |
+ checkPointer(); |
+ return *this; |
+ } |
+ |
+ template<typename U> |
+ UnsafePtr& operator=(RawPtr<U> other) |
+ { |
+ m_raw = other; |
+ checkPointer(); |
+ return *this; |
+ } |
+ |
+ UnsafePtr& operator=(std::nullptr_t) |
+ { |
+ m_raw = nullptr; |
+ return *this; |
+ } |
+ |
+ void swap(UnsafePtr<T>& other) |
+ { |
+ std::swap(m_raw, other.m_raw); |
+ checkPointer(); |
+ } |
+ |
+ T* get() const { return m_raw; } |
+ |
+ void clear() { m_raw = nullptr; } |
+ |
+ |
+protected: |
+ void checkPointer() |
+ { |
+#if ENABLE(ASSERT) |
+ if (!m_raw) |
+ return; |
+ |
+ // TODO(haraken): What we really want to check here is that the pointer |
+ // is a traceable object. In other words, the pointer is either of: |
+ // |
+ // (a) a pointer to the head of an on-heap object. |
+ // (b) a pointer to the head of an on-heap mixin object. |
+ // |
+ // We can check it by calling Heap::isHeapObjectAlive(m_raw), |
+ // but we cannot call it here because it requires to include T.h. |
+ // So we currently only try to implement the check for (a), but do |
+ // not insist that T's definition is in scope. |
+ if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value) |
+ ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader()); |
+#endif |
+ } |
+ |
+ T* m_raw; |
+}; |
+ |
// Comparison operators between (Weak)Members and Persistents |
template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); } |
template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); } |