Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/compiler.cc

Issue 2505933008: [compiler] Ensure code unsupported by Crankshaft goes to Ignition. (Closed)
Patch Set: Disable two failing tests Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler.h" 5 #include "src/compiler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 9
10 #include "src/asmjs/asm-js.h" 10 #include "src/asmjs/asm-js.h"
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 } 298 }
299 299
300 // It's very important that recompiles do not alter the structure of the type 300 // It's very important that recompiles do not alter the structure of the type
301 // feedback vector. Verify that the structure fits the function literal. 301 // feedback vector. Verify that the structure fits the function literal.
302 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom( 302 CHECK(!info->shared_info()->feedback_metadata()->SpecDiffersFrom(
303 info->literal()->feedback_vector_spec())); 303 info->literal()->feedback_vector_spec()));
304 } 304 }
305 305
306 bool UseTurboFan(Handle<SharedFunctionInfo> shared) { 306 bool UseTurboFan(Handle<SharedFunctionInfo> shared) {
307 bool optimization_disabled = shared->optimization_disabled(); 307 bool optimization_disabled = shared->optimization_disabled();
308 bool dont_crankshaft = shared->dont_crankshaft(); 308 bool must_use_ignition_turbo = shared->must_use_ignition_turbo();
309 309
310 // Check the enabling conditions for Turbofan. 310 // Check the enabling conditions for Turbofan.
311 // 1. "use asm" code. 311 // 1. "use asm" code.
312 bool is_turbofanable_asm = 312 bool is_turbofanable_asm =
313 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled; 313 FLAG_turbo_asm && shared->asm_function() && !optimization_disabled;
314 314
315 // 2. Fallback for features unsupported by Crankshaft. 315 // 2. Fallback for features unsupported by Crankshaft.
316 bool is_unsupported_by_crankshaft_but_turbofanable = 316 bool is_unsupported_by_crankshaft_but_turbofanable =
317 dont_crankshaft && strcmp(FLAG_turbo_filter, "~~") == 0 && 317 must_use_ignition_turbo && strcmp(FLAG_turbo_filter, "~~") == 0 &&
318 !optimization_disabled; 318 !optimization_disabled;
319 319
320 // 3. Explicitly enabled by the command-line filter. 320 // 3. Explicitly enabled by the command-line filter.
321 bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter); 321 bool passes_turbo_filter = shared->PassesFilter(FLAG_turbo_filter);
322 322
323 return is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable || 323 return is_turbofanable_asm || is_unsupported_by_crankshaft_but_turbofanable ||
324 passes_turbo_filter; 324 passes_turbo_filter;
325 } 325 }
326 326
327 bool ShouldUseIgnition(CompilationInfo* info) { 327 bool ShouldUseIgnition(CompilationInfo* info) {
328 DCHECK(info->has_shared_info()); 328 DCHECK(info->has_shared_info());
329 Handle<SharedFunctionInfo> shared = info->shared_info();
330
331 // Code which can't be supported by the old pipeline should use Ignition.
332 if (shared->must_use_ignition_turbo()) return true;
329 333
330 // Resumable functions are not supported by {FullCodeGenerator}, suspended 334 // Resumable functions are not supported by {FullCodeGenerator}, suspended
331 // activations stored as {JSGeneratorObject} on the heap always assume the 335 // activations stored as {JSGeneratorObject} on the heap always assume the
332 // underlying code to be based on the bytecode array. 336 // underlying code to be based on the bytecode array.
333 // TODO(mstarzinger): Once we want to deprecate even more support from the 337 DCHECK(!IsResumableFunction(shared->kind()));
334 // {FullCodeGenerator}, we will compute an appropriate bit in {AstNumbering}
335 // and turn this predicate into a DCHECK instead.
336 if (IsResumableFunction(info->shared_info()->kind())) {
337 return true;
338 }
339 338
340 // Skip Ignition for asm.js functions. 339 // Skip Ignition for asm.js functions.
341 if (info->shared_info()->asm_function()) { 340 if (shared->asm_function()) return false;
341
342 // Skip Ignition for asm wasm code.
343 if (FLAG_validate_asm && shared->HasAsmWasmData()) {
342 return false; 344 return false;
343 } 345 }
344 346
345 // When requesting debug code as a replacement for existing code, we provide 347 // When requesting debug code as a replacement for existing code, we provide
346 // the same kind as the existing code (to prevent implicit tier-change). 348 // the same kind as the existing code (to prevent implicit tier-change).
347 if (info->is_debug() && info->shared_info()->is_compiled()) { 349 if (info->is_debug() && shared->is_compiled()) {
348 return !info->shared_info()->HasBaselineCode(); 350 return !shared->HasBaselineCode();
349 } 351 }
350 352
351 // Code destined for TurboFan should be compiled with Ignition first. 353 // Code destined for TurboFan should be compiled with Ignition first.
352 if (UseTurboFan(info->shared_info())) return true; 354 if (UseTurboFan(shared)) return true;
353 355
354 // Only use Ignition for any other function if FLAG_ignition is true. 356 // Only use Ignition for any other function if FLAG_ignition is true.
355 if (!FLAG_ignition) return false; 357 if (!FLAG_ignition) return false;
356 358
357 // Checks whether top level functions should be passed by the filter. 359 // Checks whether top level functions should be passed by the filter.
358 if (info->shared_info()->is_toplevel()) { 360 if (shared->is_toplevel()) {
359 Vector<const char> filter = CStrVector(FLAG_ignition_filter); 361 Vector<const char> filter = CStrVector(FLAG_ignition_filter);
360 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*'); 362 return (filter.length() == 0) || (filter.length() == 1 && filter[0] == '*');
361 } 363 }
362 364
363 // Finally respect the filter. 365 // Finally respect the filter.
364 return info->shared_info()->PassesFilter(FLAG_ignition_filter); 366 return shared->PassesFilter(FLAG_ignition_filter);
365 } 367 }
366 368
367 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) { 369 CompilationJob* GetUnoptimizedCompilationJob(CompilationInfo* info) {
368 // Function should have been parsed and analyzed before creating a compilation 370 // Function should have been parsed and analyzed before creating a compilation
369 // job. 371 // job.
370 DCHECK_NOT_NULL(info->literal()); 372 DCHECK_NOT_NULL(info->literal());
371 DCHECK_NOT_NULL(info->scope()); 373 DCHECK_NOT_NULL(info->scope());
372 374
373 EnsureFeedbackMetadata(info); 375 EnsureFeedbackMetadata(info);
374 if (ShouldUseIgnition(info)) { 376 if (ShouldUseIgnition(info)) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 parse_info->literal())) { 522 parse_info->literal())) {
521 return false; 523 return false;
522 } 524 }
523 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); 525 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info();
524 if (!shared_info.is_null()) { 526 if (!shared_info.is_null()) {
525 FunctionLiteral* lit = parse_info->literal(); 527 FunctionLiteral* lit = parse_info->literal();
526 shared_info->set_ast_node_count(lit->ast_node_count()); 528 shared_info->set_ast_node_count(lit->ast_node_count());
527 if (lit->dont_optimize_reason() != kNoReason) { 529 if (lit->dont_optimize_reason() != kNoReason) {
528 shared_info->DisableOptimization(lit->dont_optimize_reason()); 530 shared_info->DisableOptimization(lit->dont_optimize_reason());
529 } 531 }
530 if (lit->flags() & AstProperties::kDontCrankshaft) { 532 if (lit->flags() & AstProperties::kMustUseIgnitionTurbo) {
531 shared_info->set_dont_crankshaft(true); 533 shared_info->set_must_use_ignition_turbo(true);
532 } 534 }
533 } 535 }
534 return true; 536 return true;
535 } 537 }
536 538
537 bool GetOptimizedCodeNow(CompilationJob* job) { 539 bool GetOptimizedCodeNow(CompilationJob* job) {
538 CompilationInfo* info = job->info(); 540 CompilationInfo* info = job->info();
539 Isolate* isolate = info->isolate(); 541 Isolate* isolate = info->isolate();
540 542
541 // Parsing is not required when optimizing from existing bytecode. 543 // Parsing is not required when optimizing from existing bytecode.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 function->ShortPrint(); 645 function->ShortPrint();
644 if (!osr_ast_id.IsNone()) { 646 if (!osr_ast_id.IsNone()) {
645 PrintF(" at OSR AST id %d", osr_ast_id.ToInt()); 647 PrintF(" at OSR AST id %d", osr_ast_id.ToInt());
646 } 648 }
647 PrintF("]\n"); 649 PrintF("]\n");
648 } 650 }
649 return cached_code; 651 return cached_code;
650 } 652 }
651 653
652 // Reset profiler ticks, function is no longer considered hot. 654 // Reset profiler ticks, function is no longer considered hot.
655 DCHECK(shared->is_compiled());
653 if (shared->HasBaselineCode()) { 656 if (shared->HasBaselineCode()) {
654 shared->code()->set_profiler_ticks(0); 657 shared->code()->set_profiler_ticks(0);
655 } else if (shared->HasBytecodeArray()) { 658 } else if (shared->HasBytecodeArray()) {
656 shared->set_profiler_ticks(0); 659 shared->set_profiler_ticks(0);
657 } 660 }
658 661
659 VMState<COMPILER> state(isolate); 662 VMState<COMPILER> state(isolate);
660 DCHECK(!isolate->has_pending_exception()); 663 DCHECK(!isolate->has_pending_exception());
661 PostponeInterruptsScope postpone(isolate); 664 PostponeInterruptsScope postpone(isolate);
662 bool use_turbofan = UseTurboFan(shared) || ignition_osr; 665 bool use_turbofan = UseTurboFan(shared) || ignition_osr;
(...skipping 19 matching lines...) Expand all
682 return MaybeHandle<Code>(); 685 return MaybeHandle<Code>();
683 } 686 }
684 687
685 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate); 688 TimerEventScope<TimerEventOptimizeCode> optimize_code_timer(isolate);
686 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode); 689 RuntimeCallTimerScope runtimeTimer(isolate, &RuntimeCallStats::OptimizeCode);
687 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode"); 690 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeCode");
688 691
689 // TurboFan can optimize directly from existing bytecode. 692 // TurboFan can optimize directly from existing bytecode.
690 if (use_turbofan && ShouldUseIgnition(info)) { 693 if (use_turbofan && ShouldUseIgnition(info)) {
691 if (info->is_osr() && !ignition_osr) return MaybeHandle<Code>(); 694 if (info->is_osr() && !ignition_osr) return MaybeHandle<Code>();
692 if (!Compiler::EnsureBytecode(info)) { 695 DCHECK(shared->HasBytecodeArray());
693 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
694 return MaybeHandle<Code>();
695 }
696 info->MarkAsOptimizeFromBytecode(); 696 info->MarkAsOptimizeFromBytecode();
697 } 697 }
698 698
699 // Verify that OSR compilations are delegated to the correct graph builder. 699 // Verify that OSR compilations are delegated to the correct graph builder.
700 // Depending on the underlying frame the semantics of the {BailoutId} differ 700 // Depending on the underlying frame the semantics of the {BailoutId} differ
701 // and the various graph builders hard-code a certain semantic: 701 // and the various graph builders hard-code a certain semantic:
702 // - Interpreter : The BailoutId represents a bytecode offset. 702 // - Interpreter : The BailoutId represents a bytecode offset.
703 // - FullCodegen : The BailoutId represents the id of an AST node. 703 // - FullCodegen : The BailoutId represents the id of an AST node.
704 DCHECK_IMPLIES(info->is_osr() && ignition_osr, 704 DCHECK_IMPLIES(info->is_osr() && ignition_osr,
705 info->is_optimizing_from_bytecode()); 705 info->is_optimizing_from_bytecode());
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 1187
1188 // Restore the original function info list in order to remain side-effect 1188 // Restore the original function info list in order to remain side-effect
1189 // free as much as possible, since some code expects the old shared function 1189 // free as much as possible, since some code expects the old shared function
1190 // infos to stick around. 1190 // infos to stick around.
1191 script->set_shared_function_infos(*old_function_infos); 1191 script->set_shared_function_infos(*old_function_infos);
1192 1192
1193 return infos; 1193 return infos;
1194 } 1194 }
1195 1195
1196 bool Compiler::EnsureBytecode(CompilationInfo* info) { 1196 bool Compiler::EnsureBytecode(CompilationInfo* info) {
1197 if (!ShouldUseIgnition(info)) return false; 1197 if (!info->shared_info()->is_compiled()) {
1198 if (!info->shared_info()->HasBytecodeArray()) {
1199 Handle<Code> original_code(info->shared_info()->code());
1200 if (GetUnoptimizedCode(info).is_null()) return false; 1198 if (GetUnoptimizedCode(info).is_null()) return false;
1201 if (info->shared_info()->HasAsmWasmData()) return false; 1199 if (info->shared_info()->HasAsmWasmData()) return false;
1202 DCHECK(info->shared_info()->is_compiled()); 1200 DCHECK(info->shared_info()->is_compiled());
1203 if (original_code->kind() == Code::FUNCTION) {
1204 // Generating bytecode will install the {InterpreterEntryTrampoline} as
1205 // shared code on the function. To avoid an implicit tier down we restore
1206 // original baseline code in case it existed beforehand.
1207 info->shared_info()->ReplaceCode(*original_code);
1208 }
1209 } 1201 }
1210 DCHECK(info->shared_info()->HasBytecodeArray()); 1202 DCHECK_EQ(ShouldUseIgnition(info), info->shared_info()->HasBytecodeArray());
1211 return true; 1203 return info->shared_info()->HasBytecodeArray();
1212 } 1204 }
1213 1205
1214 // TODO(turbofan): In the future, unoptimized code with deopt support could 1206 // TODO(turbofan): In the future, unoptimized code with deopt support could
1215 // be generated lazily once deopt is triggered. 1207 // be generated lazily once deopt is triggered.
1216 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { 1208 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
1217 DCHECK_NOT_NULL(info->literal()); 1209 DCHECK_NOT_NULL(info->literal());
1218 DCHECK_NOT_NULL(info->scope()); 1210 DCHECK_NOT_NULL(info->scope());
1219 Handle<SharedFunctionInfo> shared = info->shared_info(); 1211 Handle<SharedFunctionInfo> shared = info->shared_info();
1220 if (!shared->has_deoptimization_support()) { 1212 if (!shared->has_deoptimization_support()) {
1221 Zone zone(info->isolate()->allocator(), ZONE_NAME); 1213 Zone zone(info->isolate()->allocator(), ZONE_NAME);
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 return true; 1699 return true;
1708 } 1700 }
1709 return false; 1701 return false;
1710 } 1702 }
1711 } 1703 }
1712 1704
1713 void Compiler::PostInstantiation(Handle<JSFunction> function, 1705 void Compiler::PostInstantiation(Handle<JSFunction> function,
1714 PretenureFlag pretenure) { 1706 PretenureFlag pretenure) {
1715 Handle<SharedFunctionInfo> shared(function->shared()); 1707 Handle<SharedFunctionInfo> shared(function->shared());
1716 1708
1717 if (FLAG_always_opt && shared->allows_lazy_compilation()) { 1709 if (FLAG_always_opt && shared->allows_lazy_compilation() &&
1710 function->shared()->is_compiled()) {
rmcilroy 2016/11/22 14:03:44 With this change we only mark for optimization if
Michael Starzinger 2016/11/22 14:53:50 Acknowledged. I thought about this for a little bi
rmcilroy 2016/11/22 17:24:02 Acknowledged.
1718 function->MarkForOptimization(); 1711 function->MarkForOptimization();
1719 } 1712 }
1720 1713
1721 CodeAndLiterals cached = shared->SearchOptimizedCodeMap( 1714 CodeAndLiterals cached = shared->SearchOptimizedCodeMap(
1722 function->context()->native_context(), BailoutId::None()); 1715 function->context()->native_context(), BailoutId::None());
1723 if (cached.code != nullptr) { 1716 if (cached.code != nullptr) {
1724 // Caching of optimized code enabled and optimized code found. 1717 // Caching of optimized code enabled and optimized code found.
1725 DCHECK(!cached.code->marked_for_deoptimization()); 1718 DCHECK(!cached.code->marked_for_deoptimization());
1726 DCHECK(function->shared()->is_compiled()); 1719 DCHECK(function->shared()->is_compiled());
1727 function->ReplaceCode(cached.code); 1720 function->ReplaceCode(cached.code);
1728 } 1721 }
1729 1722
1730 if (cached.literals != nullptr) { 1723 if (cached.literals != nullptr) {
1731 DCHECK(shared->is_compiled()); 1724 DCHECK(shared->is_compiled());
1732 function->set_literals(cached.literals); 1725 function->set_literals(cached.literals);
1733 } else if (shared->is_compiled()) { 1726 } else if (shared->is_compiled()) {
1734 // TODO(mvstanton): pass pretenure flag to EnsureLiterals. 1727 // TODO(mvstanton): pass pretenure flag to EnsureLiterals.
1735 JSFunction::EnsureLiterals(function); 1728 JSFunction::EnsureLiterals(function);
1736 } 1729 }
1737 } 1730 }
1738 1731
1739 } // namespace internal 1732 } // namespace internal
1740 } // namespace v8 1733 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698