Chromium Code Reviews| 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 |