2 * Copyright (C) 2011, 2012 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.
26 #ifndef DFGCapabilities_h
27 #define DFGCapabilities_h
29 #include "Intrinsic.h"
30 #include "DFGCommon.h"
32 #include "Executable.h"
34 #include "Interpreter.h"
35 #include <wtf/Platform.h>
37 namespace JSC { namespace DFG {
40 // Fast check functions; if they return true it is still necessary to
42 inline bool mightCompileEval(CodeBlock* codeBlock)
44 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
46 inline bool mightCompileProgram(CodeBlock* codeBlock)
48 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
50 inline bool mightCompileFunctionForCall(CodeBlock* codeBlock)
52 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
54 inline bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
56 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
59 inline bool mightInlineFunctionForCall(CodeBlock* codeBlock)
61 return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount
62 && !codeBlock->ownerExecutable()->needsActivation();
64 inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
66 return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount
67 && !codeBlock->ownerExecutable()->needsActivation();
71 inline CapabilityLevel canCompileOpcode(OpcodeID opcodeID, CodeBlock*, Instruction*)
93 #if ENABLE(DEBUG_WITH_BREAKPOINT)
97 case op_check_has_instance:
118 case op_method_check:
119 case op_get_scoped_var:
120 case op_put_scoped_var:
123 case op_put_by_id_transition_direct:
124 case op_put_by_id_transition_normal:
125 case op_get_global_var:
126 case op_put_global_var:
131 case op_loop_if_true:
132 case op_loop_if_false:
144 case op_loop_if_less:
145 case op_loop_if_lesseq:
146 case op_loop_if_greater:
147 case op_loop_if_greatereq:
150 case op_call_put_result:
152 case op_resolve_base:
153 case op_resolve_global:
156 case op_new_array_buffer:
158 case op_to_primitive:
160 case op_throw_reference_error:
164 case op_init_lazy_reg:
165 case op_create_activation:
166 case op_tear_off_activation:
167 case op_create_arguments:
168 case op_tear_off_arguments:
170 case op_new_func_exp:
171 case op_get_argument_by_val:
172 case op_get_arguments_length:
176 case op_call_varargs:
180 return CannotCompile;
184 inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction* pc)
188 // These opcodes would be easy to support with inlining, but we currently don't do it.
189 // The issue is that the scope chain will not be set correctly.
190 case op_get_scoped_var:
191 case op_put_scoped_var:
193 case op_resolve_base:
194 case op_resolve_global:
196 // Constant buffers aren't copied correctly. This is easy to fix, but for
197 // now we just disable inlining for functions that use them.
198 case op_new_array_buffer:
200 // Inlining doesn't correctly remap regular expression operands.
203 // We don't support inlining code that creates activations or has nested functions.
204 case op_create_activation:
205 case op_tear_off_activation:
207 case op_new_func_exp:
210 // Inlining supports op_call_varargs if it's a call that just forwards the caller's
212 case op_call_varargs:
213 return codeBlock->usesArguments() && pc[3].u.operand == codeBlock->argumentsRegister();
216 return canCompileOpcode(opcodeID, codeBlock, pc) == CanCompile;
220 CapabilityLevel canCompileOpcodes(CodeBlock*);
221 bool canInlineOpcodes(CodeBlock*);
222 #else // ENABLE(DFG_JIT)
223 inline bool mightCompileEval(CodeBlock*) { return false; }
224 inline bool mightCompileProgram(CodeBlock*) { return false; }
225 inline bool mightCompileFunctionForCall(CodeBlock*) { return false; }
226 inline bool mightCompileFunctionForConstruct(CodeBlock*) { return false; }
227 inline bool mightInlineFunctionForCall(CodeBlock*) { return false; }
228 inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
230 inline CapabilityLevel canCompileOpcode(OpcodeID, CodeBlock*, Instruction*) { return CannotCompile; }
231 inline bool canInlineOpcode(OpcodeID, CodeBlock*, Instruction*) { return false; }
232 inline CapabilityLevel canCompileOpcodes(CodeBlock*) { return CannotCompile; }
233 inline bool canInlineOpcodes(CodeBlock*) { return false; }
234 #endif // ENABLE(DFG_JIT)
236 inline CapabilityLevel canCompileEval(CodeBlock* codeBlock)
238 if (!mightCompileEval(codeBlock))
239 return CannotCompile;
241 return canCompileOpcodes(codeBlock);
244 inline CapabilityLevel canCompileProgram(CodeBlock* codeBlock)
246 if (!mightCompileProgram(codeBlock))
247 return CannotCompile;
249 return canCompileOpcodes(codeBlock);
252 inline CapabilityLevel canCompileFunctionForCall(CodeBlock* codeBlock)
254 if (!mightCompileFunctionForCall(codeBlock))
255 return CannotCompile;
257 return canCompileOpcodes(codeBlock);
260 inline CapabilityLevel canCompileFunctionForConstruct(CodeBlock* codeBlock)
262 if (!mightCompileFunctionForConstruct(codeBlock))
263 return CannotCompile;
265 return canCompileOpcodes(codeBlock);
268 inline bool canInlineFunctionForCall(CodeBlock* codeBlock)
270 return mightInlineFunctionForCall(codeBlock) && canInlineOpcodes(codeBlock);
273 inline bool canInlineFunctionForConstruct(CodeBlock* codeBlock)
275 return mightInlineFunctionForConstruct(codeBlock) && canInlineOpcodes(codeBlock);
278 inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
280 if (kind == CodeForCall)
281 return mightInlineFunctionForCall(codeBlock);
282 ASSERT(kind == CodeForConstruct);
283 return mightInlineFunctionForConstruct(codeBlock);
286 inline bool canInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
288 if (kind == CodeForCall)
289 return canInlineFunctionForCall(codeBlock);
290 ASSERT(kind == CodeForConstruct);
291 return canInlineFunctionForConstruct(codeBlock);
294 } } // namespace JSC::DFG
296 #endif // DFGCapabilities_h