]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGJITCode.cpp
0d690791840211258d3b3f072ed23110da006e51
2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGJITCode.h"
31 #include "CodeBlock.h"
32 #include "JSCInlines.h"
34 namespace JSC
{ namespace DFG
{
37 : DirectJITCode(DFGJIT
)
40 , abandonOSREntry(false)
41 #endif // ENABLE(FTL_JIT)
49 CommonData
* JITCode::dfgCommon()
54 JITCode
* JITCode::dfg()
59 void JITCode::shrinkToFit()
62 osrEntry
.shrinkToFit();
63 osrExit
.shrinkToFit();
64 speculationRecovery
.shrinkToFit();
65 minifiedDFG
.prepareAndShrink();
66 variableEventStream
.shrinkToFit();
69 void JITCode::reconstruct(
70 CodeBlock
* codeBlock
, CodeOrigin codeOrigin
, unsigned streamIndex
,
71 Operands
<ValueRecovery
>& result
)
73 variableEventStream
.reconstruct(
74 codeBlock
, codeOrigin
, minifiedDFG
, streamIndex
, result
);
77 void JITCode::reconstruct(
78 ExecState
* exec
, CodeBlock
* codeBlock
, CodeOrigin codeOrigin
, unsigned streamIndex
,
79 Operands
<JSValue
>& result
)
81 Operands
<ValueRecovery
> recoveries
;
82 reconstruct(codeBlock
, codeOrigin
, streamIndex
, recoveries
);
84 result
= Operands
<JSValue
>(OperandsLike
, recoveries
);
85 for (size_t i
= result
.size(); i
--;) {
86 int operand
= result
.operandForIndex(i
);
88 if (codeOrigin
== CodeOrigin(0)
89 && operandIsArgument(operand
)
90 && !VirtualRegister(operand
).toArgument()
91 && codeBlock
->codeType() == FunctionCode
92 && codeBlock
->specializationKind() == CodeForConstruct
) {
93 // Ugh. If we're in a constructor, the 'this' argument may hold garbage. It will
94 // also never be used. It doesn't matter what we put into the value for this,
95 // but it has to be an actual value that can be grokked by subsequent DFG passes,
96 // so we sanitize it here by turning it into Undefined.
97 result
[i
] = jsUndefined();
101 result
[i
] = recoveries
[i
].recover(exec
);
106 bool JITCode::checkIfOptimizationThresholdReached(CodeBlock
* codeBlock
)
108 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
109 return tierUpCounter
.checkIfThresholdCrossedAndSet(codeBlock
->baselineVersion());
112 void JITCode::optimizeNextInvocation(CodeBlock
* codeBlock
)
114 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
115 if (Options::verboseOSR())
116 dataLog(*codeBlock
, ": FTL-optimizing next invocation.\n");
117 tierUpCounter
.setNewThreshold(0, codeBlock
->baselineVersion());
120 void JITCode::dontOptimizeAnytimeSoon(CodeBlock
* codeBlock
)
122 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
123 if (Options::verboseOSR())
124 dataLog(*codeBlock
, ": Not FTL-optimizing anytime soon.\n");
125 tierUpCounter
.deferIndefinitely();
128 void JITCode::optimizeAfterWarmUp(CodeBlock
* codeBlock
)
130 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
131 if (Options::verboseOSR())
132 dataLog(*codeBlock
, ": FTL-optimizing after warm-up.\n");
133 CodeBlock
* baseline
= codeBlock
->baselineVersion();
134 tierUpCounter
.setNewThreshold(
135 baseline
->adjustedCounterValue(Options::thresholdForFTLOptimizeAfterWarmUp()),
139 void JITCode::optimizeSoon(CodeBlock
* codeBlock
)
141 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
142 if (Options::verboseOSR())
143 dataLog(*codeBlock
, ": FTL-optimizing soon.\n");
144 CodeBlock
* baseline
= codeBlock
->baselineVersion();
145 tierUpCounter
.setNewThreshold(
146 baseline
->adjustedCounterValue(Options::thresholdForFTLOptimizeSoon()),
150 void JITCode::forceOptimizationSlowPathConcurrently(CodeBlock
* codeBlock
)
152 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
153 if (Options::verboseOSR())
154 dataLog(*codeBlock
, ": Forcing slow path concurrently for FTL entry.\n");
155 tierUpCounter
.forceSlowPathConcurrently();
158 void JITCode::setOptimizationThresholdBasedOnCompilationResult(
159 CodeBlock
* codeBlock
, CompilationResult result
)
161 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
163 case CompilationSuccessful
:
164 optimizeNextInvocation(codeBlock
);
165 codeBlock
->baselineVersion()->m_hasBeenCompiledWithFTL
= true;
167 case CompilationFailed
:
168 dontOptimizeAnytimeSoon(codeBlock
);
169 codeBlock
->baselineVersion()->m_didFailFTLCompilation
= true;
171 case CompilationDeferred
:
172 optimizeAfterWarmUp(codeBlock
);
174 case CompilationInvalidated
:
175 // This is weird - it will only happen in cases when the DFG code block (i.e.
176 // the code block that this JITCode belongs to) is also invalidated. So it
177 // doesn't really matter what we do. But, we do the right thing anyway. Note
178 // that us counting the reoptimization actually means that we might count it
179 // twice. But that's generally OK. It's better to overcount reoptimizations
180 // than it is to undercount them.
181 codeBlock
->baselineVersion()->countReoptimization();
182 optimizeAfterWarmUp(codeBlock
);
185 RELEASE_ASSERT_NOT_REACHED();
187 #endif // ENABLE(FTL_JIT)
189 } } // namespace JSC::DFG
191 #endif // ENABLE(DFG_JIT)