]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGJITCode.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGJITCode.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 "DFGJITCode.h"
28
29#if ENABLE(DFG_JIT)
30
31#include "CodeBlock.h"
32#include "JSCInlines.h"
ed1e77d3 33#include "TrackedReferences.h"
81345200
A
34
35namespace JSC { namespace DFG {
36
37JITCode::JITCode()
38 : DirectJITCode(DFGJIT)
39#if ENABLE(FTL_JIT)
40 , osrEntryRetry(0)
41 , abandonOSREntry(false)
42#endif // ENABLE(FTL_JIT)
43{
44}
45
46JITCode::~JITCode()
47{
48}
49
50CommonData* JITCode::dfgCommon()
51{
52 return &common;
53}
54
55JITCode* JITCode::dfg()
56{
57 return this;
58}
59
60void JITCode::shrinkToFit()
61{
62 common.shrinkToFit();
63 osrEntry.shrinkToFit();
64 osrExit.shrinkToFit();
65 speculationRecovery.shrinkToFit();
66 minifiedDFG.prepareAndShrink();
67 variableEventStream.shrinkToFit();
68}
69
70void JITCode::reconstruct(
71 CodeBlock* codeBlock, CodeOrigin codeOrigin, unsigned streamIndex,
72 Operands<ValueRecovery>& result)
73{
74 variableEventStream.reconstruct(
75 codeBlock, codeOrigin, minifiedDFG, streamIndex, result);
76}
77
78void JITCode::reconstruct(
79 ExecState* exec, CodeBlock* codeBlock, CodeOrigin codeOrigin, unsigned streamIndex,
80 Operands<JSValue>& result)
81{
82 Operands<ValueRecovery> recoveries;
83 reconstruct(codeBlock, codeOrigin, streamIndex, recoveries);
84
85 result = Operands<JSValue>(OperandsLike, recoveries);
ed1e77d3 86 for (size_t i = result.size(); i--;)
81345200 87 result[i] = recoveries[i].recover(exec);
81345200
A
88}
89
90#if ENABLE(FTL_JIT)
91bool JITCode::checkIfOptimizationThresholdReached(CodeBlock* codeBlock)
92{
93 ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
94 return tierUpCounter.checkIfThresholdCrossedAndSet(codeBlock->baselineVersion());
95}
96
97void JITCode::optimizeNextInvocation(CodeBlock* codeBlock)
98{
99 ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
100 if (Options::verboseOSR())
101 dataLog(*codeBlock, ": FTL-optimizing next invocation.\n");
102 tierUpCounter.setNewThreshold(0, codeBlock->baselineVersion());
103}
104
105void JITCode::dontOptimizeAnytimeSoon(CodeBlock* codeBlock)
106{
107 ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
108 if (Options::verboseOSR())
109 dataLog(*codeBlock, ": Not FTL-optimizing anytime soon.\n");
110 tierUpCounter.deferIndefinitely();
111}
112
113void JITCode::optimizeAfterWarmUp(CodeBlock* codeBlock)
114{
115 ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
116 if (Options::verboseOSR())
117 dataLog(*codeBlock, ": FTL-optimizing after warm-up.\n");
118 CodeBlock* baseline = codeBlock->baselineVersion();
119 tierUpCounter.setNewThreshold(
120 baseline->adjustedCounterValue(Options::thresholdForFTLOptimizeAfterWarmUp()),
121 baseline);
122}
123
124void JITCode::optimizeSoon(CodeBlock* codeBlock)
125{
126 ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
127 if (Options::verboseOSR())
128 dataLog(*codeBlock, ": FTL-optimizing soon.\n");
129 CodeBlock* baseline = codeBlock->baselineVersion();
130 tierUpCounter.setNewThreshold(
131 baseline->adjustedCounterValue(Options::thresholdForFTLOptimizeSoon()),
132 baseline);
133}
134
135void JITCode::forceOptimizationSlowPathConcurrently(CodeBlock* codeBlock)
136{
137 ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
138 if (Options::verboseOSR())
139 dataLog(*codeBlock, ": Forcing slow path concurrently for FTL entry.\n");
140 tierUpCounter.forceSlowPathConcurrently();
141}
142
143void JITCode::setOptimizationThresholdBasedOnCompilationResult(
144 CodeBlock* codeBlock, CompilationResult result)
145{
146 ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
147 switch (result) {
148 case CompilationSuccessful:
149 optimizeNextInvocation(codeBlock);
150 codeBlock->baselineVersion()->m_hasBeenCompiledWithFTL = true;
151 return;
152 case CompilationFailed:
153 dontOptimizeAnytimeSoon(codeBlock);
154 codeBlock->baselineVersion()->m_didFailFTLCompilation = true;
155 return;
156 case CompilationDeferred:
157 optimizeAfterWarmUp(codeBlock);
158 return;
159 case CompilationInvalidated:
160 // This is weird - it will only happen in cases when the DFG code block (i.e.
161 // the code block that this JITCode belongs to) is also invalidated. So it
162 // doesn't really matter what we do. But, we do the right thing anyway. Note
163 // that us counting the reoptimization actually means that we might count it
164 // twice. But that's generally OK. It's better to overcount reoptimizations
165 // than it is to undercount them.
166 codeBlock->baselineVersion()->countReoptimization();
167 optimizeAfterWarmUp(codeBlock);
168 return;
169 }
170 RELEASE_ASSERT_NOT_REACHED();
171}
172#endif // ENABLE(FTL_JIT)
173
ed1e77d3
A
174void JITCode::validateReferences(const TrackedReferences& trackedReferences)
175{
176 common.validateReferences(trackedReferences);
177
178 for (OSREntryData& entry : osrEntry) {
179 for (unsigned i = entry.m_expectedValues.size(); i--;)
180 entry.m_expectedValues[i].validateReferences(trackedReferences);
181 }
182
183 minifiedDFG.validateReferences(trackedReferences);
184}
185
81345200
A
186} } // namespace JSC::DFG
187
188#endif // ENABLE(DFG_JIT)