2011-05-26 Geoffrey Garen <ggaren@apple.com>
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 May 2011 18:54:25 +0000 (18:54 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 May 2011 18:54:25 +0000 (18:54 +0000)
        Reviewed by Oliver Hunt.

        Filled out some features in DoublyLinkedList
        https://bugs.webkit.org/show_bug.cgi?id=61549

        * heap/MarkedBlock.h: Use DoublyLinkedListNode to simplify our class
        definition.

        * wtf/DoublyLinkedList.h:
        (WTF::::DoublyLinkedListNode):
        (WTF::::setPrev):
        (WTF::::setNext):
        (WTF::::prev):
        (WTF::::next): Added a helper base class for being a node in a list.
        The odd idioms here allow subclasses to choose their own data member
        layout, which is sometimes important for performance.

        (WTF::::DoublyLinkedList):
        (WTF::::isEmpty):
        (WTF::::size):
        (WTF::::clear):
        (WTF::::head):
        (WTF::::append):
        (WTF::::remove):
        (WTF::::removeHead): Change "Node" to "T" to be more idiomatic, and added
        clear(), removeHead(), and size() functions.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87408 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/heap/MarkedBlock.cpp
Source/JavaScriptCore/heap/MarkedBlock.h
Source/JavaScriptCore/wtf/DoublyLinkedList.h

index d348909..04871b2 100644 (file)
@@ -2,6 +2,35 @@
 
         Reviewed by Oliver Hunt.
 
+        Filled out some features in DoublyLinkedList
+        https://bugs.webkit.org/show_bug.cgi?id=61549
+
+        * heap/MarkedBlock.h: Use DoublyLinkedListNode to simplify our class
+        definition.
+
+        * wtf/DoublyLinkedList.h:
+        (WTF::::DoublyLinkedListNode):
+        (WTF::::setPrev):
+        (WTF::::setNext):
+        (WTF::::prev):
+        (WTF::::next): Added a helper base class for being a node in a list.
+        The odd idioms here allow subclasses to choose their own data member
+        layout, which is sometimes important for performance.
+
+        (WTF::::DoublyLinkedList):
+        (WTF::::isEmpty):
+        (WTF::::size):
+        (WTF::::clear):
+        (WTF::::head):
+        (WTF::::append):
+        (WTF::::remove):
+        (WTF::::removeHead): Change "Node" to "T" to be more idiomatic, and added
+        clear(), removeHead(), and size() functions.
+
+2011-05-26  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Oliver Hunt.
+
         Provide a real owner when copying a property table, for the sake of
         write barriers.
         https://bugs.webkit.org/show_bug.cgi?id=61547
index aa93b05..94757bc 100644 (file)
@@ -52,8 +52,6 @@ MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, JSGlobalData*
     : m_nextAtom(firstAtom())
     , m_allocation(allocation)
     , m_heap(&globalData->heap)
-    , m_prev(0)
-    , m_next(0)
 {
     m_atomsPerCell = (cellSize + atomSize - 1) / atomSize;
     m_endAtom = atomsPerBlock - m_atomsPerCell + 1;
index 1ff5f29..39fa634 100644 (file)
@@ -23,6 +23,7 @@
 #define MarkedBlock_h
 
 #include <wtf/Bitmap.h>
+#include <wtf/DoublyLinkedList.h>
 #include <wtf/PageAllocationAligned.h>
 #include <wtf/StdLibExtras.h>
 
@@ -36,7 +37,8 @@ namespace JSC {
 
     static const size_t KB = 1024;
 
-    class MarkedBlock {
+    class MarkedBlock : public DoublyLinkedListNode<MarkedBlock> {
+        friend class DoublyLinkedListNode<MarkedBlock>;
     public:
         static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
 
@@ -49,11 +51,6 @@ namespace JSC {
         
         Heap* heap() const;
 
-        void setPrev(MarkedBlock*);
-        void setNext(MarkedBlock*);
-        MarkedBlock* prev() const;
-        MarkedBlock* next() const;
-        
         void* allocate();
         void reset();
         void sweep();
@@ -124,26 +121,6 @@ namespace JSC {
         return m_heap;
     }
 
-    inline void MarkedBlock::setPrev(MarkedBlock* prev)
-    {
-        m_prev = prev;
-    }
-
-    inline void MarkedBlock::setNext(MarkedBlock* next)
-    {
-        m_next = next;
-    }
-
-    inline MarkedBlock* MarkedBlock::prev() const
-    {
-        return m_prev;
-    }
-
-    inline MarkedBlock* MarkedBlock::next() const
-    {
-        return m_next;
-    }
-
     inline void MarkedBlock::reset()
     {
         m_nextAtom = firstAtom();
index 9351263..18aa00e 100644 (file)
 
 namespace WTF {
 
-template <typename Node> class DoublyLinkedList {
+// This class allows nodes to share code without dictating data member layout.
+template<typename T> class DoublyLinkedListNode {
+public:
+    DoublyLinkedListNode();
+    
+    void setPrev(T*);
+    void setNext(T*);
+    
+    T* prev() const;
+    T* next() const;
+};
+
+template<typename T> inline DoublyLinkedListNode<T>::DoublyLinkedListNode()
+{
+    setPrev(0);
+    setNext(0);
+}
+
+template<typename T> inline void DoublyLinkedListNode<T>::setPrev(T* prev)
+{
+    static_cast<T*>(this)->m_prev = prev;
+}
+
+template<typename T> inline void DoublyLinkedListNode<T>::setNext(T* next)
+{
+    static_cast<T*>(this)->m_next = next;
+}
+
+template<typename T> inline T* DoublyLinkedListNode<T>::prev() const
+{
+    return static_cast<const T*>(this)->m_prev;
+}
+
+template<typename T> inline T* DoublyLinkedListNode<T>::next() const
+{
+    return static_cast<const T*>(this)->m_next;
+}
+
+template<typename T> class DoublyLinkedList {
 public:
     DoublyLinkedList();
     
-    bool isEmpty();
+    bool isEmpty() const;
+    size_t size() const; // This is O(n).
+    void clear();
 
-    Node* head();
+    T* head() const;
+    T* removeHead();
 
-    void append(Node*);
-    void remove(Node*);
+    void append(T*);
+    void remove(T*);
 
 private:
-    Node* m_head;
-    Node* m_tail;
+    T* m_head;
+    T* m_tail;
 };
 
-template <typename Node> inline DoublyLinkedList<Node>::DoublyLinkedList()
+template<typename T> inline DoublyLinkedList<T>::DoublyLinkedList()
     : m_head(0)
     , m_tail(0)
 {
 }
 
-template <typename Node> inline bool DoublyLinkedList<Node>::isEmpty()
+template<typename T> inline bool DoublyLinkedList<T>::isEmpty() const
 {
     return !m_head;
 }
 
-template <typename Node> inline Node* DoublyLinkedList<Node>::head()
+template<typename T> inline size_t DoublyLinkedList<T>::size() const
+{
+    size_t size = 0;
+    for (T* node = m_head; node; node = node->next())
+        ++size;
+    return size;
+}
+
+template<typename T> inline void DoublyLinkedList<T>::clear()
+{
+    m_head = 0;
+    m_tail = 0;
+}
+
+template<typename T> inline T* DoublyLinkedList<T>::head() const
 {
     return m_head;
 }
 
-template <typename Node> inline void DoublyLinkedList<Node>::append(Node* node)
+template<typename T> inline void DoublyLinkedList<T>::append(T* node)
 {
     if (!m_tail) {
         ASSERT(!m_head);
@@ -78,7 +133,7 @@ template <typename Node> inline void DoublyLinkedList<Node>::append(Node* node)
     m_tail = node;
 }
 
-template <typename Node> inline void DoublyLinkedList<Node>::remove(Node* node)
+template<typename T> inline void DoublyLinkedList<T>::remove(T* node)
 {
     if (node->prev()) {
         ASSERT(node != m_head);
@@ -97,8 +152,17 @@ template <typename Node> inline void DoublyLinkedList<Node>::remove(Node* node)
     }
 }
 
+template<typename T> inline T* DoublyLinkedList<T>::removeHead()
+{
+    T* node = head();
+    if (node)
+        remove(node);
+    return node;
+}
+
 } // namespace WTF
 
+using WTF::DoublyLinkedListNode;
 using WTF::DoublyLinkedList;
 
 #endif