OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/compiler.h" | 5 #include "vm/compiler.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
8 | 8 |
9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
10 #include "vm/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
405 | 405 |
406 // We may reattempt compilation if the function needs to be assembled using | 406 // We may reattempt compilation if the function needs to be assembled using |
407 // far branches on ARM and MIPS. In the else branch of the setjmp call, | 407 // far branches on ARM and MIPS. In the else branch of the setjmp call, |
408 // done is set to false, and use_far_branches is set to true if there is a | 408 // done is set to false, and use_far_branches is set to true if there is a |
409 // longjmp from the ARM or MIPS assemblers. In all other paths through this | 409 // longjmp from the ARM or MIPS assemblers. In all other paths through this |
410 // while loop, done is set to true. use_far_branches is always false on ia32 | 410 // while loop, done is set to true. use_far_branches is always false on ia32 |
411 // and x64. | 411 // and x64. |
412 bool done = false; | 412 bool done = false; |
413 // volatile because the variable may be clobbered by a longjmp. | 413 // volatile because the variable may be clobbered by a longjmp. |
414 volatile bool use_far_branches = false; | 414 volatile bool use_far_branches = false; |
415 volatile bool use_speculative_inlining = true; | |
416 GrowableArray<intptr_t> inlining_black_list; | |
417 | |
415 while (!done) { | 418 while (!done) { |
416 const intptr_t prev_deopt_id = thread->deopt_id(); | 419 const intptr_t prev_deopt_id = thread->deopt_id(); |
417 thread->set_deopt_id(0); | 420 thread->set_deopt_id(0); |
418 LongJumpScope jump; | 421 LongJumpScope jump; |
419 if (setjmp(*jump.Set()) == 0) { | 422 intptr_t val = setjmp(*jump.Set()); |
srdjan
2015/11/17 17:35:23
const intptr_t val =
srdjan
2015/11/17 17:35:23
Add Comment that val may contain deopt_id of the f
Florian Schneider
2015/11/17 19:38:56
Done.
Florian Schneider
2015/11/17 19:38:56
Done.
| |
423 if (val == 0) { | |
420 FlowGraph* flow_graph = NULL; | 424 FlowGraph* flow_graph = NULL; |
421 | 425 |
422 // Class hierarchy analysis is registered with the isolate in the | 426 // Class hierarchy analysis is registered with the isolate in the |
423 // constructor and unregisters itself upon destruction. | 427 // constructor and unregisters itself upon destruction. |
424 CHA cha(thread); | 428 CHA cha(thread); |
425 | 429 |
426 // TimerScope needs an isolate to be properly terminated in case of a | 430 // TimerScope needs an isolate to be properly terminated in case of a |
427 // LongJump. | 431 // LongJump. |
428 { | 432 { |
429 CSTAT_TIMER_SCOPE(thread, graphbuilder_timer); | 433 CSTAT_TIMER_SCOPE(thread, graphbuilder_timer); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 GrowableArray<intptr_t> caller_inline_id; | 497 GrowableArray<intptr_t> caller_inline_id; |
494 // Collect all instance fields that are loaded in the graph and | 498 // Collect all instance fields that are loaded in the graph and |
495 // have non-generic type feedback attached to them that can | 499 // have non-generic type feedback attached to them that can |
496 // potentially affect optimizations. | 500 // potentially affect optimizations. |
497 if (optimized) { | 501 if (optimized) { |
498 inline_id_to_function.Add(&function); | 502 inline_id_to_function.Add(&function); |
499 // Top scope function has no caller (-1). | 503 // Top scope function has no caller (-1). |
500 caller_inline_id.Add(-1); | 504 caller_inline_id.Add(-1); |
501 CSTAT_TIMER_SCOPE(thread, graphoptimizer_timer); | 505 CSTAT_TIMER_SCOPE(thread, graphoptimizer_timer); |
502 | 506 |
503 FlowGraphOptimizer optimizer(flow_graph); | 507 FlowGraphOptimizer optimizer(flow_graph, |
508 use_speculative_inlining, | |
509 &inlining_black_list); | |
504 if (Compiler::always_optimize()) { | 510 if (Compiler::always_optimize()) { |
505 optimizer.PopulateWithICData(); | 511 optimizer.PopulateWithICData(); |
512 | |
513 optimizer.ApplyClassIds(); | |
Florian Schneider
2015/11/17 12:39:25
Adding an early pass of specializing based on gues
| |
514 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | |
515 | |
516 FlowGraphTypePropagator::Propagate(flow_graph); | |
517 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | |
506 } | 518 } |
507 optimizer.ApplyICData(); | 519 optimizer.ApplyICData(); |
508 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 520 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
509 | 521 |
510 // Optimize (a << b) & c patterns, merge operations. | 522 // Optimize (a << b) & c patterns, merge operations. |
511 // Run early in order to have more opportunity to optimize left shifts. | 523 // Run early in order to have more opportunity to optimize left shifts. |
512 optimizer.TryOptimizePatterns(); | 524 optimizer.TryOptimizePatterns(); |
513 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 525 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
514 | 526 |
515 FlowGraphInliner::SetInliningId(flow_graph, 0); | 527 FlowGraphInliner::SetInliningId(flow_graph, 0); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
863 // We bailed out or we encountered an error. | 875 // We bailed out or we encountered an error. |
864 const Error& error = Error::Handle( | 876 const Error& error = Error::Handle( |
865 isolate->object_store()->sticky_error()); | 877 isolate->object_store()->sticky_error()); |
866 | 878 |
867 if (error.raw() == Object::branch_offset_error().raw()) { | 879 if (error.raw() == Object::branch_offset_error().raw()) { |
868 // Compilation failed due to an out of range branch offset in the | 880 // Compilation failed due to an out of range branch offset in the |
869 // assembler. We try again (done = false) with far branches enabled. | 881 // assembler. We try again (done = false) with far branches enabled. |
870 done = false; | 882 done = false; |
871 ASSERT(!use_far_branches); | 883 ASSERT(!use_far_branches); |
872 use_far_branches = true; | 884 use_far_branches = true; |
885 } else if (error.raw() == Object::speculative_inlining_error().raw()) { | |
886 done = false; | |
887 ASSERT(use_speculative_inlining); | |
888 for (intptr_t i = 0; i < inlining_black_list.length(); ++i) { | |
889 ASSERT(inlining_black_list[i] != val); | |
890 } | |
srdjan
2015/11/17 17:35:23
The loop above should be tun in DEBUG mode only. A
Florian Schneider
2015/11/17 19:38:56
Done.
| |
891 inlining_black_list.Add(val); | |
892 const intptr_t kMaxAttempts = 1; | |
893 if (inlining_black_list.length() >= kMaxAttempts) { | |
srdjan
2015/11/17 17:35:23
Use flag instead of kMaxAttempt.
Florian Schneider
2015/11/17 19:38:56
Done.
| |
894 use_speculative_inlining = false; | |
895 if (FLAG_trace_compiler) { | |
896 THR_Print("Disabled speculative inlining after %" Pd " attempts.\n", | |
897 inlining_black_list.length()); | |
898 } | |
899 } | |
873 } else { | 900 } else { |
874 // If the error isn't due to an out of range branch offset, we don't | 901 // If the error isn't due to an out of range branch offset, we don't |
875 // try again (done = true), and indicate that we did not finish | 902 // try again (done = true), and indicate that we did not finish |
876 // compiling (is_compiled = false). | 903 // compiling (is_compiled = false). |
877 if (FLAG_trace_bailout) { | 904 if (FLAG_trace_bailout) { |
878 THR_Print("%s\n", error.ToErrorCString()); | 905 THR_Print("%s\n", error.ToErrorCString()); |
879 } | 906 } |
880 done = true; | 907 done = true; |
881 } | 908 } |
882 | 909 |
(...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1965 isolate->set_background_compiler(task); | 1992 isolate->set_background_compiler(task); |
1966 start_task = true; | 1993 start_task = true; |
1967 } | 1994 } |
1968 } | 1995 } |
1969 if (start_task) { | 1996 if (start_task) { |
1970 Dart::thread_pool()->Run(isolate->background_compiler()); | 1997 Dart::thread_pool()->Run(isolate->background_compiler()); |
1971 } | 1998 } |
1972 } | 1999 } |
1973 | 2000 |
1974 } // namespace dart | 2001 } // namespace dart |
OLD | NEW |