]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/HandleSet.cpp
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / heap / HandleSet.cpp
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#include "config.h"
27#include "HandleSet.h"
28
93a37866
A
29#include "HandleBlock.h"
30#include "HandleBlockInlines.h"
6fe7ccc8
A
31#include "HeapRootVisitor.h"
32#include "JSObject.h"
93a37866
A
33#include "Operations.h"
34#include <wtf/DataLog.h>
6fe7ccc8
A
35
36namespace JSC {
37
93a37866
A
38HandleSet::HandleSet(VM* vm)
39 : m_vm(vm)
6fe7ccc8
A
40 , m_nextToFinalize(0)
41{
42 grow();
43}
44
93a37866
A
45HandleSet::~HandleSet()
46{
47 while (!m_blockList.isEmpty())
48 m_vm->heap.blockAllocator().deallocate(HandleBlock::destroy(m_blockList.removeHead()));
49}
50
6fe7ccc8
A
51void HandleSet::grow()
52{
93a37866
A
53 HandleBlock* newBlock = HandleBlock::create(m_vm->heap.blockAllocator().allocate<HandleBlock>(), this);
54 m_blockList.append(newBlock);
55
56 for (int i = newBlock->nodeCapacity() - 1; i >= 0; --i) {
57 Node* node = newBlock->nodeAtIndex(i);
58 new (NotNull, node) Node;
6fe7ccc8
A
59 m_freeList.push(node);
60 }
61}
62
63void HandleSet::visitStrongHandles(HeapRootVisitor& heapRootVisitor)
64{
65 Node* end = m_strongList.end();
66 for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
67#if ENABLE(GC_VALIDATION)
93a37866 68 RELEASE_ASSERT(isLiveNode(node));
6fe7ccc8
A
69#endif
70 heapRootVisitor.visit(node->slot());
71 }
72}
73
74void HandleSet::writeBarrier(HandleSlot slot, const JSValue& value)
75{
76 // Forbid assignment to handles during the finalization phase, since it would violate many GC invariants.
77 // File a bug with stack trace if you hit this.
93a37866 78 RELEASE_ASSERT(!m_nextToFinalize);
6fe7ccc8
A
79
80 if (!value == !*slot && slot->isCell() == value.isCell())
81 return;
82
83 Node* node = toNode(slot);
84#if ENABLE(GC_VALIDATION)
93a37866 85 RELEASE_ASSERT(isLiveNode(node));
6fe7ccc8
A
86#endif
87 SentinelLinkedList<Node>::remove(node);
88 if (!value || !value.isCell()) {
89 m_immediateList.push(node);
90 return;
91 }
92
93 m_strongList.push(node);
94#if ENABLE(GC_VALIDATION)
93a37866 95 RELEASE_ASSERT(isLiveNode(node));
6fe7ccc8
A
96#endif
97}
98
99unsigned HandleSet::protectedGlobalObjectCount()
100{
101 unsigned count = 0;
102 Node* end = m_strongList.end();
103 for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
104 JSValue value = *node->slot();
105 if (value.isObject() && asObject(value.asCell())->isGlobalObject())
106 count++;
107 }
108 return count;
109}
110
111#if ENABLE(GC_VALIDATION) || !ASSERT_DISABLED
112bool HandleSet::isLiveNode(Node* node)
113{
114 if (node->prev()->next() != node)
115 return false;
116 if (node->next()->prev() != node)
117 return false;
118
119 return true;
120}
121#endif
122
123} // namespace JSC