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

Unified Diff: public/platform/WebPrivatePtr.h

Issue 168963003: Make WebPrivatePtr capable of wrapping garbage collected objects. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Temporarily drop back to using .reset() instead of nullptr. Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « public/DEPS ('k') | public/web/WebSpeechGrammar.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: public/platform/WebPrivatePtr.h
diff --git a/public/platform/WebPrivatePtr.h b/public/platform/WebPrivatePtr.h
index a0b57c9a41b70178e273615194888766576cf7c5..4b3da1c3400713d15b662e19784df23ce6f12de6 100644
--- a/public/platform/WebPrivatePtr.h
+++ b/public/platform/WebPrivatePtr.h
@@ -34,11 +34,129 @@
#include "WebCommon.h"
#if INSIDE_BLINK
+#include "heap/Handle.h"
#include "wtf/PassRefPtr.h"
+#include "wtf/TypeTraits.h"
#endif
namespace blink {
+#if INSIDE_BLINK
+enum LifetimeManagementType {
+ RefCountedLifetime,
+ GarbageCollectedLifetime,
+ RefCountedGarbageCollectedLifetime
+};
+
+template<typename T>
+class LifetimeOf {
+ static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, WebCore::GarbageCollected>::value;
+ static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T, WebCore::RefCountedGarbageCollected>::value;
+public:
+ static const LifetimeManagementType value =
+ !isGarbageCollected ? RefCountedLifetime :
+ isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : GarbageCollectedLifetime;
+};
+
+template<typename T, LifetimeManagementType lifetime>
+class PtrStorageImpl;
+
+template<typename T>
+class PtrStorageImpl<T, RefCountedLifetime> {
+public:
+ typedef PassRefPtr<T> BlinkPtrType;
+
+ void assign(const BlinkPtrType& val)
+ {
+ release();
+ m_ptr = val.leakRef();
+ }
+
+ void assign(const PtrStorageImpl& other)
+ {
+ release();
+ T* val = other.get();
+ if (val)
+ val->ref();
+ m_ptr = val;
+ }
+
+ T* get() const { return m_ptr; }
+
+ void release()
+ {
+ if (m_ptr)
+ m_ptr->deref();
+ m_ptr = 0;
+ }
+
+private:
+ T* m_ptr;
+};
+
+template<typename T>
+class PtrStorageImpl<T, GarbageCollectedLifetime> {
+public:
+ void assign(const RawPtr<T>& val)
+ {
+ if (!val) {
+ release();
+ return;
+ }
+
+ if (!m_handle)
+ m_handle = new WebCore::Persistent<T>();
+
+ (*m_handle) = val;
+ }
+
+ void assign(T* ptr) { assign(RawPtr<T>(ptr)); }
+
+ void assign(const PtrStorageImpl& other) { assign(other.get()); }
+
+ T* get() const { return m_handle ? m_handle->get() : 0; }
+
+ void release()
+ {
+ delete m_handle;
+ m_handle = 0;
+ }
+
+private:
+ WebCore::Persistent<T>* m_handle;
+};
+
+template<typename T>
+class PtrStorageImpl<T, RefCountedGarbageCollectedLifetime> : public PtrStorageImpl<T, GarbageCollectedLifetime> {
+public:
+ void assign(const PassRefPtr<T>& val) { PtrStorageImpl<T, GarbageCollectedLifetime>::assign(val.get()); }
+
+ void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, GarbageCollectedLifetime>::assign(other.get()); }
+};
+
+template<typename T>
+class PtrStorage : public PtrStorageImpl<T, LifetimeOf<T>::value> {
+public:
+ static PtrStorage& fromSlot(void** slot)
+ {
+ COMPILE_ASSERT(sizeof(PtrStorage) == sizeof(void*), PtrStorage_must_be_pointer_size);
+ return *reinterpret_cast<PtrStorage*>(slot);
+ }
+
+ static const PtrStorage& fromSlot(void* const* slot)
+ {
+ COMPILE_ASSERT(sizeof(PtrStorage) == sizeof(void*), PtrStorage_must_be_pointer_size);
+ return *reinterpret_cast<const PtrStorage*>(slot);
+ }
+
+private:
+ // Prevent construction via normal means.
+ PtrStorage();
+ PtrStorage(const PtrStorage&);
+};
+#endif
+
+
// This class is an implementation detail of the Blink API. It exists to help
// simplify the implementation of Blink interfaces that merely wrap a reference
// counted WebCore class.
@@ -78,66 +196,63 @@ namespace blink {
template <typename T>
class WebPrivatePtr {
public:
- WebPrivatePtr() : m_ptr(0) { }
+ WebPrivatePtr() : m_storage(0) { }
~WebPrivatePtr()
{
// We don't destruct the object pointed by m_ptr here because we don't
// want to expose destructors of core classes to embedders. We should
// call reset() manually in destructors of classes with WebPrivatePtr
// members.
- BLINK_ASSERT(!m_ptr);
+ BLINK_ASSERT(!m_storage);
}
- bool isNull() const { return !m_ptr; }
+ bool isNull() const { return !m_storage; }
#if INSIDE_BLINK
- WebPrivatePtr(const PassRefPtr<T>& prp)
- : m_ptr(prp.leakRef())
+ template<typename U>
+ WebPrivatePtr(const U& ptr)
+ : m_storage(0)
{
+ storage().assign(ptr);
}
- void reset()
- {
- assign(0);
- }
+ void reset() { storage().release(); }
WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other)
{
- T* p = other.m_ptr;
- if (p)
- p->ref();
- assign(p);
+ storage().assign(other.storage());
return *this;
}
- WebPrivatePtr<T>& operator=(const PassRefPtr<T>& prp)
+ WebPrivatePtr<T>& operator=(std::nullptr_t&)
jamesr 2014/02/18 22:18:53 NAK on this - we can't expose std::nullptr_t throu
jamesr 2014/02/18 22:20:30 Ah - I missed that this was in the INSIDE_BLINK se
sof 2014/02/19 06:11:44 It will go away once https://codereview.chromium.o
{
- assign(prp.leakRef());
+ reset();
return *this;
}
- T* get() const
+ template<typename U>
+ WebPrivatePtr<T>& operator=(const U& ptr)
{
- return m_ptr;
+ storage().assign(ptr);
+ return *this;
}
+ T* get() const { return storage().get(); }
+
T* operator->() const
{
- ASSERT(m_ptr);
- return m_ptr;
+ ASSERT(m_storage);
+ return get();
}
#endif
private:
#if INSIDE_BLINK
- void assign(T* p)
- {
- // p is already ref'd for us by the caller
- if (m_ptr)
- m_ptr->deref();
- m_ptr = p;
- }
-#else
+ PtrStorage<T>& storage() { return PtrStorage<T>::fromSlot(&m_storage); }
+ const PtrStorage<T>& storage() const { return PtrStorage<T>::fromSlot(&m_storage); }
+#endif
+
+#if !INSIDE_BLINK
// Disable the assignment operator; we define it above for when
// INSIDE_BLINK is set, but we need to make sure that it is not
// used outside there; the compiler-provided version won't handle reference
@@ -148,7 +263,7 @@ private:
// should implement their copy constructor using assign().
WebPrivatePtr(const WebPrivatePtr<T>&);
- T* m_ptr;
+ void* m_storage;
};
} // namespace blink
« no previous file with comments | « public/DEPS ('k') | public/web/WebSpeechGrammar.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698