Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(513)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 2692803006: Track the 'awaiter return' call stack use it to detect uncaught exceptions in async functions (Closed)
Patch Set: rmacnak review Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698