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

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

Issue 2322853003: VM: Zero-cost try-finally with an empty finally-block. (Closed)
Patch Set: detect rethrow correctly Created 4 years, 3 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
« no previous file with comments | « runtime/vm/ast.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4207 matching lines...) Expand 10 before | Expand all | Expand 10 after
4218 BuildRestoreContext(node->context_var(), node->token_pos()); 4218 BuildRestoreContext(node->context_var(), node->token_pos());
4219 4219
4220 EffectGraphVisitor for_catch(owner()); 4220 EffectGraphVisitor for_catch(owner());
4221 node->VisitChildren(&for_catch); 4221 node->VisitChildren(&for_catch);
4222 Append(for_catch); 4222 Append(for_catch);
4223 } 4223 }
4224 4224
4225 4225
4226 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { 4226 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
4227 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); 4227 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)");
4228 CatchClauseNode* catch_block = node->catch_block();
4229 SequenceNode* finally_block = node->finally_block();
4230 if ((finally_block != NULL) && (finally_block->length() == 0)) {
4231 SequenceNode* catch_sequence = catch_block->sequence();
4232 if (catch_sequence->length() == 1) {
4233 // Check for a single rethrow statement. This only matches the synthetic
4234 // catch-clause generated for try-finally.
4235 ThrowNode* throw_node = catch_sequence-> NodeAt(0)->AsThrowNode();
rmacnak 2016/09/09 20:24:35 extra space in "-> NodeAt"
Florian Schneider 2016/09/09 20:30:07 Done.
4236 if ((throw_node != NULL) && (throw_node->stacktrace() != NULL)) {
4237 // Empty finally-block in a try-finally can be optimized away.
4238 EffectGraphVisitor for_try(owner());
4239 node->try_block()->Visit(&for_try);
4240 Append(for_try);
4241 return;
4242 }
4243 }
4244 }
4245
4228 const intptr_t original_handler_index = owner()->try_index(); 4246 const intptr_t original_handler_index = owner()->try_index();
4229 const intptr_t try_handler_index = node->try_index(); 4247 const intptr_t try_handler_index = node->try_index();
4230 ASSERT(try_handler_index != original_handler_index); 4248 ASSERT(try_handler_index != original_handler_index);
4231 owner()->set_try_index(try_handler_index); 4249 owner()->set_try_index(try_handler_index);
4232 4250
4233 // Preserve current context into local variable ':saved_try_context_var'. 4251 // Preserve current context into local variable ':saved_try_context_var'.
4234 BuildSaveContext(node->context_var(), ST(node->token_pos())); 4252 BuildSaveContext(node->context_var(), ST(node->token_pos()));
4235 4253
4236 EffectGraphVisitor for_try(owner()); 4254 EffectGraphVisitor for_try(owner());
4237 node->try_block()->Visit(&for_try); 4255 node->try_block()->Visit(&for_try);
4238 4256
4239 if (for_try.is_open()) { 4257 if (for_try.is_open()) {
4240 JoinEntryInstr* after_try = 4258 JoinEntryInstr* after_try =
4241 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), 4259 new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
4242 original_handler_index); 4260 original_handler_index);
4243 for_try.Goto(after_try); 4261 for_try.Goto(after_try);
4244 for_try.exit_ = after_try; 4262 for_try.exit_ = after_try;
4245 } 4263 }
4246 4264
4247 JoinEntryInstr* try_entry = 4265 JoinEntryInstr* try_entry =
4248 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index); 4266 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
4249 4267
4250 Goto(try_entry); 4268 Goto(try_entry);
4251 AppendFragment(try_entry, for_try); 4269 AppendFragment(try_entry, for_try);
4252 exit_ = for_try.exit_; 4270 exit_ = for_try.exit_;
4253 4271
4254 // We are done generating code for the try block. 4272 // We are done generating code for the try block.
4255 owner()->set_try_index(original_handler_index); 4273 owner()->set_try_index(original_handler_index);
4256 4274
4257 CatchClauseNode* catch_block = node->catch_block();
4258 SequenceNode* finally_block = node->finally_block();
4259
4260 // If there is a finally block, it is the handler for code in the catch 4275 // If there is a finally block, it is the handler for code in the catch
4261 // block. 4276 // block.
4262 const intptr_t catch_handler_index = (finally_block == NULL) 4277 const intptr_t catch_handler_index = (finally_block == NULL)
4263 ? original_handler_index 4278 ? original_handler_index
4264 : catch_block->catch_handler_index(); 4279 : catch_block->catch_handler_index();
4265 4280
4266 const intptr_t prev_catch_try_index = owner()->catch_try_index(); 4281 const intptr_t prev_catch_try_index = owner()->catch_try_index();
4267 4282
4268 owner()->set_try_index(catch_handler_index); 4283 owner()->set_try_index(catch_handler_index);
4269 owner()->set_catch_try_index(try_handler_index); 4284 owner()->set_catch_try_index(try_handler_index);
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
4598 block_marks); 4613 block_marks);
4599 ASSERT(found); 4614 ASSERT(found);
4600 } 4615 }
4601 4616
4602 4617
4603 void FlowGraphBuilder::Bailout(const char* reason) const { 4618 void FlowGraphBuilder::Bailout(const char* reason) const {
4604 parsed_function_.Bailout("FlowGraphBuilder", reason); 4619 parsed_function_.Bailout("FlowGraphBuilder", reason);
4605 } 4620 }
4606 4621
4607 } // namespace dart 4622 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/ast.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698