]> git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGCapabilities.h
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGCapabilities.h
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. ``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 #ifndef DFGCapabilities_h
27 #define DFGCapabilities_h
28
29 #include "Intrinsic.h"
30 #include "DFGNode.h"
31 #include "Executable.h"
32 #include "Options.h"
33 #include "Interpreter.h"
34 #include <wtf/Platform.h>
35
36 namespace JSC { namespace DFG {
37
38 #if ENABLE(DFG_JIT)
39 // Fast check functions; if they return true it is still necessary to
40 // check opcodes.
41 inline bool mightCompileEval(CodeBlock* codeBlock)
42 {
43 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
44 }
45 inline bool mightCompileProgram(CodeBlock* codeBlock)
46 {
47 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
48 }
49 inline bool mightCompileFunctionForCall(CodeBlock* codeBlock)
50 {
51 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
52 }
53 inline bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
54 {
55 return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount;
56 }
57
58 inline bool mightInlineFunctionForCall(CodeBlock* codeBlock)
59 {
60 return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount
61 && !codeBlock->ownerExecutable()->needsActivation();
62 }
63 inline bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
64 {
65 return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount
66 && !codeBlock->ownerExecutable()->needsActivation();
67 }
68
69 // Opcode checking.
70 inline bool canCompileOpcode(OpcodeID opcodeID)
71 {
72 switch (opcodeID) {
73 case op_enter:
74 case op_convert_this:
75 case op_create_this:
76 case op_get_callee:
77 case op_bitand:
78 case op_bitor:
79 case op_bitxor:
80 case op_rshift:
81 case op_lshift:
82 case op_urshift:
83 case op_pre_inc:
84 case op_post_inc:
85 case op_pre_dec:
86 case op_post_dec:
87 case op_add:
88 case op_sub:
89 case op_negate:
90 case op_mul:
91 case op_mod:
92 case op_div:
93 #if ENABLE(DEBUG_WITH_BREAKPOINT)
94 case op_debug:
95 #endif
96 case op_mov:
97 case op_check_has_instance:
98 case op_instanceof:
99 case op_is_undefined:
100 case op_is_boolean:
101 case op_is_number:
102 case op_is_string:
103 case op_is_object:
104 case op_is_function:
105 case op_not:
106 case op_less:
107 case op_lesseq:
108 case op_greater:
109 case op_greatereq:
110 case op_eq:
111 case op_eq_null:
112 case op_stricteq:
113 case op_neq:
114 case op_neq_null:
115 case op_nstricteq:
116 case op_get_by_val:
117 case op_put_by_val:
118 case op_method_check:
119 case op_get_scoped_var:
120 case op_put_scoped_var:
121 case op_get_by_id:
122 case op_put_by_id:
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:
127 case op_jmp:
128 case op_loop:
129 case op_jtrue:
130 case op_jfalse:
131 case op_loop_if_true:
132 case op_loop_if_false:
133 case op_jeq_null:
134 case op_jneq_null:
135 case op_jless:
136 case op_jlesseq:
137 case op_jgreater:
138 case op_jgreatereq:
139 case op_jnless:
140 case op_jnlesseq:
141 case op_jngreater:
142 case op_jngreatereq:
143 case op_loop_hint:
144 case op_loop_if_less:
145 case op_loop_if_lesseq:
146 case op_loop_if_greater:
147 case op_loop_if_greatereq:
148 case op_ret:
149 case op_end:
150 case op_call_put_result:
151 case op_resolve:
152 case op_resolve_base:
153 case op_resolve_global:
154 case op_new_object:
155 case op_new_array:
156 case op_new_array_buffer:
157 case op_strcat:
158 case op_to_primitive:
159 case op_throw:
160 case op_throw_reference_error:
161 case op_call:
162 case op_construct:
163 case op_new_regexp:
164 case op_init_lazy_reg:
165 case op_create_activation:
166 case op_tear_off_activation:
167 case op_new_func:
168 case op_new_func_exp:
169 return true;
170
171 default:
172 return false;
173 }
174 }
175
176 inline bool canInlineOpcode(OpcodeID opcodeID)
177 {
178 switch (opcodeID) {
179
180 // These opcodes would be easy to support with inlining, but we currently don't do it.
181 // The issue is that the scope chain will not be set correctly.
182 case op_get_scoped_var:
183 case op_put_scoped_var:
184 case op_resolve:
185 case op_resolve_base:
186 case op_resolve_global:
187
188 // Constant buffers aren't copied correctly. This is easy to fix, but for
189 // now we just disable inlining for functions that use them.
190 case op_new_array_buffer:
191
192 // Inlining doesn't correctly remap regular expression operands.
193 case op_new_regexp:
194 return false;
195
196 // We don't support inlining code that creates activations or has nested functions.
197 case op_init_lazy_reg:
198 case op_create_activation:
199 case op_tear_off_activation:
200 case op_new_func:
201 case op_new_func_exp:
202 return false;
203
204 default:
205 return canCompileOpcode(opcodeID);
206 }
207 }
208
209 bool canCompileOpcodes(CodeBlock*);
210 bool canInlineOpcodes(CodeBlock*);
211 #else // ENABLE(DFG_JIT)
212 inline bool mightCompileEval(CodeBlock*) { return false; }
213 inline bool mightCompileProgram(CodeBlock*) { return false; }
214 inline bool mightCompileFunctionForCall(CodeBlock*) { return false; }
215 inline bool mightCompileFunctionForConstruct(CodeBlock*) { return false; }
216 inline bool mightInlineFunctionForCall(CodeBlock*) { return false; }
217 inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
218
219 inline bool canCompileOpcode(OpcodeID) { return false; }
220 inline bool canInlineOpcode(OpcodeID) { return false; }
221 inline bool canCompileOpcodes(CodeBlock*) { return false; }
222 inline bool canInlineOpcodes(CodeBlock*) { return false; }
223 #endif // ENABLE(DFG_JIT)
224
225 inline bool canCompileEval(CodeBlock* codeBlock)
226 {
227 return mightCompileEval(codeBlock) && canCompileOpcodes(codeBlock);
228 }
229
230 inline bool canCompileProgram(CodeBlock* codeBlock)
231 {
232 return mightCompileProgram(codeBlock) && canCompileOpcodes(codeBlock);
233 }
234
235 inline bool canCompileFunctionForCall(CodeBlock* codeBlock)
236 {
237 return mightCompileFunctionForCall(codeBlock) && canCompileOpcodes(codeBlock);
238 }
239
240 inline bool canCompileFunctionForConstruct(CodeBlock* codeBlock)
241 {
242 return mightCompileFunctionForConstruct(codeBlock) && canCompileOpcodes(codeBlock);
243 }
244
245 inline bool canInlineFunctionForCall(CodeBlock* codeBlock)
246 {
247 return mightInlineFunctionForCall(codeBlock) && canInlineOpcodes(codeBlock);
248 }
249
250 inline bool canInlineFunctionForConstruct(CodeBlock* codeBlock)
251 {
252 return mightInlineFunctionForConstruct(codeBlock) && canInlineOpcodes(codeBlock);
253 }
254
255 inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
256 {
257 if (kind == CodeForCall)
258 return mightInlineFunctionForCall(codeBlock);
259 ASSERT(kind == CodeForConstruct);
260 return mightInlineFunctionForConstruct(codeBlock);
261 }
262
263 inline bool canInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
264 {
265 if (kind == CodeForCall)
266 return canInlineFunctionForCall(codeBlock);
267 ASSERT(kind == CodeForConstruct);
268 return canInlineFunctionForConstruct(codeBlock);
269 }
270
271 } } // namespace JSC::DFG
272
273 #endif // DFGCapabilities_h
274