]> git.saurik.com Git - apple/javascriptcore.git/blob - heap/HandleSet.cpp
JavaScriptCore-1218.35.tar.gz
[apple/javascriptcore.git] / heap / HandleSet.cpp
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
29 #include "HandleBlock.h"
30 #include "HandleBlockInlines.h"
31 #include "HeapRootVisitor.h"
32 #include "JSObject.h"
33 #include "Operations.h"
34 #include <wtf/DataLog.h>
35
36 namespace JSC {
37
38 HandleSet::HandleSet(VM* vm)
39 : m_vm(vm)
40 , m_nextToFinalize(0)
41 {
42 grow();
43 }
44
45 HandleSet::~HandleSet()
46 {
47 while (!m_blockList.isEmpty())
48 m_vm->heap.blockAllocator().deallocate(HandleBlock::destroy(m_blockList.removeHead()));
49 }
50
51 void HandleSet::grow()
52 {
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;
59 m_freeList.push(node);
60 }
61 }
62
63 void 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)
68 RELEASE_ASSERT(isLiveNode(node));
69 #endif
70 heapRootVisitor.visit(node->slot());
71 }
72 }
73
74 void 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.
78 RELEASE_ASSERT(!m_nextToFinalize);
79
80 if (!value == !*slot && slot->isCell() == value.isCell())
81 return;
82
83 Node* node = toNode(slot);
84 #if ENABLE(GC_VALIDATION)
85 RELEASE_ASSERT(isLiveNode(node));
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)
95 RELEASE_ASSERT(isLiveNode(node));
96 #endif
97 }
98
99 unsigned 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
112 bool 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