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/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 last_used_block_id_(0), // 0 is used for the graph entry. | 316 last_used_block_id_(0), // 0 is used for the graph entry. |
317 try_index_(CatchClauseNode::kInvalidTryIndex), | 317 try_index_(CatchClauseNode::kInvalidTryIndex), |
318 catch_try_index_(CatchClauseNode::kInvalidTryIndex), | 318 catch_try_index_(CatchClauseNode::kInvalidTryIndex), |
319 loop_depth_(0), | 319 loop_depth_(0), |
320 graph_entry_(NULL), | 320 graph_entry_(NULL), |
321 temp_count_(0), | 321 temp_count_(0), |
322 args_pushed_(0), | 322 args_pushed_(0), |
323 nesting_stack_(NULL), | 323 nesting_stack_(NULL), |
324 osr_id_(osr_id), | 324 osr_id_(osr_id), |
325 jump_count_(0), | 325 jump_count_(0), |
326 await_joins_(new (Z) ZoneGrowableArray<JoinEntryInstr*>()) {} | 326 await_joins_(new (Z) ZoneGrowableArray<JoinEntryInstr*>()), |
| 327 await_token_positions_(new (Z) ZoneGrowableArray<TokenPosition>()) {} |
327 | 328 |
328 | 329 |
329 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { | 330 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { |
330 graph_entry_->AddCatchEntry(entry); | 331 graph_entry_->AddCatchEntry(entry); |
331 } | 332 } |
332 | 333 |
333 | 334 |
334 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { | 335 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { |
335 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); | 336 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); |
336 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); | 337 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); |
(...skipping 1842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2179 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); | 2180 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); |
2180 const intptr_t jump_count = owner()->next_await_counter(); | 2181 const intptr_t jump_count = owner()->next_await_counter(); |
2181 ASSERT(jump_count >= 0); | 2182 ASSERT(jump_count >= 0); |
2182 // Sanity check that we always add a JoinEntryInstr before adding a new | 2183 // Sanity check that we always add a JoinEntryInstr before adding a new |
2183 // state. | 2184 // state. |
2184 ASSERT(jump_count == owner()->await_joins()->length()); | 2185 ASSERT(jump_count == owner()->await_joins()->length()); |
2185 // Store the counter in :await_jump_var. | 2186 // Store the counter in :await_jump_var. |
2186 Value* jump_val = Bind(new (Z) ConstantInstr( | 2187 Value* jump_val = Bind(new (Z) ConstantInstr( |
2187 Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos())); | 2188 Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos())); |
2188 Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos())); | 2189 Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos())); |
| 2190 // Add a mapping from jump_count -> token_position. |
| 2191 owner()->AppendAwaitTokenPosition(node->token_pos()); |
2189 // Save the current context for resuming. | 2192 // Save the current context for resuming. |
2190 BuildSaveContext(*ctx_var, node->token_pos()); | 2193 BuildSaveContext(*ctx_var, node->token_pos()); |
2191 } | 2194 } |
2192 | 2195 |
2193 | 2196 |
2194 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { | 2197 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { |
2195 return kFirstLocalSlotFromFp - owner()->num_stack_locals() - | 2198 return kFirstLocalSlotFromFp - owner()->num_stack_locals() - |
2196 owner()->num_copied_params() - owner()->args_pushed() - | 2199 owner()->num_copied_params() - owner()->args_pushed() - |
2197 owner()->temp_count() + 1; | 2200 owner()->temp_count() + 1; |
2198 } | 2201 } |
(...skipping 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4071 catch_block->Visit(&for_catch); | 4074 catch_block->Visit(&for_catch); |
4072 owner()->set_catch_try_index(prev_catch_try_index); | 4075 owner()->set_catch_try_index(prev_catch_try_index); |
4073 | 4076 |
4074 // NOTE: The implicit variables ':saved_try_context_var', ':exception_var' | 4077 // NOTE: The implicit variables ':saved_try_context_var', ':exception_var' |
4075 // and ':stack_trace_var' can never be captured variables. | 4078 // and ':stack_trace_var' can never be captured variables. |
4076 ASSERT(!catch_block->context_var().is_captured()); | 4079 ASSERT(!catch_block->context_var().is_captured()); |
4077 ASSERT(!catch_block->exception_var().is_captured()); | 4080 ASSERT(!catch_block->exception_var().is_captured()); |
4078 ASSERT(!catch_block->stacktrace_var().is_captured()); | 4081 ASSERT(!catch_block->stacktrace_var().is_captured()); |
4079 | 4082 |
4080 CatchBlockEntryInstr* catch_entry = new (Z) CatchBlockEntryInstr( | 4083 CatchBlockEntryInstr* catch_entry = new (Z) CatchBlockEntryInstr( |
| 4084 catch_block->token_pos(), (node->token_pos() == TokenPosition::kNoSource), |
4081 owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(), | 4085 owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(), |
4082 catch_block->handler_types(), try_handler_index, | 4086 catch_block->handler_types(), try_handler_index, |
4083 catch_block->exception_var(), catch_block->stacktrace_var(), | 4087 catch_block->exception_var(), catch_block->stacktrace_var(), |
4084 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId()); | 4088 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId()); |
4085 owner()->AddCatchEntry(catch_entry); | 4089 owner()->AddCatchEntry(catch_entry); |
4086 AppendFragment(catch_entry, for_catch); | 4090 AppendFragment(catch_entry, for_catch); |
4087 | 4091 |
4088 if (for_catch.is_open()) { | 4092 if (for_catch.is_open()) { |
4089 JoinEntryInstr* join = new (Z) | 4093 JoinEntryInstr* join = new (Z) |
4090 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); | 4094 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); |
(...skipping 22 matching lines...) Expand all Loading... |
4113 for_finally.PushArgument(stacktrace); | 4117 for_finally.PushArgument(stacktrace); |
4114 for_finally.AddInstruction( | 4118 for_finally.AddInstruction( |
4115 new (Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index)); | 4119 new (Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index)); |
4116 for_finally.CloseFragment(); | 4120 for_finally.CloseFragment(); |
4117 } | 4121 } |
4118 ASSERT(!for_finally.is_open()); | 4122 ASSERT(!for_finally.is_open()); |
4119 | 4123 |
4120 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); | 4124 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); |
4121 types.SetAt(0, Object::dynamic_type()); | 4125 types.SetAt(0, Object::dynamic_type()); |
4122 CatchBlockEntryInstr* finally_entry = new (Z) CatchBlockEntryInstr( | 4126 CatchBlockEntryInstr* finally_entry = new (Z) CatchBlockEntryInstr( |
| 4127 finally_block->token_pos(), |
| 4128 true, // this is not a catch block from user code. |
4123 owner()->AllocateBlockId(), original_handler_index, | 4129 owner()->AllocateBlockId(), original_handler_index, |
4124 owner()->graph_entry(), types, catch_handler_index, | 4130 owner()->graph_entry(), types, catch_handler_index, |
4125 catch_block->exception_var(), catch_block->stacktrace_var(), | 4131 catch_block->exception_var(), catch_block->stacktrace_var(), |
4126 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId()); | 4132 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId()); |
4127 owner()->AddCatchEntry(finally_entry); | 4133 owner()->AddCatchEntry(finally_entry); |
4128 AppendFragment(finally_entry, for_finally); | 4134 AppendFragment(finally_entry, for_finally); |
4129 } | 4135 } |
4130 | 4136 |
4131 // Generate code for the finally block if one exists. | 4137 // Generate code for the finally block if one exists. |
4132 if ((finally_block != NULL) && is_open()) { | 4138 if ((finally_block != NULL) && is_open()) { |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4360 | 4366 |
4361 // When compiling for OSR, use a depth first search to prune instructions | 4367 // When compiling for OSR, use a depth first search to prune instructions |
4362 // unreachable from the OSR entry. Catch entries are always considered | 4368 // unreachable from the OSR entry. Catch entries are always considered |
4363 // reachable, even if they become unreachable after OSR. | 4369 // reachable, even if they become unreachable after OSR. |
4364 if (osr_id_ != Compiler::kNoOSRDeoptId) { | 4370 if (osr_id_ != Compiler::kNoOSRDeoptId) { |
4365 PruneUnreachable(); | 4371 PruneUnreachable(); |
4366 } | 4372 } |
4367 | 4373 |
4368 FlowGraph* graph = | 4374 FlowGraph* graph = |
4369 new (Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_); | 4375 new (Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_); |
| 4376 graph->set_await_token_positions(await_token_positions_); |
4370 return graph; | 4377 return graph; |
4371 } | 4378 } |
4372 | 4379 |
4373 | 4380 |
| 4381 void FlowGraphBuilder::AppendAwaitTokenPosition(TokenPosition token_pos) { |
| 4382 await_token_positions_->Add(token_pos); |
| 4383 } |
| 4384 |
| 4385 |
4374 void FlowGraphBuilder::PruneUnreachable() { | 4386 void FlowGraphBuilder::PruneUnreachable() { |
4375 ASSERT(osr_id_ != Compiler::kNoOSRDeoptId); | 4387 ASSERT(osr_id_ != Compiler::kNoOSRDeoptId); |
4376 BitVector* block_marks = new (Z) BitVector(Z, last_used_block_id_ + 1); | 4388 BitVector* block_marks = new (Z) BitVector(Z, last_used_block_id_ + 1); |
4377 bool found = | 4389 bool found = |
4378 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); | 4390 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); |
4379 ASSERT(found); | 4391 ASSERT(found); |
4380 } | 4392 } |
4381 | 4393 |
4382 | 4394 |
4383 void FlowGraphBuilder::Bailout(const char* reason) const { | 4395 void FlowGraphBuilder::Bailout(const char* reason) const { |
4384 parsed_function_.Bailout("FlowGraphBuilder", reason); | 4396 parsed_function_.Bailout("FlowGraphBuilder", reason); |
4385 } | 4397 } |
4386 | 4398 |
4387 } // namespace dart | 4399 } // namespace dart |
OLD | NEW |