Index: Source/heap/Handle.h |
diff --git a/Source/heap/Handle.h b/Source/heap/Handle.h |
index 5e281866df16118b6aed095ab1e155c81cc18f05..5afd9e9d47ebe2f407440157105b1b0920dae7d6 100644 |
--- a/Source/heap/Handle.h |
+++ b/Source/heap/Handle.h |
@@ -38,12 +38,25 @@ |
namespace WebCore { |
template<typename T> class Member; |
+template<typename T> struct OffHeapCollectionTraceTrait; |
class PersistentNode { |
public: |
- explicit PersistentNode(TraceCallback trace) : m_trace(trace) { } |
+ explicit PersistentNode(TraceCallback trace) |
+ : m_trace(trace) |
+#ifndef NDEBUG |
Mads Ager (chromium)
2014/01/15 08:48:17
Thanks for adding verification; that should make f
|
+ , m_alive(true) |
+#endif |
+ { |
+ } |
- virtual ~PersistentNode() { } |
+ virtual ~PersistentNode() |
+ { |
+#ifndef NDEBUG |
+ ASSERT(m_alive); |
+ m_alive = false; |
+#endif |
+ } |
// Ideally the trace method should be virtual and automatically dispatch |
// to the most specific implementation. However having a virtual method |
@@ -60,6 +73,10 @@ public: |
protected: |
TraceCallback m_trace; |
+#ifndef NDEBUG |
+ bool m_alive; |
+#endif |
+ |
private: |
PersistentNode* m_next; |
PersistentNode* m_prev; |
@@ -75,6 +92,9 @@ public: |
~PersistentBase() |
{ |
#ifndef NDEBUG |
+ ASSERT(m_alive); |
+ ASSERT(m_next->m_alive); |
+ ASSERT(m_prev->m_alive); |
m_threadState->checkThread(); |
#endif |
m_next->m_prev = m_prev; |
@@ -135,7 +155,11 @@ public: |
void trace(Visitor*) { } |
private: |
- virtual ~PersistentAnchor() { } |
+ virtual ~PersistentAnchor() |
+ { |
+ ASSERT(m_next == this); |
+ ASSERT(m_prev == this); |
+ } |
PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &PersistentAnchor::trace>::trampoline) |
{ |
m_next = this; |
@@ -321,9 +345,9 @@ public: |
void swap(Member<T>& other) { std::swap(m_raw, other.m_raw); } |
-protected: |
T* raw() const { return m_raw; } |
+protected: |
haraken
2014/01/15 04:48:35
Don't we want private here?
zerny-chromium
2014/01/15 08:05:27
WeakMember needs access to m_raw.
btw, most of th
Mads Ager (chromium)
2014/01/15 08:48:17
Drive-by answer. :-)
We don't need private here.
|
T* m_raw; |
template<typename U> friend class Member; |
@@ -417,12 +441,60 @@ private: |
// 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.m_raw == b.m_raw; } |
template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.m_raw != b.m_raw; } |
-template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.m_raw == b.m_raw; } |
-template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.m_raw != b.m_raw; } |
-template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.m_raw == b.m_raw; } |
-template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.m_raw != b.m_raw; } |
-template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.m_raw == b.m_raw; } |
-template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.m_raw != b.m_raw; } |
+template<typename T, typename U> inline bool operator==(const Member<T>& a, const Persistent<U>& b) { return a.m_raw == b.raw(); } |
Mads Ager (chromium)
2014/01/15 08:48:17
This is a complete mess. Let us just use a.get() =
|
+template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Persistent<U>& b) { return a.m_raw != b.raw(); } |
+template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Member<U>& b) { return a.raw() == b.m_raw; } |
+template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Member<U>& b) { return a.raw() != b.m_raw; } |
+template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.raw() == b.raw(); } |
+template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.raw() != b.raw(); } |
+ |
+template<typename Collection, ThreadAffinity Affinity = MainThreadOnly> class CollectionPersistent; |
+ |
+// Used to inject correctly typed operator[] into CollectionPersistent when we are wrapping Vector. |
+template<typename T> class IndexingBehavior { }; |
+ |
+template<typename T, size_t inlineCapacity> |
+class IndexingBehavior<CollectionPersistent<Vector<T, inlineCapacity, WTF::DefaultAllocator> > > { |
+ typedef CollectionPersistent<Vector<T, inlineCapacity, WTF::DefaultAllocator> > CollectionPersistentType; |
+public: |
+ T& operator[] (size_t i) { return (**static_cast<CollectionPersistentType*>(this))[i]; } |
+ const T& operator[] (size_t i) const { return (**static_cast<const CollectionPersistentType*>(this))[i]; } |
+}; |
+ |
+template<typename Collection, ThreadAffinity Affinity> |
+class CollectionPersistent |
+ : public PersistentBase<Affinity, CollectionPersistent<Collection, Affinity> > |
+ , public IndexingBehavior<CollectionPersistent<Collection, Affinity> > { |
+public: |
+ typedef Collection CollectionType; |
+ typedef typename Collection::iterator iterator; |
+ typedef typename Collection::const_iterator const_iterator; |
+ |
+ CollectionPersistent() { } |
+ explicit CollectionPersistent(size_t size) : m_collection(Collection(size)) { } |
+ explicit CollectionPersistent(const Collection& collection) : m_collection(collection) { } |
+ CollectionPersistent& operator=(const Collection& collection) { m_collection = collection; return *this; } |
+ Collection* operator->() { return &m_collection; } |
+ const Collection* operator->() const { return &m_collection; } |
+ Collection& operator*() { return m_collection; } |
+ const Collection& operator*() const { return m_collection; } |
+ |
+ void trace(Visitor* visitor) |
+ { |
+ OffHeapCollectionTraceTrait<Collection>::mark(visitor, m_collection); } |
haraken
2014/01/15 04:48:35
Write } in the next line.
Erik Corry
2014/01/15 09:27:32
Done.
|
+ |
+#if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING |
+ virtual const char* name() OVERRIDE |
+ { |
+ ASSERT(this == static_cast<PersistentNode*>(this)); |
+ const char* n = FieldAnnotationBase::fromAddress(this); |
+ return n ? n : "CollectionPersistent"; |
+ } |
+#endif |
+ |
+private: |
+ Collection m_collection; |
+}; |
} // namespace WebCore |
@@ -449,13 +521,13 @@ template<typename T> struct HashTraits<WebCore::Member<T> > : SimpleClassHashTra |
// in the marking Visitor. |
typedef T* PeekInType; |
typedef T* PassInType; |
- typedef T* IteratorGetType; |
- typedef T* IteratorConstGetType; |
+ typedef WebCore::Member<T>* IteratorGetType; |
+ typedef const WebCore::Member<T>* IteratorConstGetType; |
typedef T* IteratorReferenceType; |
typedef T* IteratorConstReferenceType; |
static IteratorConstGetType getToConstGetConversion(const WebCore::Member<T>* x) { return x->raw(); } |
- static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return x; } |
- static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x; } |
+ static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return x->raw(); } |
+ static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->raw(); } |
// FIXME: Similarly, there is no need for a distinction between PeekOutType |
// and PassOutType without reference counting. |
typedef T* PeekOutType; |
@@ -477,13 +549,13 @@ template<typename T> struct HashTraits<WebCore::WeakMember<T> > : SimpleClassHas |
// in the marking Visitor. |
typedef T* PeekInType; |
typedef T* PassInType; |
- typedef T* IteratorGetType; |
- typedef T* IteratorConstGetType; |
+ typedef WebCore::WeakMember<T>* IteratorGetType; |
+ typedef const WebCore::WeakMember<T>* IteratorConstGetType; |
typedef T* IteratorReferenceType; |
typedef T* IteratorConstReferenceType; |
static IteratorConstGetType getToConstGetConversion(const WebCore::WeakMember<T>* x) { return x->raw(); } |
- static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return x; } |
- static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x; } |
+ static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { return x->raw(); } |
+ static IteratorConstReferenceType getToReferenceConstConversion(IteratorConstGetType x) { return x->raw(); } |
// FIXME: Similarly, there is no need for a distinction between PeekOutType |
// and PassOutType without reference counting. |
typedef T* PeekOutType; |