Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/flow_graph_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
| 6 | 6 |
| 7 #include "vm/block_scheduler.h" | 7 #include "vm/block_scheduler.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 479 function.ToCString(), | 479 function.ToCString(), |
| 480 function.deoptimization_counter())); | 480 function.deoptimization_counter())); |
| 481 | 481 |
| 482 // TODO(fschneider): Enable inlining inside try-blocks. | 482 // TODO(fschneider): Enable inlining inside try-blocks. |
| 483 if (call_data->call->GetBlock()->try_index() != | 483 if (call_data->call->GetBlock()->try_index() != |
| 484 CatchClauseNode::kInvalidTryIndex) { | 484 CatchClauseNode::kInvalidTryIndex) { |
| 485 TRACE_INLINING(OS::Print(" Bailout: inside try-block\n")); | 485 TRACE_INLINING(OS::Print(" Bailout: inside try-block\n")); |
| 486 return false; | 486 return false; |
| 487 } | 487 } |
| 488 | 488 |
| 489 // Make a handle for the unoptimized code so that it is not disconnected | |
| 490 // from the function while we are trying to inline it. | |
| 491 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); | |
| 489 // Abort if the inlinable bit on the function is low. | 492 // Abort if the inlinable bit on the function is low. |
| 490 if (!function.IsInlineable()) { | 493 if (!function.IsInlineable()) { |
| 491 TRACE_INLINING(OS::Print(" Bailout: not inlinable\n")); | 494 TRACE_INLINING(OS::Print(" Bailout: not inlinable\n")); |
| 492 return false; | 495 return false; |
| 493 } | 496 } |
| 494 | 497 |
| 495 // Abort if this function has deoptimized too much. | 498 // Abort if this function has deoptimized too much. |
| 496 if (function.deoptimization_counter() >= | 499 if (function.deoptimization_counter() >= |
| 497 FLAG_deoptimization_counter_threshold) { | 500 FLAG_deoptimization_counter_threshold) { |
| 498 function.set_is_inlinable(false); | 501 function.set_is_inlinable(false); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 ParsedFunction* parsed_function; | 541 ParsedFunction* parsed_function; |
| 539 { | 542 { |
| 540 TimerScope timer(FLAG_compiler_stats, | 543 TimerScope timer(FLAG_compiler_stats, |
| 541 &CompilerStats::graphinliner_parse_timer, | 544 &CompilerStats::graphinliner_parse_timer, |
| 542 isolate); | 545 isolate); |
| 543 parsed_function = GetParsedFunction(function, &in_cache); | 546 parsed_function = GetParsedFunction(function, &in_cache); |
| 544 } | 547 } |
| 545 | 548 |
| 546 // Load IC data for the callee. | 549 // Load IC data for the callee. |
| 547 Array& ic_data_array = Array::Handle(); | 550 Array& ic_data_array = Array::Handle(); |
| 548 if (function.HasCode()) { | 551 |
| 549 const Code& unoptimized_code = | 552 // IsInlineable above checked HasCode. Creating a ZoneHandle for the code |
|
srdjan
2013/11/19 19:18:29
s/ZoneHandle/Handle/ since you stored it into a sc
zra
2013/11/22 17:18:54
Done.
| |
| 550 Code::Handle(function.unoptimized_code()); | 553 // should have kept GC from detaching, but let's assert just to make sure. |
| 551 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray(); | 554 ASSERT(function.HasCode()); |
| 552 } | 555 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray(); |
| 553 | 556 |
| 554 // Build the callee graph. | 557 // Build the callee graph. |
| 555 InlineExitCollector* exit_collector = | 558 InlineExitCollector* exit_collector = |
| 556 new InlineExitCollector(caller_graph_, call); | 559 new InlineExitCollector(caller_graph_, call); |
| 557 FlowGraphBuilder builder(parsed_function, | 560 FlowGraphBuilder builder(parsed_function, |
| 558 ic_data_array, | 561 ic_data_array, |
| 559 exit_collector, | 562 exit_collector, |
| 560 Isolate::kNoDeoptId); | 563 Isolate::kNoDeoptId); |
| 561 builder.SetInitialBlockId(caller_graph_->max_block_id()); | 564 builder.SetInitialBlockId(caller_graph_->max_block_id()); |
| 562 FlowGraph* callee_graph; | 565 FlowGraph* callee_graph; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 "const args: %" Pd "\n", | 663 "const args: %" Pd "\n", |
| 661 size, | 664 size, |
| 662 call_site_count, | 665 call_site_count, |
| 663 constants_count)); | 666 constants_count)); |
| 664 return false; | 667 return false; |
| 665 } | 668 } |
| 666 | 669 |
| 667 collected_call_sites_->FindCallSites(callee_graph, inlining_depth_); | 670 collected_call_sites_->FindCallSites(callee_graph, inlining_depth_); |
| 668 | 671 |
| 669 // Add the function to the cache. | 672 // Add the function to the cache. |
| 670 if (!in_cache) function_cache_.Add(parsed_function); | 673 if (!in_cache) { |
| 674 function_cache_.Add(parsed_function); | |
| 675 } | |
| 671 | 676 |
| 672 // Build succeeded so we restore the bailout jump. | 677 // Build succeeded so we restore the bailout jump. |
| 673 inlined_ = true; | 678 inlined_ = true; |
| 674 inlined_size_ += size; | 679 inlined_size_ += size; |
| 675 isolate->set_long_jump_base(base); | 680 isolate->set_long_jump_base(base); |
| 676 isolate->set_deopt_id(prev_deopt_id); | 681 isolate->set_deopt_id(prev_deopt_id); |
| 677 | 682 |
| 678 call_data->callee_graph = callee_graph; | 683 call_data->callee_graph = callee_graph; |
| 679 call_data->parameter_stubs = param_stubs; | 684 call_data->parameter_stubs = param_stubs; |
| 680 call_data->exit_collector = exit_collector; | 685 call_data->exit_collector = exit_collector; |
| 681 | 686 |
| 682 // When inlined, we add the guarded fields of the callee to the caller's | 687 // When inlined, we add the guarded fields of the callee to the caller's |
| 683 // list of guarded fields. | 688 // list of guarded fields. |
| 684 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) { | 689 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) { |
| 685 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(), | 690 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(), |
| 686 (*callee_graph->guarded_fields())[i]); | 691 (*callee_graph->guarded_fields())[i]); |
| 687 } | 692 } |
| 688 | 693 |
| 694 // We allocate a ZoneHandle for the unoptimized code so that it cannot be | |
| 695 // disconnected from its function during the rest of compilation. | |
| 696 Code::ZoneHandle(unoptimized_code.raw()); | |
| 689 TRACE_INLINING(OS::Print(" Success\n")); | 697 TRACE_INLINING(OS::Print(" Success\n")); |
| 690 return true; | 698 return true; |
| 691 } else { | 699 } else { |
| 692 Error& error = Error::Handle(); | 700 Error& error = Error::Handle(); |
| 693 error = isolate->object_store()->sticky_error(); | 701 error = isolate->object_store()->sticky_error(); |
| 694 isolate->object_store()->clear_sticky_error(); | 702 isolate->object_store()->clear_sticky_error(); |
| 695 isolate->set_long_jump_base(base); | 703 isolate->set_long_jump_base(base); |
| 696 isolate->set_deopt_id(prev_deopt_id); | 704 isolate->set_deopt_id(prev_deopt_id); |
| 697 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString())); | 705 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString())); |
| 698 return false; | 706 return false; |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1522 OS::Print("After Inlining of %s\n", flow_graph_-> | 1530 OS::Print("After Inlining of %s\n", flow_graph_-> |
| 1523 parsed_function().function().ToFullyQualifiedCString()); | 1531 parsed_function().function().ToFullyQualifiedCString()); |
| 1524 FlowGraphPrinter printer(*flow_graph_); | 1532 FlowGraphPrinter printer(*flow_graph_); |
| 1525 printer.PrintBlocks(); | 1533 printer.PrintBlocks(); |
| 1526 } | 1534 } |
| 1527 } | 1535 } |
| 1528 } | 1536 } |
| 1529 } | 1537 } |
| 1530 | 1538 |
| 1531 } // namespace dart | 1539 } // namespace dart |
| OLD | NEW |