Index: Source/platform/Supplementable.h |
diff --git a/Source/platform/Supplementable.h b/Source/platform/Supplementable.h |
index 7d238da4040fdde9c212a643ea4e4c870e0a8d12..eef553d6ca5525b7a7cd81bcb3cdd7500ea86bcc 100644 |
--- a/Source/platform/Supplementable.h |
+++ b/Source/platform/Supplementable.h |
@@ -26,6 +26,7 @@ |
#ifndef Supplementable_h |
#define Supplementable_h |
+#include "heap/Handle.h" |
#include "wtf/Assertions.h" |
#include "wtf/HashMap.h" |
#include "wtf/OwnPtr.h" |
@@ -87,37 +88,84 @@ namespace WebCore { |
// Note that reattachThread() does nothing if assertion is not enabled. |
// |
+template<typename T, bool isGarbageCollected> |
+class SupplementBase; |
+ |
+template<typename T, bool isGarbageCollected> |
+class SupplementableBase; |
+ |
+template<typename T, bool isGarbageCollected> |
+struct SupplementableTraitsImpl; |
+ |
+template<typename T> |
+struct SupplementableTraitsImpl<T, true> { |
+ typedef RawPtr<SupplementBase<T, true> > SupplementArgumentType; |
Mads Ager (chromium)
2014/02/26 08:00:36
Shouldn't this be PassOwnPtrWillBeRawPtr?
sof
2014/02/26 09:11:21
Yes, that would be tidier.
|
+ typedef WillBeHeapHashMap<const char*, RefPtrWillBeMember<SupplementBase<T, true> >, PtrHash<const char*> > SupplementMap; |
Mads Ager (chromium)
2014/02/26 08:00:36
Shouldn't this be OwnPtrWillBeMember?
sof
2014/02/26 09:11:21
Done.
|
+}; |
+ |
template<typename T> |
-class Supplementable; |
+struct SupplementableTraitsImpl<T, false> { |
+ typedef PassOwnPtr<SupplementBase<T, false> > SupplementArgumentType; |
+ typedef HashMap<const char*, OwnPtr<SupplementBase<T, false> >, PtrHash<const char*> > SupplementMap; |
+}; |
+// FIXME: oilpan: this doesn't work as wanted when used in e.g., |
+// |
+// class C : public GarbageCollected<C>, Supplementable<C> { .. }; |
+// |
+// as deriving that C is a subclass of GarbageCollected while declaring C doesn't |
+// appear possible (returns 'false'.) |
+// |
+// This is why we have a bool template argument instead. This has some merit while |
+// in transition, as it allows the Supplementable to remain off-heap while converting |
+// the object itself. |
template<typename T> |
-class Supplement { |
+struct SupplementableTraits : public SupplementableTraitsImpl<T, WTF::IsSubclassOfTemplate<T, WebCore::GarbageCollected>::value> { |
Mads Ager (chromium)
2014/02/26 08:00:36
Let's remove SupplementableTraits. As you state it
sof
2014/02/26 09:11:21
yes, i'm currently out of ideas of how to derive a
|
+}; |
+ |
+template<bool> |
+class SupplementTracing; |
+ |
+template<> |
+class SupplementTracing<true> { |
+public: |
+ virtual void trace(Visitor*) = 0; |
+}; |
+ |
+template<> |
+class SupplementTracing<false> { |
+public: |
+ virtual void trace(Visitor*) { } |
+}; |
+ |
+template<typename T, bool isGarbageCollected = false> |
+class SupplementBase : public SupplementTracing<isGarbageCollected> { |
public: |
- virtual ~Supplement() { } |
+ virtual ~SupplementBase() { } |
#if SECURITY_ASSERT_ENABLED |
virtual bool isRefCountedWrapper() const { return false; } |
#endif |
- static void provideTo(Supplementable<T>& host, const char* key, PassOwnPtr<Supplement<T> > supplement) |
+ static void provideTo(SupplementableBase<T, isGarbageCollected>& host, const char* key, typename SupplementableTraitsImpl<T, isGarbageCollected>::SupplementArgumentType supplement) |
{ |
host.provideSupplement(key, supplement); |
} |
- static Supplement<T>* from(Supplementable<T>& host, const char* key) |
+ static SupplementBase<T, isGarbageCollected>* from(SupplementableBase<T, isGarbageCollected>& host, const char* key) |
{ |
return host.requireSupplement(key); |
} |
- static Supplement<T>* from(Supplementable<T>* host, const char* key) |
+ static SupplementBase<T, isGarbageCollected>* from(SupplementableBase<T, isGarbageCollected>* host, const char* key) |
{ |
return host ? host->requireSupplement(key) : 0; |
} |
}; |
-template<typename T> |
-class Supplementable { |
+template<typename T, bool isGarbageCollected = false> |
+class SupplementableBase { |
public: |
- void provideSupplement(const char* key, PassOwnPtr<Supplement<T> > supplement) |
+ void provideSupplement(const char* key, typename SupplementableTraitsImpl<T, isGarbageCollected>::SupplementArgumentType supplement) |
{ |
ASSERT(m_threadId == currentThread()); |
ASSERT(!m_supplements.get(key)); |
@@ -130,7 +178,7 @@ public: |
m_supplements.remove(key); |
} |
- Supplement<T>* requireSupplement(const char* key) |
+ SupplementBase<T, isGarbageCollected>* requireSupplement(const char* key) |
{ |
ASSERT(m_threadId == currentThread()); |
return m_supplements.get(key); |
@@ -143,19 +191,45 @@ public: |
#endif |
} |
+ void trace(Visitor* visitor) |
+ { |
+ visitor->trace(m_supplements); |
+ } |
+ |
#if !ASSERT_DISABLED |
protected: |
- Supplementable() : m_threadId(currentThread()) { } |
+ SupplementableBase() : m_threadId(currentThread()) { } |
#endif |
private: |
- typedef HashMap<const char*, OwnPtr<Supplement<T> >, PtrHash<const char*> > SupplementMap; |
- SupplementMap m_supplements; |
+ typename SupplementableTraitsImpl<T, isGarbageCollected>::SupplementMap m_supplements; |
#if !ASSERT_DISABLED |
ThreadIdentifier m_threadId; |
#endif |
}; |
+template<typename T> |
+class HeapSupplement : public SupplementBase<T, true> { }; |
+ |
+template<typename T> |
+class HeapSupplementable : public SupplementableBase<T, true> { }; |
+ |
+template<typename T> |
+class Supplement : public SupplementBase<T, false> { }; |
+ |
+template<typename T> |
+class Supplementable : public SupplementableBase<T, false> { }; |
+ |
+template<typename T> |
+struct ThreadingTrait<WebCore::SupplementBase<T, true> > { |
+ static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
+}; |
+ |
+template<typename T> |
+struct ThreadingTrait<WebCore::SupplementableBase<T, true> > { |
+ static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; |
+}; |
+ |
} // namespace WebCore |
#endif // Supplementable_h |