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

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

Issue 360503003: Eliminate calls to Isolate::Current from the flow-graph builder. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.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/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 118
119 intptr_t FlowGraphBuilder::context_level() const { 119 intptr_t FlowGraphBuilder::context_level() const {
120 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel(); 120 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel();
121 } 121 }
122 122
123 123
124 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) { 124 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) {
125 if (label != label_) return NULL; 125 if (label != label_) return NULL;
126 if (break_target_ == NULL) { 126 if (break_target_ == NULL) {
127 break_target_ = 127 break_target_ =
128 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 128 new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(),
129 owner()->try_index());
129 } 130 }
130 return break_target_; 131 return break_target_;
131 } 132 }
132 133
133 134
134 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) { 135 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) {
135 return NULL; 136 return NULL;
136 } 137 }
137 138
138 139
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 176
176 private: 177 private:
177 JoinEntryInstr* continue_target_; 178 JoinEntryInstr* continue_target_;
178 }; 179 };
179 180
180 181
181 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) { 182 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) {
182 if (label != this->label()) return NULL; 183 if (label != this->label()) return NULL;
183 if (continue_target_ == NULL) { 184 if (continue_target_ == NULL) {
184 continue_target_ = 185 continue_target_ =
185 new JoinEntryInstr(owner()->AllocateBlockId(), try_index()); 186 new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(),
187 try_index());
186 } 188 }
187 return continue_target_; 189 return continue_target_;
188 } 190 }
189 191
190 192
191 // A nested switch which can be the target of a break if labeled, and whose 193 // A nested switch which can be the target of a break if labeled, and whose
192 // cases can be the targets of continues. 194 // cases can be the targets of continues.
193 class NestedSwitch : public NestedStatement { 195 class NestedSwitch : public NestedStatement {
194 public: 196 public:
195 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node); 197 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node);
(...skipping 22 matching lines...) Expand all
218 220
219 221
220 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) { 222 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) {
221 // Allocate a join for a case clause that matches the label. This block 223 // Allocate a join for a case clause that matches the label. This block
222 // is not necessarily targeted by a continue, but we always use a join in 224 // is not necessarily targeted by a continue, but we always use a join in
223 // the graph anyway. 225 // the graph anyway.
224 for (intptr_t i = 0; i < case_labels_.length(); ++i) { 226 for (intptr_t i = 0; i < case_labels_.length(); ++i) {
225 if (label != case_labels_[i]) continue; 227 if (label != case_labels_[i]) continue;
226 if (case_targets_[i] == NULL) { 228 if (case_targets_[i] == NULL) {
227 case_targets_[i] = 229 case_targets_[i] =
228 new JoinEntryInstr(owner()->AllocateBlockId(), try_index()); 230 new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(),
231 try_index());
229 } 232 }
230 return case_targets_[i]; 233 return case_targets_[i];
231 } 234 }
232 return NULL; 235 return NULL;
233 } 236 }
234 237
235 238
236 FlowGraphBuilder::FlowGraphBuilder( 239 FlowGraphBuilder::FlowGraphBuilder(
237 ParsedFunction* parsed_function, 240 ParsedFunction* parsed_function,
238 const ZoneGrowableArray<const ICData*>& ic_data_array, 241 const ZoneGrowableArray<const ICData*>& ic_data_array,
239 InlineExitCollector* exit_collector, 242 InlineExitCollector* exit_collector,
240 intptr_t osr_id, 243 intptr_t osr_id,
241 bool is_optimizing) : 244 bool is_optimizing) :
242 parsed_function_(parsed_function), 245 parsed_function_(parsed_function),
243 ic_data_array_(ic_data_array), 246 ic_data_array_(ic_data_array),
244 num_copied_params_(parsed_function->num_copied_params()), 247 num_copied_params_(parsed_function->num_copied_params()),
245 // All parameters are copied if any parameter is. 248 // All parameters are copied if any parameter is.
246 num_non_copied_params_((num_copied_params_ == 0) 249 num_non_copied_params_((num_copied_params_ == 0)
247 ? parsed_function->function().num_fixed_parameters() 250 ? parsed_function->function().num_fixed_parameters()
248 : 0), 251 : 0),
249 num_stack_locals_(parsed_function->num_stack_locals()), 252 num_stack_locals_(parsed_function->num_stack_locals()),
250 exit_collector_(exit_collector), 253 exit_collector_(exit_collector),
251 guarded_fields_(new ZoneGrowableArray<const Field*>()), 254 guarded_fields_(new(I) ZoneGrowableArray<const Field*>()),
252 last_used_block_id_(0), // 0 is used for the graph entry. 255 last_used_block_id_(0), // 0 is used for the graph entry.
253 try_index_(CatchClauseNode::kInvalidTryIndex), 256 try_index_(CatchClauseNode::kInvalidTryIndex),
254 catch_try_index_(CatchClauseNode::kInvalidTryIndex), 257 catch_try_index_(CatchClauseNode::kInvalidTryIndex),
255 loop_depth_(0), 258 loop_depth_(0),
256 graph_entry_(NULL), 259 graph_entry_(NULL),
257 temp_count_(0), 260 temp_count_(0),
258 args_pushed_(0), 261 args_pushed_(0),
259 nesting_stack_(NULL), 262 nesting_stack_(NULL),
260 osr_id_(osr_id), 263 osr_id_(osr_id),
261 is_optimizing_(is_optimizing) { } 264 is_optimizing_(is_optimizing) { }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 ReturnAt(0)->UnuseAllInputs(); 349 ReturnAt(0)->UnuseAllInputs();
347 *exit_block = ExitBlockAt(0); 350 *exit_block = ExitBlockAt(0);
348 *last_instruction = LastInstructionAt(0); 351 *last_instruction = LastInstructionAt(0);
349 return call_->HasUses() ? ValueAt(0)->definition() : NULL; 352 return call_->HasUses() ? ValueAt(0)->definition() : NULL;
350 } else { 353 } else {
351 ASSERT(num_exits > 1); 354 ASSERT(num_exits > 1);
352 // Create a join of the returns. 355 // Create a join of the returns.
353 intptr_t join_id = caller_graph_->max_block_id() + 1; 356 intptr_t join_id = caller_graph_->max_block_id() + 1;
354 caller_graph_->set_max_block_id(join_id); 357 caller_graph_->set_max_block_id(join_id);
355 JoinEntryInstr* join = 358 JoinEntryInstr* join =
356 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); 359 new(I) JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex);
357 join->InheritDeoptTargetAfter(isolate(), call_); 360 join->InheritDeoptTargetAfter(isolate(), call_);
358 361
359 // The dominator set of the join is the intersection of the dominator 362 // The dominator set of the join is the intersection of the dominator
360 // sets of all the predecessors. If we keep the dominator sets ordered 363 // sets of all the predecessors. If we keep the dominator sets ordered
361 // by height in the dominator tree, we can also get the immediate 364 // by height in the dominator tree, we can also get the immediate
362 // dominator of the join node from the intersection. 365 // dominator of the join node from the intersection.
363 // 366 //
364 // block_dominators is the dominator set for each block, ordered from 367 // block_dominators is the dominator set for each block, ordered from
365 // the immediate dominator to the root of the dominator tree. This is 368 // the immediate dominator to the root of the dominator tree. This is
366 // the order we collect them in (adding at the end). 369 // the order we collect them in (adding at the end).
367 // 370 //
368 // join_dominators is the join's dominators ordered from the root of the 371 // join_dominators is the join's dominators ordered from the root of the
369 // dominator tree to the immediate dominator. This order supports 372 // dominator tree to the immediate dominator. This order supports
370 // removing during intersection by truncating the list. 373 // removing during intersection by truncating the list.
371 GrowableArray<BlockEntryInstr*> block_dominators; 374 GrowableArray<BlockEntryInstr*> block_dominators;
372 GrowableArray<BlockEntryInstr*> join_dominators; 375 GrowableArray<BlockEntryInstr*> join_dominators;
373 for (intptr_t i = 0; i < num_exits; ++i) { 376 for (intptr_t i = 0; i < num_exits; ++i) {
374 // Add the control-flow edge. 377 // Add the control-flow edge.
375 GotoInstr* goto_instr = new GotoInstr(join); 378 GotoInstr* goto_instr = new(I) GotoInstr(join);
376 goto_instr->InheritDeoptTarget(isolate(), ReturnAt(i)); 379 goto_instr->InheritDeoptTarget(isolate(), ReturnAt(i));
377 LastInstructionAt(i)->LinkTo(goto_instr); 380 LastInstructionAt(i)->LinkTo(goto_instr);
378 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); 381 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next());
379 join->predecessors_.Add(ExitBlockAt(i)); 382 join->predecessors_.Add(ExitBlockAt(i));
380 383
381 // Collect the block's dominators. 384 // Collect the block's dominators.
382 block_dominators.Clear(); 385 block_dominators.Clear();
383 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator(); 386 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator();
384 while (dominator != NULL) { 387 while (dominator != NULL) {
385 block_dominators.Add(dominator); 388 block_dominators.Add(dominator);
(...skipping 25 matching lines...) Expand all
411 } 414 }
412 // The immediate dominator of the join is the last one in the ordered 415 // The immediate dominator of the join is the last one in the ordered
413 // intersection. 416 // intersection.
414 join_dominators.Last()->AddDominatedBlock(join); 417 join_dominators.Last()->AddDominatedBlock(join);
415 *exit_block = join; 418 *exit_block = join;
416 *last_instruction = join; 419 *last_instruction = join;
417 420
418 // If the call has uses, create a phi of the returns. 421 // If the call has uses, create a phi of the returns.
419 if (call_->HasUses()) { 422 if (call_->HasUses()) {
420 // Add a phi of the return values. 423 // Add a phi of the return values.
421 PhiInstr* phi = new PhiInstr(join, num_exits); 424 PhiInstr* phi = new(I) PhiInstr(join, num_exits);
422 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index()); 425 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index());
423 phi->mark_alive(); 426 phi->mark_alive();
424 for (intptr_t i = 0; i < num_exits; ++i) { 427 for (intptr_t i = 0; i < num_exits; ++i) {
425 ReturnAt(i)->RemoveEnvironment(); 428 ReturnAt(i)->RemoveEnvironment();
426 phi->SetInputAt(i, ValueAt(i)); 429 phi->SetInputAt(i, ValueAt(i));
427 } 430 }
428 join->InsertPhi(phi); 431 join->InsertPhi(phi);
429 return phi; 432 return phi;
430 } else { 433 } else {
431 // In the case that the result is unused, remove the return value uses 434 // In the case that the result is unused, remove the return value uses
(...skipping 17 matching lines...) Expand all
449 Instruction* callee_last_instruction = NULL; 452 Instruction* callee_last_instruction = NULL;
450 453
451 if (exits_.length() == 0) { 454 if (exits_.length() == 0) {
452 // Handle the case when there are no normal return exits from the callee 455 // Handle the case when there are no normal return exits from the callee
453 // (i.e. the callee unconditionally throws) by inserting an artificial 456 // (i.e. the callee unconditionally throws) by inserting an artificial
454 // branch (true === true). 457 // branch (true === true).
455 // The true successor is the inlined body, the false successor 458 // The true successor is the inlined body, the false successor
456 // goes to the rest of the caller graph. It is removed as unreachable code 459 // goes to the rest of the caller graph. It is removed as unreachable code
457 // by the constant propagation. 460 // by the constant propagation.
458 TargetEntryInstr* false_block = 461 TargetEntryInstr* false_block =
459 new TargetEntryInstr(caller_graph_->allocate_block_id(), 462 new(I) TargetEntryInstr(caller_graph_->allocate_block_id(),
460 call_block->try_index()); 463 call_block->try_index());
461 false_block->InheritDeoptTargetAfter(isolate(), call_); 464 false_block->InheritDeoptTargetAfter(isolate(), call_);
462 false_block->LinkTo(call_->next()); 465 false_block->LinkTo(call_->next());
463 call_block->ReplaceAsPredecessorWith(false_block); 466 call_block->ReplaceAsPredecessorWith(false_block);
464 467
465 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); 468 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
466 BranchInstr* branch = 469 BranchInstr* branch =
467 new BranchInstr(new StrictCompareInstr(call_block->start_pos(), 470 new(I) BranchInstr(
468 Token::kEQ_STRICT, 471 new(I) StrictCompareInstr(call_block->start_pos(),
469 new Value(true_const), 472 Token::kEQ_STRICT,
470 new Value(true_const), 473 new(I) Value(true_const),
471 false)); // No number check. 474 new(I) Value(true_const),
475 false)); // No number check.
472 branch->InheritDeoptTarget(isolate(), call_); 476 branch->InheritDeoptTarget(isolate(), call_);
473 *branch->true_successor_address() = callee_entry; 477 *branch->true_successor_address() = callee_entry;
474 *branch->false_successor_address() = false_block; 478 *branch->false_successor_address() = false_block;
475 479
476 call_->previous()->AppendInstruction(branch); 480 call_->previous()->AppendInstruction(branch);
477 call_block->set_last_instruction(branch); 481 call_block->set_last_instruction(branch);
478 482
479 // Update dominator tree. 483 // Update dominator tree.
480 call_block->AddDominatedBlock(callee_entry); 484 call_block->AddDominatedBlock(callee_entry);
481 call_block->AddDominatedBlock(false_block); 485 call_block->AddDominatedBlock(false_block);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 ASSERT(is_open()); 571 ASSERT(is_open());
568 owner()->DeallocateTemps(definition->InputCount()); 572 owner()->DeallocateTemps(definition->InputCount());
569 owner()->add_args_pushed(-definition->ArgumentCount()); 573 owner()->add_args_pushed(-definition->ArgumentCount());
570 definition->set_temp_index(owner()->AllocateTemp()); 574 definition->set_temp_index(owner()->AllocateTemp());
571 if (is_empty()) { 575 if (is_empty()) {
572 entry_ = definition; 576 entry_ = definition;
573 } else { 577 } else {
574 exit()->LinkTo(definition); 578 exit()->LinkTo(definition);
575 } 579 }
576 exit_ = definition; 580 exit_ = definition;
577 return new Value(definition); 581 return new(I) Value(definition);
578 } 582 }
579 583
580 584
581 void EffectGraphVisitor::Do(Definition* definition) { 585 void EffectGraphVisitor::Do(Definition* definition) {
582 ASSERT(is_open()); 586 ASSERT(is_open());
583 owner()->DeallocateTemps(definition->InputCount()); 587 owner()->DeallocateTemps(definition->InputCount());
584 owner()->add_args_pushed(-definition->ArgumentCount()); 588 owner()->add_args_pushed(-definition->ArgumentCount());
585 if (is_empty()) { 589 if (is_empty()) {
586 entry_ = definition; 590 entry_ = definition;
587 } else { 591 } else {
(...skipping 13 matching lines...) Expand all
601 entry_ = exit_ = instruction; 605 entry_ = exit_ = instruction;
602 } else { 606 } else {
603 exit()->LinkTo(instruction); 607 exit()->LinkTo(instruction);
604 exit_ = instruction; 608 exit_ = instruction;
605 } 609 }
606 } 610 }
607 611
608 612
609 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) { 613 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) {
610 ASSERT(is_open()); 614 ASSERT(is_open());
611 ReturnInstr* return_instr = new ReturnInstr(token_pos, value); 615 ReturnInstr* return_instr = new(I) ReturnInstr(token_pos, value);
612 AddInstruction(return_instr); 616 AddInstruction(return_instr);
613 InlineExitCollector* exit_collector = owner()->exit_collector(); 617 InlineExitCollector* exit_collector = owner()->exit_collector();
614 if (exit_collector != NULL) { 618 if (exit_collector != NULL) {
615 exit_collector->AddExit(return_instr); 619 exit_collector->AddExit(return_instr);
616 } 620 }
617 CloseFragment(); 621 CloseFragment();
618 } 622 }
619 623
620 624
621 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { 625 void EffectGraphVisitor::Goto(JoinEntryInstr* join) {
622 ASSERT(is_open()); 626 ASSERT(is_open());
623 if (is_empty()) { 627 if (is_empty()) {
624 entry_ = new GotoInstr(join); 628 entry_ = new(I) GotoInstr(join);
625 } else { 629 } else {
626 exit()->Goto(join); 630 exit()->Goto(join);
627 } 631 }
628 CloseFragment(); 632 CloseFragment();
629 } 633 }
630 634
631 635
632 // Appends a graph fragment to a block entry instruction. Returns the entry 636 // Appends a graph fragment to a block entry instruction. Returns the entry
633 // instruction if the fragment was empty or else the exit of the fragment if 637 // instruction if the fragment was empty or else the exit of the fragment if
634 // it was non-empty (so NULL if the fragment is closed). 638 // it was non-empty (so NULL if the fragment is closed).
(...skipping 29 matching lines...) Expand all
664 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor(); 668 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor();
665 Instruction* false_exit = AppendFragment(false_entry, false_fragment); 669 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
666 670
667 // 3. Add a join or select one (or neither) of the arms as exit. 671 // 3. Add a join or select one (or neither) of the arms as exit.
668 if (true_exit == NULL) { 672 if (true_exit == NULL) {
669 exit_ = false_exit; // May be NULL. 673 exit_ = false_exit; // May be NULL.
670 } else if (false_exit == NULL) { 674 } else if (false_exit == NULL) {
671 exit_ = true_exit; 675 exit_ = true_exit;
672 } else { 676 } else {
673 JoinEntryInstr* join = 677 JoinEntryInstr* join =
674 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 678 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
675 true_exit->Goto(join); 679 true_exit->Goto(join);
676 false_exit->Goto(join); 680 false_exit->Goto(join);
677 exit_ = join; 681 exit_ = join;
678 } 682 }
679 } 683 }
680 684
681 685
682 void EffectGraphVisitor::TieLoop(intptr_t token_pos, 686 void EffectGraphVisitor::TieLoop(intptr_t token_pos,
683 const TestGraphVisitor& test_fragment, 687 const TestGraphVisitor& test_fragment,
684 const EffectGraphVisitor& body_fragment) { 688 const EffectGraphVisitor& body_fragment) {
685 // We have: a test graph fragment with zero, one, or two available exits; 689 // We have: a test graph fragment with zero, one, or two available exits;
686 // and an effect graph fragment with zero or one available exits. We want 690 // and an effect graph fragment with zero or one available exits. We want
687 // to append the 'while loop' consisting of the test graph fragment as 691 // to append the 'while loop' consisting of the test graph fragment as
688 // condition and the effect graph fragment as body. 692 // condition and the effect graph fragment as body.
689 ASSERT(is_open()); 693 ASSERT(is_open());
690 694
691 // 1. Connect the body to the test if it is reachable, and if so record 695 // 1. Connect the body to the test if it is reachable, and if so record
692 // its exit (if any). 696 // its exit (if any).
693 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); 697 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
694 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 698 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
695 699
696 // 2. Connect the test to this graph, including the body if reachable and 700 // 2. Connect the test to this graph, including the body if reachable and
697 // using a fresh join node if the body is reachable and has an open exit. 701 // using a fresh join node if the body is reachable and has an open exit.
698 if (body_exit == NULL) { 702 if (body_exit == NULL) {
699 Append(test_fragment); 703 Append(test_fragment);
700 } else { 704 } else {
701 JoinEntryInstr* join = 705 JoinEntryInstr* join =
702 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 706 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
703 CheckStackOverflowInstr* check = 707 CheckStackOverflowInstr* check =
704 new CheckStackOverflowInstr(token_pos, owner()->loop_depth()); 708 new(I) CheckStackOverflowInstr(token_pos, owner()->loop_depth());
705 join->LinkTo(check); 709 join->LinkTo(check);
706 check->LinkTo(test_fragment.entry()); 710 check->LinkTo(test_fragment.entry());
707 Goto(join); 711 Goto(join);
708 body_exit->Goto(join); 712 body_exit->Goto(join);
709 } 713 }
710 714
711 // 3. Set the exit to the graph to be the false successor of the test, a 715 // 3. Set the exit to the graph to be the false successor of the test, a
712 // fresh target node 716 // fresh target node
713 exit_ = test_fragment.CreateFalseSuccessor(); 717 exit_ = test_fragment.CreateFalseSuccessor();
714 } 718 }
715 719
716 720
717 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 721 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
718 owner_->add_args_pushed(1); 722 owner_->add_args_pushed(1);
719 PushArgumentInstr* result = new PushArgumentInstr(value); 723 PushArgumentInstr* result = new(I) PushArgumentInstr(value);
720 AddInstruction(result); 724 AddInstruction(result);
721 return result; 725 return result;
722 } 726 }
723 727
724 728
725 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, 729 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
726 Value* value) { 730 Value* value) {
727 ASSERT(!local.is_captured()); 731 ASSERT(!local.is_captured());
728 return new StoreLocalInstr(local, value); 732 return new(I) StoreLocalInstr(local, value);
729 } 733 }
730 734
731 735
732 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) { 736 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) {
733 return BuildStoreTemp(*owner()->parsed_function()->expression_temp_var(), 737 return BuildStoreTemp(*owner()->parsed_function()->expression_temp_var(),
734 value); 738 value);
735 } 739 }
736 740
737 741
738 Definition* EffectGraphVisitor::BuildLoadExprTemp() { 742 Definition* EffectGraphVisitor::BuildLoadExprTemp() {
739 return BuildLoadLocal(*owner()->parsed_function()->expression_temp_var()); 743 return BuildLoadLocal(*owner()->parsed_function()->expression_temp_var());
740 } 744 }
741 745
742 746
743 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, 747 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
744 Value* value) { 748 Value* value) {
745 if (local.is_captured()) { 749 if (local.is_captured()) {
746 LocalVariable* tmp_var = EnterTempLocalScope(value); 750 LocalVariable* tmp_var = EnterTempLocalScope(value);
747 intptr_t delta = 751 intptr_t delta =
748 owner()->context_level() - local.owner()->context_level(); 752 owner()->context_level() - local.owner()->context_level();
749 ASSERT(delta >= 0); 753 ASSERT(delta >= 0);
750 Value* context = Bind(new CurrentContextInstr()); 754 Value* context = Bind(new(I) CurrentContextInstr());
751 while (delta-- > 0) { 755 while (delta-- > 0) {
752 context = Bind(new LoadFieldInstr( 756 context = Bind(new(I) LoadFieldInstr(
753 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), 757 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
754 Scanner::kNoSourcePos)); 758 Scanner::kNoSourcePos));
755 } 759 }
756 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); 760 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var));
757 StoreInstanceFieldInstr* store = 761 StoreInstanceFieldInstr* store =
758 new StoreInstanceFieldInstr(Context::variable_offset(local.index()), 762 new(I) StoreInstanceFieldInstr(Context::variable_offset(local.index()),
759 context, 763 context,
760 tmp_val, 764 tmp_val,
761 kEmitStoreBarrier, 765 kEmitStoreBarrier,
762 Scanner::kNoSourcePos); 766 Scanner::kNoSourcePos);
763 Do(store); 767 Do(store);
764 return ExitTempLocalScope(tmp_var); 768 return ExitTempLocalScope(tmp_var);
765 } else { 769 } else {
766 return new StoreLocalInstr(local, value); 770 return new(I) StoreLocalInstr(local, value);
767 } 771 }
768 } 772 }
769 773
770 774
771 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { 775 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
772 if (local.IsConst()) { 776 if (local.IsConst()) {
773 return new ConstantInstr(*local.ConstValue()); 777 return new(I) ConstantInstr(*local.ConstValue());
774 } else if (local.is_captured()) { 778 } else if (local.is_captured()) {
775 intptr_t delta = 779 intptr_t delta =
776 owner()->context_level() - local.owner()->context_level(); 780 owner()->context_level() - local.owner()->context_level();
777 ASSERT(delta >= 0); 781 ASSERT(delta >= 0);
778 Value* context = Bind(new CurrentContextInstr()); 782 Value* context = Bind(new(I) CurrentContextInstr());
779 while (delta-- > 0) { 783 while (delta-- > 0) {
780 context = Bind(new LoadFieldInstr( 784 context = Bind(new(I) LoadFieldInstr(
781 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), 785 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
782 Scanner::kNoSourcePos)); 786 Scanner::kNoSourcePos));
783 } 787 }
784 return new LoadFieldInstr(context, 788 return new(I) LoadFieldInstr(context,
785 Context::variable_offset(local.index()), 789 Context::variable_offset(local.index()),
786 local.type(), 790 local.type(),
787 Scanner::kNoSourcePos); 791 Scanner::kNoSourcePos);
788 } else { 792 } else {
789 return new LoadLocalInstr(local); 793 return new(I) LoadLocalInstr(local);
790 } 794 }
791 } 795 }
792 796
793 797
794 // Stores current context into the 'variable' 798 // Stores current context into the 'variable'
795 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) { 799 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) {
796 Value* context = Bind(new CurrentContextInstr()); 800 Value* context = Bind(new(I) CurrentContextInstr());
797 Do(BuildStoreLocal(variable, context)); 801 Do(BuildStoreLocal(variable, context));
798 } 802 }
799 803
800 804
801 // Loads context saved in 'context_variable' into the current context. 805 // Loads context saved in 'context_variable' into the current context.
802 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) { 806 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) {
803 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 807 Value* load_saved_context = Bind(BuildLoadLocal(variable));
804 AddInstruction(new StoreContextInstr(load_saved_context)); 808 AddInstruction(new(I) StoreContextInstr(load_saved_context));
805 } 809 }
806 810
807 811
808 void TestGraphVisitor::ConnectBranchesTo( 812 void TestGraphVisitor::ConnectBranchesTo(
809 const GrowableArray<TargetEntryInstr**>& branches, 813 const GrowableArray<TargetEntryInstr**>& branches,
810 JoinEntryInstr* join) const { 814 JoinEntryInstr* join) const {
811 ASSERT(!branches.is_empty()); 815 ASSERT(!branches.is_empty());
812 for (intptr_t i = 0; i < branches.length(); i++) { 816 for (intptr_t i = 0; i < branches.length(); i++) {
813 TargetEntryInstr* target = 817 TargetEntryInstr* target =
814 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 818 new(I) TargetEntryInstr(owner()->AllocateBlockId(),
819 owner()->try_index());
815 *(branches[i]) = target; 820 *(branches[i]) = target;
816 target->Goto(join); 821 target->Goto(join);
817 } 822 }
818 } 823 }
819 824
820 825
821 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { 826 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
822 ConnectBranchesTo(true_successor_addresses_, join); 827 ConnectBranchesTo(true_successor_addresses_, join);
823 } 828 }
824 829
825 830
826 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { 831 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
827 ConnectBranchesTo(false_successor_addresses_, join); 832 ConnectBranchesTo(false_successor_addresses_, join);
828 } 833 }
829 834
830 835
831 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( 836 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
832 const GrowableArray<TargetEntryInstr**>& branches) const { 837 const GrowableArray<TargetEntryInstr**>& branches) const {
833 ASSERT(!branches.is_empty()); 838 ASSERT(!branches.is_empty());
834 839
835 if (branches.length() == 1) { 840 if (branches.length() == 1) {
836 TargetEntryInstr* target = 841 TargetEntryInstr* target =
837 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 842 new(I) TargetEntryInstr(owner()->AllocateBlockId(),
843 owner()->try_index());
838 *(branches[0]) = target; 844 *(branches[0]) = target;
839 return target; 845 return target;
840 } 846 }
841 847
842 JoinEntryInstr* join = 848 JoinEntryInstr* join =
843 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 849 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
844 ConnectBranchesTo(branches, join); 850 ConnectBranchesTo(branches, join);
845 return join; 851 return join;
846 } 852 }
847 853
848 854
849 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { 855 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
850 return CreateSuccessorFor(true_successor_addresses_); 856 return CreateSuccessorFor(true_successor_addresses_);
851 } 857 }
852 858
853 859
854 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { 860 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
855 return CreateSuccessorFor(false_successor_addresses_); 861 return CreateSuccessorFor(false_successor_addresses_);
856 } 862 }
857 863
858 864
859 void TestGraphVisitor::ReturnValue(Value* value) { 865 void TestGraphVisitor::ReturnValue(Value* value) {
860 if (FLAG_enable_type_checks) { 866 if (FLAG_enable_type_checks) {
861 value = Bind(new AssertBooleanInstr(condition_token_pos(), value)); 867 value = Bind(new(I) AssertBooleanInstr(condition_token_pos(), value));
862 } 868 }
863 Value* constant_true = Bind(new ConstantInstr(Bool::True())); 869 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True()));
864 StrictCompareInstr* comp = 870 StrictCompareInstr* comp =
865 new StrictCompareInstr(condition_token_pos(), 871 new(I) StrictCompareInstr(condition_token_pos(),
866 Token::kEQ_STRICT, 872 Token::kEQ_STRICT,
867 value, 873 value,
868 constant_true, 874 constant_true,
869 false); // No number check. 875 false); // No number check.
870 BranchInstr* branch = new BranchInstr(comp); 876 BranchInstr* branch = new(I) BranchInstr(comp);
871 AddInstruction(branch); 877 AddInstruction(branch);
872 CloseFragment(); 878 CloseFragment();
873 879
874 true_successor_addresses_.Add(branch->true_successor_address()); 880 true_successor_addresses_.Add(branch->true_successor_address());
875 false_successor_addresses_.Add(branch->false_successor_address()); 881 false_successor_addresses_.Add(branch->false_successor_address());
876 } 882 }
877 883
878 884
879 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) { 885 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
880 BranchInstr* branch; 886 BranchInstr* branch;
881 if (Token::IsStrictEqualityOperator(comp->kind())) { 887 if (Token::IsStrictEqualityOperator(comp->kind())) {
882 ASSERT(comp->IsStrictCompare()); 888 ASSERT(comp->IsStrictCompare());
883 branch = new BranchInstr(comp); 889 branch = new(I) BranchInstr(comp);
884 } else if (Token::IsEqualityOperator(comp->kind()) && 890 } else if (Token::IsEqualityOperator(comp->kind()) &&
885 (comp->left()->BindsToConstantNull() || 891 (comp->left()->BindsToConstantNull() ||
886 comp->right()->BindsToConstantNull())) { 892 comp->right()->BindsToConstantNull())) {
887 branch = new BranchInstr(new StrictCompareInstr( 893 branch = new(I) BranchInstr(new(I) StrictCompareInstr(
888 comp->token_pos(), 894 comp->token_pos(),
889 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 895 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
890 comp->left(), 896 comp->left(),
891 comp->right(), 897 comp->right(),
892 false)); // No number check. 898 false)); // No number check.
893 } else { 899 } else {
894 branch = new BranchInstr(comp); 900 branch = new(I) BranchInstr(comp);
895 branch->set_is_checked(FLAG_enable_type_checks); 901 branch->set_is_checked(FLAG_enable_type_checks);
896 } 902 }
897 AddInstruction(branch); 903 AddInstruction(branch);
898 CloseFragment(); 904 CloseFragment();
899 true_successor_addresses_.Add(branch->true_successor_address()); 905 true_successor_addresses_.Add(branch->true_successor_address());
900 false_successor_addresses_.Add(branch->false_successor_address()); 906 false_successor_addresses_.Add(branch->false_successor_address());
901 } 907 }
902 908
903 909
904 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 910 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
905 ASSERT(!FLAG_enable_type_checks); 911 ASSERT(!FLAG_enable_type_checks);
906 Value* constant_true = Bind(new ConstantInstr(Bool::True())); 912 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True()));
907 StrictCompareInstr* comp = 913 StrictCompareInstr* comp =
908 new StrictCompareInstr(condition_token_pos(), 914 new(I) StrictCompareInstr(condition_token_pos(),
909 Token::kNE_STRICT, 915 Token::kNE_STRICT,
910 neg->value(), 916 neg->value(),
911 constant_true, 917 constant_true,
912 false); // No number check. 918 false); // No number check.
913 BranchInstr* branch = new BranchInstr(comp); 919 BranchInstr* branch = new(I) BranchInstr(comp);
914 AddInstruction(branch); 920 AddInstruction(branch);
915 CloseFragment(); 921 CloseFragment();
916 true_successor_addresses_.Add(branch->true_successor_address()); 922 true_successor_addresses_.Add(branch->true_successor_address());
917 false_successor_addresses_.Add(branch->false_successor_address()); 923 false_successor_addresses_.Add(branch->false_successor_address());
918 } 924 }
919 925
920 926
921 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 927 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
922 ComparisonInstr* comp = definition->AsComparison(); 928 ComparisonInstr* comp = definition->AsComparison();
923 if (comp != NULL) { 929 if (comp != NULL) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 } 1008 }
1003 1009
1004 // Call to stub that checks whether the debugger is in single 1010 // Call to stub that checks whether the debugger is in single
1005 // step mode. This call must happen before the contexts are 1011 // step mode. This call must happen before the contexts are
1006 // unchained so that captured variables can be inspected. 1012 // unchained so that captured variables can be inspected.
1007 // No debugger check is done in native functions or for return 1013 // No debugger check is done in native functions or for return
1008 // statements for which there is no associated source position. 1014 // statements for which there is no associated source position.
1009 const Function& function = owner()->parsed_function()->function(); 1015 const Function& function = owner()->parsed_function()->function();
1010 if ((node->token_pos() != Scanner::kNoSourcePos) && 1016 if ((node->token_pos() != Scanner::kNoSourcePos) &&
1011 !function.is_native() && FLAG_enable_debugger) { 1017 !function.is_native() && FLAG_enable_debugger) {
1012 AddInstruction(new DebugStepCheckInstr(node->token_pos(), 1018 AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(),
1013 PcDescriptors::kRuntimeCall)); 1019 PcDescriptors::kRuntimeCall));
1014 } 1020 }
1015 1021
1016 if (FLAG_enable_type_checks) { 1022 if (FLAG_enable_type_checks) {
1017 const bool is_implicit_dynamic_getter = 1023 const bool is_implicit_dynamic_getter =
1018 (!function.is_static() && 1024 (!function.is_static() &&
1019 ((function.kind() == RawFunction::kImplicitGetter) || 1025 ((function.kind() == RawFunction::kImplicitGetter) ||
1020 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); 1026 (function.kind() == RawFunction::kImplicitStaticFinalGetter)));
1021 // Implicit getters do not need a type check at return, unless they compute 1027 // Implicit getters do not need a type check at return, unless they compute
1022 // the initial value of a static field. 1028 // the initial value of a static field.
1023 // The body of a constructor cannot modify the type of the 1029 // The body of a constructor cannot modify the type of the
(...skipping 17 matching lines...) Expand all
1041 } else { 1047 } else {
1042 UnchainContexts(current_context_level); 1048 UnchainContexts(current_context_level);
1043 } 1049 }
1044 1050
1045 AddReturnExit(node->token_pos(), return_value); 1051 AddReturnExit(node->token_pos(), return_value);
1046 } 1052 }
1047 1053
1048 1054
1049 // <Expression> ::= Literal { literal: Instance } 1055 // <Expression> ::= Literal { literal: Instance }
1050 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 1056 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
1051 ReturnDefinition(new ConstantInstr(node->literal())); 1057 ReturnDefinition(new(I) ConstantInstr(node->literal()));
1052 } 1058 }
1053 1059
1054 1060
1055 // Type nodes are used when a type is referenced as a literal. Type nodes 1061 // Type nodes are used when a type is referenced as a literal. Type nodes
1056 // can also be used for the right-hand side of instanceof comparisons, 1062 // can also be used for the right-hand side of instanceof comparisons,
1057 // but they are handled specially in that context, not here. 1063 // but they are handled specially in that context, not here.
1058 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { 1064 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) {
1059 return; 1065 return;
1060 } 1066 }
1061 1067
1062 1068
1063 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { 1069 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
1064 const AbstractType& type = node->type(); 1070 const AbstractType& type = node->type();
1065 // Type may be malbounded, but not malformed. 1071 // Type may be malbounded, but not malformed.
1066 ASSERT(type.IsFinalized() && !type.IsMalformed()); 1072 ASSERT(type.IsFinalized() && !type.IsMalformed());
1067 if (type.IsInstantiated()) { 1073 if (type.IsInstantiated()) {
1068 ReturnDefinition(new ConstantInstr(type)); 1074 ReturnDefinition(new(I) ConstantInstr(type));
1069 } else { 1075 } else {
1070 const Class& instantiator_class = Class::ZoneHandle( 1076 const Class& instantiator_class = Class::ZoneHandle(
1071 I, owner()->parsed_function()->function().Owner()); 1077 I, owner()->parsed_function()->function().Owner());
1072 Value* instantiator_value = BuildInstantiatorTypeArguments( 1078 Value* instantiator_value = BuildInstantiatorTypeArguments(
1073 node->token_pos(), instantiator_class, NULL); 1079 node->token_pos(), instantiator_class, NULL);
1074 ReturnDefinition(new InstantiateTypeInstr( 1080 ReturnDefinition(new(I) InstantiateTypeInstr(
1075 node->token_pos(), type, instantiator_class, instantiator_value)); 1081 node->token_pos(), type, instantiator_class, instantiator_value));
1076 } 1082 }
1077 } 1083 }
1078 1084
1079 1085
1080 // Returns true if the type check can be skipped, for example, if the 1086 // Returns true if the type check can be skipped, for example, if the
1081 // destination type is dynamic or if the compile type of the value is a subtype 1087 // destination type is dynamic or if the compile type of the value is a subtype
1082 // of the destination type. 1088 // of the destination type.
1083 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, 1089 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos,
1084 Value* value, 1090 Value* value,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { 1135 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) {
1130 ValueGraphVisitor for_value(owner()); 1136 ValueGraphVisitor for_value(owner());
1131 node->expr()->Visit(&for_value); 1137 node->expr()->Visit(&for_value);
1132 Append(for_value); 1138 Append(for_value);
1133 Definition* checked_value; 1139 Definition* checked_value;
1134 if (CanSkipTypeCheck(node->expr()->token_pos(), 1140 if (CanSkipTypeCheck(node->expr()->token_pos(),
1135 for_value.value(), 1141 for_value.value(),
1136 node->type(), 1142 node->type(),
1137 node->dst_name())) { 1143 node->dst_name())) {
1138 // Drop the value and 0 additional temporaries. 1144 // Drop the value and 0 additional temporaries.
1139 checked_value = new DropTempsInstr(0, for_value.value()); 1145 checked_value = new(I) DropTempsInstr(0, for_value.value());
1140 } else { 1146 } else {
1141 checked_value = BuildAssertAssignable(node->expr()->token_pos(), 1147 checked_value = BuildAssertAssignable(node->expr()->token_pos(),
1142 for_value.value(), 1148 for_value.value(),
1143 node->type(), 1149 node->type(),
1144 node->dst_name()); 1150 node->dst_name());
1145 } 1151 }
1146 ReturnDefinition(checked_value); 1152 ReturnDefinition(checked_value);
1147 } 1153 }
1148 1154
1149 1155
(...skipping 16 matching lines...) Expand all
1166 // operator. 1172 // operator.
1167 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1173 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1168 // See ValueGraphVisitor::VisitBinaryOpNode. 1174 // See ValueGraphVisitor::VisitBinaryOpNode.
1169 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1175 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1170 node->left()->Visit(&for_left); 1176 node->left()->Visit(&for_left);
1171 EffectGraphVisitor empty(owner()); 1177 EffectGraphVisitor empty(owner());
1172 if (FLAG_enable_type_checks) { 1178 if (FLAG_enable_type_checks) {
1173 ValueGraphVisitor for_right(owner()); 1179 ValueGraphVisitor for_right(owner());
1174 node->right()->Visit(&for_right); 1180 node->right()->Visit(&for_right);
1175 Value* right_value = for_right.value(); 1181 Value* right_value = for_right.value();
1176 for_right.Do(new AssertBooleanInstr(node->right()->token_pos(), 1182 for_right.Do(new(I) AssertBooleanInstr(node->right()->token_pos(),
1177 right_value)); 1183 right_value));
1178 if (node->kind() == Token::kAND) { 1184 if (node->kind() == Token::kAND) {
1179 Join(for_left, for_right, empty); 1185 Join(for_left, for_right, empty);
1180 } else { 1186 } else {
1181 Join(for_left, empty, for_right); 1187 Join(for_left, empty, for_right);
1182 } 1188 }
1183 } else { 1189 } else {
1184 EffectGraphVisitor for_right(owner()); 1190 EffectGraphVisitor for_right(owner());
1185 node->right()->Visit(&for_right); 1191 node->right()->Visit(&for_right);
1186 if (node->kind() == Token::kAND) { 1192 if (node->kind() == Token::kAND) {
1187 Join(for_left, for_right, empty); 1193 Join(for_left, for_right, empty);
1188 } else { 1194 } else {
1189 Join(for_left, empty, for_right); 1195 Join(for_left, empty, for_right);
1190 } 1196 }
1191 } 1197 }
1192 return; 1198 return;
1193 } 1199 }
1194 ValueGraphVisitor for_left_value(owner()); 1200 ValueGraphVisitor for_left_value(owner());
1195 node->left()->Visit(&for_left_value); 1201 node->left()->Visit(&for_left_value);
1196 Append(for_left_value); 1202 Append(for_left_value);
1197 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1203 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1198 1204
1199 ValueGraphVisitor for_right_value(owner()); 1205 ValueGraphVisitor for_right_value(owner());
1200 node->right()->Visit(&for_right_value); 1206 node->right()->Visit(&for_right_value);
1201 Append(for_right_value); 1207 Append(for_right_value);
1202 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1208 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1203 1209
1204 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1210 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1205 new ZoneGrowableArray<PushArgumentInstr*>(2); 1211 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
1206 arguments->Add(push_left); 1212 arguments->Add(push_left);
1207 arguments->Add(push_right); 1213 arguments->Add(push_right);
1208 const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName())); 1214 const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName()));
1209 const intptr_t kNumArgsChecked = 2; 1215 const intptr_t kNumArgsChecked = 2;
1210 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), 1216 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
1211 name, 1217 name,
1212 node->kind(), 1218 node->kind(),
1213 arguments, 1219 arguments,
1214 Object::null_array(), 1220 Object::null_array(),
1215 kNumArgsChecked, 1221 kNumArgsChecked,
1216 owner()->ic_data_array()); 1222 owner()->ic_data_array());
1217 ReturnDefinition(call); 1223 ReturnDefinition(call);
1218 } 1224 }
1219 1225
1220 1226
1221 // Special handling for AND/OR. 1227 // Special handling for AND/OR.
1222 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1228 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1223 // Operators "&&" and "||" cannot be overloaded therefore do not call 1229 // Operators "&&" and "||" cannot be overloaded therefore do not call
1224 // operator. 1230 // operator.
1225 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1231 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1226 // Implement short-circuit logic: do not evaluate right if evaluation 1232 // Implement short-circuit logic: do not evaluate right if evaluation
1227 // of left is sufficient. 1233 // of left is sufficient.
1228 // AND: left ? right === true : false; 1234 // AND: left ? right === true : false;
1229 // OR: left ? true : right === true; 1235 // OR: left ? true : right === true;
1230 1236
1231 TestGraphVisitor for_test(owner(), node->left()->token_pos()); 1237 TestGraphVisitor for_test(owner(), node->left()->token_pos());
1232 node->left()->Visit(&for_test); 1238 node->left()->Visit(&for_test);
1233 1239
1234 ValueGraphVisitor for_right(owner()); 1240 ValueGraphVisitor for_right(owner());
1235 node->right()->Visit(&for_right); 1241 node->right()->Visit(&for_right);
1236 Value* right_value = for_right.value(); 1242 Value* right_value = for_right.value();
1237 if (FLAG_enable_type_checks) { 1243 if (FLAG_enable_type_checks) {
1238 right_value = 1244 right_value =
1239 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), 1245 for_right.Bind(new(I) AssertBooleanInstr(node->right()->token_pos(),
1240 right_value)); 1246 right_value));
1241 } 1247 }
1242 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); 1248 Value* constant_true = for_right.Bind(new(I) ConstantInstr(Bool::True()));
1243 Value* compare = 1249 Value* compare =
1244 for_right.Bind(new StrictCompareInstr(node->token_pos(), 1250 for_right.Bind(new(I) StrictCompareInstr(node->token_pos(),
1245 Token::kEQ_STRICT, 1251 Token::kEQ_STRICT,
1246 right_value, 1252 right_value,
1247 constant_true, 1253 constant_true,
1248 false)); // No number check. 1254 false)); // No number check.
1249 for_right.Do(BuildStoreExprTemp(compare)); 1255 for_right.Do(BuildStoreExprTemp(compare));
1250 1256
1251 if (node->kind() == Token::kAND) { 1257 if (node->kind() == Token::kAND) {
1252 ValueGraphVisitor for_false(owner()); 1258 ValueGraphVisitor for_false(owner());
1253 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); 1259 Value* constant_false =
1260 for_false.Bind(new(I) ConstantInstr(Bool::False()));
1254 for_false.Do(BuildStoreExprTemp(constant_false)); 1261 for_false.Do(BuildStoreExprTemp(constant_false));
1255 Join(for_test, for_right, for_false); 1262 Join(for_test, for_right, for_false);
1256 } else { 1263 } else {
1257 ASSERT(node->kind() == Token::kOR); 1264 ASSERT(node->kind() == Token::kOR);
1258 ValueGraphVisitor for_true(owner()); 1265 ValueGraphVisitor for_true(owner());
1259 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True())); 1266 Value* constant_true = for_true.Bind(new(I) ConstantInstr(Bool::True()));
1260 for_true.Do(BuildStoreExprTemp(constant_true)); 1267 for_true.Do(BuildStoreExprTemp(constant_true));
1261 Join(for_test, for_true, for_right); 1268 Join(for_test, for_true, for_right);
1262 } 1269 }
1263 ReturnDefinition(BuildLoadExprTemp()); 1270 ReturnDefinition(BuildLoadExprTemp());
1264 return; 1271 return;
1265 } 1272 }
1266 EffectGraphVisitor::VisitBinaryOpNode(node); 1273 EffectGraphVisitor::VisitBinaryOpNode(node);
1267 } 1274 }
1268 1275
1269 1276
(...skipping 16 matching lines...) Expand all
1286 ValueGraphVisitor for_left_value(owner()); 1293 ValueGraphVisitor for_left_value(owner());
1287 node->left()->Visit(&for_left_value); 1294 node->left()->Visit(&for_left_value);
1288 Append(for_left_value); 1295 Append(for_left_value);
1289 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1296 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1290 1297
1291 ValueGraphVisitor for_right_value(owner()); 1298 ValueGraphVisitor for_right_value(owner());
1292 node->right()->Visit(&for_right_value); 1299 node->right()->Visit(&for_right_value);
1293 Append(for_right_value); 1300 Append(for_right_value);
1294 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1301 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1295 1302
1296 Value* mask_value = Bind(new ConstantInstr( 1303 Value* mask_value = Bind(new(I) ConstantInstr(
1297 Integer::ZoneHandle(I, Integer::New(node->mask32(), Heap::kOld)))); 1304 Integer::ZoneHandle(I, Integer::New(node->mask32(), Heap::kOld))));
1298 PushArgumentInstr* push_mask = PushArgument(mask_value); 1305 PushArgumentInstr* push_mask = PushArgument(mask_value);
1299 1306
1300 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1307 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1301 new ZoneGrowableArray<PushArgumentInstr*>(3); 1308 new(I) ZoneGrowableArray<PushArgumentInstr*>(3);
1302 arguments->Add(push_left); 1309 arguments->Add(push_left);
1303 arguments->Add(push_right); 1310 arguments->Add(push_right);
1304 // Call to special method 'BinaryOpAndMaskName(node)'. 1311 // Call to special method 'BinaryOpAndMaskName(node)'.
1305 arguments->Add(push_mask); 1312 arguments->Add(push_mask);
1306 const intptr_t kNumArgsChecked = 2; 1313 const intptr_t kNumArgsChecked = 2;
1307 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), 1314 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
1308 BinaryOpAndMaskName(node), 1315 BinaryOpAndMaskName(node),
1309 Token::kILLEGAL, 1316 Token::kILLEGAL,
1310 arguments, 1317 arguments,
1311 Object::null_array(), 1318 Object::null_array(),
1312 kNumArgsChecked, 1319 kNumArgsChecked,
1313 owner()->ic_data_array()); 1320 owner()->ic_data_array());
1314 ReturnDefinition(call); 1321 ReturnDefinition(call);
1315 } 1322 }
1316 1323
1317 1324
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1365 Value* loaded = Bind(BuildLoadExprTemp()); 1372 Value* loaded = Bind(BuildLoadExprTemp());
1366 instantiator_type_arguments = 1373 instantiator_type_arguments =
1367 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); 1374 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded);
1368 } 1375 }
1369 *instantiator_result = instantiator; 1376 *instantiator_result = instantiator;
1370 *instantiator_type_arguments_result = instantiator_type_arguments; 1377 *instantiator_type_arguments_result = instantiator_type_arguments;
1371 } 1378 }
1372 1379
1373 1380
1374 Value* EffectGraphVisitor::BuildNullValue() { 1381 Value* EffectGraphVisitor::BuildNullValue() {
1375 return Bind(new ConstantInstr(Object::ZoneHandle(I, Object::null()))); 1382 return Bind(new(I) ConstantInstr(Object::ZoneHandle(I, Object::null())));
1376 } 1383 }
1377 1384
1378 1385
1379 // Used for testing incoming arguments. 1386 // Used for testing incoming arguments.
1380 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( 1387 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable(
1381 intptr_t token_pos, 1388 intptr_t token_pos,
1382 Value* value, 1389 Value* value,
1383 const AbstractType& dst_type, 1390 const AbstractType& dst_type,
1384 const String& dst_name) { 1391 const String& dst_name) {
1385 // Build the type check computation. 1392 // Build the type check computation.
1386 Value* instantiator = NULL; 1393 Value* instantiator = NULL;
1387 Value* instantiator_type_arguments = NULL; 1394 Value* instantiator_type_arguments = NULL;
1388 if (dst_type.IsInstantiated()) { 1395 if (dst_type.IsInstantiated()) {
1389 instantiator = BuildNullValue(); 1396 instantiator = BuildNullValue();
1390 instantiator_type_arguments = BuildNullValue(); 1397 instantiator_type_arguments = BuildNullValue();
1391 } else { 1398 } else {
1392 BuildTypecheckArguments(token_pos, 1399 BuildTypecheckArguments(token_pos,
1393 &instantiator, 1400 &instantiator,
1394 &instantiator_type_arguments); 1401 &instantiator_type_arguments);
1395 } 1402 }
1396 return new AssertAssignableInstr(token_pos, 1403 return new(I) AssertAssignableInstr(token_pos,
1397 value, 1404 value,
1398 instantiator, 1405 instantiator,
1399 instantiator_type_arguments, 1406 instantiator_type_arguments,
1400 dst_type, 1407 dst_type,
1401 dst_name); 1408 dst_name);
1402 } 1409 }
1403 1410
1404 1411
1405 // Used for type casts and to test assignments. 1412 // Used for type casts and to test assignments.
1406 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, 1413 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos,
1407 Value* value, 1414 Value* value,
1408 const AbstractType& dst_type, 1415 const AbstractType& dst_type,
1409 const String& dst_name) { 1416 const String& dst_name) {
1410 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { 1417 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) {
1411 return value; 1418 return value;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 const AbstractType& type = node->right()->AsTypeNode()->type(); 1450 const AbstractType& type = node->right()->AsTypeNode()->type();
1444 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 1451 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
1445 const bool negate_result = (node->kind() == Token::kISNOT); 1452 const bool negate_result = (node->kind() == Token::kISNOT);
1446 // All objects are instances of type T if Object type is a subtype of type T. 1453 // All objects are instances of type T if Object type is a subtype of type T.
1447 const Type& object_type = Type::Handle(I, Type::ObjectType()); 1454 const Type& object_type = Type::Handle(I, Type::ObjectType());
1448 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { 1455 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) {
1449 // Must evaluate left side. 1456 // Must evaluate left side.
1450 EffectGraphVisitor for_left_value(owner()); 1457 EffectGraphVisitor for_left_value(owner());
1451 node->left()->Visit(&for_left_value); 1458 node->left()->Visit(&for_left_value);
1452 Append(for_left_value); 1459 Append(for_left_value);
1453 ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result))); 1460 ReturnDefinition(new(I) ConstantInstr(Bool::Get(!negate_result)));
1454 return; 1461 return;
1455 } 1462 }
1456 ValueGraphVisitor for_left_value(owner()); 1463 ValueGraphVisitor for_left_value(owner());
1457 node->left()->Visit(&for_left_value); 1464 node->left()->Visit(&for_left_value);
1458 Append(for_left_value); 1465 Append(for_left_value);
1459 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1466 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1460 PushArgumentInstr* push_instantiator = NULL; 1467 PushArgumentInstr* push_instantiator = NULL;
1461 PushArgumentInstr* push_type_args = NULL; 1468 PushArgumentInstr* push_type_args = NULL;
1462 if (type.IsInstantiated()) { 1469 if (type.IsInstantiated()) {
1463 push_instantiator = PushArgument(BuildNullValue()); 1470 push_instantiator = PushArgument(BuildNullValue());
1464 push_type_args = PushArgument(BuildNullValue()); 1471 push_type_args = PushArgument(BuildNullValue());
1465 } else { 1472 } else {
1466 BuildTypecheckPushArguments(node->token_pos(), 1473 BuildTypecheckPushArguments(node->token_pos(),
1467 &push_instantiator, 1474 &push_instantiator,
1468 &push_type_args); 1475 &push_type_args);
1469 } 1476 }
1470 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1477 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1471 new ZoneGrowableArray<PushArgumentInstr*>(5); 1478 new(I) ZoneGrowableArray<PushArgumentInstr*>(5);
1472 arguments->Add(push_left); 1479 arguments->Add(push_left);
1473 arguments->Add(push_instantiator); 1480 arguments->Add(push_instantiator);
1474 arguments->Add(push_type_args); 1481 arguments->Add(push_type_args);
1475 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1482 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1476 Value* type_arg = Bind( 1483 Value* type_arg = Bind(
1477 new ConstantInstr(node->right()->AsTypeNode()->type())); 1484 new(I) ConstantInstr(node->right()->AsTypeNode()->type()));
1478 arguments->Add(PushArgument(type_arg)); 1485 arguments->Add(PushArgument(type_arg));
1479 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT); 1486 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
1480 Value* negate_arg = Bind(new ConstantInstr(negate)); 1487 Value* negate_arg = Bind(new(I) ConstantInstr(negate));
1481 arguments->Add(PushArgument(negate_arg)); 1488 arguments->Add(PushArgument(negate_arg));
1482 const intptr_t kNumArgsChecked = 1; 1489 const intptr_t kNumArgsChecked = 1;
1483 InstanceCallInstr* call = new InstanceCallInstr( 1490 InstanceCallInstr* call = new(I) InstanceCallInstr(
1484 node->token_pos(), 1491 node->token_pos(),
1485 Library::PrivateCoreLibName(Symbols::_instanceOf()), 1492 Library::PrivateCoreLibName(Symbols::_instanceOf()),
1486 node->kind(), 1493 node->kind(),
1487 arguments, 1494 arguments,
1488 Object::null_array(), // No argument names. 1495 Object::null_array(), // No argument names.
1489 kNumArgsChecked, 1496 kNumArgsChecked,
1490 owner()->ic_data_array()); 1497 owner()->ic_data_array());
1491 ReturnDefinition(call); 1498 ReturnDefinition(call);
1492 } 1499 }
1493 1500
(...skipping 25 matching lines...) Expand all
1519 PushArgumentInstr* push_type_args = NULL; 1526 PushArgumentInstr* push_type_args = NULL;
1520 if (type.IsInstantiated()) { 1527 if (type.IsInstantiated()) {
1521 push_instantiator = PushArgument(BuildNullValue()); 1528 push_instantiator = PushArgument(BuildNullValue());
1522 push_type_args = PushArgument(BuildNullValue()); 1529 push_type_args = PushArgument(BuildNullValue());
1523 } else { 1530 } else {
1524 BuildTypecheckPushArguments(node->token_pos(), 1531 BuildTypecheckPushArguments(node->token_pos(),
1525 &push_instantiator, 1532 &push_instantiator,
1526 &push_type_args); 1533 &push_type_args);
1527 } 1534 }
1528 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1535 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1529 new ZoneGrowableArray<PushArgumentInstr*>(4); 1536 new(I) ZoneGrowableArray<PushArgumentInstr*>(4);
1530 arguments->Add(push_left); 1537 arguments->Add(push_left);
1531 arguments->Add(push_instantiator); 1538 arguments->Add(push_instantiator);
1532 arguments->Add(push_type_args); 1539 arguments->Add(push_type_args);
1533 Value* type_arg = Bind(new ConstantInstr(type)); 1540 Value* type_arg = Bind(new(I) ConstantInstr(type));
1534 arguments->Add(PushArgument(type_arg)); 1541 arguments->Add(PushArgument(type_arg));
1535 const intptr_t kNumArgsChecked = 1; 1542 const intptr_t kNumArgsChecked = 1;
1536 InstanceCallInstr* call = new InstanceCallInstr( 1543 InstanceCallInstr* call = new(I) InstanceCallInstr(
1537 node->token_pos(), 1544 node->token_pos(),
1538 Library::PrivateCoreLibName(Symbols::_as()), 1545 Library::PrivateCoreLibName(Symbols::_as()),
1539 node->kind(), 1546 node->kind(),
1540 arguments, 1547 arguments,
1541 Object::null_array(), // No argument names. 1548 Object::null_array(), // No argument names.
1542 kNumArgsChecked, 1549 kNumArgsChecked,
1543 owner()->ic_data_array()); 1550 owner()->ic_data_array());
1544 ReturnDefinition(call); 1551 ReturnDefinition(call);
1545 } 1552 }
1546 1553
1547 1554
1548 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left, 1555 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left,
1549 AstNode* right, 1556 AstNode* right,
1550 Token::Kind kind, 1557 Token::Kind kind,
1551 intptr_t token_pos) { 1558 intptr_t token_pos) {
1552 ValueGraphVisitor for_left_value(owner()); 1559 ValueGraphVisitor for_left_value(owner());
1553 left->Visit(&for_left_value); 1560 left->Visit(&for_left_value);
1554 Append(for_left_value); 1561 Append(for_left_value);
1555 ValueGraphVisitor for_right_value(owner()); 1562 ValueGraphVisitor for_right_value(owner());
1556 right->Visit(&for_right_value); 1563 right->Visit(&for_right_value);
1557 Append(for_right_value); 1564 Append(for_right_value);
1558 StrictCompareInstr* comp = new StrictCompareInstr(token_pos, 1565 StrictCompareInstr* comp = new(I) StrictCompareInstr(token_pos,
1559 kind, 1566 kind,
1560 for_left_value.value(), 1567 for_left_value.value(),
1561 for_right_value.value(), 1568 for_right_value.value(),
1562 true); // Number check. 1569 true); // Number check.
1563 return comp; 1570 return comp;
1564 } 1571 }
1565 1572
1566 1573
1567 // <Expression> :: Comparison { kind: Token::Kind 1574 // <Expression> :: Comparison { kind: Token::Kind
1568 // left: <Expression> 1575 // left: <Expression>
1569 // right: <Expression> } 1576 // right: <Expression> }
1570 // TODO(srdjan): Implement new equality.
1571 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 1577 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
1572 if (Token::IsTypeTestOperator(node->kind())) { 1578 if (Token::IsTypeTestOperator(node->kind())) {
1573 BuildTypeTest(node); 1579 BuildTypeTest(node);
1574 return; 1580 return;
1575 } 1581 }
1576 if (Token::IsTypeCastOperator(node->kind())) { 1582 if (Token::IsTypeCastOperator(node->kind())) {
1577 BuildTypeCast(node); 1583 BuildTypeCast(node);
1578 return; 1584 return;
1579 } 1585 }
1580 1586
(...skipping 13 matching lines...) Expand all
1594 Token::Kind kind = 1600 Token::Kind kind =
1595 (node->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT; 1601 (node->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT;
1596 StrictCompareInstr* compare = 1602 StrictCompareInstr* compare =
1597 BuildStrictCompare(node->left(), node->right(), 1603 BuildStrictCompare(node->left(), node->right(),
1598 kind, node->token_pos()); 1604 kind, node->token_pos());
1599 ReturnDefinition(compare); 1605 ReturnDefinition(compare);
1600 return; 1606 return;
1601 } 1607 }
1602 1608
1603 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1609 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1604 new ZoneGrowableArray<PushArgumentInstr*>(2); 1610 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
1605 1611
1606 ValueGraphVisitor for_left_value(owner()); 1612 ValueGraphVisitor for_left_value(owner());
1607 node->left()->Visit(&for_left_value); 1613 node->left()->Visit(&for_left_value);
1608 Append(for_left_value); 1614 Append(for_left_value);
1609 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1615 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1610 arguments->Add(push_left); 1616 arguments->Add(push_left);
1611 1617
1612 ValueGraphVisitor for_right_value(owner()); 1618 ValueGraphVisitor for_right_value(owner());
1613 node->right()->Visit(&for_right_value); 1619 node->right()->Visit(&for_right_value);
1614 Append(for_right_value); 1620 Append(for_right_value);
1615 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1621 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1616 arguments->Add(push_right); 1622 arguments->Add(push_right);
1617 1623
1618 Definition* result = 1624 Definition* result =
1619 new InstanceCallInstr(node->token_pos(), 1625 new(I) InstanceCallInstr(node->token_pos(),
1620 Symbols::EqualOperator(), 1626 Symbols::EqualOperator(),
1621 Token::kEQ, // Result is negated later for kNE. 1627 Token::kEQ, // Result is negated later for kNE.
1622 arguments, 1628 arguments,
1623 Object::null_array(), 1629 Object::null_array(),
1624 2, 1630 2,
1625 owner()->ic_data_array()); 1631 owner()->ic_data_array());
1626 if (node->kind() == Token::kNE) { 1632 if (node->kind() == Token::kNE) {
1627 if (FLAG_enable_type_checks) { 1633 if (FLAG_enable_type_checks) {
1628 Value* value = Bind(result); 1634 Value* value = Bind(result);
1629 result = new AssertBooleanInstr(node->token_pos(), value); 1635 result = new(I) AssertBooleanInstr(node->token_pos(), value);
1630 } 1636 }
1631 Value* value = Bind(result); 1637 Value* value = Bind(result);
1632 result = new BooleanNegateInstr(value); 1638 result = new(I) BooleanNegateInstr(value);
1633 } 1639 }
1634 ReturnDefinition(result); 1640 ReturnDefinition(result);
1635 return; 1641 return;
1636 } 1642 }
1637 1643
1638 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1644 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1639 new ZoneGrowableArray<PushArgumentInstr*>(2); 1645 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
1640 1646
1641 ValueGraphVisitor for_left_value(owner()); 1647 ValueGraphVisitor for_left_value(owner());
1642 node->left()->Visit(&for_left_value); 1648 node->left()->Visit(&for_left_value);
1643 Append(for_left_value); 1649 Append(for_left_value);
1644 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1650 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1645 arguments->Add(push_left); 1651 arguments->Add(push_left);
1646 1652
1647 ValueGraphVisitor for_right_value(owner()); 1653 ValueGraphVisitor for_right_value(owner());
1648 node->right()->Visit(&for_right_value); 1654 node->right()->Visit(&for_right_value);
1649 Append(for_right_value); 1655 Append(for_right_value);
1650 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1656 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1651 arguments->Add(push_right); 1657 arguments->Add(push_right);
1652 1658
1653 ASSERT(Token::IsRelationalOperator(node->kind())); 1659 ASSERT(Token::IsRelationalOperator(node->kind()));
1654 InstanceCallInstr* comp = 1660 InstanceCallInstr* comp =
1655 new InstanceCallInstr(node->token_pos(), 1661 new(I) InstanceCallInstr(node->token_pos(),
1656 String::ZoneHandle( 1662 String::ZoneHandle(
1657 I, Symbols::New(node->TokenName())), 1663 I, Symbols::New(node->TokenName())),
1658 node->kind(), 1664 node->kind(),
1659 arguments, 1665 arguments,
1660 Object::null_array(), 1666 Object::null_array(),
1661 2, 1667 2,
1662 owner()->ic_data_array()); 1668 owner()->ic_data_array());
1663 ReturnDefinition(comp); 1669 ReturnDefinition(comp);
1664 } 1670 }
1665 1671
1666 1672
1667 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1673 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1668 // "!" cannot be overloaded, therefore do not call operator. 1674 // "!" cannot be overloaded, therefore do not call operator.
1669 if (node->kind() == Token::kNOT) { 1675 if (node->kind() == Token::kNOT) {
1670 ValueGraphVisitor for_value(owner()); 1676 ValueGraphVisitor for_value(owner());
1671 node->operand()->Visit(&for_value); 1677 node->operand()->Visit(&for_value);
1672 Append(for_value); 1678 Append(for_value);
1673 Value* value = for_value.value(); 1679 Value* value = for_value.value();
1674 if (FLAG_enable_type_checks) { 1680 if (FLAG_enable_type_checks) {
1675 value = 1681 value =
1676 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); 1682 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value));
1677 } 1683 }
1678 BooleanNegateInstr* negate = new BooleanNegateInstr(value); 1684 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value);
1679 ReturnDefinition(negate); 1685 ReturnDefinition(negate);
1680 return; 1686 return;
1681 } 1687 }
1682 1688
1683 ValueGraphVisitor for_value(owner()); 1689 ValueGraphVisitor for_value(owner());
1684 node->operand()->Visit(&for_value); 1690 node->operand()->Visit(&for_value);
1685 Append(for_value); 1691 Append(for_value);
1686 PushArgumentInstr* push_value = PushArgument(for_value.value()); 1692 PushArgumentInstr* push_value = PushArgument(for_value.value());
1687 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1693 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1688 new ZoneGrowableArray<PushArgumentInstr*>(1); 1694 new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
1689 arguments->Add(push_value); 1695 arguments->Add(push_value);
1690 InstanceCallInstr* call = 1696 InstanceCallInstr* call =
1691 new InstanceCallInstr(node->token_pos(), 1697 new(I) InstanceCallInstr(node->token_pos(),
1692 String::ZoneHandle( 1698 String::ZoneHandle(
1693 I, Symbols::New(node->TokenName())), 1699 I, Symbols::New(node->TokenName())),
1694 node->kind(), 1700 node->kind(),
1695 arguments, 1701 arguments,
1696 Object::null_array(), 1702 Object::null_array(),
1697 1, 1703 1,
1698 owner()->ic_data_array()); 1704 owner()->ic_data_array());
1699 ReturnDefinition(call); 1705 ReturnDefinition(call);
1700 } 1706 }
1701 1707
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 // 1790 //
1785 // Note: The specification of switch/case is under discussion and may change 1791 // Note: The specification of switch/case is under discussion and may change
1786 // drastically. 1792 // drastically.
1787 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { 1793 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
1788 const intptr_t len = node->case_expressions()->length(); 1794 const intptr_t len = node->case_expressions()->length();
1789 // Create case statements instructions. 1795 // Create case statements instructions.
1790 EffectGraphVisitor for_case_statements(owner()); 1796 EffectGraphVisitor for_case_statements(owner());
1791 // Compute the start of the statements fragment. 1797 // Compute the start of the statements fragment.
1792 JoinEntryInstr* statement_start = NULL; 1798 JoinEntryInstr* statement_start = NULL;
1793 if (node->label() == NULL) { 1799 if (node->label() == NULL) {
1794 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), 1800 statement_start = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
1795 owner()->try_index()); 1801 owner()->try_index());
1796 } else { 1802 } else {
1797 // The case nodes are nested inside a SequenceNode that is the body of a 1803 // The case nodes are nested inside a SequenceNode that is the body of a
1798 // SwitchNode. The SwitchNode on the nesting stack contains the 1804 // SwitchNode. The SwitchNode on the nesting stack contains the
1799 // continue labels for all the case clauses. 1805 // continue labels for all the case clauses.
1800 statement_start = 1806 statement_start =
1801 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label()); 1807 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label());
1802 } 1808 }
1803 ASSERT(statement_start != NULL); 1809 ASSERT(statement_start != NULL);
1804 node->statements()->Visit(&for_case_statements); 1810 node->statements()->Visit(&for_case_statements);
1805 Instruction* statement_exit = 1811 Instruction* statement_exit =
(...skipping 30 matching lines...) Expand all
1836 // Handle last (or only) case: false goes to exit or to statement if this 1842 // Handle last (or only) case: false goes to exit or to statement if this
1837 // node contains default. 1843 // node contains default.
1838 if (len > 0) { 1844 if (len > 0) {
1839 ASSERT(next_target != NULL); 1845 ASSERT(next_target != NULL);
1840 if (node->contains_default()) { 1846 if (node->contains_default()) {
1841 // True and false go to statement start. 1847 // True and false go to statement start.
1842 next_target->Goto(statement_start); 1848 next_target->Goto(statement_start);
1843 exit_instruction = statement_exit; 1849 exit_instruction = statement_exit;
1844 } else { 1850 } else {
1845 if (statement_exit != NULL) { 1851 if (statement_exit != NULL) {
1846 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), 1852 JoinEntryInstr* join = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
1847 owner()->try_index()); 1853 owner()->try_index());
1848 statement_exit->Goto(join); 1854 statement_exit->Goto(join);
1849 next_target->Goto(join); 1855 next_target->Goto(join);
1850 exit_instruction = join; 1856 exit_instruction = join;
1851 } else { 1857 } else {
1852 exit_instruction = next_target; 1858 exit_instruction = next_target;
1853 } 1859 }
1854 } 1860 }
1855 } else { 1861 } else {
1856 // A CaseNode without case expressions must contain default. 1862 // A CaseNode without case expressions must contain default.
1857 ASSERT(node->contains_default()); 1863 ASSERT(node->contains_default());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 // Traverse the body first in order to generate continue and break labels. 1920 // Traverse the body first in order to generate continue and break labels.
1915 EffectGraphVisitor for_body(owner()); 1921 EffectGraphVisitor for_body(owner());
1916 node->body()->Visit(&for_body); 1922 node->body()->Visit(&for_body);
1917 1923
1918 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1924 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1919 node->condition()->Visit(&for_test); 1925 node->condition()->Visit(&for_test);
1920 ASSERT(is_open()); 1926 ASSERT(is_open());
1921 1927
1922 // Tie do-while loop (test is after the body). 1928 // Tie do-while loop (test is after the body).
1923 JoinEntryInstr* body_entry_join = 1929 JoinEntryInstr* body_entry_join =
1924 new JoinEntryInstr(owner()->AllocateBlockId(), 1930 new(I) JoinEntryInstr(owner()->AllocateBlockId(),
1925 owner()->try_index()); 1931 owner()->try_index());
1926 Goto(body_entry_join); 1932 Goto(body_entry_join);
1927 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 1933 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
1928 1934
1929 JoinEntryInstr* join = nested_loop.continue_target(); 1935 JoinEntryInstr* join = nested_loop.continue_target();
1930 if ((body_exit != NULL) || (join != NULL)) { 1936 if ((body_exit != NULL) || (join != NULL)) {
1931 if (join == NULL) { 1937 if (join == NULL) {
1932 join = new JoinEntryInstr(owner()->AllocateBlockId(), 1938 join = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
1933 owner()->try_index()); 1939 owner()->try_index());
1934 } 1940 }
1935 CheckStackOverflowInstr* check = 1941 CheckStackOverflowInstr* check = new(I) CheckStackOverflowInstr(
1936 new CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth()); 1942 node->token_pos(), owner()->loop_depth());
1937 join->LinkTo(check); 1943 join->LinkTo(check);
1938 check->LinkTo(for_test.entry()); 1944 check->LinkTo(for_test.entry());
1939 if (body_exit != NULL) { 1945 if (body_exit != NULL) {
1940 body_exit->Goto(join); 1946 body_exit->Goto(join);
1941 } 1947 }
1942 } 1948 }
1943 1949
1944 for_test.IfTrueGoto(body_entry_join); 1950 for_test.IfTrueGoto(body_entry_join);
1945 join = nested_loop.break_target(); 1951 join = nested_loop.break_target();
1946 if (join == NULL) { 1952 if (join == NULL) {
(...skipping 28 matching lines...) Expand all
1975 EffectGraphVisitor for_body(owner()); 1981 EffectGraphVisitor for_body(owner());
1976 node->body()->Visit(&for_body); 1982 node->body()->Visit(&for_body);
1977 1983
1978 EffectGraphVisitor for_increment(owner()); 1984 EffectGraphVisitor for_increment(owner());
1979 node->increment()->Visit(&for_increment); 1985 node->increment()->Visit(&for_increment);
1980 1986
1981 // Join the loop body and increment and then tie the loop. 1987 // Join the loop body and increment and then tie the loop.
1982 JoinEntryInstr* continue_join = nested_loop.continue_target(); 1988 JoinEntryInstr* continue_join = nested_loop.continue_target();
1983 if ((continue_join != NULL) || for_body.is_open()) { 1989 if ((continue_join != NULL) || for_body.is_open()) {
1984 JoinEntryInstr* loop_entry = 1990 JoinEntryInstr* loop_entry =
1985 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 1991 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1986 if (continue_join != NULL) { 1992 if (continue_join != NULL) {
1987 if (for_body.is_open()) for_body.Goto(continue_join); 1993 if (for_body.is_open()) for_body.Goto(continue_join);
1988 Instruction* current = AppendFragment(continue_join, for_increment); 1994 Instruction* current = AppendFragment(continue_join, for_increment);
1989 current->Goto(loop_entry); 1995 current->Goto(loop_entry);
1990 } else { 1996 } else {
1991 for_body.Append(for_increment); 1997 for_body.Append(for_increment);
1992 for_body.Goto(loop_entry); 1998 for_body.Goto(loop_entry);
1993 } 1999 }
1994 Goto(loop_entry); 2000 Goto(loop_entry);
1995 exit_ = loop_entry; 2001 exit_ = loop_entry;
1996 AddInstruction( 2002 AddInstruction(
1997 new CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth())); 2003 new(I) CheckStackOverflowInstr(node->token_pos(),
2004 owner()->loop_depth()));
1998 } 2005 }
1999 2006
2000 if (node->condition() == NULL) { 2007 if (node->condition() == NULL) {
2001 // Endless loop, no test. 2008 // Endless loop, no test.
2002 Append(for_body); 2009 Append(for_body);
2003 exit_ = nested_loop.break_target(); // May be NULL. 2010 exit_ = nested_loop.break_target(); // May be NULL.
2004 } else { 2011 } else {
2005 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 2012 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
2006 node->condition()->Visit(&for_test); 2013 node->condition()->Visit(&for_test);
2007 Append(for_test); 2014 Append(for_test);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { 2082 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const {
2076 return kFirstLocalSlotFromFp 2083 return kFirstLocalSlotFromFp
2077 - owner()->num_stack_locals() 2084 - owner()->num_stack_locals()
2078 - owner()->num_copied_params() 2085 - owner()->num_copied_params()
2079 - owner()->args_pushed() 2086 - owner()->args_pushed()
2080 - owner()->temp_count() + 1; 2087 - owner()->temp_count() + 1;
2081 } 2088 }
2082 2089
2083 2090
2084 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { 2091 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
2085 Do(new PushTempInstr(value)); 2092 Do(new(I) PushTempInstr(value));
2086 owner()->AllocateTemp(); 2093 owner()->AllocateTemp();
2087 2094
2088 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); 2095 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
2089 intptr_t index = GetCurrentTempLocalIndex(); 2096 intptr_t index = GetCurrentTempLocalIndex();
2090 char name[64]; 2097 char name[64];
2091 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); 2098 OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
2092 LocalVariable* var = 2099 LocalVariable* var =
2093 new LocalVariable(0, 2100 new(I) LocalVariable(0,
2094 String::ZoneHandle(I, Symbols::New(name)), 2101 String::ZoneHandle(I, Symbols::New(name)),
2095 *value->Type()->ToAbstractType()); 2102 *value->Type()->ToAbstractType());
2096 var->set_index(index); 2103 var->set_index(index);
2097 return var; 2104 return var;
2098 } 2105 }
2099 2106
2100 2107
2101 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { 2108 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) {
2102 Value* tmp = Bind(new LoadLocalInstr(*var)); 2109 Value* tmp = Bind(new(I) LoadLocalInstr(*var));
2103 owner()->DeallocateTemps(1); 2110 owner()->DeallocateTemps(1);
2104 ASSERT(GetCurrentTempLocalIndex() == var->index()); 2111 ASSERT(GetCurrentTempLocalIndex() == var->index());
2105 return new DropTempsInstr(1, tmp); 2112 return new(I) DropTempsInstr(1, tmp);
2106 } 2113 }
2107 2114
2108 2115
2109 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { 2116 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) {
2110 intptr_t num_temps = node->num_temps(); 2117 intptr_t num_temps = node->num_temps();
2111 for (intptr_t i = 0; i < num_temps; ++i) { 2118 for (intptr_t i = 0; i < num_temps; ++i) {
2112 ValueGraphVisitor for_value(owner()); 2119 ValueGraphVisitor for_value(owner());
2113 node->InitializerAt(i)->Visit(&for_value); 2120 node->InitializerAt(i)->Visit(&for_value);
2114 Append(for_value); 2121 Append(for_value);
2115 Value* temp_val = for_value.value(); 2122 Value* temp_val = for_value.value();
2116 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); 2123 node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
2117 Do(new PushTempInstr(temp_val)); 2124 Do(new(I) PushTempInstr(temp_val));
2118 owner()->AllocateTemp(); 2125 owner()->AllocateTemp();
2119 } 2126 }
2120 } 2127 }
2121 2128
2122 2129
2123 void EffectGraphVisitor::VisitLetNode(LetNode* node) { 2130 void EffectGraphVisitor::VisitLetNode(LetNode* node) {
2124 BuildLetTempExpressions(node); 2131 BuildLetTempExpressions(node);
2125 2132
2126 // Visit body. 2133 // Visit body.
2127 for (intptr_t i = 0; i < node->nodes().length(); ++i) { 2134 for (intptr_t i = 0; i < node->nodes().length(); ++i) {
2128 EffectGraphVisitor for_effect(owner()); 2135 EffectGraphVisitor for_effect(owner());
2129 node->nodes()[i]->Visit(&for_effect); 2136 node->nodes()[i]->Visit(&for_effect);
2130 Append(for_effect); 2137 Append(for_effect);
2131 } 2138 }
2132 2139
2133 intptr_t num_temps = node->num_temps(); 2140 intptr_t num_temps = node->num_temps();
2134 if (num_temps > 0) { 2141 if (num_temps > 0) {
2135 owner()->DeallocateTemps(num_temps); 2142 owner()->DeallocateTemps(num_temps);
2136 Do(new DropTempsInstr(num_temps)); 2143 Do(new(I) DropTempsInstr(num_temps));
2137 } 2144 }
2138 } 2145 }
2139 2146
2140 2147
2141 void ValueGraphVisitor::VisitLetNode(LetNode* node) { 2148 void ValueGraphVisitor::VisitLetNode(LetNode* node) {
2142 BuildLetTempExpressions(node); 2149 BuildLetTempExpressions(node);
2143 2150
2144 // Visit body. 2151 // Visit body.
2145 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { 2152 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) {
2146 EffectGraphVisitor for_effect(owner()); 2153 EffectGraphVisitor for_effect(owner());
2147 node->nodes()[i]->Visit(&for_effect); 2154 node->nodes()[i]->Visit(&for_effect);
2148 Append(for_effect); 2155 Append(for_effect);
2149 } 2156 }
2150 // Visit the last body expression for value. 2157 // Visit the last body expression for value.
2151 ValueGraphVisitor for_value(owner()); 2158 ValueGraphVisitor for_value(owner());
2152 node->nodes().Last()->Visit(&for_value); 2159 node->nodes().Last()->Visit(&for_value);
2153 Append(for_value); 2160 Append(for_value);
2154 Value* result_value = for_value.value(); 2161 Value* result_value = for_value.value();
2155 2162
2156 intptr_t num_temps = node->num_temps(); 2163 intptr_t num_temps = node->num_temps();
2157 if (num_temps > 0) { 2164 if (num_temps > 0) {
2158 owner()->DeallocateTemps(num_temps); 2165 owner()->DeallocateTemps(num_temps);
2159 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); 2166 ReturnDefinition(new(I) DropTempsInstr(num_temps, result_value));
2160 } else { 2167 } else {
2161 ReturnValue(result_value); 2168 ReturnValue(result_value);
2162 } 2169 }
2163 } 2170 }
2164 2171
2165 2172
2166 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 2173 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
2167 const TypeArguments& type_args = 2174 const TypeArguments& type_args =
2168 TypeArguments::ZoneHandle(I, node->type().arguments()); 2175 TypeArguments::ZoneHandle(I, node->type().arguments());
2169 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 2176 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
2170 type_args); 2177 type_args);
2171 Value* num_elements = 2178 Value* num_elements =
2172 Bind(new ConstantInstr(Smi::ZoneHandle(I, Smi::New(node->length())))); 2179 Bind(new(I) ConstantInstr(Smi::ZoneHandle(I, Smi::New(node->length()))));
2173 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), 2180 CreateArrayInstr* create = new(I) CreateArrayInstr(node->token_pos(),
2174 element_type, 2181 element_type,
2175 num_elements); 2182 num_elements);
2176 Value* array_val = Bind(create); 2183 Value* array_val = Bind(create);
2177 2184
2178 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); 2185 { LocalVariable* tmp_var = EnterTempLocalScope(array_val);
2179 const intptr_t class_id = kArrayCid; 2186 const intptr_t class_id = kArrayCid;
2180 const intptr_t deopt_id = Isolate::kNoDeoptId; 2187 const intptr_t deopt_id = Isolate::kNoDeoptId;
2181 for (int i = 0; i < node->length(); ++i) { 2188 for (int i = 0; i < node->length(); ++i) {
2182 Value* array = Bind(new LoadLocalInstr(*tmp_var)); 2189 Value* array = Bind(new(I) LoadLocalInstr(*tmp_var));
2183 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(I, Smi::New(i)))); 2190 Value* index =
2191 Bind(new(I) ConstantInstr(Smi::ZoneHandle(I, Smi::New(i))));
2184 ValueGraphVisitor for_value(owner()); 2192 ValueGraphVisitor for_value(owner());
2185 node->ElementAt(i)->Visit(&for_value); 2193 node->ElementAt(i)->Visit(&for_value);
2186 Append(for_value); 2194 Append(for_value);
2187 // No store barrier needed for constants. 2195 // No store barrier needed for constants.
2188 const StoreBarrierType emit_store_barrier = 2196 const StoreBarrierType emit_store_barrier =
2189 for_value.value()->BindsToConstant() 2197 for_value.value()->BindsToConstant()
2190 ? kNoStoreBarrier 2198 ? kNoStoreBarrier
2191 : kEmitStoreBarrier; 2199 : kEmitStoreBarrier;
2192 const intptr_t index_scale = Instance::ElementSizeFor(class_id); 2200 const intptr_t index_scale = Instance::ElementSizeFor(class_id);
2193 StoreIndexedInstr* store = new StoreIndexedInstr( 2201 StoreIndexedInstr* store = new(I) StoreIndexedInstr(
2194 array, index, for_value.value(), emit_store_barrier, 2202 array, index, for_value.value(), emit_store_barrier,
2195 index_scale, class_id, deopt_id, node->token_pos()); 2203 index_scale, class_id, deopt_id, node->token_pos());
2196 Do(store); 2204 Do(store);
2197 } 2205 }
2198 ReturnDefinition(ExitTempLocalScope(tmp_var)); 2206 ReturnDefinition(ExitTempLocalScope(tmp_var));
2199 } 2207 }
2200 } 2208 }
2201 2209
2202 2210
2203 void EffectGraphVisitor::VisitStringInterpolateNode( 2211 void EffectGraphVisitor::VisitStringInterpolateNode(
2204 StringInterpolateNode* node) { 2212 StringInterpolateNode* node) {
2205 ValueGraphVisitor for_argument(owner()); 2213 ValueGraphVisitor for_argument(owner());
2206 node->value()->Visit(&for_argument); 2214 node->value()->Visit(&for_argument);
2207 Append(for_argument); 2215 Append(for_argument);
2208 StringInterpolateInstr* instr = 2216 StringInterpolateInstr* instr =
2209 new StringInterpolateInstr(for_argument.value(), node->token_pos()); 2217 new(I) StringInterpolateInstr(for_argument.value(), node->token_pos());
2210 ReturnDefinition(instr); 2218 ReturnDefinition(instr);
2211 } 2219 }
2212 2220
2213 2221
2214 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 2222 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
2215 const Function& function = node->function(); 2223 const Function& function = node->function();
2216 2224
2217 if (function.IsImplicitStaticClosureFunction()) { 2225 if (function.IsImplicitStaticClosureFunction()) {
2218 const Instance& closure = 2226 const Instance& closure =
2219 Instance::ZoneHandle(I, function.ImplicitStaticClosure()); 2227 Instance::ZoneHandle(I, function.ImplicitStaticClosure());
2220 ReturnDefinition(new ConstantInstr(closure)); 2228 ReturnDefinition(new(I) ConstantInstr(closure));
2221 return; 2229 return;
2222 } 2230 }
2223 const bool is_implicit = function.IsImplicitInstanceClosureFunction(); 2231 const bool is_implicit = function.IsImplicitInstanceClosureFunction();
2224 ASSERT(is_implicit || function.IsNonImplicitClosureFunction()); 2232 ASSERT(is_implicit || function.IsNonImplicitClosureFunction());
2225 // The context scope may have already been set by the non-optimizing 2233 // The context scope may have already been set by the non-optimizing
2226 // compiler. If it was not, set it here. 2234 // compiler. If it was not, set it here.
2227 if (function.context_scope() == ContextScope::null()) { 2235 if (function.context_scope() == ContextScope::null()) {
2228 ASSERT(!is_implicit); 2236 ASSERT(!is_implicit);
2229 const ContextScope& context_scope = ContextScope::ZoneHandle( 2237 const ContextScope& context_scope = ContextScope::ZoneHandle(
2230 I, node->scope()->PreserveOuterScope(owner()->context_level())); 2238 I, node->scope()->PreserveOuterScope(owner()->context_level()));
(...skipping 16 matching lines...) Expand all
2247 I, cls.LookupClosureFunction(function.token_pos())); 2255 I, cls.LookupClosureFunction(function.token_pos()));
2248 2256
2249 if (found_func.IsNull() || 2257 if (found_func.IsNull() ||
2250 (found_func.token_pos() != function.token_pos()) || 2258 (found_func.token_pos() != function.token_pos()) ||
2251 (found_func.script() != function.script()) || 2259 (found_func.script() != function.script()) ||
2252 (found_func.parent_function() != function.parent_function())) { 2260 (found_func.parent_function() != function.parent_function())) {
2253 cls.AddClosureFunction(function); 2261 cls.AddClosureFunction(function);
2254 } 2262 }
2255 } 2263 }
2256 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2264 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2257 new ZoneGrowableArray<PushArgumentInstr*>(1); 2265 new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
2258 ASSERT(function.context_scope() != ContextScope::null()); 2266 ASSERT(function.context_scope() != ContextScope::null());
2259 2267
2260 // The function type of a closure may have type arguments. In that case, 2268 // The function type of a closure may have type arguments. In that case,
2261 // pass the type arguments of the instantiator. 2269 // pass the type arguments of the instantiator.
2262 const Class& cls = Class::ZoneHandle(I, function.signature_class()); 2270 const Class& cls = Class::ZoneHandle(I, function.signature_class());
2263 ASSERT(!cls.IsNull()); 2271 ASSERT(!cls.IsNull());
2264 const bool requires_type_arguments = cls.NumTypeArguments() > 0; 2272 const bool requires_type_arguments = cls.NumTypeArguments() > 0;
2265 Value* type_arguments = NULL; 2273 Value* type_arguments = NULL;
2266 if (requires_type_arguments) { 2274 if (requires_type_arguments) {
2267 ASSERT(cls.type_arguments_field_offset() == 2275 ASSERT(cls.type_arguments_field_offset() ==
2268 Closure::type_arguments_offset()); 2276 Closure::type_arguments_offset());
2269 ASSERT(cls.instance_size() == Closure::InstanceSize()); 2277 ASSERT(cls.instance_size() == Closure::InstanceSize());
2270 const Class& instantiator_class = Class::Handle( 2278 const Class& instantiator_class = Class::Handle(
2271 I, owner()->parsed_function()->function().Owner()); 2279 I, owner()->parsed_function()->function().Owner());
2272 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), 2280 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2273 instantiator_class, 2281 instantiator_class,
2274 NULL); 2282 NULL);
2275 arguments->Add(PushArgument(type_arguments)); 2283 arguments->Add(PushArgument(type_arguments));
2276 } 2284 }
2277 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(), 2285 AllocateObjectInstr* alloc = new(I) AllocateObjectInstr(node->token_pos(),
2278 cls, 2286 cls,
2279 arguments); 2287 arguments);
2280 alloc->set_closure_function(function); 2288 alloc->set_closure_function(function);
2281 2289
2282 Value* closure_val = Bind(alloc); 2290 Value* closure_val = Bind(alloc);
2283 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); 2291 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val);
2284 // Store function. 2292 // Store function.
2285 Value* closure_tmp_val = Bind(new LoadLocalInstr(*closure_tmp_var)); 2293 Value* closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var));
2286 Value* func_val = 2294 Value* func_val =
2287 Bind(new ConstantInstr(Function::ZoneHandle(I, function.raw()))); 2295 Bind(new(I) ConstantInstr(Function::ZoneHandle(I, function.raw())));
2288 Do(new StoreInstanceFieldInstr(Closure::function_offset(), 2296 Do(new(I) StoreInstanceFieldInstr(Closure::function_offset(),
2289 closure_tmp_val, 2297 closure_tmp_val,
2290 func_val, 2298 func_val,
2291 kEmitStoreBarrier, 2299 kEmitStoreBarrier,
2292 node->token_pos())); 2300 node->token_pos()));
2293 if (is_implicit) { 2301 if (is_implicit) {
2294 // Create new context containing the receiver. 2302 // Create new context containing the receiver.
2295 const intptr_t kNumContextVariables = 1; // The receiver. 2303 const intptr_t kNumContextVariables = 1; // The receiver.
2296 Value* allocated_context = 2304 Value* allocated_context =
2297 Bind(new AllocateContextInstr(node->token_pos(), 2305 Bind(new(I) AllocateContextInstr(node->token_pos(),
2298 kNumContextVariables)); 2306 kNumContextVariables));
2299 { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context); 2307 { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context);
2300 // Store receiver in context. 2308 // Store receiver in context.
2301 Value* context_tmp_val = Bind(new LoadLocalInstr(*context_tmp_var)); 2309 Value* context_tmp_val = Bind(new(I) LoadLocalInstr(*context_tmp_var));
2302 ValueGraphVisitor for_receiver(owner()); 2310 ValueGraphVisitor for_receiver(owner());
2303 node->receiver()->Visit(&for_receiver); 2311 node->receiver()->Visit(&for_receiver);
2304 Append(for_receiver); 2312 Append(for_receiver);
2305 Value* receiver = for_receiver.value(); 2313 Value* receiver = for_receiver.value();
2306 Do(new StoreInstanceFieldInstr(Context::variable_offset(0), 2314 Do(new(I) StoreInstanceFieldInstr(Context::variable_offset(0),
2307 context_tmp_val, 2315 context_tmp_val,
2308 receiver, 2316 receiver,
2309 kEmitStoreBarrier, 2317 kEmitStoreBarrier,
2310 node->token_pos())); 2318 node->token_pos()));
2311 // Store new context in closure. 2319 // Store new context in closure.
2312 closure_tmp_val = Bind(new LoadLocalInstr(*closure_tmp_var)); 2320 closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var));
2313 context_tmp_val = Bind(new LoadLocalInstr(*context_tmp_var)); 2321 context_tmp_val = Bind(new(I) LoadLocalInstr(*context_tmp_var));
2314 Do(new StoreInstanceFieldInstr(Closure::context_offset(), 2322 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(),
2315 closure_tmp_val, 2323 closure_tmp_val,
2316 context_tmp_val, 2324 context_tmp_val,
2317 kEmitStoreBarrier, 2325 kEmitStoreBarrier,
2318 node->token_pos())); 2326 node->token_pos()));
2319 Do(ExitTempLocalScope(context_tmp_var)); 2327 Do(ExitTempLocalScope(context_tmp_var));
2320 } 2328 }
2321 } else { 2329 } else {
2322 // Store current context in closure. 2330 // Store current context in closure.
2323 closure_tmp_val = Bind(new LoadLocalInstr(*closure_tmp_var)); 2331 closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var));
2324 Value* context = Bind(new CurrentContextInstr()); 2332 Value* context = Bind(new(I) CurrentContextInstr());
2325 Do(new StoreInstanceFieldInstr(Closure::context_offset(), 2333 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(),
2326 closure_tmp_val, 2334 closure_tmp_val,
2327 context, 2335 context,
2328 kEmitStoreBarrier, 2336 kEmitStoreBarrier,
2329 node->token_pos())); 2337 node->token_pos()));
2330 } 2338 }
2331 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); 2339 ReturnDefinition(ExitTempLocalScope(closure_tmp_var));
2332 } 2340 }
2333 } 2341 }
2334 2342
2335 2343
2336 void EffectGraphVisitor::BuildPushArguments( 2344 void EffectGraphVisitor::BuildPushArguments(
2337 const ArgumentListNode& node, 2345 const ArgumentListNode& node,
2338 ZoneGrowableArray<PushArgumentInstr*>* values) { 2346 ZoneGrowableArray<PushArgumentInstr*>* values) {
2339 for (intptr_t i = 0; i < node.length(); ++i) { 2347 for (intptr_t i = 0; i < node.length(); ++i) {
2340 ValueGraphVisitor for_argument(owner()); 2348 ValueGraphVisitor for_argument(owner());
2341 node.NodeAt(i)->Visit(&for_argument); 2349 node.NodeAt(i)->Visit(&for_argument);
2342 Append(for_argument); 2350 Append(for_argument);
2343 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 2351 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
2344 values->Add(push_arg); 2352 values->Add(push_arg);
2345 } 2353 }
2346 } 2354 }
2347 2355
2348 2356
2349 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 2357 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
2350 ValueGraphVisitor for_receiver(owner()); 2358 ValueGraphVisitor for_receiver(owner());
2351 node->receiver()->Visit(&for_receiver); 2359 node->receiver()->Visit(&for_receiver);
2352 Append(for_receiver); 2360 Append(for_receiver);
2353 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2361 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2354 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2362 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2355 new ZoneGrowableArray<PushArgumentInstr*>( 2363 new(I) ZoneGrowableArray<PushArgumentInstr*>(
2356 node->arguments()->length() + 1); 2364 node->arguments()->length() + 1);
2357 arguments->Add(push_receiver); 2365 arguments->Add(push_receiver);
2358 2366
2359 BuildPushArguments(*node->arguments(), arguments); 2367 BuildPushArguments(*node->arguments(), arguments);
2360 InstanceCallInstr* call = new InstanceCallInstr( 2368 InstanceCallInstr* call = new(I) InstanceCallInstr(
2361 node->token_pos(), 2369 node->token_pos(),
2362 node->function_name(), 2370 node->function_name(),
2363 Token::kILLEGAL, 2371 Token::kILLEGAL,
2364 arguments, 2372 arguments,
2365 node->arguments()->names(), 2373 node->arguments()->names(),
2366 1, 2374 1,
2367 owner()->ic_data_array()); 2375 owner()->ic_data_array());
2368 ReturnDefinition(call); 2376 ReturnDefinition(call);
2369 } 2377 }
2370 2378
(...skipping 25 matching lines...) Expand all
2396 } 2404 }
2397 } 2405 }
2398 return kDynamicCid; 2406 return kDynamicCid;
2399 } 2407 }
2400 2408
2401 2409
2402 // <Expression> ::= StaticCall { function: Function 2410 // <Expression> ::= StaticCall { function: Function
2403 // arguments: <ArgumentList> } 2411 // arguments: <ArgumentList> }
2404 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 2412 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
2405 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2413 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2406 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 2414 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
2407 BuildPushArguments(*node->arguments(), arguments); 2415 BuildPushArguments(*node->arguments(), arguments);
2408 StaticCallInstr* call = 2416 StaticCallInstr* call =
2409 new StaticCallInstr(node->token_pos(), 2417 new(I) StaticCallInstr(node->token_pos(),
2410 node->function(), 2418 node->function(),
2411 node->arguments()->names(), 2419 node->arguments()->names(),
2412 arguments, 2420 arguments,
2413 owner()->ic_data_array()); 2421 owner()->ic_data_array());
2414 if (node->function().is_native()) { 2422 if (node->function().is_native()) {
2415 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function()); 2423 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function());
2416 if (result_cid != kDynamicCid) { 2424 if (result_cid != kDynamicCid) {
2417 call->set_result_cid(result_cid); 2425 call->set_result_cid(result_cid);
2418 call->set_is_native_list_factory(true); 2426 call->set_is_native_list_factory(true);
2419 } 2427 }
2420 } 2428 }
2421 ReturnDefinition(call); 2429 ReturnDefinition(call);
2422 } 2430 }
2423 2431
2424 2432
2425 void EffectGraphVisitor::BuildClosureCall( 2433 void EffectGraphVisitor::BuildClosureCall(
2426 ClosureCallNode* node, bool result_needed) { 2434 ClosureCallNode* node, bool result_needed) {
2427 ValueGraphVisitor for_closure(owner()); 2435 ValueGraphVisitor for_closure(owner());
2428 node->closure()->Visit(&for_closure); 2436 node->closure()->Visit(&for_closure);
2429 Append(for_closure); 2437 Append(for_closure);
2430 2438
2431 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value()); 2439 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value());
2432 2440
2433 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2441 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2434 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 2442 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
2435 Value* closure_val = Bind(new LoadLocalInstr(*tmp_var)); 2443 Value* closure_val = Bind(new(I) LoadLocalInstr(*tmp_var));
2436 PushArgumentInstr* push_closure = PushArgument(closure_val); 2444 PushArgumentInstr* push_closure = PushArgument(closure_val);
2437 arguments->Add(push_closure); 2445 arguments->Add(push_closure);
2438 BuildPushArguments(*node->arguments(), arguments); 2446 BuildPushArguments(*node->arguments(), arguments);
2439 2447
2440 // Save context around the call. 2448 // Save context around the call.
2441 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); 2449 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
2442 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); 2450 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var());
2443 closure_val = Bind(new LoadLocalInstr(*tmp_var)); 2451 closure_val = Bind(new(I) LoadLocalInstr(*tmp_var));
2444 LoadFieldInstr* context_load = new LoadFieldInstr( 2452 LoadFieldInstr* context_load = new(I) LoadFieldInstr(
2445 closure_val, 2453 closure_val,
2446 Closure::context_offset(), 2454 Closure::context_offset(),
2447 AbstractType::ZoneHandle(I, AbstractType::null()), 2455 AbstractType::ZoneHandle(I, AbstractType::null()),
2448 node->token_pos()); 2456 node->token_pos());
2449 context_load->set_is_immutable(true); 2457 context_load->set_is_immutable(true);
2450 Value* context_val = Bind(context_load); 2458 Value* context_val = Bind(context_load);
2451 AddInstruction(new StoreContextInstr(context_val)); 2459 AddInstruction(new(I) StoreContextInstr(context_val));
2452 closure_val = Bind(new LoadLocalInstr(*tmp_var)); 2460 closure_val = Bind(new(I) LoadLocalInstr(*tmp_var));
2453 LoadFieldInstr* function_load = new LoadFieldInstr( 2461 LoadFieldInstr* function_load = new(I) LoadFieldInstr(
2454 closure_val, 2462 closure_val,
2455 Closure::function_offset(), 2463 Closure::function_offset(),
2456 AbstractType::ZoneHandle(I, AbstractType::null()), 2464 AbstractType::ZoneHandle(I, AbstractType::null()),
2457 node->token_pos()); 2465 node->token_pos());
2458 function_load->set_is_immutable(true); 2466 function_load->set_is_immutable(true);
2459 Value* function_val = Bind(function_load); 2467 Value* function_val = Bind(function_load);
2460 Definition* closure_call = 2468 Definition* closure_call =
2461 new ClosureCallInstr(function_val, node, arguments); 2469 new(I) ClosureCallInstr(function_val, node, arguments);
2462 if (result_needed) { 2470 if (result_needed) {
2463 Value* result = Bind(closure_call); 2471 Value* result = Bind(closure_call);
2464 Do(new StoreLocalInstr(*tmp_var, result)); 2472 Do(new(I) StoreLocalInstr(*tmp_var, result));
2465 // Restore context from temp. 2473 // Restore context from temp.
2466 BuildRestoreContext( 2474 BuildRestoreContext(
2467 *owner()->parsed_function()->saved_current_context_var()); 2475 *owner()->parsed_function()->saved_current_context_var());
2468 ReturnDefinition(ExitTempLocalScope(tmp_var)); 2476 ReturnDefinition(ExitTempLocalScope(tmp_var));
2469 } else { 2477 } else {
2470 Do(closure_call); 2478 Do(closure_call);
2471 // Restore context from saved location. 2479 // Restore context from saved location.
2472 BuildRestoreContext( 2480 BuildRestoreContext(
2473 *owner()->parsed_function()->saved_current_context_var()); 2481 *owner()->parsed_function()->saved_current_context_var());
2474 Do(ExitTempLocalScope(tmp_var)); 2482 Do(ExitTempLocalScope(tmp_var));
2475 } 2483 }
2476 } 2484 }
2477 2485
2478 2486
2479 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2487 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2480 BuildClosureCall(node, false); 2488 BuildClosureCall(node, false);
2481 } 2489 }
2482 2490
2483 2491
2484 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2492 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2485 BuildClosureCall(node, true); 2493 BuildClosureCall(node, true);
2486 } 2494 }
2487 2495
2488 2496
2489 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 2497 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
2490 Value* context = Bind(new CurrentContextInstr()); 2498 Value* context = Bind(new(I) CurrentContextInstr());
2491 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); 2499 Value* clone = Bind(new(I) CloneContextInstr(node->token_pos(), context));
2492 AddInstruction(new StoreContextInstr(clone)); 2500 AddInstruction(new(I) StoreContextInstr(clone));
2493 } 2501 }
2494 2502
2495 2503
2496 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { 2504 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
2497 const Class& cls = Class::ZoneHandle(I, node->constructor().Owner()); 2505 const Class& cls = Class::ZoneHandle(I, node->constructor().Owner());
2498 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; 2506 const bool cls_is_parameterized = cls.NumTypeArguments() > 0;
2499 2507
2500 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = 2508 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2501 new ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0); 2509 new(I) ZoneGrowableArray<PushArgumentInstr*>(
2510 cls_is_parameterized ? 1 : 0);
2502 if (cls_is_parameterized) { 2511 if (cls_is_parameterized) {
2503 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(), 2512 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(),
2504 node->type_arguments()); 2513 node->type_arguments());
2505 allocate_arguments->Add(PushArgument(type_args)); 2514 allocate_arguments->Add(PushArgument(type_args));
2506 } 2515 }
2507 2516
2508 Definition* allocation = new AllocateObjectInstr( 2517 Definition* allocation = new(I) AllocateObjectInstr(
2509 node->token_pos(), 2518 node->token_pos(),
2510 Class::ZoneHandle(I, node->constructor().Owner()), 2519 Class::ZoneHandle(I, node->constructor().Owner()),
2511 allocate_arguments); 2520 allocate_arguments);
2512 2521
2513 return Bind(allocation); 2522 return Bind(allocation);
2514 } 2523 }
2515 2524
2516 2525
2517 void EffectGraphVisitor::BuildConstructorCall( 2526 void EffectGraphVisitor::BuildConstructorCall(
2518 ConstructorCallNode* node, 2527 ConstructorCallNode* node,
2519 PushArgumentInstr* push_alloc_value) { 2528 PushArgumentInstr* push_alloc_value) {
2520 Value* ctor_arg = Bind( 2529 Value* ctor_arg = Bind(new(I) ConstantInstr(
2521 new ConstantInstr(Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll)))); 2530 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll))));
2522 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); 2531 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
2523 2532
2524 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2533 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2525 new ZoneGrowableArray<PushArgumentInstr*>(2); 2534 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
2526 arguments->Add(push_alloc_value); 2535 arguments->Add(push_alloc_value);
2527 arguments->Add(push_ctor_arg); 2536 arguments->Add(push_ctor_arg);
2528 2537
2529 BuildPushArguments(*node->arguments(), arguments); 2538 BuildPushArguments(*node->arguments(), arguments);
2530 Do(new StaticCallInstr(node->token_pos(), 2539 Do(new(I) StaticCallInstr(node->token_pos(),
2531 node->constructor(), 2540 node->constructor(),
2532 node->arguments()->names(), 2541 node->arguments()->names(),
2533 arguments, 2542 arguments,
2534 owner()->ic_data_array())); 2543 owner()->ic_data_array()));
2535 } 2544 }
2536 2545
2537 2546
2538 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { 2547 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) {
2539 const Function& function = node->constructor(); 2548 const Function& function = node->constructor();
2540 const Class& function_class = Class::Handle(function.Owner()); 2549 const Class& function_class = Class::Handle(function.Owner());
(...skipping 14 matching lines...) Expand all
2555 } 2564 }
2556 return FactoryRecognizer::ResultCid(function); 2565 return FactoryRecognizer::ResultCid(function);
2557 } 2566 }
2558 return kDynamicCid; // Not a known list constructor. 2567 return kDynamicCid; // Not a known list constructor.
2559 } 2568 }
2560 2569
2561 2570
2562 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2571 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2563 if (node->constructor().IsFactory()) { 2572 if (node->constructor().IsFactory()) {
2564 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2573 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2565 new ZoneGrowableArray<PushArgumentInstr*>(); 2574 new(I) ZoneGrowableArray<PushArgumentInstr*>();
2566 PushArgumentInstr* push_type_arguments = PushArgument( 2575 PushArgumentInstr* push_type_arguments = PushArgument(
2567 BuildInstantiatedTypeArguments(node->token_pos(), 2576 BuildInstantiatedTypeArguments(node->token_pos(),
2568 node->type_arguments())); 2577 node->type_arguments()));
2569 arguments->Add(push_type_arguments); 2578 arguments->Add(push_type_arguments);
2570 ASSERT(arguments->length() == 1); 2579 ASSERT(arguments->length() == 1);
2571 BuildPushArguments(*node->arguments(), arguments); 2580 BuildPushArguments(*node->arguments(), arguments);
2572 StaticCallInstr* call = 2581 StaticCallInstr* call =
2573 new StaticCallInstr(node->token_pos(), 2582 new(I) StaticCallInstr(node->token_pos(),
2574 node->constructor(), 2583 node->constructor(),
2575 node->arguments()->names(), 2584 node->arguments()->names(),
2576 arguments, 2585 arguments,
2577 owner()->ic_data_array()); 2586 owner()->ic_data_array());
2578 const intptr_t result_cid = GetResultCidOfListFactory(node); 2587 const intptr_t result_cid = GetResultCidOfListFactory(node);
2579 if (result_cid != kDynamicCid) { 2588 if (result_cid != kDynamicCid) {
2580 call->set_result_cid(result_cid); 2589 call->set_result_cid(result_cid);
2581 call->set_is_known_list_constructor(true); 2590 call->set_is_known_list_constructor(true);
2582 // Recognized fixed length array factory must have two arguments: 2591 // Recognized fixed length array factory must have two arguments:
2583 // (0) type-arguments, (1) length. 2592 // (0) type-arguments, (1) length.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2629 TypeArguments::ZoneHandle(I, TypeArguments::null()); 2638 TypeArguments::ZoneHandle(I, TypeArguments::null());
2630 // Type is temporary. Only its type arguments are preserved. 2639 // Type is temporary. Only its type arguments are preserved.
2631 Type& type = Type::Handle( 2640 Type& type = Type::Handle(
2632 I, 2641 I,
2633 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2642 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
2634 type ^= ClassFinalizer::FinalizeType( 2643 type ^= ClassFinalizer::FinalizeType(
2635 instantiator_class, type, ClassFinalizer::kFinalize); 2644 instantiator_class, type, ClassFinalizer::kFinalize);
2636 ASSERT(!type.IsMalformedOrMalbounded()); 2645 ASSERT(!type.IsMalformedOrMalbounded());
2637 type_arguments = type.arguments(); 2646 type_arguments = type.arguments();
2638 type_arguments = type_arguments.Canonicalize(); 2647 type_arguments = type_arguments.Canonicalize();
2639 return Bind(new ConstantInstr(type_arguments)); 2648 return Bind(new(I) ConstantInstr(type_arguments));
2640 } 2649 }
2641 Function& outer_function = 2650 Function& outer_function =
2642 Function::Handle(I, owner()->parsed_function()->function().raw()); 2651 Function::Handle(I, owner()->parsed_function()->function().raw());
2643 while (outer_function.IsLocalFunction()) { 2652 while (outer_function.IsLocalFunction()) {
2644 outer_function = outer_function.parent_function(); 2653 outer_function = outer_function.parent_function();
2645 } 2654 }
2646 if (outer_function.IsFactory()) { 2655 if (outer_function.IsFactory()) {
2647 // No instantiator for factories. 2656 // No instantiator for factories.
2648 ASSERT(instantiator == NULL); 2657 ASSERT(instantiator == NULL);
2649 LocalVariable* instantiator_var = 2658 LocalVariable* instantiator_var =
2650 owner()->parsed_function()->instantiator(); 2659 owner()->parsed_function()->instantiator();
2651 ASSERT(instantiator_var != NULL); 2660 ASSERT(instantiator_var != NULL);
2652 return Bind(BuildLoadLocal(*instantiator_var)); 2661 return Bind(BuildLoadLocal(*instantiator_var));
2653 } 2662 }
2654 if (instantiator == NULL) { 2663 if (instantiator == NULL) {
2655 instantiator = BuildInstantiator(instantiator_class); 2664 instantiator = BuildInstantiator(instantiator_class);
2656 } 2665 }
2657 // The instantiator is the receiver of the caller, which is not a factory. 2666 // The instantiator is the receiver of the caller, which is not a factory.
2658 // The receiver cannot be null; extract its TypeArguments object. 2667 // The receiver cannot be null; extract its TypeArguments object.
2659 // Note that in the factory case, the instantiator is the first parameter 2668 // Note that in the factory case, the instantiator is the first parameter
2660 // of the factory, i.e. already a TypeArguments object. 2669 // of the factory, i.e. already a TypeArguments object.
2661 intptr_t type_arguments_field_offset = 2670 intptr_t type_arguments_field_offset =
2662 instantiator_class.type_arguments_field_offset(); 2671 instantiator_class.type_arguments_field_offset();
2663 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2672 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2664 2673
2665 return Bind(new LoadFieldInstr( 2674 return Bind(new(I) LoadFieldInstr(
2666 instantiator, 2675 instantiator,
2667 type_arguments_field_offset, 2676 type_arguments_field_offset,
2668 Type::ZoneHandle(I, Type::null()), // Not an instance, no type. 2677 Type::ZoneHandle(I, Type::null()), // Not an instance, no type.
2669 Scanner::kNoSourcePos)); 2678 Scanner::kNoSourcePos));
2670 } 2679 }
2671 2680
2672 2681
2673 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2682 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2674 intptr_t token_pos, 2683 intptr_t token_pos,
2675 const TypeArguments& type_arguments) { 2684 const TypeArguments& type_arguments) {
2676 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2685 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2677 return Bind(new ConstantInstr(type_arguments)); 2686 return Bind(new(I) ConstantInstr(type_arguments));
2678 } 2687 }
2679 // The type arguments are uninstantiated. 2688 // The type arguments are uninstantiated.
2680 const Class& instantiator_class = Class::ZoneHandle( 2689 const Class& instantiator_class = Class::ZoneHandle(
2681 I, owner()->parsed_function()->function().Owner()); 2690 I, owner()->parsed_function()->function().Owner());
2682 Value* instantiator_value = 2691 Value* instantiator_value =
2683 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 2692 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2684 const bool use_instantiator_type_args = 2693 const bool use_instantiator_type_args =
2685 type_arguments.IsUninstantiatedIdentity() || 2694 type_arguments.IsUninstantiatedIdentity() ||
2686 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); 2695 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class);
2687 if (use_instantiator_type_args) { 2696 if (use_instantiator_type_args) {
2688 return instantiator_value; 2697 return instantiator_value;
2689 } else { 2698 } else {
2690 return Bind(new InstantiateTypeArgumentsInstr(token_pos, 2699 return Bind(new(I) InstantiateTypeArgumentsInstr(token_pos,
2691 type_arguments, 2700 type_arguments,
2692 instantiator_class, 2701 instantiator_class,
2693 instantiator_value)); 2702 instantiator_value));
2694 } 2703 }
2695 } 2704 }
2696 2705
2697 2706
2698 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2707 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2699 if (node->constructor().IsFactory()) { 2708 if (node->constructor().IsFactory()) {
2700 EffectGraphVisitor::VisitConstructorCallNode(node); 2709 EffectGraphVisitor::VisitConstructorCallNode(node);
2701 return; 2710 return;
2702 } 2711 }
2703 2712
2704 // t_n contains the allocated and initialized object. 2713 // t_n contains the allocated and initialized object.
2705 // t_n <- AllocateObject(class) 2714 // t_n <- AllocateObject(class)
2706 // t_n <- StoreLocal(temp, t_n); 2715 // t_n <- StoreLocal(temp, t_n);
2707 // t_n+1 <- ctor-arg 2716 // t_n+1 <- ctor-arg
2708 // t_n+2... <- constructor arguments start here 2717 // t_n+2... <- constructor arguments start here
2709 // StaticCall(constructor, t_n, t_n+1, ...) 2718 // StaticCall(constructor, t_n, t_n+1, ...)
2710 // tn <- LoadLocal(temp) 2719 // tn <- LoadLocal(temp)
2711 2720
2712 Value* allocate = BuildObjectAllocation(node); 2721 Value* allocate = BuildObjectAllocation(node);
2713 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); 2722 { LocalVariable* tmp_var = EnterTempLocalScope(allocate);
2714 Value* allocated_tmp = Bind(new LoadLocalInstr(*tmp_var)); 2723 Value* allocated_tmp = Bind(new(I) LoadLocalInstr(*tmp_var));
2715 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); 2724 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
2716 BuildConstructorCall(node, push_allocated_value); 2725 BuildConstructorCall(node, push_allocated_value);
2717 ReturnDefinition(ExitTempLocalScope(tmp_var)); 2726 ReturnDefinition(ExitTempLocalScope(tmp_var));
2718 } 2727 }
2719 } 2728 }
2720 2729
2721 2730
2722 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 2731 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
2723 ValueGraphVisitor for_receiver(owner()); 2732 ValueGraphVisitor for_receiver(owner());
2724 node->receiver()->Visit(&for_receiver); 2733 node->receiver()->Visit(&for_receiver);
2725 Append(for_receiver); 2734 Append(for_receiver);
2726 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2735 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2727 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2736 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2728 new ZoneGrowableArray<PushArgumentInstr*>(1); 2737 new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
2729 arguments->Add(push_receiver); 2738 arguments->Add(push_receiver);
2730 const String& name = 2739 const String& name =
2731 String::ZoneHandle(I, Field::GetterSymbol(node->field_name())); 2740 String::ZoneHandle(I, Field::GetterSymbol(node->field_name()));
2732 InstanceCallInstr* call = new InstanceCallInstr( 2741 InstanceCallInstr* call = new(I) InstanceCallInstr(
2733 node->token_pos(), 2742 node->token_pos(),
2734 name, 2743 name,
2735 Token::kGET, 2744 Token::kGET,
2736 arguments, Object::null_array(), 2745 arguments, Object::null_array(),
2737 1, 2746 1,
2738 owner()->ic_data_array()); 2747 owner()->ic_data_array());
2739 ReturnDefinition(call); 2748 ReturnDefinition(call);
2740 } 2749 }
2741 2750
2742 2751
(...skipping 15 matching lines...) Expand all
2758 value = Bind(BuildStoreExprTemp(for_value.value())); 2767 value = Bind(BuildStoreExprTemp(for_value.value()));
2759 } else { 2768 } else {
2760 value = for_value.value(); 2769 value = for_value.value();
2761 } 2770 }
2762 arguments->Add(PushArgument(value)); 2771 arguments->Add(PushArgument(value));
2763 } 2772 }
2764 2773
2765 2774
2766 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 2775 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
2767 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2776 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2768 new ZoneGrowableArray<PushArgumentInstr*>(2); 2777 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
2769 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); 2778 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
2770 const String& name = 2779 const String& name =
2771 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); 2780 String::ZoneHandle(I, Field::SetterSymbol(node->field_name()));
2772 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), 2781 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
2773 name, 2782 name,
2774 Token::kSET, 2783 Token::kSET,
2775 arguments, 2784 arguments,
2776 Object::null_array(), 2785 Object::null_array(),
2777 2, // Checked arg count. 2786 2, // Checked arg count.
2778 owner()->ic_data_array()); 2787 owner()->ic_data_array());
2779 ReturnDefinition(call); 2788 ReturnDefinition(call);
2780 } 2789 }
2781 2790
2782 2791
2783 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 2792 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
2784 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2793 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2785 new ZoneGrowableArray<PushArgumentInstr*>(2); 2794 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
2786 BuildInstanceSetterArguments(node, arguments, kResultNeeded); 2795 BuildInstanceSetterArguments(node, arguments, kResultNeeded);
2787 const String& name = 2796 const String& name =
2788 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); 2797 String::ZoneHandle(I, Field::SetterSymbol(node->field_name()));
2789 Do(new InstanceCallInstr(node->token_pos(), 2798 Do(new(I) InstanceCallInstr(node->token_pos(),
2790 name, 2799 name,
2791 Token::kSET, 2800 Token::kSET,
2792 arguments, 2801 arguments,
2793 Object::null_array(), 2802 Object::null_array(),
2794 2, // Checked argument count. 2803 2, // Checked argument count.
2795 owner()->ic_data_array())); 2804 owner()->ic_data_array()));
2796 ReturnDefinition(BuildLoadExprTemp()); 2805 ReturnDefinition(BuildLoadExprTemp());
2797 } 2806 }
2798 2807
2799 2808
2800 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { 2809 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
2801 const String& getter_name = 2810 const String& getter_name =
2802 String::ZoneHandle(I, Field::GetterSymbol(node->field_name())); 2811 String::ZoneHandle(I, Field::GetterSymbol(node->field_name()));
2803 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2812 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2804 new ZoneGrowableArray<PushArgumentInstr*>(); 2813 new(I) ZoneGrowableArray<PushArgumentInstr*>();
2805 Function& getter_function = Function::ZoneHandle(I, Function::null()); 2814 Function& getter_function = Function::ZoneHandle(I, Function::null());
2806 if (node->is_super_getter()) { 2815 if (node->is_super_getter()) {
2807 // Statically resolved instance getter, i.e. "super getter". 2816 // Statically resolved instance getter, i.e. "super getter".
2808 ASSERT(node->receiver() != NULL); 2817 ASSERT(node->receiver() != NULL);
2809 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); 2818 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
2810 if (getter_function.IsNull()) { 2819 if (getter_function.IsNull()) {
2811 // Resolve and call noSuchMethod. 2820 // Resolve and call noSuchMethod.
2812 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2821 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
2813 arguments->Add(node->receiver()); 2822 arguments->Add(node->receiver());
2814 StaticCallInstr* call = 2823 StaticCallInstr* call =
2815 BuildStaticNoSuchMethodCall(node->cls(), 2824 BuildStaticNoSuchMethodCall(node->cls(),
2816 node->receiver(), 2825 node->receiver(),
2817 getter_name, 2826 getter_name,
2818 arguments, 2827 arguments,
2819 false, // Don't save last argument. 2828 false, // Don't save last argument.
2820 true); // Super invocation. 2829 true); // Super invocation.
2821 ReturnDefinition(call); 2830 ReturnDefinition(call);
2822 return; 2831 return;
(...skipping 29 matching lines...) Expand all
2852 InvocationMirror::EncodeType( 2861 InvocationMirror::EncodeType(
2853 node->cls().IsTopLevel() ? 2862 node->cls().IsTopLevel() ?
2854 InvocationMirror::kTopLevel : 2863 InvocationMirror::kTopLevel :
2855 InvocationMirror::kStatic, 2864 InvocationMirror::kStatic,
2856 InvocationMirror::kGetter)); 2865 InvocationMirror::kGetter));
2857 ReturnDefinition(call); 2866 ReturnDefinition(call);
2858 return; 2867 return;
2859 } 2868 }
2860 } 2869 }
2861 ASSERT(!getter_function.IsNull()); 2870 ASSERT(!getter_function.IsNull());
2862 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), 2871 StaticCallInstr* call = new(I) StaticCallInstr(
2863 getter_function, 2872 node->token_pos(),
2864 Object::null_array(), // No names 2873 getter_function,
2865 arguments, 2874 Object::null_array(), // No names
2866 owner()->ic_data_array()); 2875 arguments,
2876 owner()->ic_data_array());
2867 ReturnDefinition(call); 2877 ReturnDefinition(call);
2868 } 2878 }
2869 2879
2870 2880
2871 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, 2881 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
2872 bool result_is_needed) { 2882 bool result_is_needed) {
2873 const String& setter_name = 2883 const String& setter_name =
2874 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); 2884 String::ZoneHandle(I, Field::SetterSymbol(node->field_name()));
2875 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2885 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2876 new ZoneGrowableArray<PushArgumentInstr*>(1); 2886 new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
2877 // A super setter is an instance setter whose setter function is 2887 // A super setter is an instance setter whose setter function is
2878 // resolved at compile time (in the caller instance getter's super class). 2888 // resolved at compile time (in the caller instance getter's super class).
2879 // Unlike a static getter, a super getter has a receiver parameter. 2889 // Unlike a static getter, a super getter has a receiver parameter.
2880 const bool is_super_setter = (node->receiver() != NULL); 2890 const bool is_super_setter = (node->receiver() != NULL);
2881 Function& setter_function = 2891 Function& setter_function =
2882 Function::ZoneHandle(I, is_super_setter 2892 Function::ZoneHandle(I, is_super_setter
2883 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) 2893 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name)
2884 : node->cls().LookupStaticFunction(setter_name)); 2894 : node->cls().LookupStaticFunction(setter_name));
2885 StaticCallInstr* call; 2895 StaticCallInstr* call;
2886 if (setter_function.IsNull()) { 2896 if (setter_function.IsNull()) {
2887 if (is_super_setter) { 2897 if (is_super_setter) {
2888 ASSERT(node->receiver() != NULL); 2898 ASSERT(node->receiver() != NULL);
2889 // Resolve and call noSuchMethod. 2899 // Resolve and call noSuchMethod.
2890 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2900 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
2891 arguments->Add(node->receiver()); 2901 arguments->Add(node->receiver());
2892 arguments->Add(node->value()); 2902 arguments->Add(node->value());
2893 call = BuildStaticNoSuchMethodCall( 2903 call = BuildStaticNoSuchMethodCall(
2894 node->cls(), 2904 node->cls(),
2895 node->receiver(), 2905 node->receiver(),
2896 setter_name, 2906 setter_name,
2897 arguments, 2907 arguments,
2898 result_is_needed, // Save last arg if result is needed. 2908 result_is_needed, // Save last arg if result is needed.
2899 true); // Super invocation. 2909 true); // Super invocation.
2900 } else { 2910 } else {
2901 // Throw a NoSuchMethodError. 2911 // Throw a NoSuchMethodError.
2902 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2912 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
2903 arguments->Add(node->value()); 2913 arguments->Add(node->value());
2904 call = BuildThrowNoSuchMethodError( 2914 call = BuildThrowNoSuchMethodError(
2905 node->token_pos(), 2915 node->token_pos(),
2906 node->cls(), 2916 node->cls(),
2907 setter_name, 2917 setter_name,
2908 arguments, // Argument is the value passed to the setter. 2918 arguments, // Argument is the value passed to the setter.
2909 InvocationMirror::EncodeType( 2919 InvocationMirror::EncodeType(
2910 node->cls().IsTopLevel() ? 2920 node->cls().IsTopLevel() ?
2911 InvocationMirror::kTopLevel : 2921 InvocationMirror::kTopLevel :
2912 InvocationMirror::kStatic, 2922 InvocationMirror::kStatic,
(...skipping 11 matching lines...) Expand all
2924 node->value()->Visit(&for_value); 2934 node->value()->Visit(&for_value);
2925 Append(for_value); 2935 Append(for_value);
2926 Value* value = NULL; 2936 Value* value = NULL;
2927 if (result_is_needed) { 2937 if (result_is_needed) {
2928 value = Bind(BuildStoreExprTemp(for_value.value())); 2938 value = Bind(BuildStoreExprTemp(for_value.value()));
2929 } else { 2939 } else {
2930 value = for_value.value(); 2940 value = for_value.value();
2931 } 2941 }
2932 arguments->Add(PushArgument(value)); 2942 arguments->Add(PushArgument(value));
2933 2943
2934 call = new StaticCallInstr(node->token_pos(), 2944 call = new(I) StaticCallInstr(node->token_pos(),
2935 setter_function, 2945 setter_function,
2936 Object::null_array(), // No names. 2946 Object::null_array(), // No names.
2937 arguments, 2947 arguments,
2938 owner()->ic_data_array()); 2948 owner()->ic_data_array());
2939 } 2949 }
2940 if (result_is_needed) { 2950 if (result_is_needed) {
2941 Do(call); 2951 Do(call);
2942 ReturnDefinition(BuildLoadExprTemp()); 2952 ReturnDefinition(BuildLoadExprTemp());
2943 } else { 2953 } else {
2944 ReturnDefinition(call); 2954 ReturnDefinition(call);
2945 } 2955 }
2946 } 2956 }
2947 2957
2948 2958
(...skipping 19 matching lines...) Expand all
2968 return TypedData::length_offset(); 2978 return TypedData::length_offset();
2969 case MethodRecognizer::kGrowableArrayLength: 2979 case MethodRecognizer::kGrowableArrayLength:
2970 return GrowableObjectArray::length_offset(); 2980 return GrowableObjectArray::length_offset();
2971 default: 2981 default:
2972 UNREACHABLE(); 2982 UNREACHABLE();
2973 return 0; 2983 return 0;
2974 } 2984 }
2975 } 2985 }
2976 2986
2977 2987
2978 static LoadLocalInstr* BuildLoadThisVar(LocalScope* scope) { 2988 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) {
2979 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), 2989 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
2980 true); // Test only. 2990 true); // Test only.
2981 return new LoadLocalInstr(*receiver_var); 2991 return new(I) LoadLocalInstr(*receiver_var);
2982 } 2992 }
2983 2993
2984 2994
2985 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { 2995 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
2986 const Function& function = owner()->parsed_function()->function(); 2996 const Function& function = owner()->parsed_function()->function();
2987 if (!function.IsClosureFunction()) { 2997 if (!function.IsClosureFunction()) {
2988 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 2998 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
2989 switch (kind) { 2999 switch (kind) {
2990 case MethodRecognizer::kObjectEquals: { 3000 case MethodRecognizer::kObjectEquals: {
2991 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3001 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
2992 LocalVariable* other_var = 3002 LocalVariable* other_var =
2993 node->scope()->LookupVariable(Symbols::Other(), 3003 node->scope()->LookupVariable(Symbols::Other(),
2994 true); // Test only. 3004 true); // Test only.
2995 Value* other = Bind(new LoadLocalInstr(*other_var)); 3005 Value* other = Bind(new(I) LoadLocalInstr(*other_var));
2996 // Receiver is not a number because numbers override equality. 3006 // Receiver is not a number because numbers override equality.
2997 const bool kNoNumberCheck = false; 3007 const bool kNoNumberCheck = false;
2998 StrictCompareInstr* compare = 3008 StrictCompareInstr* compare =
2999 new StrictCompareInstr(node->token_pos(), 3009 new(I) StrictCompareInstr(node->token_pos(),
3000 Token::kEQ_STRICT, 3010 Token::kEQ_STRICT,
3001 receiver, 3011 receiver,
3002 other, 3012 other,
3003 kNoNumberCheck); 3013 kNoNumberCheck);
3004 return ReturnDefinition(compare); 3014 return ReturnDefinition(compare);
3005 } 3015 }
3006 case MethodRecognizer::kStringBaseLength: 3016 case MethodRecognizer::kStringBaseLength:
3007 case MethodRecognizer::kStringBaseIsEmpty: { 3017 case MethodRecognizer::kStringBaseIsEmpty: {
3008 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3018 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3009 // Treat length loads as mutable (i.e. affected by side effects) to 3019 // Treat length loads as mutable (i.e. affected by side effects) to
3010 // avoid hoisting them since we can't hoist the preceding class-check. 3020 // avoid hoisting them since we can't hoist the preceding class-check.
3011 // This is because of externalization of strings that affects their 3021 // This is because of externalization of strings that affects their
3012 // class-id. 3022 // class-id.
3013 LoadFieldInstr* load = new LoadFieldInstr( 3023 LoadFieldInstr* load = new(I) LoadFieldInstr(
3014 receiver, 3024 receiver,
3015 String::length_offset(), 3025 String::length_offset(),
3016 Type::ZoneHandle(I, Type::SmiType()), 3026 Type::ZoneHandle(I, Type::SmiType()),
3017 node->token_pos()); 3027 node->token_pos());
3018 load->set_result_cid(kSmiCid); 3028 load->set_result_cid(kSmiCid);
3019 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); 3029 load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
3020 if (kind == MethodRecognizer::kStringBaseLength) { 3030 if (kind == MethodRecognizer::kStringBaseLength) {
3021 return ReturnDefinition(load); 3031 return ReturnDefinition(load);
3022 } 3032 }
3023 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); 3033 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty);
3024 Value* zero_val = Bind(new ConstantInstr( 3034 Value* zero_val = Bind(new(I) ConstantInstr(
3025 Smi::ZoneHandle(I, Smi::New(0)))); 3035 Smi::ZoneHandle(I, Smi::New(0))));
3026 Value* load_val = Bind(load); 3036 Value* load_val = Bind(load);
3027 StrictCompareInstr* compare = 3037 StrictCompareInstr* compare =
3028 new StrictCompareInstr(node->token_pos(), 3038 new(I) StrictCompareInstr(node->token_pos(),
3029 Token::kEQ_STRICT, 3039 Token::kEQ_STRICT,
3030 load_val, 3040 load_val,
3031 zero_val, 3041 zero_val,
3032 false); // No number check. 3042 false); // No number check.
3033 return ReturnDefinition(compare); 3043 return ReturnDefinition(compare);
3034 } 3044 }
3035 case MethodRecognizer::kGrowableArrayLength: 3045 case MethodRecognizer::kGrowableArrayLength:
3036 case MethodRecognizer::kObjectArrayLength: 3046 case MethodRecognizer::kObjectArrayLength:
3037 case MethodRecognizer::kImmutableArrayLength: 3047 case MethodRecognizer::kImmutableArrayLength:
3038 case MethodRecognizer::kTypedDataLength: { 3048 case MethodRecognizer::kTypedDataLength: {
3039 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3049 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3040 LoadFieldInstr* load = new LoadFieldInstr( 3050 LoadFieldInstr* load = new(I) LoadFieldInstr(
3041 receiver, 3051 receiver,
3042 OffsetForLengthGetter(kind), 3052 OffsetForLengthGetter(kind),
3043 Type::ZoneHandle(I, Type::SmiType()), 3053 Type::ZoneHandle(I, Type::SmiType()),
3044 node->token_pos()); 3054 node->token_pos());
3045 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); 3055 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength);
3046 load->set_result_cid(kSmiCid); 3056 load->set_result_cid(kSmiCid);
3047 load->set_recognized_kind(kind); 3057 load->set_recognized_kind(kind);
3048 return ReturnDefinition(load); 3058 return ReturnDefinition(load);
3049 } 3059 }
3050 case MethodRecognizer::kClassIDgetID: { 3060 case MethodRecognizer::kClassIDgetID: {
3051 LocalVariable* value_var = 3061 LocalVariable* value_var =
3052 node->scope()->LookupVariable(Symbols::Value(), true); 3062 node->scope()->LookupVariable(Symbols::Value(), true);
3053 Value* value = Bind(new LoadLocalInstr(*value_var)); 3063 Value* value = Bind(new(I) LoadLocalInstr(*value_var));
3054 LoadClassIdInstr* load = new LoadClassIdInstr(value); 3064 LoadClassIdInstr* load = new(I) LoadClassIdInstr(value);
3055 return ReturnDefinition(load); 3065 return ReturnDefinition(load);
3056 } 3066 }
3057 case MethodRecognizer::kGrowableArrayCapacity: { 3067 case MethodRecognizer::kGrowableArrayCapacity: {
3058 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3068 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3059 LoadFieldInstr* data_load = new LoadFieldInstr( 3069 LoadFieldInstr* data_load = new(I) LoadFieldInstr(
3060 receiver, 3070 receiver,
3061 Array::data_offset(), 3071 Array::data_offset(),
3062 Type::ZoneHandle(I, Type::DynamicType()), 3072 Type::ZoneHandle(I, Type::DynamicType()),
3063 node->token_pos()); 3073 node->token_pos());
3064 data_load->set_result_cid(kArrayCid); 3074 data_load->set_result_cid(kArrayCid);
3065 Value* data = Bind(data_load); 3075 Value* data = Bind(data_load);
3066 LoadFieldInstr* length_load = new LoadFieldInstr( 3076 LoadFieldInstr* length_load = new(I) LoadFieldInstr(
3067 data, 3077 data,
3068 Array::length_offset(), 3078 Array::length_offset(),
3069 Type::ZoneHandle(I, Type::SmiType()), 3079 Type::ZoneHandle(I, Type::SmiType()),
3070 node->token_pos()); 3080 node->token_pos());
3071 length_load->set_result_cid(kSmiCid); 3081 length_load->set_result_cid(kSmiCid);
3072 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); 3082 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
3073 return ReturnDefinition(length_load); 3083 return ReturnDefinition(length_load);
3074 } 3084 }
3075 default: 3085 default:
3076 break; 3086 break;
3077 } 3087 }
3078 } 3088 }
3079 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); 3089 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
3080 NativeCallInstr* native_call = new NativeCallInstr(node); 3090 NativeCallInstr* native_call = new(I) NativeCallInstr(node);
3081 ReturnDefinition(native_call); 3091 ReturnDefinition(native_call);
3082 } 3092 }
3083 3093
3084 3094
3085 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { 3095 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
3086 // PrimaryNodes are temporary during parsing. 3096 // PrimaryNodes are temporary during parsing.
3087 UNREACHABLE(); 3097 UNREACHABLE();
3088 } 3098 }
3089 3099
3090 3100
(...skipping 11 matching lines...) Expand all
3102 3112
3103 // <Expression> ::= StoreLocal { local: LocalVariable 3113 // <Expression> ::= StoreLocal { local: LocalVariable
3104 // value: <Expression> } 3114 // value: <Expression> }
3105 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 3115 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
3106 // If the right hand side is an expression that does not contain 3116 // If the right hand side is an expression that does not contain
3107 // a safe point for the debugger to stop, add an explicit stub 3117 // a safe point for the debugger to stop, add an explicit stub
3108 // call. 3118 // call.
3109 if (node->value()->IsLiteralNode() || 3119 if (node->value()->IsLiteralNode() ||
3110 node->value()->IsLoadLocalNode()) { 3120 node->value()->IsLoadLocalNode()) {
3111 if (FLAG_enable_debugger) { 3121 if (FLAG_enable_debugger) {
3112 AddInstruction(new DebugStepCheckInstr(node->token_pos(), 3122 AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(),
3113 PcDescriptors::kRuntimeCall)); 3123 PcDescriptors::kRuntimeCall));
3114 } 3124 }
3115 } 3125 }
3116 3126
3117 ValueGraphVisitor for_value(owner()); 3127 ValueGraphVisitor for_value(owner());
3118 node->value()->Visit(&for_value); 3128 node->value()->Visit(&for_value);
3119 Append(for_value); 3129 Append(for_value);
3120 Value* store_value = for_value.value(); 3130 Value* store_value = for_value.value();
3121 if (FLAG_enable_type_checks) { 3131 if (FLAG_enable_type_checks) {
3122 store_value = BuildAssignableValue(node->value()->token_pos(), 3132 store_value = BuildAssignableValue(node->value()->token_pos(),
3123 store_value, 3133 store_value,
3124 node->local().type(), 3134 node->local().type(),
3125 node->local().name()); 3135 node->local().name());
3126 } 3136 }
3127 Definition* store = BuildStoreLocal(node->local(), store_value); 3137 Definition* store = BuildStoreLocal(node->local(), store_value);
3128 ReturnDefinition(store); 3138 ReturnDefinition(store);
3129 } 3139 }
3130 3140
3131 3141
3132 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 3142 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
3133 LoadInstanceFieldNode* node) { 3143 LoadInstanceFieldNode* node) {
3134 ValueGraphVisitor for_instance(owner()); 3144 ValueGraphVisitor for_instance(owner());
3135 node->instance()->Visit(&for_instance); 3145 node->instance()->Visit(&for_instance);
3136 Append(for_instance); 3146 Append(for_instance);
3137 LoadFieldInstr* load = new LoadFieldInstr( 3147 LoadFieldInstr* load = new(I) LoadFieldInstr(
3138 for_instance.value(), 3148 for_instance.value(),
3139 &node->field(), 3149 &node->field(),
3140 AbstractType::ZoneHandle(I, node->field().type()), 3150 AbstractType::ZoneHandle(I, node->field().type()),
3141 node->token_pos()); 3151 node->token_pos());
3142 if (node->field().guarded_cid() != kIllegalCid) { 3152 if (node->field().guarded_cid() != kIllegalCid) {
3143 if (!node->field().is_nullable() || 3153 if (!node->field().is_nullable() ||
3144 (node->field().guarded_cid() == kNullCid)) { 3154 (node->field().guarded_cid() == kNullCid)) {
3145 load->set_result_cid(node->field().guarded_cid()); 3155 load->set_result_cid(node->field().guarded_cid());
3146 } 3156 }
3147 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); 3157 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field());
(...skipping 16 matching lines...) Expand all
3164 AbstractType::ZoneHandle(I, node->field().type()); 3174 AbstractType::ZoneHandle(I, node->field().type());
3165 const String& dst_name = String::ZoneHandle(I, node->field().name()); 3175 const String& dst_name = String::ZoneHandle(I, node->field().name());
3166 store_value = BuildAssignableValue(node->value()->token_pos(), 3176 store_value = BuildAssignableValue(node->value()->token_pos(),
3167 store_value, 3177 store_value,
3168 type, 3178 type,
3169 dst_name); 3179 dst_name);
3170 } 3180 }
3171 3181
3172 store_value = Bind(BuildStoreExprTemp(store_value)); 3182 store_value = Bind(BuildStoreExprTemp(store_value));
3173 GuardFieldClassInstr* guard_field_class = 3183 GuardFieldClassInstr* guard_field_class =
3174 new GuardFieldClassInstr(store_value, 3184 new(I) GuardFieldClassInstr(store_value,
3175 node->field(), 3185 node->field(),
3176 I->GetNextDeoptId()); 3186 I->GetNextDeoptId());
3177 AddInstruction(guard_field_class); 3187 AddInstruction(guard_field_class);
3178 3188
3179 store_value = Bind(BuildLoadExprTemp()); 3189 store_value = Bind(BuildLoadExprTemp());
3180 GuardFieldLengthInstr* guard_field_length = 3190 GuardFieldLengthInstr* guard_field_length =
3181 new GuardFieldLengthInstr(store_value, 3191 new(I) GuardFieldLengthInstr(store_value,
3182 node->field(), 3192 node->field(),
3183 I->GetNextDeoptId()); 3193 I->GetNextDeoptId());
3184 AddInstruction(guard_field_length); 3194 AddInstruction(guard_field_length);
3185 3195
3186 store_value = Bind(BuildLoadExprTemp()); 3196 store_value = Bind(BuildLoadExprTemp());
3187 StoreInstanceFieldInstr* store = 3197 StoreInstanceFieldInstr* store =
3188 new StoreInstanceFieldInstr(node->field(), 3198 new(I) StoreInstanceFieldInstr(node->field(),
3189 for_instance.value(), 3199 for_instance.value(),
3190 store_value, 3200 store_value,
3191 kEmitStoreBarrier, 3201 kEmitStoreBarrier,
3192 node->token_pos()); 3202 node->token_pos());
3193 store->set_is_initialization(true); // Maybe initializing store. 3203 store->set_is_initialization(true); // Maybe initializing store.
3194 ReturnDefinition(store); 3204 ReturnDefinition(store);
3195 } 3205 }
3196 3206
3197 3207
3198 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 3208 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
3199 if (node->field().is_const()) { 3209 if (node->field().is_const()) {
3200 ASSERT(node->field().value() != Object::sentinel().raw()); 3210 ASSERT(node->field().value() != Object::sentinel().raw());
3201 ASSERT(node->field().value() != Object::transition_sentinel().raw()); 3211 ASSERT(node->field().value() != Object::transition_sentinel().raw());
3202 Definition* result = 3212 Definition* result =
3203 new ConstantInstr(Instance::ZoneHandle(I, node->field().value())); 3213 new(I) ConstantInstr(Instance::ZoneHandle(I, node->field().value()));
3204 return ReturnDefinition(result); 3214 return ReturnDefinition(result);
3205 } 3215 }
3206 Value* field_value = Bind(new ConstantInstr(node->field())); 3216 Value* field_value = Bind(new(I) ConstantInstr(node->field()));
3207 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(field_value); 3217 LoadStaticFieldInstr* load = new(I) LoadStaticFieldInstr(field_value);
3208 ReturnDefinition(load); 3218 ReturnDefinition(load);
3209 } 3219 }
3210 3220
3211 3221
3212 Definition* EffectGraphVisitor::BuildStoreStaticField( 3222 Definition* EffectGraphVisitor::BuildStoreStaticField(
3213 StoreStaticFieldNode* node, bool result_is_needed) { 3223 StoreStaticFieldNode* node, bool result_is_needed) {
3214 ValueGraphVisitor for_value(owner()); 3224 ValueGraphVisitor for_value(owner());
3215 node->value()->Visit(&for_value); 3225 node->value()->Visit(&for_value);
3216 Append(for_value); 3226 Append(for_value);
3217 Value* store_value = NULL; 3227 Value* store_value = NULL;
3218 if (result_is_needed) { 3228 if (result_is_needed) {
3219 store_value = Bind(BuildStoreExprTemp(for_value.value())); 3229 store_value = Bind(BuildStoreExprTemp(for_value.value()));
3220 } else { 3230 } else {
3221 store_value = for_value.value(); 3231 store_value = for_value.value();
3222 } 3232 }
3223 StoreStaticFieldInstr* store = 3233 StoreStaticFieldInstr* store =
3224 new StoreStaticFieldInstr(node->field(), store_value); 3234 new(I) StoreStaticFieldInstr(node->field(), store_value);
3225 3235
3226 if (result_is_needed) { 3236 if (result_is_needed) {
3227 Do(store); 3237 Do(store);
3228 return BuildLoadExprTemp(); 3238 return BuildLoadExprTemp();
3229 } else { 3239 } else {
3230 return store; 3240 return store;
3231 } 3241 }
3232 } 3242 }
3233 3243
3234 3244
(...skipping 10 matching lines...) Expand all
3245 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { 3255 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
3246 Function* super_function = NULL; 3256 Function* super_function = NULL;
3247 if (node->IsSuperLoad()) { 3257 if (node->IsSuperLoad()) {
3248 // Resolve the load indexed operator in the super class. 3258 // Resolve the load indexed operator in the super class.
3249 super_function = &Function::ZoneHandle( 3259 super_function = &Function::ZoneHandle(
3250 I, Resolver::ResolveDynamicAnyArgs(node->super_class(), 3260 I, Resolver::ResolveDynamicAnyArgs(node->super_class(),
3251 Symbols::IndexToken())); 3261 Symbols::IndexToken()));
3252 if (super_function->IsNull()) { 3262 if (super_function->IsNull()) {
3253 // Could not resolve super operator. Generate call noSuchMethod() of the 3263 // Could not resolve super operator. Generate call noSuchMethod() of the
3254 // super class instead. 3264 // super class instead.
3255 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 3265 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
3256 arguments->Add(node->array()); 3266 arguments->Add(node->array());
3257 arguments->Add(node->index_expr()); 3267 arguments->Add(node->index_expr());
3258 StaticCallInstr* call = 3268 StaticCallInstr* call =
3259 BuildStaticNoSuchMethodCall(node->super_class(), 3269 BuildStaticNoSuchMethodCall(node->super_class(),
3260 node->array(), 3270 node->array(),
3261 Symbols::IndexToken(), 3271 Symbols::IndexToken(),
3262 arguments, 3272 arguments,
3263 false, // Don't save last arg. 3273 false, // Don't save last arg.
3264 true); // Super invocation. 3274 true); // Super invocation.
3265 ReturnDefinition(call); 3275 ReturnDefinition(call);
3266 return; 3276 return;
3267 } 3277 }
3268 } 3278 }
3269 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3279 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3270 new ZoneGrowableArray<PushArgumentInstr*>(2); 3280 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
3271 ValueGraphVisitor for_array(owner()); 3281 ValueGraphVisitor for_array(owner());
3272 node->array()->Visit(&for_array); 3282 node->array()->Visit(&for_array);
3273 Append(for_array); 3283 Append(for_array);
3274 arguments->Add(PushArgument(for_array.value())); 3284 arguments->Add(PushArgument(for_array.value()));
3275 3285
3276 ValueGraphVisitor for_index(owner()); 3286 ValueGraphVisitor for_index(owner());
3277 node->index_expr()->Visit(&for_index); 3287 node->index_expr()->Visit(&for_index);
3278 Append(for_index); 3288 Append(for_index);
3279 arguments->Add(PushArgument(for_index.value())); 3289 arguments->Add(PushArgument(for_index.value()));
3280 3290
3281 if (super_function != NULL) { 3291 if (super_function != NULL) {
3282 // Generate static call to super operator. 3292 // Generate static call to super operator.
3283 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), 3293 StaticCallInstr* load = new(I) StaticCallInstr(node->token_pos(),
3284 *super_function, 3294 *super_function,
3285 Object::null_array(), 3295 Object::null_array(),
3286 arguments, 3296 arguments,
3287 owner()->ic_data_array()); 3297 owner()->ic_data_array());
3288 ReturnDefinition(load); 3298 ReturnDefinition(load);
3289 } else { 3299 } else {
3290 // Generate dynamic call to index operator. 3300 // Generate dynamic call to index operator.
3291 const intptr_t checked_argument_count = 1; 3301 const intptr_t checked_argument_count = 1;
3292 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), 3302 InstanceCallInstr* load = new(I) InstanceCallInstr(node->token_pos(),
3293 Symbols::IndexToken(), 3303 Symbols::IndexToken(),
3294 Token::kINDEX, 3304 Token::kINDEX,
3295 arguments, 3305 arguments,
3296 Object::null_array(), 3306 Object::null_array(),
3297 checked_argument_count, 3307 checked_argument_count,
3298 owner()->ic_data_array()); 3308 owner()->ic_data_array());
3299 ReturnDefinition(load); 3309 ReturnDefinition(load);
3300 } 3310 }
3301 } 3311 }
3302 3312
3303 3313
3304 Definition* EffectGraphVisitor::BuildStoreIndexedValues( 3314 Definition* EffectGraphVisitor::BuildStoreIndexedValues(
3305 StoreIndexedNode* node, 3315 StoreIndexedNode* node,
3306 bool result_is_needed) { 3316 bool result_is_needed) {
3307 Function* super_function = NULL; 3317 Function* super_function = NULL;
3308 if (node->IsSuperStore()) { 3318 if (node->IsSuperStore()) {
3309 // Resolve the store indexed operator in the super class. 3319 // Resolve the store indexed operator in the super class.
3310 super_function = &Function::ZoneHandle( 3320 super_function = &Function::ZoneHandle(
3311 I, Resolver::ResolveDynamicAnyArgs(node->super_class(), 3321 I, Resolver::ResolveDynamicAnyArgs(node->super_class(),
3312 Symbols::AssignIndexToken())); 3322 Symbols::AssignIndexToken()));
3313 if (super_function->IsNull()) { 3323 if (super_function->IsNull()) {
3314 // Could not resolve super operator. Generate call noSuchMethod() of the 3324 // Could not resolve super operator. Generate call noSuchMethod() of the
3315 // super class instead. 3325 // super class instead.
3316 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 3326 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
3317 arguments->Add(node->array()); 3327 arguments->Add(node->array());
3318 arguments->Add(node->index_expr()); 3328 arguments->Add(node->index_expr());
3319 arguments->Add(node->value()); 3329 arguments->Add(node->value());
3320 StaticCallInstr* call = BuildStaticNoSuchMethodCall( 3330 StaticCallInstr* call = BuildStaticNoSuchMethodCall(
3321 node->super_class(), 3331 node->super_class(),
3322 node->array(), 3332 node->array(),
3323 Symbols::AssignIndexToken(), 3333 Symbols::AssignIndexToken(),
3324 arguments, 3334 arguments,
3325 result_is_needed, // Save last arg if result is needed. 3335 result_is_needed, // Save last arg if result is needed.
3326 true); // Super invocation. 3336 true); // Super invocation.
3327 if (result_is_needed) { 3337 if (result_is_needed) {
3328 Do(call); 3338 Do(call);
3329 // BuildStaticNoSuchMethodCall stores the value in expression_temp. 3339 // BuildStaticNoSuchMethodCall stores the value in expression_temp.
3330 return BuildLoadExprTemp(); 3340 return BuildLoadExprTemp();
3331 } else { 3341 } else {
3332 return call; 3342 return call;
3333 } 3343 }
3334 } 3344 }
3335 } 3345 }
3336 3346
3337 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3347 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3338 new ZoneGrowableArray<PushArgumentInstr*>(3); 3348 new(I) ZoneGrowableArray<PushArgumentInstr*>(3);
3339 ValueGraphVisitor for_array(owner()); 3349 ValueGraphVisitor for_array(owner());
3340 node->array()->Visit(&for_array); 3350 node->array()->Visit(&for_array);
3341 Append(for_array); 3351 Append(for_array);
3342 arguments->Add(PushArgument(for_array.value())); 3352 arguments->Add(PushArgument(for_array.value()));
3343 3353
3344 ValueGraphVisitor for_index(owner()); 3354 ValueGraphVisitor for_index(owner());
3345 node->index_expr()->Visit(&for_index); 3355 node->index_expr()->Visit(&for_index);
3346 Append(for_index); 3356 Append(for_index);
3347 arguments->Add(PushArgument(for_index.value())); 3357 arguments->Add(PushArgument(for_index.value()));
3348 3358
3349 ValueGraphVisitor for_value(owner()); 3359 ValueGraphVisitor for_value(owner());
3350 node->value()->Visit(&for_value); 3360 node->value()->Visit(&for_value);
3351 Append(for_value); 3361 Append(for_value);
3352 Value* value = NULL; 3362 Value* value = NULL;
3353 if (result_is_needed) { 3363 if (result_is_needed) {
3354 value = Bind(BuildStoreExprTemp(for_value.value())); 3364 value = Bind(BuildStoreExprTemp(for_value.value()));
3355 } else { 3365 } else {
3356 value = for_value.value(); 3366 value = for_value.value();
3357 } 3367 }
3358 arguments->Add(PushArgument(value)); 3368 arguments->Add(PushArgument(value));
3359 3369
3360 if (super_function != NULL) { 3370 if (super_function != NULL) {
3361 // Generate static call to super operator []=. 3371 // Generate static call to super operator []=.
3362 3372
3363 StaticCallInstr* store = 3373 StaticCallInstr* store =
3364 new StaticCallInstr(node->token_pos(), 3374 new(I) StaticCallInstr(node->token_pos(),
3365 *super_function, 3375 *super_function,
3366 Object::null_array(), 3376 Object::null_array(),
3367 arguments, 3377 arguments,
3368 owner()->ic_data_array()); 3378 owner()->ic_data_array());
3369 if (result_is_needed) { 3379 if (result_is_needed) {
3370 Do(store); 3380 Do(store);
3371 return BuildLoadExprTemp(); 3381 return BuildLoadExprTemp();
3372 } else { 3382 } else {
3373 return store; 3383 return store;
3374 } 3384 }
3375 } else { 3385 } else {
3376 // Generate dynamic call to operator []=. 3386 // Generate dynamic call to operator []=.
3377 const intptr_t checked_argument_count = 3; 3387 const intptr_t checked_argument_count = 3;
3378 const String& name = 3388 const String& name =
3379 String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); 3389 String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
3380 InstanceCallInstr* store = 3390 InstanceCallInstr* store =
3381 new InstanceCallInstr(node->token_pos(), 3391 new(I) InstanceCallInstr(node->token_pos(),
3382 name, 3392 name,
3383 Token::kASSIGN_INDEX, 3393 Token::kASSIGN_INDEX,
3384 arguments, 3394 arguments,
3385 Object::null_array(), 3395 Object::null_array(),
3386 checked_argument_count, 3396 checked_argument_count,
3387 owner()->ic_data_array()); 3397 owner()->ic_data_array());
3388 if (result_is_needed) { 3398 if (result_is_needed) {
3389 Do(store); 3399 Do(store);
3390 return BuildLoadExprTemp(); 3400 return BuildLoadExprTemp();
3391 } else { 3401 } else {
(...skipping 14 matching lines...) Expand all
3406 3416
3407 3417
3408 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { 3418 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
3409 return (node == owner()->parsed_function()->node_sequence()) && 3419 return (node == owner()->parsed_function()->node_sequence()) &&
3410 (owner()->parsed_function()->saved_entry_context_var() != NULL); 3420 (owner()->parsed_function()->saved_entry_context_var() != NULL);
3411 } 3421 }
3412 3422
3413 3423
3414 void EffectGraphVisitor::UnchainContexts(intptr_t n) { 3424 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
3415 if (n > 0) { 3425 if (n > 0) {
3416 Value* context = Bind(new CurrentContextInstr()); 3426 Value* context = Bind(new(I) CurrentContextInstr());
3417 while (n-- > 0) { 3427 while (n-- > 0) {
3418 context = Bind( 3428 context = Bind(
3419 new LoadFieldInstr(context, 3429 new(I) LoadFieldInstr(context,
3420 Context::parent_offset(), 3430 Context::parent_offset(),
3421 // Not an instance, no type. 3431 // Not an instance, no type.
3422 Type::ZoneHandle(I, Type::null()), 3432 Type::ZoneHandle(I, Type::null()),
3423 Scanner::kNoSourcePos)); 3433 Scanner::kNoSourcePos));
3424 } 3434 }
3425 AddInstruction(new StoreContextInstr(context)); 3435 AddInstruction(new(I) StoreContextInstr(context));
3426 } 3436 }
3427 } 3437 }
3428 3438
3429 3439
3430 // <Statement> ::= Sequence { scope: LocalScope 3440 // <Statement> ::= Sequence { scope: LocalScope
3431 // nodes: <Statement>* 3441 // nodes: <Statement>*
3432 // label: SourceLabel } 3442 // label: SourceLabel }
3433 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { 3443 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
3434 LocalScope* scope = node->scope(); 3444 LocalScope* scope = node->scope();
3435 const intptr_t num_context_variables = 3445 const intptr_t num_context_variables =
3436 (scope != NULL) ? scope->num_context_variables() : 0; 3446 (scope != NULL) ? scope->num_context_variables() : 0;
3437 // The outermost function sequence cannot contain a label. 3447 // The outermost function sequence cannot contain a label.
3438 ASSERT((node->label() == NULL) || 3448 ASSERT((node->label() == NULL) ||
3439 (node != owner()->parsed_function()->node_sequence())); 3449 (node != owner()->parsed_function()->node_sequence()));
3440 NestedBlock nested_block(owner(), node); 3450 NestedBlock nested_block(owner(), node);
3441 3451
3442 if (num_context_variables > 0) { 3452 if (num_context_variables > 0) {
3443 // The loop local scope declares variables that are captured. 3453 // The loop local scope declares variables that are captured.
3444 // Allocate and chain a new context. 3454 // Allocate and chain a new context.
3445 // Allocate context computation (uses current CTX) 3455 // Allocate context computation (uses current CTX)
3446 Value* allocated_context = 3456 Value* allocated_context =
3447 Bind(new AllocateContextInstr(node->token_pos(), 3457 Bind(new(I) AllocateContextInstr(node->token_pos(),
3448 num_context_variables)); 3458 num_context_variables));
3449 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); 3459 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
3450 // If this node_sequence is the body of the function being compiled, and 3460 // If this node_sequence is the body of the function being compiled, and
3451 // if this function allocates context variables, but none of its enclosing 3461 // if this function allocates context variables, but none of its enclosing
3452 // functions do, the context on entry is not linked as parent of the 3462 // functions do, the context on entry is not linked as parent of the
3453 // allocated context but saved on entry and restored on exit as to prevent 3463 // allocated context but saved on entry and restored on exit as to prevent
3454 // memory leaks. 3464 // memory leaks.
3455 // In this case, the parser pre-allocates a variable to save the context. 3465 // In this case, the parser pre-allocates a variable to save the context.
3456 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); 3466 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var));
3457 Value* parent_context = NULL; 3467 Value* parent_context = NULL;
3458 if (MustSaveRestoreContext(node)) { 3468 if (MustSaveRestoreContext(node)) {
3459 BuildSaveContext( 3469 BuildSaveContext(
3460 *owner()->parsed_function()->saved_entry_context_var()); 3470 *owner()->parsed_function()->saved_entry_context_var());
3461 parent_context = Bind( 3471 parent_context = Bind(
3462 new ConstantInstr(Object::ZoneHandle(I, Object::null()))); 3472 new(I) ConstantInstr(Object::ZoneHandle(I, Object::null())));
3463 } else { 3473 } else {
3464 parent_context = Bind(new CurrentContextInstr()); 3474 parent_context = Bind(new(I) CurrentContextInstr());
3465 } 3475 }
3466 Do(new StoreInstanceFieldInstr(Context::parent_offset(), 3476 Do(new(I) StoreInstanceFieldInstr(Context::parent_offset(),
3467 tmp_val, 3477 tmp_val,
3468 parent_context, 3478 parent_context,
3469 kEmitStoreBarrier, 3479 kEmitStoreBarrier,
3470 Scanner::kNoSourcePos)); 3480 Scanner::kNoSourcePos));
3471 AddInstruction( 3481 AddInstruction(
3472 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var)))); 3482 new(I) StoreContextInstr(Bind(ExitTempLocalScope(tmp_var))));
3473 } 3483 }
3474 3484
3475 // If this node_sequence is the body of the function being compiled, copy 3485 // If this node_sequence is the body of the function being compiled, copy
3476 // the captured parameters from the frame into the context. 3486 // the captured parameters from the frame into the context.
3477 if (node == owner()->parsed_function()->node_sequence()) { 3487 if (node == owner()->parsed_function()->node_sequence()) {
3478 ASSERT(scope->context_level() == 1); 3488 ASSERT(scope->context_level() == 1);
3479 const Function& function = owner()->parsed_function()->function(); 3489 const Function& function = owner()->parsed_function()->function();
3480 const int num_params = function.NumParameters(); 3490 const int num_params = function.NumParameters();
3481 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 3491 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
3482 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; 3492 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp;
3483 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 3493 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
3484 const LocalVariable& parameter = *scope->VariableAt(pos); 3494 const LocalVariable& parameter = *scope->VariableAt(pos);
3485 ASSERT(parameter.owner() == scope); 3495 ASSERT(parameter.owner() == scope);
3486 if (parameter.is_captured()) { 3496 if (parameter.is_captured()) {
3487 // Create a temporary local describing the original position. 3497 // Create a temporary local describing the original position.
3488 const String& temp_name = Symbols::TempParam(); 3498 const String& temp_name = Symbols::TempParam();
3489 LocalVariable* temp_local = new LocalVariable( 3499 LocalVariable* temp_local = new(I) LocalVariable(
3490 0, // Token index. 3500 0, // Token index.
3491 temp_name, 3501 temp_name,
3492 Type::ZoneHandle(I, Type::DynamicType())); // Type. 3502 Type::ZoneHandle(I, Type::DynamicType())); // Type.
3493 temp_local->set_index(param_frame_index); 3503 temp_local->set_index(param_frame_index);
3494 3504
3495 // Copy parameter from local frame to current context. 3505 // Copy parameter from local frame to current context.
3496 Value* load = Bind(BuildLoadLocal(*temp_local)); 3506 Value* load = Bind(BuildLoadLocal(*temp_local));
3497 Do(BuildStoreLocal(parameter, load)); 3507 Do(BuildStoreLocal(parameter, load));
3498 // Write NULL to the source location to detect buggy accesses and 3508 // Write NULL to the source location to detect buggy accesses and
3499 // allow GC of passed value if it gets overwritten by a new value in 3509 // allow GC of passed value if it gets overwritten by a new value in
3500 // the function. 3510 // the function.
3501 Value* null_constant = Bind(new ConstantInstr( 3511 Value* null_constant = Bind(new(I) ConstantInstr(
3502 Object::ZoneHandle(I, Object::null()))); 3512 Object::ZoneHandle(I, Object::null())));
3503 Do(BuildStoreLocal(*temp_local, null_constant)); 3513 Do(BuildStoreLocal(*temp_local, null_constant));
3504 } 3514 }
3505 } 3515 }
3506 } 3516 }
3507 } else if (MustSaveRestoreContext(node)) { 3517 } else if (MustSaveRestoreContext(node)) {
3508 // Even when the current scope has no context variables, we may 3518 // Even when the current scope has no context variables, we may
3509 // still need to save the current context if, for example, there 3519 // still need to save the current context if, for example, there
3510 // are loop scopes below this which will allocate a context 3520 // are loop scopes below this which will allocate a context
3511 // object. 3521 // object.
3512 BuildSaveContext( 3522 BuildSaveContext(
3513 *owner()->parsed_function()->saved_entry_context_var()); 3523 *owner()->parsed_function()->saved_entry_context_var());
3514 AddInstruction( 3524 AddInstruction(
3515 new StoreContextInstr(Bind(new ConstantInstr(Object::ZoneHandle( 3525 new(I) StoreContextInstr(Bind(new(I) ConstantInstr(Object::ZoneHandle(
3516 I, I->object_store()->empty_context()))))); 3526 I, I->object_store()->empty_context())))));
3517 } 3527 }
3518 3528
3519 // This check may be deleted if the generated code is leaf. 3529 // This check may be deleted if the generated code is leaf.
3520 // Native functions don't need a stack check at entry. 3530 // Native functions don't need a stack check at entry.
3521 const Function& function = owner()->parsed_function()->function(); 3531 const Function& function = owner()->parsed_function()->function();
3522 if ((node == owner()->parsed_function()->node_sequence()) && 3532 if ((node == owner()->parsed_function()->node_sequence()) &&
3523 !function.is_native()) { 3533 !function.is_native()) {
3524 // Always allocate CheckOverflowInstr so that deopt-ids match regardless 3534 // Always allocate CheckOverflowInstr so that deopt-ids match regardless
3525 // if we inline or not. 3535 // if we inline or not.
3526 if (!function.IsImplicitGetterFunction() && 3536 if (!function.IsImplicitGetterFunction() &&
3527 !function.IsImplicitSetterFunction()) { 3537 !function.IsImplicitSetterFunction()) {
3528 CheckStackOverflowInstr* check = 3538 CheckStackOverflowInstr* check =
3529 new CheckStackOverflowInstr(function.token_pos(), 0); 3539 new(I) CheckStackOverflowInstr(function.token_pos(), 0);
3530 // If we are inlining don't actually attach the stack check. We must still 3540 // If we are inlining don't actually attach the stack check. We must still
3531 // create the stack check in order to allocate a deopt id. 3541 // create the stack check in order to allocate a deopt id.
3532 if (!owner()->IsInlining()) { 3542 if (!owner()->IsInlining()) {
3533 AddInstruction(check); 3543 AddInstruction(check);
3534 } 3544 }
3535 } 3545 }
3536 } 3546 }
3537 3547
3538 if (FLAG_enable_type_checks && 3548 if (FLAG_enable_type_checks &&
3539 (node == owner()->parsed_function()->node_sequence())) { 3549 (node == owner()->parsed_function()->node_sequence())) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3619 owner()->set_try_index(try_handler_index); 3629 owner()->set_try_index(try_handler_index);
3620 3630
3621 // Preserve CTX into local variable '%saved_context'. 3631 // Preserve CTX into local variable '%saved_context'.
3622 BuildSaveContext(node->context_var()); 3632 BuildSaveContext(node->context_var());
3623 3633
3624 EffectGraphVisitor for_try(owner()); 3634 EffectGraphVisitor for_try(owner());
3625 node->try_block()->Visit(&for_try); 3635 node->try_block()->Visit(&for_try);
3626 3636
3627 if (for_try.is_open()) { 3637 if (for_try.is_open()) {
3628 JoinEntryInstr* after_try = 3638 JoinEntryInstr* after_try =
3629 new JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); 3639 new(I) JoinEntryInstr(owner()->AllocateBlockId(),
3640 original_handler_index);
3630 for_try.Goto(after_try); 3641 for_try.Goto(after_try);
3631 for_try.exit_ = after_try; 3642 for_try.exit_ = after_try;
3632 } 3643 }
3633 3644
3634 JoinEntryInstr* try_entry = 3645 JoinEntryInstr* try_entry =
3635 new JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index); 3646 new(I) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
3636 3647
3637 Goto(try_entry); 3648 Goto(try_entry);
3638 AppendFragment(try_entry, for_try); 3649 AppendFragment(try_entry, for_try);
3639 exit_ = for_try.exit_; 3650 exit_ = for_try.exit_;
3640 3651
3641 // We are done generating code for the try block. 3652 // We are done generating code for the try block.
3642 owner()->set_try_index(original_handler_index); 3653 owner()->set_try_index(original_handler_index);
3643 3654
3644 CatchClauseNode* catch_block = node->catch_block(); 3655 CatchClauseNode* catch_block = node->catch_block();
3645 SequenceNode* finally_block = node->finally_block(); 3656 SequenceNode* finally_block = node->finally_block();
(...skipping 11 matching lines...) Expand all
3657 EffectGraphVisitor for_catch(owner()); 3668 EffectGraphVisitor for_catch(owner());
3658 catch_block->Visit(&for_catch); 3669 catch_block->Visit(&for_catch);
3659 owner()->set_catch_try_index(prev_catch_try_index); 3670 owner()->set_catch_try_index(prev_catch_try_index);
3660 3671
3661 // NOTE: The implicit variables ':saved_context', ':exception_var' 3672 // NOTE: The implicit variables ':saved_context', ':exception_var'
3662 // and ':stacktrace_var' can never be captured variables. 3673 // and ':stacktrace_var' can never be captured variables.
3663 ASSERT(!catch_block->exception_var().is_captured()); 3674 ASSERT(!catch_block->exception_var().is_captured());
3664 ASSERT(!catch_block->stacktrace_var().is_captured()); 3675 ASSERT(!catch_block->stacktrace_var().is_captured());
3665 3676
3666 CatchBlockEntryInstr* catch_entry = 3677 CatchBlockEntryInstr* catch_entry =
3667 new CatchBlockEntryInstr(owner()->AllocateBlockId(), 3678 new(I) CatchBlockEntryInstr(owner()->AllocateBlockId(),
3668 catch_handler_index, 3679 catch_handler_index,
3669 catch_block->handler_types(), 3680 catch_block->handler_types(),
3670 try_handler_index, 3681 try_handler_index,
3671 catch_block->exception_var(), 3682 catch_block->exception_var(),
3672 catch_block->stacktrace_var(), 3683 catch_block->stacktrace_var(),
3673 catch_block->needs_stacktrace()); 3684 catch_block->needs_stacktrace());
3674 owner()->AddCatchEntry(catch_entry); 3685 owner()->AddCatchEntry(catch_entry);
3675 AppendFragment(catch_entry, for_catch); 3686 AppendFragment(catch_entry, for_catch);
3676 3687
3677 if (for_catch.is_open()) { 3688 if (for_catch.is_open()) {
3678 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), 3689 JoinEntryInstr* join = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
3679 original_handler_index); 3690 original_handler_index);
3680 for_catch.Goto(join); 3691 for_catch.Goto(join);
3681 if (is_open()) Goto(join); 3692 if (is_open()) Goto(join);
3682 exit_ = join; 3693 exit_ = join;
3683 } 3694 }
3684 3695
3685 if (finally_block != NULL) { 3696 if (finally_block != NULL) {
3686 // Create a handler for the code in the catch block, containing the 3697 // Create a handler for the code in the catch block, containing the
3687 // code in the finally block. 3698 // code in the finally block.
3688 owner()->set_try_index(original_handler_index); 3699 owner()->set_try_index(original_handler_index);
3689 EffectGraphVisitor for_finally(owner()); 3700 EffectGraphVisitor for_finally(owner());
3690 for_finally.BuildRestoreContext(catch_block->context_var()); 3701 for_finally.BuildRestoreContext(catch_block->context_var());
3691 3702
3692 finally_block->Visit(&for_finally); 3703 finally_block->Visit(&for_finally);
3693 if (for_finally.is_open()) { 3704 if (for_finally.is_open()) {
3694 // Rethrow the exception. Manually build the graph for rethrow. 3705 // Rethrow the exception. Manually build the graph for rethrow.
3695 Value* exception = for_finally.Bind( 3706 Value* exception = for_finally.Bind(
3696 for_finally.BuildLoadLocal(catch_block->exception_var())); 3707 for_finally.BuildLoadLocal(catch_block->exception_var()));
3697 for_finally.PushArgument(exception); 3708 for_finally.PushArgument(exception);
3698 Value* stacktrace = for_finally.Bind( 3709 Value* stacktrace = for_finally.Bind(
3699 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); 3710 for_finally.BuildLoadLocal(catch_block->stacktrace_var()));
3700 for_finally.PushArgument(stacktrace); 3711 for_finally.PushArgument(stacktrace);
3701 for_finally.AddInstruction( 3712 for_finally.AddInstruction(
3702 new ReThrowInstr(catch_block->token_pos(), catch_handler_index)); 3713 new(I) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
3703 for_finally.CloseFragment(); 3714 for_finally.CloseFragment();
3704 } 3715 }
3705 ASSERT(!for_finally.is_open()); 3716 ASSERT(!for_finally.is_open());
3706 3717
3707 const Array& types = Array::ZoneHandle(I, Array::New(1, Heap::kOld)); 3718 const Array& types = Array::ZoneHandle(I, Array::New(1, Heap::kOld));
3708 types.SetAt(0, Type::Handle(I, Type::DynamicType())); 3719 types.SetAt(0, Type::Handle(I, Type::DynamicType()));
3709 CatchBlockEntryInstr* finally_entry = 3720 CatchBlockEntryInstr* finally_entry =
3710 new CatchBlockEntryInstr(owner()->AllocateBlockId(), 3721 new(I) CatchBlockEntryInstr(owner()->AllocateBlockId(),
3711 original_handler_index, 3722 original_handler_index,
3712 types, 3723 types,
3713 catch_handler_index, 3724 catch_handler_index,
3714 catch_block->exception_var(), 3725 catch_block->exception_var(),
3715 catch_block->stacktrace_var(), 3726 catch_block->stacktrace_var(),
3716 catch_block->needs_stacktrace()); 3727 catch_block->needs_stacktrace());
3717 owner()->AddCatchEntry(finally_entry); 3728 owner()->AddCatchEntry(finally_entry);
3718 AppendFragment(finally_entry, for_finally); 3729 AppendFragment(finally_entry, for_finally);
3719 } 3730 }
3720 3731
(...skipping 25 matching lines...) Expand all
3746 method_name, 3757 method_name,
3747 *method_arguments, 3758 *method_arguments,
3748 temp, 3759 temp,
3749 is_super_invocation); 3760 is_super_invocation);
3750 const Function& no_such_method_func = Function::ZoneHandle( 3761 const Function& no_such_method_func = Function::ZoneHandle(
3751 I, 3762 I,
3752 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); 3763 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod()));
3753 // We are guaranteed to find noSuchMethod of class Object. 3764 // We are guaranteed to find noSuchMethod of class Object.
3754 ASSERT(!no_such_method_func.IsNull()); 3765 ASSERT(!no_such_method_func.IsNull());
3755 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = 3766 ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
3756 new ZoneGrowableArray<PushArgumentInstr*>(2); 3767 new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
3757 BuildPushArguments(*args, push_arguments); 3768 BuildPushArguments(*args, push_arguments);
3758 return new StaticCallInstr(args_pos, 3769 return new(I) StaticCallInstr(args_pos,
3759 no_such_method_func, 3770 no_such_method_func,
3760 Object::null_array(), 3771 Object::null_array(),
3761 push_arguments, 3772 push_arguments,
3762 owner()->ic_data_array()); 3773 owner()->ic_data_array());
3763 } 3774 }
3764 3775
3765 3776
3766 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( 3777 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
3767 intptr_t token_pos, 3778 intptr_t token_pos,
3768 const Class& function_class, 3779 const Class& function_class,
3769 const String& function_name, 3780 const String& function_name,
3770 ArgumentListNode* function_arguments, 3781 ArgumentListNode* function_arguments,
3771 int invocation_type) { 3782 int invocation_type) {
3772 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3783 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3773 new ZoneGrowableArray<PushArgumentInstr*>(); 3784 new(I) ZoneGrowableArray<PushArgumentInstr*>();
3774 // Object receiver, actually a class literal of the unresolved method's owner. 3785 // Object receiver, actually a class literal of the unresolved method's owner.
3775 Type& type = Type::ZoneHandle( 3786 Type& type = Type::ZoneHandle(
3776 I, 3787 I,
3777 Type::New(function_class, 3788 Type::New(function_class,
3778 TypeArguments::Handle(I, TypeArguments::null()), 3789 TypeArguments::Handle(I, TypeArguments::null()),
3779 token_pos, 3790 token_pos,
3780 Heap::kOld)); 3791 Heap::kOld));
3781 type ^= ClassFinalizer::FinalizeType( 3792 type ^= ClassFinalizer::FinalizeType(
3782 function_class, type, ClassFinalizer::kCanonicalize); 3793 function_class, type, ClassFinalizer::kCanonicalize);
3783 Value* receiver_value = Bind(new ConstantInstr(type)); 3794 Value* receiver_value = Bind(new(I) ConstantInstr(type));
3784 arguments->Add(PushArgument(receiver_value)); 3795 arguments->Add(PushArgument(receiver_value));
3785 // String memberName. 3796 // String memberName.
3786 const String& member_name = 3797 const String& member_name =
3787 String::ZoneHandle(I, Symbols::New(function_name)); 3798 String::ZoneHandle(I, Symbols::New(function_name));
3788 Value* member_name_value = Bind(new ConstantInstr(member_name)); 3799 Value* member_name_value = Bind(new(I) ConstantInstr(member_name));
3789 arguments->Add(PushArgument(member_name_value)); 3800 arguments->Add(PushArgument(member_name_value));
3790 // Smi invocation_type. 3801 // Smi invocation_type.
3791 Value* invocation_type_value = Bind(new ConstantInstr( 3802 Value* invocation_type_value = Bind(new(I) ConstantInstr(
3792 Smi::ZoneHandle(I, Smi::New(invocation_type)))); 3803 Smi::ZoneHandle(I, Smi::New(invocation_type))));
3793 arguments->Add(PushArgument(invocation_type_value)); 3804 arguments->Add(PushArgument(invocation_type_value));
3794 // List arguments. 3805 // List arguments.
3795 if (function_arguments == NULL) { 3806 if (function_arguments == NULL) {
3796 Value* arguments_value = Bind( 3807 Value* arguments_value = Bind(
3797 new ConstantInstr(Array::ZoneHandle(I, Array::null()))); 3808 new(I) ConstantInstr(Array::ZoneHandle(I, Array::null())));
3798 arguments->Add(PushArgument(arguments_value)); 3809 arguments->Add(PushArgument(arguments_value));
3799 } else { 3810 } else {
3800 ValueGraphVisitor array_val(owner()); 3811 ValueGraphVisitor array_val(owner());
3801 ArrayNode* array = 3812 ArrayNode* array =
3802 new ArrayNode(token_pos, Type::ZoneHandle(I, Type::ArrayType()), 3813 new(I) ArrayNode(token_pos, Type::ZoneHandle(I, Type::ArrayType()),
3803 function_arguments->nodes()); 3814 function_arguments->nodes());
3804 array->Visit(&array_val); 3815 array->Visit(&array_val);
3805 Append(array_val); 3816 Append(array_val);
3806 arguments->Add(PushArgument(array_val.value())); 3817 arguments->Add(PushArgument(array_val.value()));
3807 } 3818 }
3808 // List argumentNames. 3819 // List argumentNames.
3809 ConstantInstr* cinstr = new ConstantInstr( 3820 ConstantInstr* cinstr = new(I) ConstantInstr(
3810 (function_arguments == NULL) ? Array::ZoneHandle(I, Array::null()) 3821 (function_arguments == NULL) ? Array::ZoneHandle(I, Array::null())
3811 : function_arguments->names()); 3822 : function_arguments->names());
3812 Value* argument_names_value = Bind(cinstr); 3823 Value* argument_names_value = Bind(cinstr);
3813 arguments->Add(PushArgument(argument_names_value)); 3824 arguments->Add(PushArgument(argument_names_value));
3814 3825
3815 // List existingArgumentNames. 3826 // List existingArgumentNames.
3816 Value* existing_argument_names_value = 3827 Value* existing_argument_names_value =
3817 Bind(new ConstantInstr(Array::ZoneHandle(I, Array::null()))); 3828 Bind(new(I) ConstantInstr(Array::ZoneHandle(I, Array::null())));
3818 arguments->Add(PushArgument(existing_argument_names_value)); 3829 arguments->Add(PushArgument(existing_argument_names_value));
3819 // Resolve and call NoSuchMethodError._throwNew. 3830 // Resolve and call NoSuchMethodError._throwNew.
3820 const Library& core_lib = Library::Handle(I, Library::CoreLibrary()); 3831 const Library& core_lib = Library::Handle(I, Library::CoreLibrary());
3821 const Class& cls = Class::Handle( 3832 const Class& cls = Class::Handle(
3822 I, core_lib.LookupClass(Symbols::NoSuchMethodError())); 3833 I, core_lib.LookupClass(Symbols::NoSuchMethodError()));
3823 ASSERT(!cls.IsNull()); 3834 ASSERT(!cls.IsNull());
3824 const Function& func = Function::ZoneHandle( 3835 const Function& func = Function::ZoneHandle(
3825 I, 3836 I,
3826 Resolver::ResolveStatic(cls, 3837 Resolver::ResolveStatic(cls,
3827 Library::PrivateCoreLibName(Symbols::ThrowNew()), 3838 Library::PrivateCoreLibName(Symbols::ThrowNew()),
3828 arguments->length(), 3839 arguments->length(),
3829 Object::null_array())); 3840 Object::null_array()));
3830 ASSERT(!func.IsNull()); 3841 ASSERT(!func.IsNull());
3831 return new StaticCallInstr(token_pos, 3842 return new(I) StaticCallInstr(token_pos,
3832 func, 3843 func,
3833 Object::null_array(), // No names. 3844 Object::null_array(), // No names.
3834 arguments, 3845 arguments,
3835 owner()->ic_data_array()); 3846 owner()->ic_data_array());
3836 } 3847 }
3837 3848
3838 3849
3839 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 3850 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
3840 ValueGraphVisitor for_exception(owner()); 3851 ValueGraphVisitor for_exception(owner());
3841 node->exception()->Visit(&for_exception); 3852 node->exception()->Visit(&for_exception);
3842 Append(for_exception); 3853 Append(for_exception);
3843 PushArgument(for_exception.value()); 3854 PushArgument(for_exception.value());
3844 Instruction* instr = NULL; 3855 Instruction* instr = NULL;
3845 if (node->stacktrace() == NULL) { 3856 if (node->stacktrace() == NULL) {
3846 instr = new ThrowInstr(node->token_pos()); 3857 instr = new(I) ThrowInstr(node->token_pos());
3847 } else { 3858 } else {
3848 ValueGraphVisitor for_stack_trace(owner()); 3859 ValueGraphVisitor for_stack_trace(owner());
3849 node->stacktrace()->Visit(&for_stack_trace); 3860 node->stacktrace()->Visit(&for_stack_trace);
3850 Append(for_stack_trace); 3861 Append(for_stack_trace);
3851 PushArgument(for_stack_trace.value()); 3862 PushArgument(for_stack_trace.value());
3852 instr = new ReThrowInstr(node->token_pos(), owner()->catch_try_index()); 3863 instr = new(I) ReThrowInstr(node->token_pos(), owner()->catch_try_index());
3853 } 3864 }
3854 AddInstruction(instr); 3865 AddInstruction(instr);
3855 } 3866 }
3856 3867
3857 3868
3858 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 3869 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
3859 BuildThrowNode(node); 3870 BuildThrowNode(node);
3860 CloseFragment(); 3871 CloseFragment();
3861 } 3872 }
3862 3873
3863 3874
3864 // A throw cannot be part of an expression, however, the parser may replace 3875 // A throw cannot be part of an expression, however, the parser may replace
3865 // certain expression nodes with a throw. In that case generate a literal null 3876 // certain expression nodes with a throw. In that case generate a literal null
3866 // so that the fragment is not closed in the middle of an expression. 3877 // so that the fragment is not closed in the middle of an expression.
3867 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { 3878 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
3868 BuildThrowNode(node); 3879 BuildThrowNode(node);
3869 ReturnDefinition(new ConstantInstr( 3880 ReturnDefinition(new(I) ConstantInstr(
3870 Instance::ZoneHandle(I, Instance::null()))); 3881 Instance::ZoneHandle(I, Instance::null())));
3871 } 3882 }
3872 3883
3873 3884
3874 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 3885 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
3875 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); 3886 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)");
3876 const intptr_t try_index = owner()->try_index(); 3887 const intptr_t try_index = owner()->try_index();
3877 if (try_index >= 0) { 3888 if (try_index >= 0) {
3878 // We are about to generate code for an inlined finally block. Exceptions 3889 // We are about to generate code for an inlined finally block. Exceptions
3879 // thrown in this block of code should be treated as though they are 3890 // thrown in this block of code should be treated as though they are
3880 // thrown not from the current try block but the outer try block if any. 3891 // thrown not from the current try block but the outer try block if any.
3881 intptr_t outer_try_index = node->try_index(); 3892 intptr_t outer_try_index = node->try_index();
3882 owner()->set_try_index(outer_try_index); 3893 owner()->set_try_index(outer_try_index);
3883 } 3894 }
3884 BuildRestoreContext(node->context_var()); 3895 BuildRestoreContext(node->context_var());
3885 3896
3886 JoinEntryInstr* finally_entry = 3897 JoinEntryInstr* finally_entry =
3887 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 3898 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
3888 EffectGraphVisitor for_finally_block(owner()); 3899 EffectGraphVisitor for_finally_block(owner());
3889 node->finally_block()->Visit(&for_finally_block); 3900 node->finally_block()->Visit(&for_finally_block);
3890 3901
3891 if (try_index >= 0) { 3902 if (try_index >= 0) {
3892 owner()->set_try_index(try_index); 3903 owner()->set_try_index(try_index);
3893 } 3904 }
3894 3905
3895 if (for_finally_block.is_open()) { 3906 if (for_finally_block.is_open()) {
3896 JoinEntryInstr* after_finally = 3907 JoinEntryInstr* after_finally =
3897 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 3908 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
3898 for_finally_block.Goto(after_finally); 3909 for_finally_block.Goto(after_finally);
3899 for_finally_block.exit_ = after_finally; 3910 for_finally_block.exit_ = after_finally;
3900 } 3911 }
3901 3912
3902 Goto(finally_entry); 3913 Goto(finally_entry);
3903 AppendFragment(finally_entry, for_finally_block); 3914 AppendFragment(finally_entry, for_finally_block);
3904 exit_ = for_finally_block.exit_; 3915 exit_ = for_finally_block.exit_;
3905 } 3916 }
3906 3917
3907 3918
3908 FlowGraph* FlowGraphBuilder::BuildGraph() { 3919 FlowGraph* FlowGraphBuilder::BuildGraph() {
3909 if (FLAG_print_ast) { 3920 if (FLAG_print_ast) {
3910 // Print the function ast before IL generation. 3921 // Print the function ast before IL generation.
3911 AstPrinter::PrintFunctionNodes(*parsed_function()); 3922 AstPrinter::PrintFunctionNodes(*parsed_function());
3912 } 3923 }
3913 if (FLAG_print_scopes) { 3924 if (FLAG_print_scopes) {
3914 AstPrinter::PrintFunctionScope(*parsed_function()); 3925 AstPrinter::PrintFunctionScope(*parsed_function());
3915 } 3926 }
3916 TargetEntryInstr* normal_entry = 3927 TargetEntryInstr* normal_entry =
3917 new TargetEntryInstr(AllocateBlockId(), 3928 new(I) TargetEntryInstr(AllocateBlockId(),
3918 CatchClauseNode::kInvalidTryIndex); 3929 CatchClauseNode::kInvalidTryIndex);
3919 graph_entry_ = new GraphEntryInstr(parsed_function(), normal_entry, osr_id_); 3930 graph_entry_ =
3931 new(I) GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
3920 EffectGraphVisitor for_effect(this); 3932 EffectGraphVisitor for_effect(this);
3921 parsed_function()->node_sequence()->Visit(&for_effect); 3933 parsed_function()->node_sequence()->Visit(&for_effect);
3922 AppendFragment(normal_entry, for_effect); 3934 AppendFragment(normal_entry, for_effect);
3923 // Check that the graph is properly terminated. 3935 // Check that the graph is properly terminated.
3924 ASSERT(!for_effect.is_open()); 3936 ASSERT(!for_effect.is_open());
3925 3937
3926 // When compiling for OSR, use a depth first search to prune instructions 3938 // When compiling for OSR, use a depth first search to prune instructions
3927 // unreachable from the OSR entry. Catch entries are always considered 3939 // unreachable from the OSR entry. Catch entries are always considered
3928 // reachable, even if they become unreachable after OSR. 3940 // reachable, even if they become unreachable after OSR.
3929 if (osr_id_ != Isolate::kNoDeoptId) { 3941 if (osr_id_ != Isolate::kNoDeoptId) {
3930 PruneUnreachable(); 3942 PruneUnreachable();
3931 } 3943 }
3932 3944
3933 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_); 3945 FlowGraph* graph = new(I) FlowGraph(*this, graph_entry_, last_used_block_id_);
3934 return graph; 3946 return graph;
3935 } 3947 }
3936 3948
3937 3949
3938 void FlowGraphBuilder::PruneUnreachable() { 3950 void FlowGraphBuilder::PruneUnreachable() {
3939 ASSERT(osr_id_ != Isolate::kNoDeoptId); 3951 ASSERT(osr_id_ != Isolate::kNoDeoptId);
3940 BitVector* block_marks = new BitVector(last_used_block_id_ + 1); 3952 BitVector* block_marks = new(I) BitVector(last_used_block_id_ + 1);
3941 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_, 3953 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_,
3942 block_marks); 3954 block_marks);
3943 ASSERT(found); 3955 ASSERT(found);
3944 } 3956 }
3945 3957
3946 3958
3947 void FlowGraphBuilder::Bailout(const char* reason) const { 3959 void FlowGraphBuilder::Bailout(const char* reason) const {
3948 const Function& function = parsed_function_->function(); 3960 const Function& function = parsed_function_->function();
3949 Report::MessageF(Report::kBailout, 3961 Report::MessageF(Report::kBailout,
3950 Script::Handle(function.script()), 3962 Script::Handle(function.script()),
3951 function.token_pos(), 3963 function.token_pos(),
3952 "FlowGraphBuilder Bailout: %s %s", 3964 "FlowGraphBuilder Bailout: %s %s",
3953 String::Handle(function.name()).ToCString(), 3965 String::Handle(function.name()).ToCString(),
3954 reason); 3966 reason);
3955 UNREACHABLE(); 3967 UNREACHABLE();
3956 } 3968 }
3957 3969
3958 } // namespace dart 3970 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698