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