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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 BlockEntryInstr* block = block_it.Current(); | 284 BlockEntryInstr* block = block_it.Current(); |
285 if (block->IsTargetEntry()) { | 285 if (block->IsTargetEntry()) { |
286 block->AsTargetEntry()->adjust_edge_weight(scale_factor); | 286 block->AsTargetEntry()->adjust_edge_weight(scale_factor); |
287 } | 287 } |
288 Instruction* instr = block; | 288 Instruction* instr = block; |
289 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 289 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
290 instr = it.Current(); | 290 instr = it.Current(); |
291 // TODO(zerny): Avoid creating unnecessary environments. Note that some | 291 // TODO(zerny): Avoid creating unnecessary environments. Note that some |
292 // optimizations need deoptimization info for non-deoptable instructions, | 292 // optimizations need deoptimization info for non-deoptable instructions, |
293 // eg, LICM on GOTOs. | 293 // eg, LICM on GOTOs. |
294 if (instr->env() != NULL) call_->env()->DeepCopyToOuter(instr); | 294 if (instr->env() != NULL) { |
| 295 call_->env()->DeepCopyToOuter(callee_graph->isolate(), instr); |
| 296 } |
295 } | 297 } |
296 if (instr->IsGoto()) { | 298 if (instr->IsGoto()) { |
297 instr->AsGoto()->adjust_edge_weight(scale_factor); | 299 instr->AsGoto()->adjust_edge_weight(scale_factor); |
298 } | 300 } |
299 } | 301 } |
300 } | 302 } |
301 | 303 |
302 | 304 |
303 void InlineExitCollector::AddExit(ReturnInstr* exit) { | 305 void InlineExitCollector::AddExit(ReturnInstr* exit) { |
304 Data data = { NULL, exit }; | 306 Data data = { NULL, exit }; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 *exit_block = ExitBlockAt(0); | 343 *exit_block = ExitBlockAt(0); |
342 *last_instruction = LastInstructionAt(0); | 344 *last_instruction = LastInstructionAt(0); |
343 return call_->HasUses() ? ValueAt(0)->definition() : NULL; | 345 return call_->HasUses() ? ValueAt(0)->definition() : NULL; |
344 } else { | 346 } else { |
345 ASSERT(num_exits > 1); | 347 ASSERT(num_exits > 1); |
346 // Create a join of the returns. | 348 // Create a join of the returns. |
347 intptr_t join_id = caller_graph_->max_block_id() + 1; | 349 intptr_t join_id = caller_graph_->max_block_id() + 1; |
348 caller_graph_->set_max_block_id(join_id); | 350 caller_graph_->set_max_block_id(join_id); |
349 JoinEntryInstr* join = | 351 JoinEntryInstr* join = |
350 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); | 352 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); |
351 join->InheritDeoptTargetAfter(call_); | 353 join->InheritDeoptTargetAfter(isolate(), call_); |
352 | 354 |
353 // The dominator set of the join is the intersection of the dominator | 355 // The dominator set of the join is the intersection of the dominator |
354 // sets of all the predecessors. If we keep the dominator sets ordered | 356 // sets of all the predecessors. If we keep the dominator sets ordered |
355 // by height in the dominator tree, we can also get the immediate | 357 // by height in the dominator tree, we can also get the immediate |
356 // dominator of the join node from the intersection. | 358 // dominator of the join node from the intersection. |
357 // | 359 // |
358 // block_dominators is the dominator set for each block, ordered from | 360 // block_dominators is the dominator set for each block, ordered from |
359 // the immediate dominator to the root of the dominator tree. This is | 361 // the immediate dominator to the root of the dominator tree. This is |
360 // the order we collect them in (adding at the end). | 362 // the order we collect them in (adding at the end). |
361 // | 363 // |
362 // join_dominators is the join's dominators ordered from the root of the | 364 // join_dominators is the join's dominators ordered from the root of the |
363 // dominator tree to the immediate dominator. This order supports | 365 // dominator tree to the immediate dominator. This order supports |
364 // removing during intersection by truncating the list. | 366 // removing during intersection by truncating the list. |
365 GrowableArray<BlockEntryInstr*> block_dominators; | 367 GrowableArray<BlockEntryInstr*> block_dominators; |
366 GrowableArray<BlockEntryInstr*> join_dominators; | 368 GrowableArray<BlockEntryInstr*> join_dominators; |
367 for (intptr_t i = 0; i < num_exits; ++i) { | 369 for (intptr_t i = 0; i < num_exits; ++i) { |
368 // Add the control-flow edge. | 370 // Add the control-flow edge. |
369 GotoInstr* goto_instr = new GotoInstr(join); | 371 GotoInstr* goto_instr = new GotoInstr(join); |
370 goto_instr->InheritDeoptTarget(ReturnAt(i)); | 372 goto_instr->InheritDeoptTarget(isolate(), ReturnAt(i)); |
371 LastInstructionAt(i)->LinkTo(goto_instr); | 373 LastInstructionAt(i)->LinkTo(goto_instr); |
372 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); | 374 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); |
373 join->predecessors_.Add(ExitBlockAt(i)); | 375 join->predecessors_.Add(ExitBlockAt(i)); |
374 | 376 |
375 // Collect the block's dominators. | 377 // Collect the block's dominators. |
376 block_dominators.Clear(); | 378 block_dominators.Clear(); |
377 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator(); | 379 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator(); |
378 while (dominator != NULL) { | 380 while (dominator != NULL) { |
379 block_dominators.Add(dominator); | 381 block_dominators.Add(dominator); |
380 dominator = dominator->dominator(); | 382 dominator = dominator->dominator(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 if (exits_.length() == 0) { | 447 if (exits_.length() == 0) { |
446 // Handle the case when there are no normal return exits from the callee | 448 // Handle the case when there are no normal return exits from the callee |
447 // (i.e. the callee unconditionally throws) by inserting an artificial | 449 // (i.e. the callee unconditionally throws) by inserting an artificial |
448 // branch (true === true). | 450 // branch (true === true). |
449 // The true successor is the inlined body, the false successor | 451 // The true successor is the inlined body, the false successor |
450 // goes to the rest of the caller graph. It is removed as unreachable code | 452 // goes to the rest of the caller graph. It is removed as unreachable code |
451 // by the constant propagation. | 453 // by the constant propagation. |
452 TargetEntryInstr* false_block = | 454 TargetEntryInstr* false_block = |
453 new TargetEntryInstr(caller_graph_->allocate_block_id(), | 455 new TargetEntryInstr(caller_graph_->allocate_block_id(), |
454 call_block->try_index()); | 456 call_block->try_index()); |
455 false_block->InheritDeoptTargetAfter(call_); | 457 false_block->InheritDeoptTargetAfter(isolate(), call_); |
456 false_block->LinkTo(call_->next()); | 458 false_block->LinkTo(call_->next()); |
457 call_block->ReplaceAsPredecessorWith(false_block); | 459 call_block->ReplaceAsPredecessorWith(false_block); |
458 | 460 |
459 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); | 461 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); |
460 BranchInstr* branch = | 462 BranchInstr* branch = |
461 new BranchInstr(new StrictCompareInstr(call_block->start_pos(), | 463 new BranchInstr(new StrictCompareInstr(call_block->start_pos(), |
462 Token::kEQ_STRICT, | 464 Token::kEQ_STRICT, |
463 new Value(true_const), | 465 new Value(true_const), |
464 new Value(true_const), | 466 new Value(true_const), |
465 false)); // No number check. | 467 false)); // No number check. |
466 branch->InheritDeoptTarget(call_); | 468 branch->InheritDeoptTarget(isolate(), call_); |
467 *branch->true_successor_address() = callee_entry; | 469 *branch->true_successor_address() = callee_entry; |
468 *branch->false_successor_address() = false_block; | 470 *branch->false_successor_address() = false_block; |
469 | 471 |
470 call_->previous()->AppendInstruction(branch); | 472 call_->previous()->AppendInstruction(branch); |
471 call_block->set_last_instruction(branch); | 473 call_block->set_last_instruction(branch); |
472 | 474 |
473 // Update dominator tree. | 475 // Update dominator tree. |
474 call_block->AddDominatedBlock(callee_entry); | 476 call_block->AddDominatedBlock(callee_entry); |
475 call_block->AddDominatedBlock(false_block); | 477 call_block->AddDominatedBlock(false_block); |
476 | 478 |
(...skipping 3497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3974 LanguageError::kBailout, | 3976 LanguageError::kBailout, |
3975 Heap::kNew, | 3977 Heap::kNew, |
3976 "FlowGraphBuilder Bailout: %s %s", | 3978 "FlowGraphBuilder Bailout: %s %s", |
3977 String::Handle(function.name()).ToCString(), | 3979 String::Handle(function.name()).ToCString(), |
3978 reason)); | 3980 reason)); |
3979 Isolate::Current()->long_jump_base()->Jump(1, error); | 3981 Isolate::Current()->long_jump_base()->Jump(1, error); |
3980 UNREACHABLE(); | 3982 UNREACHABLE(); |
3981 } | 3983 } |
3982 | 3984 |
3983 } // namespace dart | 3985 } // namespace dart |
OLD | NEW |