| 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/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 94 |
| 95 bool FlowGraphCompiler::HasFinally() const { | 95 bool FlowGraphCompiler::HasFinally() const { |
| 96 return parsed_function().function().has_finally(); | 96 return parsed_function().function().has_finally(); |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 void FlowGraphCompiler::InitCompiler() { | 100 void FlowGraphCompiler::InitCompiler() { |
| 101 pc_descriptors_list_ = new DescriptorList(64); | 101 pc_descriptors_list_ = new DescriptorList(64); |
| 102 exception_handlers_list_ = new ExceptionHandlerList(); | 102 exception_handlers_list_ = new ExceptionHandlerList(); |
| 103 block_info_.Clear(); | 103 block_info_.Clear(); |
| 104 bool is_leaf = !parsed_function().function().IsClosureFunction() && | 104 // Conservative detection of leaf routines used to remove the stack check |
| 105 is_optimizing(); | 105 // on function entry. |
| 106 bool is_leaf = !parsed_function().function().IsClosureFunction() |
| 107 && is_optimizing() |
| 108 && !flow_graph().IsCompiledForOsr(); |
| 109 // Initialize block info and search optimized (non-OSR) code for calls |
| 110 // indicating a non-leaf routine and calls without IC data indicating |
| 111 // possible reoptimization. |
| 106 for (int i = 0; i < block_order_.length(); ++i) { | 112 for (int i = 0; i < block_order_.length(); ++i) { |
| 107 block_info_.Add(new BlockInfo()); | 113 block_info_.Add(new BlockInfo()); |
| 108 if (is_optimizing()) { | 114 if (is_optimizing() && !flow_graph().IsCompiledForOsr()) { |
| 109 BlockEntryInstr* entry = block_order_[i]; | 115 BlockEntryInstr* entry = block_order_[i]; |
| 110 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 116 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 111 Instruction* current = it.Current(); | 117 Instruction* current = it.Current(); |
| 112 const ICData* ic_data = NULL; | |
| 113 if (current->IsBranch()) { | 118 if (current->IsBranch()) { |
| 114 current = current->AsBranch()->comparison(); | 119 current = current->AsBranch()->comparison(); |
| 115 } | 120 } |
| 116 // In optimized code, ICData is always set in the instructions. | 121 // In optimized code, ICData is always set in the instructions. |
| 122 const ICData* ic_data = NULL; |
| 117 if (current->IsInstanceCall()) { | 123 if (current->IsInstanceCall()) { |
| 118 ic_data = current->AsInstanceCall()->ic_data(); | 124 ic_data = current->AsInstanceCall()->ic_data(); |
| 119 ASSERT(ic_data != NULL); | 125 ASSERT(ic_data != NULL); |
| 120 } else if (current->IsRelationalOp()) { | 126 } else if (current->IsRelationalOp()) { |
| 121 ic_data = current->AsRelationalOp()->ic_data(); | 127 ic_data = current->AsRelationalOp()->ic_data(); |
| 122 ASSERT(ic_data != NULL); | 128 ASSERT(ic_data != NULL); |
| 123 } else if (current->IsEqualityCompare()) { | 129 } else if (current->IsEqualityCompare()) { |
| 124 ic_data = current->AsEqualityCompare()->ic_data(); | 130 ic_data = current->AsEqualityCompare()->ic_data(); |
| 125 ASSERT(ic_data != NULL); | 131 ASSERT(ic_data != NULL); |
| 126 } | 132 } |
| 127 if ((ic_data != NULL) && (ic_data->NumberOfChecks() == 0)) { | 133 if ((ic_data != NULL) && (ic_data->NumberOfChecks() == 0)) { |
| 128 may_reoptimize_ = true; | 134 may_reoptimize_ = true; |
| 129 break; | |
| 130 } | 135 } |
| 131 if (is_leaf && !current->IsCheckStackOverflow()) { | 136 if (is_leaf && !current->IsCheckStackOverflow()) { |
| 132 // Note that we do no care if the code contains instructions that | 137 // Note that we do not care if the code contains instructions that |
| 133 // can deoptimize. | 138 // can deoptimize. |
| 134 LocationSummary* locs = current->locs(); | 139 LocationSummary* locs = current->locs(); |
| 135 if ((locs != NULL) && locs->can_call()) { | 140 if ((locs != NULL) && locs->can_call()) { |
| 136 is_leaf = false; | 141 is_leaf = false; |
| 137 } | 142 } |
| 138 } | 143 } |
| 139 } | 144 } |
| 140 } | 145 } |
| 141 } | 146 } |
| 142 if (is_leaf) { | 147 if (is_leaf) { |
| 143 // Remove check stack overflow at entry. | 148 // Remove the stack overflow check at function entry. |
| 144 CheckStackOverflowInstr* check = flow_graph_.graph_entry()->normal_entry() | 149 Instruction* first = flow_graph_.graph_entry()->normal_entry()->next(); |
| 145 ->next()->AsCheckStackOverflow(); | 150 ASSERT(first->IsCheckStackOverflow()); |
| 146 ASSERT(check != NULL); | 151 if (first->IsCheckStackOverflow()) first->RemoveFromGraph(); |
| 147 check->RemoveFromGraph(); | |
| 148 } | 152 } |
| 149 } | 153 } |
| 150 | 154 |
| 151 | 155 |
| 152 bool FlowGraphCompiler::CanOptimize() { | 156 bool FlowGraphCompiler::CanOptimize() { |
| 153 return !FLAG_report_usage_count && | 157 return !FLAG_report_usage_count && |
| 154 (FLAG_optimization_counter_threshold >= 0); | 158 (FLAG_optimization_counter_threshold >= 0); |
| 155 } | 159 } |
| 156 | 160 |
| 157 | 161 |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 label_address = StubCode::ClosureCallInlineCacheEntryPoint(); | 551 label_address = StubCode::ClosureCallInlineCacheEntryPoint(); |
| 548 ExternalLabel target_label("InlineCache", label_address); | 552 ExternalLabel target_label("InlineCache", label_address); |
| 549 EmitInstanceCall(&target_label, | 553 EmitInstanceCall(&target_label, |
| 550 ICData::ZoneHandle(ic_data.AsUnaryClassChecks()), | 554 ICData::ZoneHandle(ic_data.AsUnaryClassChecks()), |
| 551 arguments_descriptor, argument_count, | 555 arguments_descriptor, argument_count, |
| 552 deopt_id, token_pos, locs); | 556 deopt_id, token_pos, locs); |
| 553 return; | 557 return; |
| 554 } | 558 } |
| 555 // Emit IC call that will count and thus may need reoptimization at | 559 // Emit IC call that will count and thus may need reoptimization at |
| 556 // function entry. | 560 // function entry. |
| 557 ASSERT(!is_optimizing() || may_reoptimize()); | 561 ASSERT(!is_optimizing() |
| 562 || may_reoptimize() |
| 563 || flow_graph().IsCompiledForOsr()); |
| 558 switch (ic_data.num_args_tested()) { | 564 switch (ic_data.num_args_tested()) { |
| 559 case 1: | 565 case 1: |
| 560 label_address = StubCode::OneArgOptimizedCheckInlineCacheEntryPoint(); | 566 label_address = StubCode::OneArgOptimizedCheckInlineCacheEntryPoint(); |
| 561 break; | 567 break; |
| 562 case 2: | 568 case 2: |
| 563 label_address = StubCode::TwoArgsOptimizedCheckInlineCacheEntryPoint(); | 569 label_address = StubCode::TwoArgsOptimizedCheckInlineCacheEntryPoint(); |
| 564 break; | 570 break; |
| 565 case 3: | 571 case 3: |
| 566 label_address = | 572 label_address = |
| 567 StubCode::ThreeArgsOptimizedCheckInlineCacheEntryPoint(); | 573 StubCode::ThreeArgsOptimizedCheckInlineCacheEntryPoint(); |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 | 1087 |
| 1082 for (int i = 0; i < len; i++) { | 1088 for (int i = 0; i < len; i++) { |
| 1083 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), | 1089 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i), |
| 1084 &Function::ZoneHandle(ic_data.GetTargetAt(i)), | 1090 &Function::ZoneHandle(ic_data.GetTargetAt(i)), |
| 1085 ic_data.GetCountAt(i))); | 1091 ic_data.GetCountAt(i))); |
| 1086 } | 1092 } |
| 1087 sorted->Sort(HighestCountFirst); | 1093 sorted->Sort(HighestCountFirst); |
| 1088 } | 1094 } |
| 1089 | 1095 |
| 1090 } // namespace dart | 1096 } // namespace dart |
| OLD | NEW |