| 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 void InlineExitCollector::AddExit(ReturnInstr* exit) { | 94 void InlineExitCollector::AddExit(ReturnInstr* exit) { |
| 95 Data data = { NULL, exit }; | 95 Data data = { NULL, exit }; |
| 96 exits_.Add(data); | 96 exits_.Add(data); |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 void InlineExitCollector::Union(const InlineExitCollector* other) { |
| 101 // It doesn't make sense to combine different calls or calls from |
| 102 // different graphs. |
| 103 ASSERT(caller_graph_ == other->caller_graph_); |
| 104 ASSERT(call_ == other->call_); |
| 105 exits_.AddArray(other->exits_); |
| 106 } |
| 107 |
| 108 |
| 100 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) { | 109 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) { |
| 101 return (a->exit_block->block_id() - b->exit_block->block_id()); | 110 return (a->exit_block->block_id() - b->exit_block->block_id()); |
| 102 } | 111 } |
| 103 | 112 |
| 104 | 113 |
| 105 void InlineExitCollector::SortExits() { | 114 void InlineExitCollector::SortExits() { |
| 106 // Assign block entries here because we did not necessarily know them when | 115 // Assign block entries here because we did not necessarily know them when |
| 107 // the return exit was added to the array. | 116 // the return exit was added to the array. |
| 108 for (int i = 0; i < exits_.length(); ++i) { | 117 for (int i = 0; i < exits_.length(); ++i) { |
| 109 exits_[i].exit_block = exits_[i].exit_return->GetBlock(); | 118 exits_[i].exit_block = exits_[i].exit_return->GetBlock(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 126 ReturnAt(0)->UnuseAllInputs(); | 135 ReturnAt(0)->UnuseAllInputs(); |
| 127 *exit_block = ExitBlockAt(0); | 136 *exit_block = ExitBlockAt(0); |
| 128 *last_instruction = LastInstructionAt(0); | 137 *last_instruction = LastInstructionAt(0); |
| 129 return call_->HasUses() ? ValueAt(0)->definition() : NULL; | 138 return call_->HasUses() ? ValueAt(0)->definition() : NULL; |
| 130 } else { | 139 } else { |
| 131 // Create a join of the returns. | 140 // Create a join of the returns. |
| 132 intptr_t join_id = caller_graph_->max_block_id() + 1; | 141 intptr_t join_id = caller_graph_->max_block_id() + 1; |
| 133 caller_graph_->set_max_block_id(join_id); | 142 caller_graph_->set_max_block_id(join_id); |
| 134 JoinEntryInstr* join = | 143 JoinEntryInstr* join = |
| 135 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); | 144 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); |
| 136 join->InheritDeoptTarget(call_); | 145 join->InheritDeoptTargetAfter(call_); |
| 137 | 146 |
| 138 // The dominator set of the join is the intersection of the dominator | 147 // The dominator set of the join is the intersection of the dominator |
| 139 // sets of all the predecessors. If we keep the dominator sets ordered | 148 // sets of all the predecessors. If we keep the dominator sets ordered |
| 140 // by height in the dominator tree, we can also get the immediate | 149 // by height in the dominator tree, we can also get the immediate |
| 141 // dominator of the join node from the intersection. | 150 // dominator of the join node from the intersection. |
| 142 // | 151 // |
| 143 // block_dominators is the dominator set for each block, ordered from | 152 // block_dominators is the dominator set for each block, ordered from |
| 144 // the immediate dominator to the root of the dominator tree. This is | 153 // the immediate dominator to the root of the dominator tree. This is |
| 145 // the order we collect them in (adding at the end). | 154 // the order we collect them in (adding at the end). |
| 146 // | 155 // |
| (...skipping 26 matching lines...) Expand all Loading... |
| 173 } | 182 } |
| 174 } else { | 183 } else { |
| 175 // Intersect the block's dominators with the join's dominators so far. | 184 // Intersect the block's dominators with the join's dominators so far. |
| 176 intptr_t last = block_dominators.length() - 1; | 185 intptr_t last = block_dominators.length() - 1; |
| 177 for (intptr_t j = 0; j < join_dominators.length(); ++j) { | 186 for (intptr_t j = 0; j < join_dominators.length(); ++j) { |
| 178 intptr_t k = last - j; // Corresponding index in block_dominators. | 187 intptr_t k = last - j; // Corresponding index in block_dominators. |
| 179 if ((k < 0) || (join_dominators[j] != block_dominators[k])) { | 188 if ((k < 0) || (join_dominators[j] != block_dominators[k])) { |
| 180 // We either exhausted the dominators for this block before | 189 // We either exhausted the dominators for this block before |
| 181 // exhausting the current intersection, or else we found a block | 190 // exhausting the current intersection, or else we found a block |
| 182 // on the path from the root of the tree that is not in common. | 191 // on the path from the root of the tree that is not in common. |
| 183 ASSERT(j >= 2); | 192 // I.e., there cannot be an empty set of dominators. |
| 193 ASSERT(j > 0); |
| 184 join_dominators.TruncateTo(j); | 194 join_dominators.TruncateTo(j); |
| 185 break; | 195 break; |
| 186 } | 196 } |
| 187 } | 197 } |
| 188 } | 198 } |
| 189 } | 199 } |
| 190 // The immediate dominator of the join is the last one in the ordered | 200 // The immediate dominator of the join is the last one in the ordered |
| 191 // intersection. | 201 // intersection. |
| 192 join->set_dominator(join_dominators.Last()); | |
| 193 join_dominators.Last()->AddDominatedBlock(join); | 202 join_dominators.Last()->AddDominatedBlock(join); |
| 194 *exit_block = join; | 203 *exit_block = join; |
| 195 *last_instruction = join; | 204 *last_instruction = join; |
| 196 | 205 |
| 197 // If the call has uses, create a phi of the returns. | 206 // If the call has uses, create a phi of the returns. |
| 198 if (call_->HasUses()) { | 207 if (call_->HasUses()) { |
| 199 // Add a phi of the return values. | 208 // Add a phi of the return values. |
| 200 PhiInstr* phi = new PhiInstr(join, num_exits); | 209 PhiInstr* phi = new PhiInstr(join, num_exits); |
| 201 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index()); | 210 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index()); |
| 202 phi->mark_alive(); | 211 phi->mark_alive(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 call_block->ReplaceAsPredecessorWith(callee_exit); | 275 call_block->ReplaceAsPredecessorWith(callee_exit); |
| 267 // For successors of 'inlined_head', the callee entry (Bi) is replaced | 276 // For successors of 'inlined_head', the callee entry (Bi) is replaced |
| 268 // as a predecessor by the call block (Bc). | 277 // as a predecessor by the call block (Bc). |
| 269 callee_entry->ReplaceAsPredecessorWith(call_block); | 278 callee_entry->ReplaceAsPredecessorWith(call_block); |
| 270 | 279 |
| 271 // The callee exit is now the immediate dominator of blocks whose | 280 // The callee exit is now the immediate dominator of blocks whose |
| 272 // immediate dominator was the call block. | 281 // immediate dominator was the call block. |
| 273 ASSERT(callee_exit->dominated_blocks().is_empty()); | 282 ASSERT(callee_exit->dominated_blocks().is_empty()); |
| 274 for (intptr_t i = 0; i < call_block->dominated_blocks().length(); ++i) { | 283 for (intptr_t i = 0; i < call_block->dominated_blocks().length(); ++i) { |
| 275 BlockEntryInstr* block = call_block->dominated_blocks()[i]; | 284 BlockEntryInstr* block = call_block->dominated_blocks()[i]; |
| 276 block->set_dominator(callee_exit); | |
| 277 callee_exit->AddDominatedBlock(block); | 285 callee_exit->AddDominatedBlock(block); |
| 278 } | 286 } |
| 279 // The call block is now the immediate dominator of blocks whose | 287 // The call block is now the immediate dominator of blocks whose |
| 280 // immediate dominator was the callee entry. | 288 // immediate dominator was the callee entry. |
| 281 call_block->ClearDominatedBlocks(); | 289 call_block->ClearDominatedBlocks(); |
| 282 for (intptr_t i = 0; i < callee_entry->dominated_blocks().length(); ++i) { | 290 for (intptr_t i = 0; i < callee_entry->dominated_blocks().length(); ++i) { |
| 283 BlockEntryInstr* block = callee_entry->dominated_blocks()[i]; | 291 BlockEntryInstr* block = callee_entry->dominated_blocks()[i]; |
| 284 block->set_dominator(call_block); | |
| 285 call_block->AddDominatedBlock(block); | 292 call_block->AddDominatedBlock(block); |
| 286 } | 293 } |
| 287 } | 294 } |
| 288 } | 295 } |
| 289 | 296 |
| 290 | 297 |
| 291 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 298 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 292 ASSERT(is_open()); | 299 ASSERT(is_open()); |
| 293 if (other_fragment.is_empty()) return; | 300 if (other_fragment.is_empty()) return; |
| 294 if (is_empty()) { | 301 if (is_empty()) { |
| (...skipping 3080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3375 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3382 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3376 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3383 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3377 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3384 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3378 const Error& error = Error::Handle( | 3385 const Error& error = Error::Handle( |
| 3379 LanguageError::New(String::Handle(String::New(chars)))); | 3386 LanguageError::New(String::Handle(String::New(chars)))); |
| 3380 Isolate::Current()->long_jump_base()->Jump(1, error); | 3387 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3381 } | 3388 } |
| 3382 | 3389 |
| 3383 | 3390 |
| 3384 } // namespace dart | 3391 } // namespace dart |
| OLD | NEW |