source: webkit/trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

Last change on this file was 291417, checked in by Mikhail R. Gadelha, 3 years ago

Unreviewed, non-unified build fix
https://bugs.webkit.org/show_bug.cgi?id=237929

  • dfg/DFGCapabilities.cpp:
  • jit/JITDisassembler.cpp:
  • jit/JITPlan.cpp:
  • llint/LLIntEntrypoint.cpp:
  • runtime/FileBasedFuzzerAgentBase.cpp:
  • runtime/ShadowRealmObject.cpp:
  • runtime/ShadowRealmPrototype.cpp:
  • Property svn:eol-style set to native
File size: 13.0 KB
Line 
1/*
2 * Copyright (C) 2011-2020 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 "DFGCapabilities.h"
28
29#if ENABLE(DFG_JIT)
30
31#include "CodeBlock.h"
32#include "DFGCommon.h"
33#include "JSCellInlines.h"
34#include "Options.h"
35
36namespace JSC { namespace DFG {
37
38bool isSupported()
39{
40 return Options::useDFGJIT() && MacroAssembler::supportsFloatingPoint();
41}
42
43bool isSupportedForInlining(CodeBlock* codeBlock)
44{
45 return codeBlock->ownerExecutable()->isInliningCandidate();
46}
47
48bool mightCompileEval(CodeBlock* codeBlock)
49{
50 return isSupported()
51 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost()
52 && codeBlock->ownerExecutable()->isOkToOptimize();
53}
54bool mightCompileProgram(CodeBlock* codeBlock)
55{
56 return isSupported()
57 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost()
58 && codeBlock->ownerExecutable()->isOkToOptimize();
59}
60bool mightCompileFunctionForCall(CodeBlock* codeBlock)
61{
62 return isSupported()
63 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost()
64 && codeBlock->ownerExecutable()->isOkToOptimize();
65}
66bool mightCompileFunctionForConstruct(CodeBlock* codeBlock)
67{
68 return isSupported()
69 && codeBlock->bytecodeCost() <= Options::maximumOptimizationCandidateBytecodeCost()
70 && codeBlock->ownerExecutable()->isOkToOptimize();
71}
72
73bool mightInlineFunctionForCall(CodeBlock* codeBlock)
74{
75 return codeBlock->bytecodeCost() <= Options::maximumFunctionForCallInlineCandidateBytecodeCost()
76 && isSupportedForInlining(codeBlock);
77}
78bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock)
79{
80 return codeBlock->bytecodeCost() <= Options::maximumFunctionForClosureCallInlineCandidateBytecodeCost()
81 && isSupportedForInlining(codeBlock);
82}
83bool mightInlineFunctionForConstruct(CodeBlock* codeBlock)
84{
85 return codeBlock->bytecodeCost() <= Options::maximumFunctionForConstructInlineCandidateBytecoodeCost()
86 && isSupportedForInlining(codeBlock);
87}
88bool canUseOSRExitFuzzing(CodeBlock* codeBlock)
89{
90 return codeBlock->ownerExecutable()->canUseOSRExitFuzzing();
91}
92
93static bool verboseCapabilities()
94{
95 return verboseCompilationEnabled() || Options::verboseDFGFailure();
96}
97
98inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel result)
99{
100 if (verboseCapabilities() && !canCompile(result))
101 dataLog("DFG rejecting opcode in ", *codeBlock, " because of opcode ", opcodeNames[opcodeID], "\n");
102}
103
104CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, const JSInstruction* pc)
105{
106 UNUSED_PARAM(codeBlock); // This function does some bytecode parsing. Ordinarily bytecode parsing requires the owning CodeBlock. It's sort of strange that we don't use it here right now.
107 UNUSED_PARAM(pc);
108
109 switch (opcodeID) {
110 case op_wide16:
111 case op_wide32:
112 RELEASE_ASSERT_NOT_REACHED();
113 case op_enter:
114 case op_to_this:
115 case op_argument_count:
116 case op_check_tdz:
117 case op_create_this:
118 case op_create_promise:
119 case op_create_generator:
120 case op_create_async_generator:
121 case op_bitnot:
122 case op_bitand:
123 case op_bitor:
124 case op_bitxor:
125 case op_rshift:
126 case op_lshift:
127 case op_urshift:
128 case op_unsigned:
129 case op_inc:
130 case op_dec:
131 case op_add:
132 case op_sub:
133 case op_negate:
134 case op_mul:
135 case op_mod:
136 case op_pow:
137 case op_div:
138 case op_debug:
139 case op_profile_type:
140 case op_profile_control_flow:
141 case op_mov:
142 case op_overrides_has_instance:
143 case op_identity_with_profile:
144 case op_instanceof:
145 case op_instanceof_custom:
146 case op_is_empty:
147 case op_typeof_is_undefined:
148 case op_typeof_is_object:
149 case op_typeof_is_function:
150 case op_is_undefined_or_null:
151 case op_is_boolean:
152 case op_is_number:
153 case op_is_big_int:
154 case op_is_object:
155 case op_is_cell_with_type:
156 case op_is_callable:
157 case op_is_constructor:
158 case op_not:
159 case op_less:
160 case op_lesseq:
161 case op_greater:
162 case op_greatereq:
163 case op_below:
164 case op_beloweq:
165 case op_eq:
166 case op_eq_null:
167 case op_stricteq:
168 case op_neq:
169 case op_neq_null:
170 case op_nstricteq:
171 case op_get_by_val:
172 case op_put_by_val:
173 case op_put_by_val_direct:
174 case op_try_get_by_id:
175 case op_get_by_id:
176 case op_get_by_id_with_this:
177 case op_get_by_id_direct:
178 case op_get_by_val_with_this:
179 case op_get_prototype_of:
180 case op_put_by_id:
181 case op_put_by_id_with_this:
182 case op_put_by_val_with_this:
183 case op_put_getter_by_id:
184 case op_put_setter_by_id:
185 case op_put_getter_setter_by_id:
186 case op_put_getter_by_val:
187 case op_put_setter_by_val:
188 case op_define_data_property:
189 case op_define_accessor_property:
190 case op_del_by_id:
191 case op_del_by_val:
192 case op_jmp:
193 case op_jtrue:
194 case op_jfalse:
195 case op_jeq_null:
196 case op_jneq_null:
197 case op_jundefined_or_null:
198 case op_jnundefined_or_null:
199 case op_jless:
200 case op_jlesseq:
201 case op_jgreater:
202 case op_jgreatereq:
203 case op_jnless:
204 case op_jnlesseq:
205 case op_jngreater:
206 case op_jngreatereq:
207 case op_jeq:
208 case op_jneq:
209 case op_jstricteq:
210 case op_jnstricteq:
211 case op_jbelow:
212 case op_jbeloweq:
213 case op_loop_hint:
214 case op_check_traps:
215 case op_nop:
216 case op_ret:
217 case op_end:
218 case op_new_object:
219 case op_new_promise:
220 case op_new_generator:
221 case op_new_array:
222 case op_new_array_with_size:
223 case op_new_array_buffer:
224 case op_new_array_with_spread:
225 case op_spread:
226 case op_strcat:
227 case op_to_primitive:
228 case op_throw:
229 case op_throw_static_error:
230 case op_call:
231 case op_tail_call:
232 case op_construct:
233 case op_call_varargs:
234 case op_tail_call_varargs:
235 case op_tail_call_forward_arguments:
236 case op_construct_varargs:
237 case op_create_direct_arguments:
238 case op_create_scoped_arguments:
239 case op_create_cloned_arguments:
240 case op_create_arguments_butterfly:
241 case op_get_from_arguments:
242 case op_put_to_arguments:
243 case op_get_argument:
244 case op_jeq_ptr:
245 case op_jneq_ptr:
246 case op_typeof:
247 case op_to_number:
248 case op_to_numeric:
249 case op_to_string:
250 case op_to_object:
251 case op_switch_imm:
252 case op_switch_char:
253 case op_in_by_val:
254 case op_in_by_id:
255 case op_has_private_name:
256 case op_has_private_brand:
257 case op_get_scope:
258 case op_get_from_scope:
259 case op_get_property_enumerator:
260 case op_new_func:
261 case op_new_func_exp:
262 case op_new_generator_func:
263 case op_new_generator_func_exp:
264 case op_new_async_generator_func:
265 case op_new_async_generator_func_exp:
266 case op_new_async_func:
267 case op_new_async_func_exp:
268 case op_set_function_name:
269 case op_create_lexical_environment:
270 case op_push_with_scope:
271 case op_get_parent_scope:
272 case op_catch:
273 case op_create_rest:
274 case op_get_rest_length:
275 case op_iterator_open:
276 case op_iterator_next:
277 case op_log_shadow_chicken_prologue:
278 case op_log_shadow_chicken_tail:
279 case op_put_to_scope:
280 case op_resolve_scope:
281 case op_resolve_scope_for_hoisting_func_decl_in_eval:
282 case op_new_regexp:
283 case op_get_internal_field:
284 case op_put_internal_field:
285 case op_to_property_key:
286 case op_unreachable:
287 case op_super_sampler_begin:
288 case op_super_sampler_end:
289 case op_get_private_name:
290 case op_put_private_name:
291 case op_set_private_brand:
292 case op_check_private_brand:
293 case op_switch_string:
294 case op_enumerator_next:
295 case op_enumerator_get_by_val:
296 case op_enumerator_in_by_val:
297 case op_enumerator_has_own_property:
298 return CanCompileAndInline;
299
300 case op_call_eval:
301 return CanCompile;
302
303 case op_yield:
304 case op_create_generator_frame_environment:
305 case llint_program_prologue:
306 case llint_eval_prologue:
307 case llint_module_program_prologue:
308 case llint_function_for_call_prologue:
309 case llint_function_for_construct_prologue:
310 case llint_function_for_call_arity_check:
311 case llint_function_for_construct_arity_check:
312 case llint_generic_return_point:
313 case llint_throw_from_slow_path_trampoline:
314 case llint_throw_during_call_trampoline:
315 case llint_native_call_trampoline:
316 case llint_native_construct_trampoline:
317 case llint_internal_function_call_trampoline:
318 case llint_internal_function_construct_trampoline:
319 case llint_link_call_trampoline:
320 case llint_virtual_call_trampoline:
321 case llint_virtual_construct_trampoline:
322 case llint_virtual_tail_call_trampoline:
323 case llint_get_host_call_return_value:
324 case llint_handle_uncaught_exception:
325 case checkpoint_osr_exit_from_inlined_call_trampoline:
326 case checkpoint_osr_exit_trampoline:
327 case normal_osr_exit_trampoline:
328 case fuzzer_return_early_from_loop_hint:
329 case op_iterator_open_return_location:
330 case op_iterator_next_return_location:
331 case op_call_return_location:
332 case op_construct_return_location:
333 case op_call_varargs_return_location:
334 case op_construct_varargs_return_location:
335 case op_call_varargs_slow_return_location:
336 case op_construct_varargs_slow_return_location:
337 case op_get_by_id_return_location:
338 case op_get_by_val_return_location:
339 case op_put_by_id_return_location:
340 case op_put_by_val_return_location:
341 case op_call_slow_return_location:
342 case op_construct_slow_return_location:
343 case op_iterator_open_slow_return_location:
344 case op_iterator_next_slow_return_location:
345 case op_tail_call_slow_return_location:
346 case op_tail_call_forward_arguments_slow_return_location:
347 case op_tail_call_varargs_slow_return_location:
348 case op_call_eval_slow_return_location:
349 case wasm_function_prologue:
350 case wasm_function_prologue_no_tls:
351 case js_trampoline_op_call:
352 case js_trampoline_op_construct:
353 case js_trampoline_op_call_varargs:
354 case js_trampoline_op_construct_varargs:
355 case js_trampoline_op_iterator_next:
356 case js_trampoline_op_iterator_open:
357 case js_trampoline_op_call_slow:
358 case js_trampoline_op_tail_call_slow:
359 case js_trampoline_op_construct_slow:
360 case js_trampoline_op_call_varargs_slow:
361 case js_trampoline_op_tail_call_varargs_slow:
362 case js_trampoline_op_tail_call_forward_arguments_slow:
363 case js_trampoline_op_construct_varargs_slow:
364 case js_trampoline_op_call_eval_slow:
365 case js_trampoline_op_iterator_next_slow:
366 case js_trampoline_op_iterator_open_slow:
367 case js_trampoline_llint_function_for_call_arity_check_untag:
368 case js_trampoline_llint_function_for_call_arity_check_tag:
369 case js_trampoline_llint_function_for_construct_arity_check_untag:
370 case js_trampoline_llint_function_for_construct_arity_check_tag:
371 case wasm_trampoline_wasm_call:
372 case wasm_trampoline_wasm_call_no_tls:
373 case wasm_trampoline_wasm_call_indirect:
374 case wasm_trampoline_wasm_call_indirect_no_tls:
375 case wasm_trampoline_wasm_call_ref:
376 case wasm_trampoline_wasm_call_ref_no_tls:
377 return CannotCompile;
378 }
379 return CannotCompile;
380}
381
382CapabilityLevel capabilityLevel(CodeBlock* codeBlock)
383{
384 CapabilityLevel result = CanCompileAndInline;
385
386 for (const auto& instruction : codeBlock->instructions()) {
387 switch (instruction->opcodeID()) {
388#define DEFINE_OP(opcode, length) \
389 case opcode: { \
390 CapabilityLevel newResult = leastUpperBound(result, capabilityLevel(opcode, codeBlock, instruction.ptr())); \
391 if (newResult != result) { \
392 debugFail(codeBlock, opcode, newResult); \
393 result = newResult; \
394 } \
395 break; \
396 }
397 FOR_EACH_OPCODE_ID(DEFINE_OP)
398#undef DEFINE_OP
399 default:
400 RELEASE_ASSERT_NOT_REACHED();
401 break;
402 }
403 }
404
405 return result;
406}
407
408} } // namespace JSC::DFG
409
410#endif
Note: See TracBrowser for help on using the repository browser.