| 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/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 intptr_t osr_id) : | 242 intptr_t osr_id) : |
| 243 parsed_function_(parsed_function), | 243 parsed_function_(parsed_function), |
| 244 ic_data_array_(ic_data_array), | 244 ic_data_array_(ic_data_array), |
| 245 num_copied_params_(parsed_function->num_copied_params()), | 245 num_copied_params_(parsed_function->num_copied_params()), |
| 246 // All parameters are copied if any parameter is. | 246 // All parameters are copied if any parameter is. |
| 247 num_non_copied_params_((num_copied_params_ == 0) | 247 num_non_copied_params_((num_copied_params_ == 0) |
| 248 ? parsed_function->function().num_fixed_parameters() | 248 ? parsed_function->function().num_fixed_parameters() |
| 249 : 0), | 249 : 0), |
| 250 num_stack_locals_(parsed_function->num_stack_locals()), | 250 num_stack_locals_(parsed_function->num_stack_locals()), |
| 251 exit_collector_(exit_collector), | 251 exit_collector_(exit_collector), |
| 252 guarded_fields_(new(I) ZoneGrowableArray<const Field*>()), | |
| 253 last_used_block_id_(0), // 0 is used for the graph entry. | 252 last_used_block_id_(0), // 0 is used for the graph entry. |
| 254 try_index_(CatchClauseNode::kInvalidTryIndex), | 253 try_index_(CatchClauseNode::kInvalidTryIndex), |
| 255 catch_try_index_(CatchClauseNode::kInvalidTryIndex), | 254 catch_try_index_(CatchClauseNode::kInvalidTryIndex), |
| 256 loop_depth_(0), | 255 loop_depth_(0), |
| 257 graph_entry_(NULL), | 256 graph_entry_(NULL), |
| 258 temp_count_(0), | 257 temp_count_(0), |
| 259 args_pushed_(0), | 258 args_pushed_(0), |
| 260 nesting_stack_(NULL), | 259 nesting_stack_(NULL), |
| 261 osr_id_(osr_id), | 260 osr_id_(osr_id), |
| 262 jump_count_(0), | 261 jump_count_(0), |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 ASSERT(delta >= 0); | 760 ASSERT(delta >= 0); |
| 762 Value* context = Bind(BuildCurrentContext()); | 761 Value* context = Bind(BuildCurrentContext()); |
| 763 while (delta-- > 0) { | 762 while (delta-- > 0) { |
| 764 context = Bind(new(I) LoadFieldInstr( | 763 context = Bind(new(I) LoadFieldInstr( |
| 765 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), | 764 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), |
| 766 Scanner::kNoSourcePos)); | 765 Scanner::kNoSourcePos)); |
| 767 } | 766 } |
| 768 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); | 767 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); |
| 769 StoreInstanceFieldInstr* store = | 768 StoreInstanceFieldInstr* store = |
| 770 new(I) StoreInstanceFieldInstr(Context::variable_offset(local.index()), | 769 new(I) StoreInstanceFieldInstr(Context::variable_offset(local.index()), |
| 771 context, | 770 context, |
| 772 tmp_val, | 771 tmp_val, |
| 773 kEmitStoreBarrier, | 772 kEmitStoreBarrier, |
| 774 Scanner::kNoSourcePos); | 773 Scanner::kNoSourcePos); |
| 775 Do(store); | 774 Do(store); |
| 776 return ExitTempLocalScope(tmp_var); | 775 return ExitTempLocalScope(tmp_var); |
| 777 } else { | 776 } else { |
| 778 return new(I) StoreLocalInstr(local, value); | 777 return new(I) StoreLocalInstr(local, value); |
| 779 } | 778 } |
| 780 } | 779 } |
| 781 | 780 |
| 782 | 781 |
| 783 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { | 782 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { |
| 784 if (local.IsConst()) { | 783 if (local.IsConst()) { |
| (...skipping 1522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2307 // Visit body. | 2306 // Visit body. |
| 2308 for (intptr_t i = 0; i < node->nodes().length(); ++i) { | 2307 for (intptr_t i = 0; i < node->nodes().length(); ++i) { |
| 2309 EffectGraphVisitor for_effect(owner()); | 2308 EffectGraphVisitor for_effect(owner()); |
| 2310 node->nodes()[i]->Visit(&for_effect); | 2309 node->nodes()[i]->Visit(&for_effect); |
| 2311 Append(for_effect); | 2310 Append(for_effect); |
| 2312 } | 2311 } |
| 2313 | 2312 |
| 2314 intptr_t num_temps = node->num_temps(); | 2313 intptr_t num_temps = node->num_temps(); |
| 2315 if (num_temps > 0) { | 2314 if (num_temps > 0) { |
| 2316 owner()->DeallocateTemps(num_temps); | 2315 owner()->DeallocateTemps(num_temps); |
| 2317 Do(new(I) DropTempsInstr(num_temps)); | 2316 Do(new(I) DropTempsInstr(num_temps, NULL)); |
| 2318 } | 2317 } |
| 2319 } | 2318 } |
| 2320 | 2319 |
| 2321 | 2320 |
| 2322 void ValueGraphVisitor::VisitLetNode(LetNode* node) { | 2321 void ValueGraphVisitor::VisitLetNode(LetNode* node) { |
| 2323 BuildLetTempExpressions(node); | 2322 BuildLetTempExpressions(node); |
| 2324 | 2323 |
| 2325 // Visit body. | 2324 // Visit body. |
| 2326 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { | 2325 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { |
| 2327 EffectGraphVisitor for_effect(owner()); | 2326 EffectGraphVisitor for_effect(owner()); |
| (...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3467 store_value = Bind(BuildStoreExprTemp(store_value)); | 3466 store_value = Bind(BuildStoreExprTemp(store_value)); |
| 3468 GuardFieldClassInstr* guard_field_class = | 3467 GuardFieldClassInstr* guard_field_class = |
| 3469 new(I) GuardFieldClassInstr(store_value, | 3468 new(I) GuardFieldClassInstr(store_value, |
| 3470 node->field(), | 3469 node->field(), |
| 3471 I->GetNextDeoptId()); | 3470 I->GetNextDeoptId()); |
| 3472 AddInstruction(guard_field_class); | 3471 AddInstruction(guard_field_class); |
| 3473 | 3472 |
| 3474 store_value = Bind(BuildLoadExprTemp()); | 3473 store_value = Bind(BuildLoadExprTemp()); |
| 3475 GuardFieldLengthInstr* guard_field_length = | 3474 GuardFieldLengthInstr* guard_field_length = |
| 3476 new(I) GuardFieldLengthInstr(store_value, | 3475 new(I) GuardFieldLengthInstr(store_value, |
| 3477 node->field(), | 3476 node->field(), |
| 3478 I->GetNextDeoptId()); | 3477 I->GetNextDeoptId()); |
| 3479 AddInstruction(guard_field_length); | 3478 AddInstruction(guard_field_length); |
| 3480 | 3479 |
| 3481 store_value = Bind(BuildLoadExprTemp()); | 3480 store_value = Bind(BuildLoadExprTemp()); |
| 3482 StoreInstanceFieldInstr* store = | 3481 StoreInstanceFieldInstr* store = |
| 3483 new(I) StoreInstanceFieldInstr(node->field(), | 3482 new(I) StoreInstanceFieldInstr(node->field(), |
| 3484 for_instance.value(), | 3483 for_instance.value(), |
| 3485 store_value, | 3484 store_value, |
| 3486 kEmitStoreBarrier, | 3485 kEmitStoreBarrier, |
| 3487 node->token_pos()); | 3486 node->token_pos()); |
| 3488 store->set_is_initialization(true); // Maybe initializing store. | 3487 store->set_is_initialization(true); // Maybe initializing store. |
| (...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4274 // Check that the graph is properly terminated. | 4273 // Check that the graph is properly terminated. |
| 4275 ASSERT(!for_effect.is_open()); | 4274 ASSERT(!for_effect.is_open()); |
| 4276 | 4275 |
| 4277 // When compiling for OSR, use a depth first search to prune instructions | 4276 // When compiling for OSR, use a depth first search to prune instructions |
| 4278 // unreachable from the OSR entry. Catch entries are always considered | 4277 // unreachable from the OSR entry. Catch entries are always considered |
| 4279 // reachable, even if they become unreachable after OSR. | 4278 // reachable, even if they become unreachable after OSR. |
| 4280 if (osr_id_ != Isolate::kNoDeoptId) { | 4279 if (osr_id_ != Isolate::kNoDeoptId) { |
| 4281 PruneUnreachable(); | 4280 PruneUnreachable(); |
| 4282 } | 4281 } |
| 4283 | 4282 |
| 4284 FlowGraph* graph = new(I) FlowGraph(*this, graph_entry_, last_used_block_id_); | 4283 FlowGraph* graph = |
| 4284 new(I) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_); |
| 4285 return graph; | 4285 return graph; |
| 4286 } | 4286 } |
| 4287 | 4287 |
| 4288 | 4288 |
| 4289 void FlowGraphBuilder::PruneUnreachable() { | 4289 void FlowGraphBuilder::PruneUnreachable() { |
| 4290 ASSERT(osr_id_ != Isolate::kNoDeoptId); | 4290 ASSERT(osr_id_ != Isolate::kNoDeoptId); |
| 4291 BitVector* block_marks = new(I) BitVector(I, last_used_block_id_ + 1); | 4291 BitVector* block_marks = new(I) BitVector(I, last_used_block_id_ + 1); |
| 4292 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_, | 4292 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_, |
| 4293 block_marks); | 4293 block_marks); |
| 4294 ASSERT(found); | 4294 ASSERT(found); |
| 4295 } | 4295 } |
| 4296 | 4296 |
| 4297 | 4297 |
| 4298 void FlowGraphBuilder::Bailout(const char* reason) const { | 4298 void FlowGraphBuilder::Bailout(const char* reason) const { |
| 4299 const Function& function = parsed_function_->function(); | 4299 const Function& function = parsed_function_->function(); |
| 4300 Report::MessageF(Report::kBailout, | 4300 Report::MessageF(Report::kBailout, |
| 4301 Script::Handle(function.script()), | 4301 Script::Handle(function.script()), |
| 4302 function.token_pos(), | 4302 function.token_pos(), |
| 4303 "FlowGraphBuilder Bailout: %s %s", | 4303 "FlowGraphBuilder Bailout: %s %s", |
| 4304 String::Handle(function.name()).ToCString(), | 4304 String::Handle(function.name()).ToCString(), |
| 4305 reason); | 4305 reason); |
| 4306 UNREACHABLE(); | 4306 UNREACHABLE(); |
| 4307 } | 4307 } |
| 4308 | 4308 |
| 4309 } // namespace dart | 4309 } // namespace dart |
| OLD | NEW |