]> git.saurik.com Git - apple/javascriptcore.git/blame - heap/CodeBlockSet.cpp
JavaScriptCore-7600.1.4.15.12.tar.gz
[apple/javascriptcore.git] / heap / CodeBlockSet.cpp
CommitLineData
81345200
A
1/*
2 * Copyright (C) 2013, 2014 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. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "CodeBlockSet.h"
28
29#include "CodeBlock.h"
30#include "JSCInlines.h"
31#include "SlotVisitor.h"
32#include <wtf/CommaPrinter.h>
33
34namespace JSC {
35
36static const bool verbose = false;
37
38CodeBlockSet::CodeBlockSet(BlockAllocator& blockAllocator)
39 : m_currentlyExecuting(blockAllocator)
40{
41}
42
43CodeBlockSet::~CodeBlockSet()
44{
45 for (CodeBlock* codeBlock : m_oldCodeBlocks)
46 codeBlock->deref();
47
48 for (CodeBlock* codeBlock : m_newCodeBlocks)
49 codeBlock->deref();
50}
51
52void CodeBlockSet::add(PassRefPtr<CodeBlock> codeBlock)
53{
54 CodeBlock* block = codeBlock.leakRef();
55 bool isNewEntry = m_newCodeBlocks.add(block).isNewEntry;
56 ASSERT_UNUSED(isNewEntry, isNewEntry);
57}
58
59void CodeBlockSet::promoteYoungCodeBlocks()
60{
61 m_oldCodeBlocks.add(m_newCodeBlocks.begin(), m_newCodeBlocks.end());
62 m_newCodeBlocks.clear();
63}
64
65void CodeBlockSet::clearMarksForFullCollection()
66{
67 for (CodeBlock* codeBlock : m_oldCodeBlocks) {
68 codeBlock->m_mayBeExecuting = false;
69 codeBlock->m_visitAggregateHasBeenCalled = false;
70 }
71
72 // We promote after we clear marks on the old generation CodeBlocks because
73 // none of the young generations CodeBlocks need to be cleared.
74 promoteYoungCodeBlocks();
75}
76
77void CodeBlockSet::clearMarksForEdenCollection(const Vector<const JSCell*>& rememberedSet)
78{
79 // This ensures that we will revisit CodeBlocks in remembered Executables even if they were previously marked.
80 for (const JSCell* cell : rememberedSet) {
81 ScriptExecutable* executable = const_cast<ScriptExecutable*>(jsDynamicCast<const ScriptExecutable*>(cell));
82 if (!executable)
83 continue;
84 executable->forEachCodeBlock([](CodeBlock* codeBlock) {
85 codeBlock->m_mayBeExecuting = false;
86 codeBlock->m_visitAggregateHasBeenCalled = false;
87 });
88 }
89}
90
91void CodeBlockSet::deleteUnmarkedAndUnreferenced(HeapOperation collectionType)
92{
93 HashSet<CodeBlock*>& set = collectionType == EdenCollection ? m_newCodeBlocks : m_oldCodeBlocks;
94
95 // This needs to be a fixpoint because code blocks that are unmarked may
96 // refer to each other. For example, a DFG code block that is owned by
97 // the GC may refer to an FTL for-entry code block that is also owned by
98 // the GC.
99 Vector<CodeBlock*, 16> toRemove;
100 if (verbose)
101 dataLog("Fixpointing over unmarked, set size = ", set.size(), "...\n");
102 for (;;) {
103 for (CodeBlock* codeBlock : set) {
104 if (!codeBlock->hasOneRef())
105 continue;
106 if (codeBlock->m_mayBeExecuting)
107 continue;
108 codeBlock->deref();
109 toRemove.append(codeBlock);
110 }
111 if (verbose)
112 dataLog(" Removing ", toRemove.size(), " blocks.\n");
113 if (toRemove.isEmpty())
114 break;
115 for (CodeBlock* codeBlock : toRemove)
116 set.remove(codeBlock);
117 toRemove.resize(0);
118 }
119
120 // Any remaining young CodeBlocks are live and need to be promoted to the set of old CodeBlocks.
121 if (collectionType == EdenCollection)
122 promoteYoungCodeBlocks();
123}
124
125void CodeBlockSet::remove(CodeBlock* codeBlock)
126{
127 codeBlock->deref();
128 if (m_oldCodeBlocks.contains(codeBlock)) {
129 m_oldCodeBlocks.remove(codeBlock);
130 return;
131 }
132 ASSERT(m_newCodeBlocks.contains(codeBlock));
133 m_newCodeBlocks.remove(codeBlock);
134}
135
136void CodeBlockSet::traceMarked(SlotVisitor& visitor)
137{
138 if (verbose)
139 dataLog("Tracing ", m_currentlyExecuting.size(), " code blocks.\n");
140 for (CodeBlock* codeBlock : m_currentlyExecuting) {
141 ASSERT(codeBlock->m_mayBeExecuting);
142 codeBlock->visitAggregate(visitor);
143 }
144}
145
146void CodeBlockSet::rememberCurrentlyExecutingCodeBlocks(Heap* heap)
147{
148#if ENABLE(GGC)
149 if (verbose)
150 dataLog("Remembering ", m_currentlyExecuting.size(), " code blocks.\n");
151 for (CodeBlock* codeBlock : m_currentlyExecuting) {
152 heap->addToRememberedSet(codeBlock->ownerExecutable());
153 ASSERT(codeBlock->m_mayBeExecuting);
154 }
155 m_currentlyExecuting.clear();
156#else
157 UNUSED_PARAM(heap);
158#endif // ENABLE(GGC)
159}
160
161void CodeBlockSet::dump(PrintStream& out) const
162{
163 CommaPrinter comma;
164 out.print("{old = [");
165 for (CodeBlock* codeBlock : m_oldCodeBlocks)
166 out.print(comma, pointerDump(codeBlock));
167 out.print("], new = [");
168 comma = CommaPrinter();
169 for (CodeBlock* codeBlock : m_newCodeBlocks)
170 out.print(comma, pointerDump(codeBlock));
171 out.print("], currentlyExecuting = [");
172 comma = CommaPrinter();
173 for (CodeBlock* codeBlock : m_currentlyExecuting)
174 out.print(comma, pointerDump(codeBlock));
175 out.print("]}");
176}
177
178} // namespace JSC
179