]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/HandleSet.h
JavaScriptCore-7600.1.4.15.12.tar.gz
[apple/javascriptcore.git] / heap / HandleSet.h
CommitLineData
6fe7ccc8
A
1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef HandleSet_h
27#define HandleSet_h
28
6fe7ccc8 29#include "Handle.h"
93a37866
A
30#include "HandleBlock.h"
31#include <wtf/DoublyLinkedList.h>
6fe7ccc8
A
32#include <wtf/HashCountedSet.h>
33#include <wtf/SentinelLinkedList.h>
34#include <wtf/SinglyLinkedList.h>
35
36namespace JSC {
37
93a37866 38class HandleBlock;
6fe7ccc8
A
39class HandleSet;
40class HeapRootVisitor;
93a37866 41class VM;
6fe7ccc8
A
42class JSValue;
43class SlotVisitor;
44
93a37866
A
45class HandleNode {
46public:
47 HandleNode(WTF::SentinelTag);
48 HandleNode();
49
50 HandleSlot slot();
51 HandleSet* handleSet();
52
53 void setPrev(HandleNode*);
54 HandleNode* prev();
55
56 void setNext(HandleNode*);
57 HandleNode* next();
58
59private:
60 JSValue m_value;
61 HandleNode* m_prev;
62 HandleNode* m_next;
63};
64
6fe7ccc8 65class HandleSet {
93a37866 66 friend class HandleBlock;
6fe7ccc8
A
67public:
68 static HandleSet* heapFor(HandleSlot);
69
93a37866
A
70 HandleSet(VM*);
71 ~HandleSet();
72
73 VM* vm();
6fe7ccc8
A
74
75 HandleSlot allocate();
76 void deallocate(HandleSlot);
77
78 void visitStrongHandles(HeapRootVisitor&);
79
80 JS_EXPORT_PRIVATE void writeBarrier(HandleSlot, const JSValue&);
81
82 unsigned protectedGlobalObjectCount();
83
84 template<typename Functor> void forEachStrongHandle(Functor&, const HashCountedSet<JSCell*>& skipSet);
85
86private:
93a37866 87 typedef HandleNode Node;
6fe7ccc8
A
88 static HandleSlot toHandle(Node*);
89 static Node* toNode(HandleSlot);
90
91 JS_EXPORT_PRIVATE void grow();
92
93#if ENABLE(GC_VALIDATION) || !ASSERT_DISABLED
94 bool isLiveNode(Node*);
95#endif
96
93a37866
A
97 VM* m_vm;
98 DoublyLinkedList<HandleBlock> m_blockList;
6fe7ccc8
A
99
100 SentinelLinkedList<Node> m_strongList;
101 SentinelLinkedList<Node> m_immediateList;
102 SinglyLinkedList<Node> m_freeList;
6fe7ccc8
A
103};
104
105inline HandleSet* HandleSet::heapFor(HandleSlot handle)
106{
107 return toNode(handle)->handleSet();
108}
109
93a37866 110inline VM* HandleSet::vm()
6fe7ccc8 111{
93a37866 112 return m_vm;
6fe7ccc8
A
113}
114
93a37866 115inline HandleSlot HandleSet::toHandle(HandleSet::Node* node)
6fe7ccc8
A
116{
117 return reinterpret_cast<HandleSlot>(node);
118}
119
120inline HandleSet::Node* HandleSet::toNode(HandleSlot handle)
121{
93a37866 122 return reinterpret_cast<HandleSet::Node*>(handle);
6fe7ccc8
A
123}
124
125inline HandleSlot HandleSet::allocate()
126{
6fe7ccc8
A
127 if (m_freeList.isEmpty())
128 grow();
129
93a37866
A
130 HandleSet::Node* node = m_freeList.pop();
131 new (NotNull, node) HandleSet::Node();
6fe7ccc8
A
132 m_immediateList.push(node);
133 return toHandle(node);
134}
135
136inline void HandleSet::deallocate(HandleSlot handle)
137{
93a37866 138 HandleSet::Node* node = toNode(handle);
93a37866 139 SentinelLinkedList<HandleSet::Node>::remove(node);
6fe7ccc8
A
140 m_freeList.push(node);
141}
142
93a37866
A
143inline HandleNode::HandleNode()
144 : m_prev(0)
6fe7ccc8
A
145 , m_next(0)
146{
147}
148
93a37866
A
149inline HandleNode::HandleNode(WTF::SentinelTag)
150 : m_prev(0)
6fe7ccc8
A
151 , m_next(0)
152{
153}
154
93a37866 155inline HandleSlot HandleNode::slot()
6fe7ccc8
A
156{
157 return &m_value;
158}
159
93a37866 160inline HandleSet* HandleNode::handleSet()
6fe7ccc8 161{
93a37866 162 return HandleBlock::blockFor(this)->handleSet();
6fe7ccc8
A
163}
164
93a37866 165inline void HandleNode::setPrev(HandleNode* prev)
6fe7ccc8
A
166{
167 m_prev = prev;
168}
169
93a37866 170inline HandleNode* HandleNode::prev()
6fe7ccc8
A
171{
172 return m_prev;
173}
174
93a37866 175inline void HandleNode::setNext(HandleNode* next)
6fe7ccc8
A
176{
177 m_next = next;
178}
179
93a37866 180inline HandleNode* HandleNode::next()
6fe7ccc8
A
181{
182 return m_next;
183}
184
185template<typename Functor> void HandleSet::forEachStrongHandle(Functor& functor, const HashCountedSet<JSCell*>& skipSet)
186{
93a37866
A
187 HandleSet::Node* end = m_strongList.end();
188 for (HandleSet::Node* node = m_strongList.begin(); node != end; node = node->next()) {
6fe7ccc8
A
189 JSValue value = *node->slot();
190 if (!value || !value.isCell())
191 continue;
192 if (skipSet.contains(value.asCell()))
193 continue;
194 functor(value.asCell());
195 }
196}
197
198}
199
200#endif