7ee78f2d383ae27e26a8df1d3e65eac41864c306
[WebKit-https.git] / Source / JavaScriptCore / heap / ListableHandler.h
1 /*
2  *  Copyright (C) 2011-2016 Apple Inc. All rights reserved.
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19
20 #pragma once
21
22 #include <stdint.h>
23 #include <wtf/Lock.h>
24 #include <wtf/Locker.h>
25 #include <wtf/Noncopyable.h>
26 #include <wtf/ThreadingPrimitives.h>
27
28 namespace JSC {
29
30 class Heap;
31 class SlotVisitor;
32
33 template<typename T>
34 class ListableHandler {
35     WTF_MAKE_NONCOPYABLE(ListableHandler);
36
37 public:    
38     bool isOnList() const
39     {
40         return m_nextAndFlag & 1;
41     }
42     
43 protected:
44     ListableHandler()
45         : m_nextAndFlag(0)
46     {
47     }
48     
49     virtual ~ListableHandler() { }
50     
51     T* next() const
52     {
53         return reinterpret_cast<T*>(m_nextAndFlag & ~1);
54     }
55
56 private:
57     // Allow these classes to use ListableHandler::List.
58     friend class Heap;
59     friend class SlotVisitor;
60     
61     class List {
62         WTF_MAKE_NONCOPYABLE(List);
63     public:
64         List()
65             : m_first(0)
66         {
67         }
68         
69         void addThreadSafe(T* handler)
70         {
71             LockHolder locker(&m_lock);
72             addNotThreadSafe(handler);
73         }
74         
75         bool hasNext()
76         {
77             return !!m_first;
78         }
79         
80         T* head()
81         {
82             return m_first;
83         }
84         
85         T* removeNext()
86         {
87             T* current = m_first;
88             T* next = current->next();
89             current->m_nextAndFlag = 0;
90             m_first = next;
91             return current;
92         }
93         
94         void removeAll()
95         {
96             while (hasNext())
97                 removeNext();
98         }
99         
100     private:
101         void addNotThreadSafe(T* handler)
102         {
103             if (handler->m_nextAndFlag & 1)
104                 return;
105             handler->m_nextAndFlag = reinterpret_cast<uintptr_t>(m_first) | 1;
106             m_first = handler;
107         }
108         
109         Lock m_lock;
110         T* m_first;
111     };
112     
113     uintptr_t m_nextAndFlag;
114 };
115
116 } // namespace JSC