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 "JSCInlines.h"
34#include <wtf/DataLog.h>
35
36namespace JSC {
37
38HandleSet::HandleSet(VM* vm)
39 : m_vm(vm)
40{
41 grow();
42}
43
44HandleSet::~HandleSet()
45{
46 while (!m_blockList.isEmpty())
47 HandleBlock::destroy(m_blockList.removeHead());
48}
49
50void HandleSet::grow()
51{
52 HandleBlock* newBlock = HandleBlock::create(this);
53 m_blockList.append(newBlock);
54
55 for (int i = newBlock->nodeCapacity() - 1; i >= 0; --i) {
56 Node* node = newBlock->nodeAtIndex(i);
57 new (NotNull, node) Node;
58 m_freeList.push(node);
59 }
60}
61
62void HandleSet::visitStrongHandles(HeapRootVisitor& heapRootVisitor)
63{
64 Node* end = m_strongList.end();
65 for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
66#if ENABLE(GC_VALIDATION)
67 RELEASE_ASSERT(isLiveNode(node));
68#endif
69 heapRootVisitor.visit(node->slot());
70 }
71}
72
73void HandleSet::writeBarrier(HandleSlot slot, const JSValue& value)
74{
75 if (!value == !*slot && slot->isCell() == value.isCell())
76 return;
77
78 Node* node = toNode(slot);
79#if ENABLE(GC_VALIDATION)
80 RELEASE_ASSERT(isLiveNode(node));
81#endif
82 SentinelLinkedList<Node>::remove(node);
83 if (!value || !value.isCell()) {
84 m_immediateList.push(node);
85 return;
86 }
87
88 m_strongList.push(node);
89#if ENABLE(GC_VALIDATION)
90 RELEASE_ASSERT(isLiveNode(node));
91#endif
92}
93
94unsigned HandleSet::protectedGlobalObjectCount()
95{
96 unsigned count = 0;
97 Node* end = m_strongList.end();
98 for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
99 JSValue value = *node->slot();
100 if (value.isObject() && asObject(value.asCell())->isGlobalObject())
101 count++;
102 }
103 return count;
104}
105
106#if ENABLE(GC_VALIDATION) || !ASSERT_DISABLED
107bool HandleSet::isLiveNode(Node* node)
108{
109 if (node->prev()->next() != node)
110 return false;
111 if (node->next()->prev() != node)
112 return false;
113
114 return true;
115}
116#endif
117
118} // namespace JSC
119