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

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

Issue 982873004: Thread/Isolate refactoring: new(Isolate) -> new(Zone) (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | 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 25 matching lines...) Expand all
36 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); 36 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
37 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); 37 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
38 DEFINE_FLAG(bool, trace_type_check_elimination, false, 38 DEFINE_FLAG(bool, trace_type_check_elimination, false,
39 "Trace type check elimination at compile time."); 39 "Trace type check elimination at compile time.");
40 40
41 DECLARE_FLAG(bool, enable_asserts); 41 DECLARE_FLAG(bool, enable_asserts);
42 DECLARE_FLAG(bool, enable_type_checks); 42 DECLARE_FLAG(bool, enable_type_checks);
43 DECLARE_FLAG(int, optimization_counter_threshold); 43 DECLARE_FLAG(int, optimization_counter_threshold);
44 DECLARE_FLAG(bool, warn_on_javascript_compatibility); 44 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
45 45
46 // Quick access to the locally defined isolate() method. 46 // Quick access to the locally defined zone() method.
47 #define I (isolate()) 47 #define Z (zone())
48 48
49 // TODO(srdjan): Allow compiler to add constants as they are encountered in 49 // TODO(srdjan): Allow compiler to add constants as they are encountered in
50 // the compilation. 50 // the compilation.
51 const double kCommonDoubleConstants[] = 51 const double kCommonDoubleConstants[] =
52 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, 52 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0,
53 10.0, 20.0, 30.0, 64.0, 255.0, NAN, 53 10.0, 20.0, 30.0, 64.0, 255.0, NAN,
54 // From dart:math 54 // From dart:math
55 2.718281828459045, 2.302585092994046, 0.6931471805599453, 55 2.718281828459045, 2.302585092994046, 0.6931471805599453,
56 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, 56 1.4426950408889634, 0.4342944819032518, 3.1415926535897932,
57 0.7071067811865476, 1.4142135623730951}; 57 0.7071067811865476, 1.4142135623730951};
(...skipping 60 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(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(), 128 new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(),
129 owner()->try_index()); 129 owner()->try_index());
130 } 130 }
131 return break_target_; 131 return break_target_;
132 } 132 }
133 133
134 134
135 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) { 135 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) {
136 return NULL; 136 return NULL;
137 } 137 }
138 138
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 176
177 private: 177 private:
178 JoinEntryInstr* continue_target_; 178 JoinEntryInstr* continue_target_;
179 }; 179 };
180 180
181 181
182 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) { 182 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) {
183 if (label != this->label()) return NULL; 183 if (label != this->label()) return NULL;
184 if (continue_target_ == NULL) { 184 if (continue_target_ == NULL) {
185 continue_target_ = 185 continue_target_ =
186 new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(), 186 new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(),
187 try_index()); 187 try_index());
188 } 188 }
189 return continue_target_; 189 return continue_target_;
190 } 190 }
191 191
192 192
193 // 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
194 // cases can be the targets of continues. 194 // cases can be the targets of continues.
195 class NestedSwitch : public NestedStatement { 195 class NestedSwitch : public NestedStatement {
196 public: 196 public:
(...skipping 23 matching lines...) Expand all
220 220
221 221
222 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) { 222 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) {
223 // 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
224 // 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
225 // the graph anyway. 225 // the graph anyway.
226 for (intptr_t i = 0; i < case_labels_.length(); ++i) { 226 for (intptr_t i = 0; i < case_labels_.length(); ++i) {
227 if (label != case_labels_[i]) continue; 227 if (label != case_labels_[i]) continue;
228 if (case_targets_[i] == NULL) { 228 if (case_targets_[i] == NULL) {
229 case_targets_[i] = 229 case_targets_[i] =
230 new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(), 230 new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(),
231 try_index()); 231 try_index());
232 } 232 }
233 return case_targets_[i]; 233 return case_targets_[i];
234 } 234 }
235 return NULL; 235 return NULL;
236 } 236 }
237 237
238 238
239 FlowGraphBuilder::FlowGraphBuilder( 239 FlowGraphBuilder::FlowGraphBuilder(
240 const ParsedFunction& parsed_function, 240 const ParsedFunction& parsed_function,
(...skipping 12 matching lines...) Expand all
253 last_used_block_id_(0), // 0 is used for the graph entry. 253 last_used_block_id_(0), // 0 is used for the graph entry.
254 try_index_(CatchClauseNode::kInvalidTryIndex), 254 try_index_(CatchClauseNode::kInvalidTryIndex),
255 catch_try_index_(CatchClauseNode::kInvalidTryIndex), 255 catch_try_index_(CatchClauseNode::kInvalidTryIndex),
256 loop_depth_(0), 256 loop_depth_(0),
257 graph_entry_(NULL), 257 graph_entry_(NULL),
258 temp_count_(0), 258 temp_count_(0),
259 args_pushed_(0), 259 args_pushed_(0),
260 nesting_stack_(NULL), 260 nesting_stack_(NULL),
261 osr_id_(osr_id), 261 osr_id_(osr_id),
262 jump_count_(0), 262 jump_count_(0),
263 await_joins_(new(I) ZoneGrowableArray<JoinEntryInstr*>()), 263 await_joins_(new(Z) ZoneGrowableArray<JoinEntryInstr*>()),
264 await_levels_(new(I) ZoneGrowableArray<intptr_t>()) { } 264 await_levels_(new(Z) ZoneGrowableArray<intptr_t>()) { }
265 265
266 266
267 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { 267 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) {
268 graph_entry_->AddCatchEntry(entry); 268 graph_entry_->AddCatchEntry(entry);
269 } 269 }
270 270
271 271
272 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { 272 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) {
273 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); 273 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
274 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); 274 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id());
(...skipping 12 matching lines...) Expand all
287 / static_cast<double>(caller_graph_->graph_entry()->entry_count()); 287 / static_cast<double>(caller_graph_->graph_entry()->entry_count());
288 for (BlockIterator block_it = callee_graph->postorder_iterator(); 288 for (BlockIterator block_it = callee_graph->postorder_iterator();
289 !block_it.Done(); 289 !block_it.Done();
290 block_it.Advance()) { 290 block_it.Advance()) {
291 BlockEntryInstr* block = block_it.Current(); 291 BlockEntryInstr* block = block_it.Current();
292 if (block->IsTargetEntry()) { 292 if (block->IsTargetEntry()) {
293 block->AsTargetEntry()->adjust_edge_weight(scale_factor); 293 block->AsTargetEntry()->adjust_edge_weight(scale_factor);
294 } 294 }
295 Instruction* instr = block; 295 Instruction* instr = block;
296 if (block->env() != NULL) { 296 if (block->env() != NULL) {
297 call_->env()->DeepCopyToOuter(callee_graph->isolate(), block); 297 call_->env()->DeepCopyToOuter(callee_graph->zone(), block);
298 } 298 }
299 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 299 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
300 instr = it.Current(); 300 instr = it.Current();
301 // TODO(zerny): Avoid creating unnecessary environments. Note that some 301 // TODO(zerny): Avoid creating unnecessary environments. Note that some
302 // optimizations need deoptimization info for non-deoptable instructions, 302 // optimizations need deoptimization info for non-deoptable instructions,
303 // eg, LICM on GOTOs. 303 // eg, LICM on GOTOs.
304 if (instr->env() != NULL) { 304 if (instr->env() != NULL) {
305 call_->env()->DeepCopyToOuter(callee_graph->isolate(), instr); 305 call_->env()->DeepCopyToOuter(callee_graph->zone(), instr);
306 } 306 }
307 } 307 }
308 if (instr->IsGoto()) { 308 if (instr->IsGoto()) {
309 instr->AsGoto()->adjust_edge_weight(scale_factor); 309 instr->AsGoto()->adjust_edge_weight(scale_factor);
310 } 310 }
311 } 311 }
312 } 312 }
313 313
314 314
315 void InlineExitCollector::AddExit(ReturnInstr* exit) { 315 void InlineExitCollector::AddExit(ReturnInstr* exit) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 ReturnAt(0)->UnuseAllInputs(); 353 ReturnAt(0)->UnuseAllInputs();
354 *exit_block = ExitBlockAt(0); 354 *exit_block = ExitBlockAt(0);
355 *last_instruction = LastInstructionAt(0); 355 *last_instruction = LastInstructionAt(0);
356 return call_->HasUses() ? ValueAt(0)->definition() : NULL; 356 return call_->HasUses() ? ValueAt(0)->definition() : NULL;
357 } else { 357 } else {
358 ASSERT(num_exits > 1); 358 ASSERT(num_exits > 1);
359 // Create a join of the returns. 359 // Create a join of the returns.
360 intptr_t join_id = caller_graph_->max_block_id() + 1; 360 intptr_t join_id = caller_graph_->max_block_id() + 1;
361 caller_graph_->set_max_block_id(join_id); 361 caller_graph_->set_max_block_id(join_id);
362 JoinEntryInstr* join = 362 JoinEntryInstr* join =
363 new(I) JoinEntryInstr(join_id, try_index); 363 new(Z) JoinEntryInstr(join_id, try_index);
364 364
365 // The dominator set of the join is the intersection of the dominator 365 // The dominator set of the join is the intersection of the dominator
366 // sets of all the predecessors. If we keep the dominator sets ordered 366 // sets of all the predecessors. If we keep the dominator sets ordered
367 // by height in the dominator tree, we can also get the immediate 367 // by height in the dominator tree, we can also get the immediate
368 // dominator of the join node from the intersection. 368 // dominator of the join node from the intersection.
369 // 369 //
370 // block_dominators is the dominator set for each block, ordered from 370 // block_dominators is the dominator set for each block, ordered from
371 // the immediate dominator to the root of the dominator tree. This is 371 // the immediate dominator to the root of the dominator tree. This is
372 // the order we collect them in (adding at the end). 372 // the order we collect them in (adding at the end).
373 // 373 //
374 // join_dominators is the join's dominators ordered from the root of the 374 // join_dominators is the join's dominators ordered from the root of the
375 // dominator tree to the immediate dominator. This order supports 375 // dominator tree to the immediate dominator. This order supports
376 // removing during intersection by truncating the list. 376 // removing during intersection by truncating the list.
377 GrowableArray<BlockEntryInstr*> block_dominators; 377 GrowableArray<BlockEntryInstr*> block_dominators;
378 GrowableArray<BlockEntryInstr*> join_dominators; 378 GrowableArray<BlockEntryInstr*> join_dominators;
379 for (intptr_t i = 0; i < num_exits; ++i) { 379 for (intptr_t i = 0; i < num_exits; ++i) {
380 // Add the control-flow edge. 380 // Add the control-flow edge.
381 GotoInstr* goto_instr = new(I) GotoInstr(join); 381 GotoInstr* goto_instr = new(Z) GotoInstr(join);
382 goto_instr->InheritDeoptTarget(isolate(), ReturnAt(i)); 382 goto_instr->InheritDeoptTarget(zone(), ReturnAt(i));
383 LastInstructionAt(i)->LinkTo(goto_instr); 383 LastInstructionAt(i)->LinkTo(goto_instr);
384 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); 384 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next());
385 join->predecessors_.Add(ExitBlockAt(i)); 385 join->predecessors_.Add(ExitBlockAt(i));
386 386
387 // Collect the block's dominators. 387 // Collect the block's dominators.
388 block_dominators.Clear(); 388 block_dominators.Clear();
389 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator(); 389 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator();
390 while (dominator != NULL) { 390 while (dominator != NULL) {
391 block_dominators.Add(dominator); 391 block_dominators.Add(dominator);
392 dominator = dominator->dominator(); 392 dominator = dominator->dominator();
(...skipping 24 matching lines...) Expand all
417 } 417 }
418 // The immediate dominator of the join is the last one in the ordered 418 // The immediate dominator of the join is the last one in the ordered
419 // intersection. 419 // intersection.
420 join_dominators.Last()->AddDominatedBlock(join); 420 join_dominators.Last()->AddDominatedBlock(join);
421 *exit_block = join; 421 *exit_block = join;
422 *last_instruction = join; 422 *last_instruction = join;
423 423
424 // If the call has uses, create a phi of the returns. 424 // If the call has uses, create a phi of the returns.
425 if (call_->HasUses()) { 425 if (call_->HasUses()) {
426 // Add a phi of the return values. 426 // Add a phi of the return values.
427 PhiInstr* phi = new(I) PhiInstr(join, num_exits); 427 PhiInstr* phi = new(Z) PhiInstr(join, num_exits);
428 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index()); 428 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index());
429 phi->mark_alive(); 429 phi->mark_alive();
430 for (intptr_t i = 0; i < num_exits; ++i) { 430 for (intptr_t i = 0; i < num_exits; ++i) {
431 ReturnAt(i)->RemoveEnvironment(); 431 ReturnAt(i)->RemoveEnvironment();
432 phi->SetInputAt(i, ValueAt(i)); 432 phi->SetInputAt(i, ValueAt(i));
433 } 433 }
434 join->InsertPhi(phi); 434 join->InsertPhi(phi);
435 join->InheritDeoptTargetAfter(caller_graph_, call_, phi); 435 join->InheritDeoptTargetAfter(caller_graph_, call_, phi);
436 return phi; 436 return phi;
437 } else { 437 } else {
(...skipping 19 matching lines...) Expand all
457 Instruction* callee_last_instruction = NULL; 457 Instruction* callee_last_instruction = NULL;
458 458
459 if (exits_.length() == 0) { 459 if (exits_.length() == 0) {
460 // Handle the case when there are no normal return exits from the callee 460 // Handle the case when there are no normal return exits from the callee
461 // (i.e. the callee unconditionally throws) by inserting an artificial 461 // (i.e. the callee unconditionally throws) by inserting an artificial
462 // branch (true === true). 462 // branch (true === true).
463 // The true successor is the inlined body, the false successor 463 // The true successor is the inlined body, the false successor
464 // goes to the rest of the caller graph. It is removed as unreachable code 464 // goes to the rest of the caller graph. It is removed as unreachable code
465 // by the constant propagation. 465 // by the constant propagation.
466 TargetEntryInstr* false_block = 466 TargetEntryInstr* false_block =
467 new(I) TargetEntryInstr(caller_graph_->allocate_block_id(), 467 new(Z) TargetEntryInstr(caller_graph_->allocate_block_id(),
468 call_block->try_index()); 468 call_block->try_index());
469 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL); 469 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
470 false_block->LinkTo(call_->next()); 470 false_block->LinkTo(call_->next());
471 call_block->ReplaceAsPredecessorWith(false_block); 471 call_block->ReplaceAsPredecessorWith(false_block);
472 472
473 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); 473 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
474 BranchInstr* branch = 474 BranchInstr* branch =
475 new(I) BranchInstr( 475 new(Z) BranchInstr(
476 new(I) StrictCompareInstr(call_block->start_pos(), 476 new(Z) StrictCompareInstr(call_block->start_pos(),
477 Token::kEQ_STRICT, 477 Token::kEQ_STRICT,
478 new(I) Value(true_const), 478 new(Z) Value(true_const),
479 new(I) Value(true_const), 479 new(Z) Value(true_const),
480 false)); // No number check. 480 false)); // No number check.
481 branch->InheritDeoptTarget(isolate(), call_); 481 branch->InheritDeoptTarget(zone(), call_);
482 *branch->true_successor_address() = callee_entry; 482 *branch->true_successor_address() = callee_entry;
483 *branch->false_successor_address() = false_block; 483 *branch->false_successor_address() = false_block;
484 484
485 call_->previous()->AppendInstruction(branch); 485 call_->previous()->AppendInstruction(branch);
486 call_block->set_last_instruction(branch); 486 call_block->set_last_instruction(branch);
487 487
488 // Update dominator tree. 488 // Update dominator tree.
489 call_block->AddDominatedBlock(callee_entry); 489 call_block->AddDominatedBlock(callee_entry);
490 call_block->AddDominatedBlock(false_block); 490 call_block->AddDominatedBlock(false_block);
491 491
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 ASSERT(is_open()); 577 ASSERT(is_open());
578 owner()->DeallocateTemps(definition->InputCount()); 578 owner()->DeallocateTemps(definition->InputCount());
579 owner()->add_args_pushed(-definition->ArgumentCount()); 579 owner()->add_args_pushed(-definition->ArgumentCount());
580 definition->set_temp_index(owner()->AllocateTemp()); 580 definition->set_temp_index(owner()->AllocateTemp());
581 if (is_empty()) { 581 if (is_empty()) {
582 entry_ = definition; 582 entry_ = definition;
583 } else { 583 } else {
584 exit()->LinkTo(definition); 584 exit()->LinkTo(definition);
585 } 585 }
586 exit_ = definition; 586 exit_ = definition;
587 return new(I) Value(definition); 587 return new(Z) Value(definition);
588 } 588 }
589 589
590 590
591 void EffectGraphVisitor::Do(Definition* definition) { 591 void EffectGraphVisitor::Do(Definition* definition) {
592 ASSERT(is_open()); 592 ASSERT(is_open());
593 owner()->DeallocateTemps(definition->InputCount()); 593 owner()->DeallocateTemps(definition->InputCount());
594 owner()->add_args_pushed(-definition->ArgumentCount()); 594 owner()->add_args_pushed(-definition->ArgumentCount());
595 if (is_empty()) { 595 if (is_empty()) {
596 entry_ = definition; 596 entry_ = definition;
597 } else { 597 } else {
(...skipping 13 matching lines...) Expand all
611 entry_ = exit_ = instruction; 611 entry_ = exit_ = instruction;
612 } else { 612 } else {
613 exit()->LinkTo(instruction); 613 exit()->LinkTo(instruction);
614 exit_ = instruction; 614 exit_ = instruction;
615 } 615 }
616 } 616 }
617 617
618 618
619 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) { 619 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) {
620 ASSERT(is_open()); 620 ASSERT(is_open());
621 ReturnInstr* return_instr = new(I) ReturnInstr(token_pos, value); 621 ReturnInstr* return_instr = new(Z) ReturnInstr(token_pos, value);
622 AddInstruction(return_instr); 622 AddInstruction(return_instr);
623 InlineExitCollector* exit_collector = owner()->exit_collector(); 623 InlineExitCollector* exit_collector = owner()->exit_collector();
624 if (exit_collector != NULL) { 624 if (exit_collector != NULL) {
625 exit_collector->AddExit(return_instr); 625 exit_collector->AddExit(return_instr);
626 } 626 }
627 CloseFragment(); 627 CloseFragment();
628 } 628 }
629 629
630 630
631 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { 631 void EffectGraphVisitor::Goto(JoinEntryInstr* join) {
632 ASSERT(is_open()); 632 ASSERT(is_open());
633 if (is_empty()) { 633 if (is_empty()) {
634 entry_ = new(I) GotoInstr(join); 634 entry_ = new(Z) GotoInstr(join);
635 } else { 635 } else {
636 exit()->Goto(join); 636 exit()->Goto(join);
637 } 637 }
638 CloseFragment(); 638 CloseFragment();
639 } 639 }
640 640
641 641
642 // Appends a graph fragment to a block entry instruction. Returns the entry 642 // Appends a graph fragment to a block entry instruction. Returns the entry
643 // instruction if the fragment was empty or else the exit of the fragment if 643 // instruction if the fragment was empty or else the exit of the fragment if
644 // it was non-empty (so NULL if the fragment is closed). 644 // it was non-empty (so NULL if the fragment is closed).
(...skipping 29 matching lines...) Expand all
674 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor(); 674 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor();
675 Instruction* false_exit = AppendFragment(false_entry, false_fragment); 675 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
676 676
677 // 3. Add a join or select one (or neither) of the arms as exit. 677 // 3. Add a join or select one (or neither) of the arms as exit.
678 if (true_exit == NULL) { 678 if (true_exit == NULL) {
679 exit_ = false_exit; // May be NULL. 679 exit_ = false_exit; // May be NULL.
680 } else if (false_exit == NULL) { 680 } else if (false_exit == NULL) {
681 exit_ = true_exit; 681 exit_ = true_exit;
682 } else { 682 } else {
683 JoinEntryInstr* join = 683 JoinEntryInstr* join =
684 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 684 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
685 true_exit->Goto(join); 685 true_exit->Goto(join);
686 false_exit->Goto(join); 686 false_exit->Goto(join);
687 exit_ = join; 687 exit_ = join;
688 } 688 }
689 } 689 }
690 690
691 691
692 void EffectGraphVisitor::TieLoop( 692 void EffectGraphVisitor::TieLoop(
693 intptr_t token_pos, 693 intptr_t token_pos,
694 const TestGraphVisitor& test_fragment, 694 const TestGraphVisitor& test_fragment,
(...skipping 10 matching lines...) Expand all
705 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); 705 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
706 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 706 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
707 707
708 // 2. Connect the test to this graph, including the body if reachable and 708 // 2. Connect the test to this graph, including the body if reachable and
709 // using a fresh join node if the body is reachable and has an open exit. 709 // using a fresh join node if the body is reachable and has an open exit.
710 if (body_exit == NULL) { 710 if (body_exit == NULL) {
711 Append(test_preamble_fragment); 711 Append(test_preamble_fragment);
712 Append(test_fragment); 712 Append(test_fragment);
713 } else { 713 } else {
714 JoinEntryInstr* join = 714 JoinEntryInstr* join =
715 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 715 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
716 CheckStackOverflowInstr* check = 716 CheckStackOverflowInstr* check =
717 new(I) CheckStackOverflowInstr(token_pos, owner()->loop_depth()); 717 new(Z) CheckStackOverflowInstr(token_pos, owner()->loop_depth());
718 join->LinkTo(check); 718 join->LinkTo(check);
719 if (!test_preamble_fragment.is_empty()) { 719 if (!test_preamble_fragment.is_empty()) {
720 check->LinkTo(test_preamble_fragment.entry()); 720 check->LinkTo(test_preamble_fragment.entry());
721 test_preamble_fragment.exit()->LinkTo(test_fragment.entry()); 721 test_preamble_fragment.exit()->LinkTo(test_fragment.entry());
722 } else { 722 } else {
723 check->LinkTo(test_fragment.entry()); 723 check->LinkTo(test_fragment.entry());
724 } 724 }
725 Goto(join); 725 Goto(join);
726 body_exit->Goto(join); 726 body_exit->Goto(join);
727 } 727 }
728 728
729 // 3. Set the exit to the graph to be the false successor of the test, a 729 // 3. Set the exit to the graph to be the false successor of the test, a
730 // fresh target node 730 // fresh target node
731 exit_ = test_fragment.CreateFalseSuccessor(); 731 exit_ = test_fragment.CreateFalseSuccessor();
732 } 732 }
733 733
734 734
735 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 735 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
736 owner_->add_args_pushed(1); 736 owner_->add_args_pushed(1);
737 PushArgumentInstr* result = new(I) PushArgumentInstr(value); 737 PushArgumentInstr* result = new(Z) PushArgumentInstr(value);
738 AddInstruction(result); 738 AddInstruction(result);
739 return result; 739 return result;
740 } 740 }
741 741
742 742
743 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, 743 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
744 Value* value) { 744 Value* value) {
745 ASSERT(!local.is_captured()); 745 ASSERT(!local.is_captured());
746 return new(I) StoreLocalInstr(local, value); 746 return new(Z) StoreLocalInstr(local, value);
747 } 747 }
748 748
749 749
750 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) { 750 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) {
751 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), 751 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(),
752 value); 752 value);
753 } 753 }
754 754
755 755
756 Definition* EffectGraphVisitor::BuildLoadExprTemp() { 756 Definition* EffectGraphVisitor::BuildLoadExprTemp() {
757 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); 757 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var());
758 } 758 }
759 759
760 760
761 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, 761 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
762 Value* value) { 762 Value* value) {
763 if (local.is_captured()) { 763 if (local.is_captured()) {
764 LocalVariable* tmp_var = EnterTempLocalScope(value); 764 LocalVariable* tmp_var = EnterTempLocalScope(value);
765 intptr_t delta = 765 intptr_t delta =
766 owner()->context_level() - local.owner()->context_level(); 766 owner()->context_level() - local.owner()->context_level();
767 ASSERT(delta >= 0); 767 ASSERT(delta >= 0);
768 Value* context = Bind(BuildCurrentContext()); 768 Value* context = Bind(BuildCurrentContext());
769 while (delta-- > 0) { 769 while (delta-- > 0) {
770 context = Bind(new(I) LoadFieldInstr( 770 context = Bind(new(Z) LoadFieldInstr(
771 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), 771 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
772 Scanner::kNoSourcePos)); 772 Scanner::kNoSourcePos));
773 } 773 }
774 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); 774 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
775 StoreInstanceFieldInstr* store = 775 StoreInstanceFieldInstr* store =
776 new(I) StoreInstanceFieldInstr(Context::variable_offset(local.index()), 776 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()),
777 context, 777 context,
778 tmp_val, 778 tmp_val,
779 kEmitStoreBarrier, 779 kEmitStoreBarrier,
780 Scanner::kNoSourcePos); 780 Scanner::kNoSourcePos);
781 Do(store); 781 Do(store);
782 return ExitTempLocalScope(tmp_var); 782 return ExitTempLocalScope(tmp_var);
783 } else { 783 } else {
784 return new(I) StoreLocalInstr(local, value); 784 return new(Z) StoreLocalInstr(local, value);
785 } 785 }
786 } 786 }
787 787
788 788
789 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { 789 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
790 if (local.IsConst()) { 790 if (local.IsConst()) {
791 return new(I) ConstantInstr(*local.ConstValue()); 791 return new(Z) ConstantInstr(*local.ConstValue());
792 } else if (local.is_captured()) { 792 } else if (local.is_captured()) {
793 intptr_t delta = 793 intptr_t delta =
794 owner()->context_level() - local.owner()->context_level(); 794 owner()->context_level() - local.owner()->context_level();
795 ASSERT(delta >= 0); 795 ASSERT(delta >= 0);
796 Value* context = Bind(BuildCurrentContext()); 796 Value* context = Bind(BuildCurrentContext());
797 while (delta-- > 0) { 797 while (delta-- > 0) {
798 context = Bind(new(I) LoadFieldInstr( 798 context = Bind(new(Z) LoadFieldInstr(
799 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), 799 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
800 Scanner::kNoSourcePos)); 800 Scanner::kNoSourcePos));
801 } 801 }
802 return new(I) LoadFieldInstr(context, 802 return new(Z) LoadFieldInstr(context,
803 Context::variable_offset(local.index()), 803 Context::variable_offset(local.index()),
804 local.type(), 804 local.type(),
805 Scanner::kNoSourcePos); 805 Scanner::kNoSourcePos);
806 } else { 806 } else {
807 return new(I) LoadLocalInstr(local); 807 return new(Z) LoadLocalInstr(local);
808 } 808 }
809 } 809 }
810 810
811 811
812 // Stores current context into the 'variable' 812 // Stores current context into the 'variable'
813 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) { 813 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) {
814 Value* context = Bind(BuildCurrentContext()); 814 Value* context = Bind(BuildCurrentContext());
815 Do(BuildStoreLocal(variable, context)); 815 Do(BuildStoreLocal(variable, context));
816 } 816 }
817 817
818 818
819 // Loads context saved in 'context_variable' into the current context. 819 // Loads context saved in 'context_variable' into the current context.
820 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) { 820 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) {
821 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 821 Value* load_saved_context = Bind(BuildLoadLocal(variable));
822 Do(BuildStoreContext(load_saved_context)); 822 Do(BuildStoreContext(load_saved_context));
823 } 823 }
824 824
825 825
826 Definition* EffectGraphVisitor::BuildStoreContext(Value* value) { 826 Definition* EffectGraphVisitor::BuildStoreContext(Value* value) {
827 return new(I) StoreLocalInstr( 827 return new(Z) StoreLocalInstr(
828 *owner()->parsed_function().current_context_var(), value); 828 *owner()->parsed_function().current_context_var(), value);
829 } 829 }
830 830
831 831
832 Definition* EffectGraphVisitor::BuildCurrentContext() { 832 Definition* EffectGraphVisitor::BuildCurrentContext() {
833 return new(I) LoadLocalInstr( 833 return new(Z) LoadLocalInstr(
834 *owner()->parsed_function().current_context_var()); 834 *owner()->parsed_function().current_context_var());
835 } 835 }
836 836
837 837
838 void TestGraphVisitor::ConnectBranchesTo( 838 void TestGraphVisitor::ConnectBranchesTo(
839 const GrowableArray<TargetEntryInstr**>& branches, 839 const GrowableArray<TargetEntryInstr**>& branches,
840 JoinEntryInstr* join) const { 840 JoinEntryInstr* join) const {
841 ASSERT(!branches.is_empty()); 841 ASSERT(!branches.is_empty());
842 for (intptr_t i = 0; i < branches.length(); i++) { 842 for (intptr_t i = 0; i < branches.length(); i++) {
843 TargetEntryInstr* target = 843 TargetEntryInstr* target =
844 new(I) TargetEntryInstr(owner()->AllocateBlockId(), 844 new(Z) TargetEntryInstr(owner()->AllocateBlockId(),
845 owner()->try_index()); 845 owner()->try_index());
846 *(branches[i]) = target; 846 *(branches[i]) = target;
847 target->Goto(join); 847 target->Goto(join);
848 } 848 }
849 } 849 }
850 850
851 851
852 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { 852 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
853 ConnectBranchesTo(true_successor_addresses_, join); 853 ConnectBranchesTo(true_successor_addresses_, join);
854 } 854 }
855 855
856 856
857 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { 857 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
858 ConnectBranchesTo(false_successor_addresses_, join); 858 ConnectBranchesTo(false_successor_addresses_, join);
859 } 859 }
860 860
861 861
862 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( 862 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
863 const GrowableArray<TargetEntryInstr**>& branches) const { 863 const GrowableArray<TargetEntryInstr**>& branches) const {
864 ASSERT(!branches.is_empty()); 864 ASSERT(!branches.is_empty());
865 865
866 if (branches.length() == 1) { 866 if (branches.length() == 1) {
867 TargetEntryInstr* target = 867 TargetEntryInstr* target =
868 new(I) TargetEntryInstr(owner()->AllocateBlockId(), 868 new(Z) TargetEntryInstr(owner()->AllocateBlockId(),
869 owner()->try_index()); 869 owner()->try_index());
870 *(branches[0]) = target; 870 *(branches[0]) = target;
871 return target; 871 return target;
872 } 872 }
873 873
874 JoinEntryInstr* join = 874 JoinEntryInstr* join =
875 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 875 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
876 ConnectBranchesTo(branches, join); 876 ConnectBranchesTo(branches, join);
877 return join; 877 return join;
878 } 878 }
879 879
880 880
881 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { 881 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
882 return CreateSuccessorFor(true_successor_addresses_); 882 return CreateSuccessorFor(true_successor_addresses_);
883 } 883 }
884 884
885 885
886 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { 886 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
887 return CreateSuccessorFor(false_successor_addresses_); 887 return CreateSuccessorFor(false_successor_addresses_);
888 } 888 }
889 889
890 890
891 void TestGraphVisitor::ReturnValue(Value* value) { 891 void TestGraphVisitor::ReturnValue(Value* value) {
892 if (Isolate::Current()->TypeChecksEnabled() || 892 if (Isolate::Current()->TypeChecksEnabled() ||
893 Isolate::Current()->AssertsEnabled()) { 893 Isolate::Current()->AssertsEnabled()) {
894 value = Bind(new(I) AssertBooleanInstr(condition_token_pos(), value)); 894 value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value));
895 } 895 }
896 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True())); 896 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
897 StrictCompareInstr* comp = 897 StrictCompareInstr* comp =
898 new(I) StrictCompareInstr(condition_token_pos(), 898 new(Z) StrictCompareInstr(condition_token_pos(),
899 Token::kEQ_STRICT, 899 Token::kEQ_STRICT,
900 value, 900 value,
901 constant_true, 901 constant_true,
902 false); // No number check. 902 false); // No number check.
903 BranchInstr* branch = new(I) BranchInstr(comp); 903 BranchInstr* branch = new(Z) BranchInstr(comp);
904 AddInstruction(branch); 904 AddInstruction(branch);
905 CloseFragment(); 905 CloseFragment();
906 906
907 true_successor_addresses_.Add(branch->true_successor_address()); 907 true_successor_addresses_.Add(branch->true_successor_address());
908 false_successor_addresses_.Add(branch->false_successor_address()); 908 false_successor_addresses_.Add(branch->false_successor_address());
909 } 909 }
910 910
911 911
912 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) { 912 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
913 BranchInstr* branch; 913 BranchInstr* branch;
914 if (Token::IsStrictEqualityOperator(comp->kind())) { 914 if (Token::IsStrictEqualityOperator(comp->kind())) {
915 ASSERT(comp->IsStrictCompare()); 915 ASSERT(comp->IsStrictCompare());
916 branch = new(I) BranchInstr(comp); 916 branch = new(Z) BranchInstr(comp);
917 } else if (Token::IsEqualityOperator(comp->kind()) && 917 } else if (Token::IsEqualityOperator(comp->kind()) &&
918 (comp->left()->BindsToConstantNull() || 918 (comp->left()->BindsToConstantNull() ||
919 comp->right()->BindsToConstantNull())) { 919 comp->right()->BindsToConstantNull())) {
920 branch = new(I) BranchInstr(new(I) StrictCompareInstr( 920 branch = new(Z) BranchInstr(new(Z) StrictCompareInstr(
921 comp->token_pos(), 921 comp->token_pos(),
922 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 922 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
923 comp->left(), 923 comp->left(),
924 comp->right(), 924 comp->right(),
925 false)); // No number check. 925 false)); // No number check.
926 } else { 926 } else {
927 branch = new(I) BranchInstr(comp); 927 branch = new(Z) BranchInstr(comp);
928 branch->set_is_checked(Isolate::Current()->TypeChecksEnabled()); 928 branch->set_is_checked(Isolate::Current()->TypeChecksEnabled());
929 } 929 }
930 AddInstruction(branch); 930 AddInstruction(branch);
931 CloseFragment(); 931 CloseFragment();
932 true_successor_addresses_.Add(branch->true_successor_address()); 932 true_successor_addresses_.Add(branch->true_successor_address());
933 false_successor_addresses_.Add(branch->false_successor_address()); 933 false_successor_addresses_.Add(branch->false_successor_address());
934 } 934 }
935 935
936 936
937 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 937 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
938 ASSERT(!Isolate::Current()->TypeChecksEnabled()); 938 ASSERT(!Isolate::Current()->TypeChecksEnabled());
939 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True())); 939 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
940 StrictCompareInstr* comp = 940 StrictCompareInstr* comp =
941 new(I) StrictCompareInstr(condition_token_pos(), 941 new(Z) StrictCompareInstr(condition_token_pos(),
942 Token::kNE_STRICT, 942 Token::kNE_STRICT,
943 neg->value(), 943 neg->value(),
944 constant_true, 944 constant_true,
945 false); // No number check. 945 false); // No number check.
946 BranchInstr* branch = new(I) BranchInstr(comp); 946 BranchInstr* branch = new(Z) BranchInstr(comp);
947 AddInstruction(branch); 947 AddInstruction(branch);
948 CloseFragment(); 948 CloseFragment();
949 true_successor_addresses_.Add(branch->true_successor_address()); 949 true_successor_addresses_.Add(branch->true_successor_address());
950 false_successor_addresses_.Add(branch->false_successor_address()); 950 false_successor_addresses_.Add(branch->false_successor_address());
951 } 951 }
952 952
953 953
954 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 954 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
955 ComparisonInstr* comp = definition->AsComparison(); 955 ComparisonInstr* comp = definition->AsComparison();
956 if (comp != NULL) { 956 if (comp != NULL) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 return_value = Bind(BuildLoadLocal(*temp)); 1035 return_value = Bind(BuildLoadLocal(*temp));
1036 } 1036 }
1037 1037
1038 // Call to stub that checks whether the debugger is in single 1038 // Call to stub that checks whether the debugger is in single
1039 // step mode. This call must happen before the contexts are 1039 // step mode. This call must happen before the contexts are
1040 // unchained so that captured variables can be inspected. 1040 // unchained so that captured variables can be inspected.
1041 // No debugger check is done in native functions or for return 1041 // No debugger check is done in native functions or for return
1042 // statements for which there is no associated source position. 1042 // statements for which there is no associated source position.
1043 const Function& function = owner()->function(); 1043 const Function& function = owner()->function();
1044 if ((node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) { 1044 if ((node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) {
1045 AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(), 1045 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(),
1046 RawPcDescriptors::kRuntimeCall)); 1046 RawPcDescriptors::kRuntimeCall));
1047 } 1047 }
1048 1048
1049 if (Isolate::Current()->TypeChecksEnabled()) { 1049 if (Isolate::Current()->TypeChecksEnabled()) {
1050 const bool is_implicit_dynamic_getter = 1050 const bool is_implicit_dynamic_getter =
1051 (!function.is_static() && 1051 (!function.is_static() &&
1052 ((function.kind() == RawFunction::kImplicitGetter) || 1052 ((function.kind() == RawFunction::kImplicitGetter) ||
1053 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); 1053 (function.kind() == RawFunction::kImplicitStaticFinalGetter)));
1054 // Implicit getters do not need a type check at return, unless they compute 1054 // Implicit getters do not need a type check at return, unless they compute
1055 // the initial value of a static field. 1055 // the initial value of a static field.
1056 // The body of a constructor cannot modify the type of the 1056 // The body of a constructor cannot modify the type of the
1057 // constructed instance, which is passed in as an implicit parameter. 1057 // constructed instance, which is passed in as an implicit parameter.
1058 // However, factories may create an instance of the wrong type. 1058 // However, factories may create an instance of the wrong type.
1059 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { 1059 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) {
1060 const AbstractType& dst_type = 1060 const AbstractType& dst_type =
1061 AbstractType::ZoneHandle(I, function.result_type()); 1061 AbstractType::ZoneHandle(Z, function.result_type());
1062 return_value = BuildAssignableValue(node->value()->token_pos(), 1062 return_value = BuildAssignableValue(node->value()->token_pos(),
1063 return_value, 1063 return_value,
1064 dst_type, 1064 dst_type,
1065 Symbols::FunctionResult()); 1065 Symbols::FunctionResult());
1066 } 1066 }
1067 } 1067 }
1068 1068
1069 // Async functions contain two types of return statements: 1069 // Async functions contain two types of return statements:
1070 // 1) Returns that should complete the completer once all finally blocks have 1070 // 1) Returns that should complete the completer once all finally blocks have
1071 // been inlined (call: :async_completer.complete(return_value)). These 1071 // been inlined (call: :async_completer.complete(return_value)). These
1072 // returns end up returning null in the end. 1072 // returns end up returning null in the end.
1073 // 2) "Continuation" returns that should not complete the completer but return 1073 // 2) "Continuation" returns that should not complete the completer but return
1074 // the value. 1074 // the value.
1075 // 1075 //
1076 // We distinguish those kinds of nodes via is_regular_return(). 1076 // We distinguish those kinds of nodes via is_regular_return().
1077 // 1077 //
1078 if (function.IsAsyncClosure() && 1078 if (function.IsAsyncClosure() &&
1079 (node->return_type() == ReturnNode::kRegular)) { 1079 (node->return_type() == ReturnNode::kRegular)) {
1080 // Temporary store the computed return value. 1080 // Temporary store the computed return value.
1081 Do(BuildStoreExprTemp(return_value)); 1081 Do(BuildStoreExprTemp(return_value));
1082 1082
1083 LocalVariable* rcv_var = 1083 LocalVariable* rcv_var =
1084 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false); 1084 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
1085 ASSERT(rcv_var != NULL && rcv_var->is_captured()); 1085 ASSERT(rcv_var != NULL && rcv_var->is_captured());
1086 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1086 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1087 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 1087 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1088 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var)); 1088 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var));
1089 arguments->Add(PushArgument(rcv_value)); 1089 arguments->Add(PushArgument(rcv_value));
1090 Value* returned_value = Bind(BuildLoadExprTemp()); 1090 Value* returned_value = Bind(BuildLoadExprTemp());
1091 arguments->Add(PushArgument(returned_value)); 1091 arguments->Add(PushArgument(returned_value));
1092 InstanceCallInstr* call = new(I) InstanceCallInstr( 1092 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1093 Scanner::kNoSourcePos, 1093 Scanner::kNoSourcePos,
1094 Symbols::CompleterComplete(), 1094 Symbols::CompleterComplete(),
1095 Token::kILLEGAL, 1095 Token::kILLEGAL,
1096 arguments, 1096 arguments,
1097 Object::null_array(), 1097 Object::null_array(),
1098 1, 1098 1,
1099 owner()->ic_data_array()); 1099 owner()->ic_data_array());
1100 Do(call); 1100 Do(call);
1101 1101
1102 // Rebind the return value for the actual return call to be null. 1102 // Rebind the return value for the actual return call to be null.
1103 return_value = BuildNullValue(); 1103 return_value = BuildNullValue();
1104 } 1104 }
1105 1105
1106 intptr_t current_context_level = owner()->context_level(); 1106 intptr_t current_context_level = owner()->context_level();
1107 ASSERT(current_context_level >= 0); 1107 ASSERT(current_context_level >= 0);
1108 if (HasContextScope()) { 1108 if (HasContextScope()) {
1109 UnchainContexts(current_context_level); 1109 UnchainContexts(current_context_level);
1110 } 1110 }
1111 1111
1112 AddReturnExit(node->token_pos(), return_value); 1112 AddReturnExit(node->token_pos(), return_value);
1113 1113
1114 if ((function.IsAsyncClosure() || 1114 if ((function.IsAsyncClosure() ||
1115 function.IsSyncGenClosure() || 1115 function.IsSyncGenClosure() ||
1116 function.IsAsyncGenClosure()) && 1116 function.IsAsyncGenClosure()) &&
1117 (node->return_type() == ReturnNode::kContinuationTarget)) { 1117 (node->return_type() == ReturnNode::kContinuationTarget)) {
1118 JoinEntryInstr* const join = new(I) JoinEntryInstr( 1118 JoinEntryInstr* const join = new(Z) JoinEntryInstr(
1119 owner()->AllocateBlockId(), owner()->try_index()); 1119 owner()->AllocateBlockId(), owner()->try_index());
1120 owner()->await_joins()->Add(join); 1120 owner()->await_joins()->Add(join);
1121 exit_ = join; 1121 exit_ = join;
1122 } 1122 }
1123 } 1123 }
1124 1124
1125 1125
1126 // <Expression> ::= Literal { literal: Instance } 1126 // <Expression> ::= Literal { literal: Instance }
1127 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 1127 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
1128 ReturnDefinition(new(I) ConstantInstr(node->literal())); 1128 ReturnDefinition(new(Z) ConstantInstr(node->literal()));
1129 } 1129 }
1130 1130
1131 1131
1132 // Type nodes are used when a type is referenced as a literal. Type nodes 1132 // Type nodes are used when a type is referenced as a literal. Type nodes
1133 // can also be used for the right-hand side of instanceof comparisons, 1133 // can also be used for the right-hand side of instanceof comparisons,
1134 // but they are handled specially in that context, not here. 1134 // but they are handled specially in that context, not here.
1135 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { 1135 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) {
1136 return; 1136 return;
1137 } 1137 }
1138 1138
1139 1139
1140 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { 1140 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
1141 const AbstractType& type = node->type(); 1141 const AbstractType& type = node->type();
1142 // Type may be malbounded, but not malformed. 1142 // Type may be malbounded, but not malformed.
1143 ASSERT(type.IsFinalized() && !type.IsMalformed()); 1143 ASSERT(type.IsFinalized() && !type.IsMalformed());
1144 if (type.IsInstantiated()) { 1144 if (type.IsInstantiated()) {
1145 ReturnDefinition(new(I) ConstantInstr(type)); 1145 ReturnDefinition(new(Z) ConstantInstr(type));
1146 } else { 1146 } else {
1147 const Class& instantiator_class = Class::ZoneHandle( 1147 const Class& instantiator_class = Class::ZoneHandle(
1148 I, owner()->function().Owner()); 1148 Z, owner()->function().Owner());
1149 Value* instantiator_value = BuildInstantiatorTypeArguments( 1149 Value* instantiator_value = BuildInstantiatorTypeArguments(
1150 node->token_pos(), instantiator_class, NULL); 1150 node->token_pos(), instantiator_class, NULL);
1151 ReturnDefinition(new(I) InstantiateTypeInstr( 1151 ReturnDefinition(new(Z) InstantiateTypeInstr(
1152 node->token_pos(), type, instantiator_class, instantiator_value)); 1152 node->token_pos(), type, instantiator_class, instantiator_value));
1153 } 1153 }
1154 } 1154 }
1155 1155
1156 1156
1157 // Returns true if the type check can be skipped, for example, if the 1157 // Returns true if the type check can be skipped, for example, if the
1158 // destination type is dynamic or if the compile type of the value is a subtype 1158 // destination type is dynamic or if the compile type of the value is a subtype
1159 // of the destination type. 1159 // of the destination type.
1160 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, 1160 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos,
1161 Value* value, 1161 Value* value,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { 1206 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) {
1207 ValueGraphVisitor for_value(owner()); 1207 ValueGraphVisitor for_value(owner());
1208 node->expr()->Visit(&for_value); 1208 node->expr()->Visit(&for_value);
1209 Append(for_value); 1209 Append(for_value);
1210 Definition* checked_value; 1210 Definition* checked_value;
1211 if (CanSkipTypeCheck(node->expr()->token_pos(), 1211 if (CanSkipTypeCheck(node->expr()->token_pos(),
1212 for_value.value(), 1212 for_value.value(),
1213 node->type(), 1213 node->type(),
1214 node->dst_name())) { 1214 node->dst_name())) {
1215 // Drop the value and 0 additional temporaries. 1215 // Drop the value and 0 additional temporaries.
1216 checked_value = new(I) DropTempsInstr(0, for_value.value()); 1216 checked_value = new(Z) DropTempsInstr(0, for_value.value());
1217 } else { 1217 } else {
1218 checked_value = BuildAssertAssignable(node->expr()->token_pos(), 1218 checked_value = BuildAssertAssignable(node->expr()->token_pos(),
1219 for_value.value(), 1219 for_value.value(),
1220 node->type(), 1220 node->type(),
1221 node->dst_name()); 1221 node->dst_name());
1222 } 1222 }
1223 ReturnDefinition(checked_value); 1223 ReturnDefinition(checked_value);
1224 } 1224 }
1225 1225
1226 1226
(...skipping 17 matching lines...) Expand all
1244 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1244 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1245 // See ValueGraphVisitor::VisitBinaryOpNode. 1245 // See ValueGraphVisitor::VisitBinaryOpNode.
1246 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1246 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1247 node->left()->Visit(&for_left); 1247 node->left()->Visit(&for_left);
1248 EffectGraphVisitor empty(owner()); 1248 EffectGraphVisitor empty(owner());
1249 if (Isolate::Current()->TypeChecksEnabled() || 1249 if (Isolate::Current()->TypeChecksEnabled() ||
1250 Isolate::Current()->AssertsEnabled()) { 1250 Isolate::Current()->AssertsEnabled()) {
1251 ValueGraphVisitor for_right(owner()); 1251 ValueGraphVisitor for_right(owner());
1252 node->right()->Visit(&for_right); 1252 node->right()->Visit(&for_right);
1253 Value* right_value = for_right.value(); 1253 Value* right_value = for_right.value();
1254 for_right.Do(new(I) AssertBooleanInstr(node->right()->token_pos(), 1254 for_right.Do(new(Z) AssertBooleanInstr(node->right()->token_pos(),
1255 right_value)); 1255 right_value));
1256 if (node->kind() == Token::kAND) { 1256 if (node->kind() == Token::kAND) {
1257 Join(for_left, for_right, empty); 1257 Join(for_left, for_right, empty);
1258 } else { 1258 } else {
1259 Join(for_left, empty, for_right); 1259 Join(for_left, empty, for_right);
1260 } 1260 }
1261 } else { 1261 } else {
1262 EffectGraphVisitor for_right(owner()); 1262 EffectGraphVisitor for_right(owner());
1263 node->right()->Visit(&for_right); 1263 node->right()->Visit(&for_right);
1264 if (node->kind() == Token::kAND) { 1264 if (node->kind() == Token::kAND) {
1265 Join(for_left, for_right, empty); 1265 Join(for_left, for_right, empty);
1266 } else { 1266 } else {
1267 Join(for_left, empty, for_right); 1267 Join(for_left, empty, for_right);
1268 } 1268 }
1269 } 1269 }
1270 return; 1270 return;
1271 } 1271 }
1272 ValueGraphVisitor for_left_value(owner()); 1272 ValueGraphVisitor for_left_value(owner());
1273 node->left()->Visit(&for_left_value); 1273 node->left()->Visit(&for_left_value);
1274 Append(for_left_value); 1274 Append(for_left_value);
1275 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1275 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1276 1276
1277 ValueGraphVisitor for_right_value(owner()); 1277 ValueGraphVisitor for_right_value(owner());
1278 node->right()->Visit(&for_right_value); 1278 node->right()->Visit(&for_right_value);
1279 Append(for_right_value); 1279 Append(for_right_value);
1280 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1280 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1281 1281
1282 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1282 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1283 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 1283 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1284 arguments->Add(push_left); 1284 arguments->Add(push_left);
1285 arguments->Add(push_right); 1285 arguments->Add(push_right);
1286 const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName())); 1286 const String& name = String::ZoneHandle(Z, Symbols::New(node->TokenName()));
1287 const intptr_t kNumArgsChecked = 2; 1287 const intptr_t kNumArgsChecked = 2;
1288 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(), 1288 InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
1289 name, 1289 name,
1290 node->kind(), 1290 node->kind(),
1291 arguments, 1291 arguments,
1292 Object::null_array(), 1292 Object::null_array(),
1293 kNumArgsChecked, 1293 kNumArgsChecked,
1294 owner()->ic_data_array()); 1294 owner()->ic_data_array());
1295 ReturnDefinition(call); 1295 ReturnDefinition(call);
1296 } 1296 }
1297 1297
1298 1298
1299 // Special handling for AND/OR. 1299 // Special handling for AND/OR.
1300 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1300 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1301 // Operators "&&" and "||" cannot be overloaded therefore do not call 1301 // Operators "&&" and "||" cannot be overloaded therefore do not call
1302 // operator. 1302 // operator.
1303 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1303 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1304 // Implement short-circuit logic: do not evaluate right if evaluation 1304 // Implement short-circuit logic: do not evaluate right if evaluation
1305 // of left is sufficient. 1305 // of left is sufficient.
1306 // AND: left ? right === true : false; 1306 // AND: left ? right === true : false;
1307 // OR: left ? true : right === true; 1307 // OR: left ? true : right === true;
1308 1308
1309 TestGraphVisitor for_test(owner(), node->left()->token_pos()); 1309 TestGraphVisitor for_test(owner(), node->left()->token_pos());
1310 node->left()->Visit(&for_test); 1310 node->left()->Visit(&for_test);
1311 1311
1312 ValueGraphVisitor for_right(owner()); 1312 ValueGraphVisitor for_right(owner());
1313 node->right()->Visit(&for_right); 1313 node->right()->Visit(&for_right);
1314 Value* right_value = for_right.value(); 1314 Value* right_value = for_right.value();
1315 if (Isolate::Current()->TypeChecksEnabled() || 1315 if (Isolate::Current()->TypeChecksEnabled() ||
1316 Isolate::Current()->AssertsEnabled()) { 1316 Isolate::Current()->AssertsEnabled()) {
1317 right_value = 1317 right_value =
1318 for_right.Bind(new(I) AssertBooleanInstr(node->right()->token_pos(), 1318 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(),
1319 right_value)); 1319 right_value));
1320 } 1320 }
1321 Value* constant_true = for_right.Bind(new(I) ConstantInstr(Bool::True())); 1321 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True()));
1322 Value* compare = 1322 Value* compare =
1323 for_right.Bind(new(I) StrictCompareInstr(node->token_pos(), 1323 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(),
1324 Token::kEQ_STRICT, 1324 Token::kEQ_STRICT,
1325 right_value, 1325 right_value,
1326 constant_true, 1326 constant_true,
1327 false)); // No number check. 1327 false)); // No number check.
1328 for_right.Do(BuildStoreExprTemp(compare)); 1328 for_right.Do(BuildStoreExprTemp(compare));
1329 1329
1330 if (node->kind() == Token::kAND) { 1330 if (node->kind() == Token::kAND) {
1331 ValueGraphVisitor for_false(owner()); 1331 ValueGraphVisitor for_false(owner());
1332 Value* constant_false = 1332 Value* constant_false =
1333 for_false.Bind(new(I) ConstantInstr(Bool::False())); 1333 for_false.Bind(new(Z) ConstantInstr(Bool::False()));
1334 for_false.Do(BuildStoreExprTemp(constant_false)); 1334 for_false.Do(BuildStoreExprTemp(constant_false));
1335 Join(for_test, for_right, for_false); 1335 Join(for_test, for_right, for_false);
1336 } else { 1336 } else {
1337 ASSERT(node->kind() == Token::kOR); 1337 ASSERT(node->kind() == Token::kOR);
1338 ValueGraphVisitor for_true(owner()); 1338 ValueGraphVisitor for_true(owner());
1339 Value* constant_true = for_true.Bind(new(I) ConstantInstr(Bool::True())); 1339 Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True()));
1340 for_true.Do(BuildStoreExprTemp(constant_true)); 1340 for_true.Do(BuildStoreExprTemp(constant_true));
1341 Join(for_test, for_true, for_right); 1341 Join(for_test, for_true, for_right);
1342 } 1342 }
1343 ReturnDefinition(BuildLoadExprTemp()); 1343 ReturnDefinition(BuildLoadExprTemp());
1344 return; 1344 return;
1345 } 1345 }
1346 EffectGraphVisitor::VisitBinaryOpNode(node); 1346 EffectGraphVisitor::VisitBinaryOpNode(node);
1347 } 1347 }
1348 1348
1349 1349
(...skipping 16 matching lines...) Expand all
1366 ValueGraphVisitor for_left_value(owner()); 1366 ValueGraphVisitor for_left_value(owner());
1367 node->left()->Visit(&for_left_value); 1367 node->left()->Visit(&for_left_value);
1368 Append(for_left_value); 1368 Append(for_left_value);
1369 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1369 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1370 1370
1371 ValueGraphVisitor for_right_value(owner()); 1371 ValueGraphVisitor for_right_value(owner());
1372 node->right()->Visit(&for_right_value); 1372 node->right()->Visit(&for_right_value);
1373 Append(for_right_value); 1373 Append(for_right_value);
1374 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1374 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1375 1375
1376 Value* mask_value = Bind(new(I) ConstantInstr( 1376 Value* mask_value = Bind(new(Z) ConstantInstr(
1377 Integer::ZoneHandle(I, Integer::New(node->mask32(), Heap::kOld)))); 1377 Integer::ZoneHandle(Z, Integer::New(node->mask32(), Heap::kOld))));
1378 PushArgumentInstr* push_mask = PushArgument(mask_value); 1378 PushArgumentInstr* push_mask = PushArgument(mask_value);
1379 1379
1380 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1380 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1381 new(I) ZoneGrowableArray<PushArgumentInstr*>(3); 1381 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3);
1382 arguments->Add(push_left); 1382 arguments->Add(push_left);
1383 arguments->Add(push_right); 1383 arguments->Add(push_right);
1384 // Call to special method 'BinaryOpAndMaskName(node)'. 1384 // Call to special method 'BinaryOpAndMaskName(node)'.
1385 arguments->Add(push_mask); 1385 arguments->Add(push_mask);
1386 const intptr_t kNumArgsChecked = 2; 1386 const intptr_t kNumArgsChecked = 2;
1387 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(), 1387 InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
1388 BinaryOpAndMaskName(node), 1388 BinaryOpAndMaskName(node),
1389 Token::kILLEGAL, 1389 Token::kILLEGAL,
1390 arguments, 1390 arguments,
1391 Object::null_array(), 1391 Object::null_array(),
1392 kNumArgsChecked, 1392 kNumArgsChecked,
1393 owner()->ic_data_array()); 1393 owner()->ic_data_array());
1394 ReturnDefinition(call); 1394 ReturnDefinition(call);
1395 } 1395 }
1396 1396
1397 1397
1398 void EffectGraphVisitor::BuildTypecheckPushArguments( 1398 void EffectGraphVisitor::BuildTypecheckPushArguments(
1399 intptr_t token_pos, 1399 intptr_t token_pos,
1400 PushArgumentInstr** push_instantiator_result, 1400 PushArgumentInstr** push_instantiator_result,
1401 PushArgumentInstr** push_instantiator_type_arguments_result) { 1401 PushArgumentInstr** push_instantiator_type_arguments_result) {
1402 const Class& instantiator_class = Class::Handle( 1402 const Class& instantiator_class = Class::Handle(
1403 I, owner()->function().Owner()); 1403 Z, owner()->function().Owner());
1404 // Since called only when type tested against is not instantiated. 1404 // Since called only when type tested against is not instantiated.
1405 ASSERT(instantiator_class.NumTypeParameters() > 0); 1405 ASSERT(instantiator_class.NumTypeParameters() > 0);
1406 Value* instantiator_type_arguments = NULL; 1406 Value* instantiator_type_arguments = NULL;
1407 Value* instantiator = BuildInstantiator(instantiator_class); 1407 Value* instantiator = BuildInstantiator(instantiator_class);
1408 if (instantiator == NULL) { 1408 if (instantiator == NULL) {
1409 // No instantiator when inside factory. 1409 // No instantiator when inside factory.
1410 *push_instantiator_result = PushArgument(BuildNullValue()); 1410 *push_instantiator_result = PushArgument(BuildNullValue());
1411 instantiator_type_arguments = 1411 instantiator_type_arguments =
1412 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1412 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1413 } else { 1413 } else {
1414 instantiator = Bind(BuildStoreExprTemp(instantiator)); 1414 instantiator = Bind(BuildStoreExprTemp(instantiator));
1415 *push_instantiator_result = PushArgument(instantiator); 1415 *push_instantiator_result = PushArgument(instantiator);
1416 Value* loaded = Bind(BuildLoadExprTemp()); 1416 Value* loaded = Bind(BuildLoadExprTemp());
1417 instantiator_type_arguments = 1417 instantiator_type_arguments =
1418 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); 1418 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded);
1419 } 1419 }
1420 *push_instantiator_type_arguments_result = 1420 *push_instantiator_type_arguments_result =
1421 PushArgument(instantiator_type_arguments); 1421 PushArgument(instantiator_type_arguments);
1422 } 1422 }
1423 1423
1424 1424
1425 1425
1426 void EffectGraphVisitor::BuildTypecheckArguments( 1426 void EffectGraphVisitor::BuildTypecheckArguments(
1427 intptr_t token_pos, 1427 intptr_t token_pos,
1428 Value** instantiator_result, 1428 Value** instantiator_result,
1429 Value** instantiator_type_arguments_result) { 1429 Value** instantiator_type_arguments_result) {
1430 Value* instantiator = NULL; 1430 Value* instantiator = NULL;
1431 Value* instantiator_type_arguments = NULL; 1431 Value* instantiator_type_arguments = NULL;
1432 const Class& instantiator_class = Class::Handle( 1432 const Class& instantiator_class = Class::Handle(
1433 I, owner()->function().Owner()); 1433 Z, owner()->function().Owner());
1434 // Since called only when type tested against is not instantiated. 1434 // Since called only when type tested against is not instantiated.
1435 ASSERT(instantiator_class.NumTypeParameters() > 0); 1435 ASSERT(instantiator_class.NumTypeParameters() > 0);
1436 instantiator = BuildInstantiator(instantiator_class); 1436 instantiator = BuildInstantiator(instantiator_class);
1437 if (instantiator == NULL) { 1437 if (instantiator == NULL) {
1438 // No instantiator when inside factory. 1438 // No instantiator when inside factory.
1439 instantiator = BuildNullValue(); 1439 instantiator = BuildNullValue();
1440 instantiator_type_arguments = 1440 instantiator_type_arguments =
1441 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1441 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1442 } else { 1442 } else {
1443 // Preserve instantiator. 1443 // Preserve instantiator.
1444 instantiator = Bind(BuildStoreExprTemp(instantiator)); 1444 instantiator = Bind(BuildStoreExprTemp(instantiator));
1445 Value* loaded = Bind(BuildLoadExprTemp()); 1445 Value* loaded = Bind(BuildLoadExprTemp());
1446 instantiator_type_arguments = 1446 instantiator_type_arguments =
1447 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); 1447 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded);
1448 } 1448 }
1449 *instantiator_result = instantiator; 1449 *instantiator_result = instantiator;
1450 *instantiator_type_arguments_result = instantiator_type_arguments; 1450 *instantiator_type_arguments_result = instantiator_type_arguments;
1451 } 1451 }
1452 1452
1453 1453
1454 Value* EffectGraphVisitor::BuildNullValue() { 1454 Value* EffectGraphVisitor::BuildNullValue() {
1455 return Bind(new(I) ConstantInstr(Object::ZoneHandle(I, Object::null()))); 1455 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())));
1456 } 1456 }
1457 1457
1458 1458
1459 // Used for testing incoming arguments. 1459 // Used for testing incoming arguments.
1460 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( 1460 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable(
1461 intptr_t token_pos, 1461 intptr_t token_pos,
1462 Value* value, 1462 Value* value,
1463 const AbstractType& dst_type, 1463 const AbstractType& dst_type,
1464 const String& dst_name) { 1464 const String& dst_name) {
1465 // Build the type check computation. 1465 // Build the type check computation.
1466 Value* instantiator = NULL; 1466 Value* instantiator = NULL;
1467 Value* instantiator_type_arguments = NULL; 1467 Value* instantiator_type_arguments = NULL;
1468 if (dst_type.IsInstantiated()) { 1468 if (dst_type.IsInstantiated()) {
1469 instantiator = BuildNullValue(); 1469 instantiator = BuildNullValue();
1470 instantiator_type_arguments = BuildNullValue(); 1470 instantiator_type_arguments = BuildNullValue();
1471 } else { 1471 } else {
1472 BuildTypecheckArguments(token_pos, 1472 BuildTypecheckArguments(token_pos,
1473 &instantiator, 1473 &instantiator,
1474 &instantiator_type_arguments); 1474 &instantiator_type_arguments);
1475 } 1475 }
1476 1476
1477 const intptr_t deopt_id = Isolate::Current()->GetNextDeoptId(); 1477 const intptr_t deopt_id = Isolate::Current()->GetNextDeoptId();
1478 return new(I) AssertAssignableInstr(token_pos, 1478 return new(Z) AssertAssignableInstr(token_pos,
1479 value, 1479 value,
1480 instantiator, 1480 instantiator,
1481 instantiator_type_arguments, 1481 instantiator_type_arguments,
1482 dst_type, 1482 dst_type,
1483 dst_name, 1483 dst_name,
1484 deopt_id); 1484 deopt_id);
1485 } 1485 }
1486 1486
1487 1487
1488 void EffectGraphVisitor::BuildSyncYieldJump(LocalVariable* old_context, 1488 void EffectGraphVisitor::BuildSyncYieldJump(LocalVariable* old_context,
(...skipping 21 matching lines...) Expand all
1510 // the restored context. 1510 // the restored context.
1511 1511
1512 // FlowGraphBuilder is at top context level, but the continuation 1512 // FlowGraphBuilder is at top context level, but the continuation
1513 // target has possibly been recorded in a nested context (old_ctx_level). 1513 // target has possibly been recorded in a nested context (old_ctx_level).
1514 // We need to unroll manually here. 1514 // We need to unroll manually here.
1515 intptr_t delta = 1515 intptr_t delta =
1516 old_ctx_level - iterator_param->owner()->context_level(); 1516 old_ctx_level - iterator_param->owner()->context_level();
1517 ASSERT(delta >= 0); 1517 ASSERT(delta >= 0);
1518 Value* context = Bind(BuildCurrentContext()); 1518 Value* context = Bind(BuildCurrentContext());
1519 while (delta-- > 0) { 1519 while (delta-- > 0) {
1520 context = Bind(new(I) LoadFieldInstr( 1520 context = Bind(new(Z) LoadFieldInstr(
1521 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), 1521 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
1522 Scanner::kNoSourcePos)); 1522 Scanner::kNoSourcePos));
1523 } 1523 }
1524 LocalVariable* temp_context_var = EnterTempLocalScope(context); 1524 LocalVariable* temp_context_var = EnterTempLocalScope(context);
1525 1525
1526 Value* context_val = Bind(new(I) LoadLocalInstr(*temp_context_var)); 1526 Value* context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
1527 Value* store_val = Bind(new(I) LoadLocalInstr(*temp_iterator_var)); 1527 Value* store_val = Bind(new(Z) LoadLocalInstr(*temp_iterator_var));
1528 StoreInstanceFieldInstr* store = new(I) StoreInstanceFieldInstr( 1528 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
1529 Context::variable_offset(iterator_param->index()), 1529 Context::variable_offset(iterator_param->index()),
1530 context_val, 1530 context_val,
1531 store_val, 1531 store_val,
1532 kEmitStoreBarrier, 1532 kEmitStoreBarrier,
1533 Scanner::kNoSourcePos); 1533 Scanner::kNoSourcePos);
1534 Do(store); 1534 Do(store);
1535 1535
1536 Do(ExitTempLocalScope(temp_context_var)); 1536 Do(ExitTempLocalScope(temp_context_var));
1537 Do(ExitTempLocalScope(temp_iterator_var)); 1537 Do(ExitTempLocalScope(temp_iterator_var));
1538 1538
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 // the restored context. 1575 // the restored context.
1576 1576
1577 // FlowGraphBuilder is at top context level, but the await target has possibly 1577 // FlowGraphBuilder is at top context level, but the await target has possibly
1578 // been recorded in a nested context (old_ctx_level). We need to unroll 1578 // been recorded in a nested context (old_ctx_level). We need to unroll
1579 // manually here. 1579 // manually here.
1580 intptr_t delta = 1580 intptr_t delta =
1581 old_ctx_level - continuation_result->owner()->context_level(); 1581 old_ctx_level - continuation_result->owner()->context_level();
1582 ASSERT(delta >= 0); 1582 ASSERT(delta >= 0);
1583 Value* context = Bind(BuildCurrentContext()); 1583 Value* context = Bind(BuildCurrentContext());
1584 while (delta-- > 0) { 1584 while (delta-- > 0) {
1585 context = Bind(new(I) LoadFieldInstr( 1585 context = Bind(new(Z) LoadFieldInstr(
1586 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), 1586 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
1587 Scanner::kNoSourcePos)); 1587 Scanner::kNoSourcePos));
1588 } 1588 }
1589 LocalVariable* temp_context_var = EnterTempLocalScope(context); 1589 LocalVariable* temp_context_var = EnterTempLocalScope(context);
1590 1590
1591 Value* context_val = Bind(new(I) LoadLocalInstr(*temp_context_var)); 1591 Value* context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
1592 Value* store_val = Bind(new(I) LoadLocalInstr(*temp_result_var)); 1592 Value* store_val = Bind(new(Z) LoadLocalInstr(*temp_result_var));
1593 StoreInstanceFieldInstr* store = new(I) StoreInstanceFieldInstr( 1593 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
1594 Context::variable_offset(continuation_result->index()), 1594 Context::variable_offset(continuation_result->index()),
1595 context_val, 1595 context_val,
1596 store_val, 1596 store_val,
1597 kEmitStoreBarrier, 1597 kEmitStoreBarrier,
1598 Scanner::kNoSourcePos); 1598 Scanner::kNoSourcePos);
1599 Do(store); 1599 Do(store);
1600 context_val = Bind(new(I) LoadLocalInstr(*temp_context_var)); 1600 context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
1601 store_val = Bind(new(I) LoadLocalInstr(*temp_error_var)); 1601 store_val = Bind(new(Z) LoadLocalInstr(*temp_error_var));
1602 StoreInstanceFieldInstr* store2 = new(I) StoreInstanceFieldInstr( 1602 StoreInstanceFieldInstr* store2 = new(Z) StoreInstanceFieldInstr(
1603 Context::variable_offset(continuation_error->index()), 1603 Context::variable_offset(continuation_error->index()),
1604 context_val, 1604 context_val,
1605 store_val, 1605 store_val,
1606 kEmitStoreBarrier, 1606 kEmitStoreBarrier,
1607 Scanner::kNoSourcePos); 1607 Scanner::kNoSourcePos);
1608 Do(store2); 1608 Do(store2);
1609 1609
1610 context_val = Bind(new(I) LoadLocalInstr(*temp_context_var)); 1610 context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
1611 store_val = Bind(new(I) LoadLocalInstr(*temp_stack_trace_var)); 1611 store_val = Bind(new(Z) LoadLocalInstr(*temp_stack_trace_var));
1612 StoreInstanceFieldInstr* store3 = new(I) StoreInstanceFieldInstr( 1612 StoreInstanceFieldInstr* store3 = new(Z) StoreInstanceFieldInstr(
1613 Context::variable_offset(continuation_stack_trace->index()), 1613 Context::variable_offset(continuation_stack_trace->index()),
1614 context_val, 1614 context_val,
1615 store_val, 1615 store_val,
1616 kEmitStoreBarrier, 1616 kEmitStoreBarrier,
1617 Scanner::kNoSourcePos); 1617 Scanner::kNoSourcePos);
1618 Do(store3); 1618 Do(store3);
1619 1619
1620 Do(ExitTempLocalScope(temp_context_var)); 1620 Do(ExitTempLocalScope(temp_context_var));
1621 Do(ExitTempLocalScope(temp_stack_trace_var)); 1621 Do(ExitTempLocalScope(temp_stack_trace_var));
1622 Do(ExitTempLocalScope(temp_error_var)); 1622 Do(ExitTempLocalScope(temp_error_var));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 return false; 1662 return false;
1663 } 1663 }
1664 1664
1665 1665
1666 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { 1666 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
1667 ASSERT(Token::IsTypeTestOperator(node->kind())); 1667 ASSERT(Token::IsTypeTestOperator(node->kind()));
1668 const AbstractType& type = node->right()->AsTypeNode()->type(); 1668 const AbstractType& type = node->right()->AsTypeNode()->type();
1669 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 1669 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
1670 const bool negate_result = (node->kind() == Token::kISNOT); 1670 const bool negate_result = (node->kind() == Token::kISNOT);
1671 // All objects are instances of type T if Object type is a subtype of type T. 1671 // All objects are instances of type T if Object type is a subtype of type T.
1672 const Type& object_type = Type::Handle(I, Type::ObjectType()); 1672 const Type& object_type = Type::Handle(Z, Type::ObjectType());
1673 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { 1673 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) {
1674 // Must evaluate left side. 1674 // Must evaluate left side.
1675 EffectGraphVisitor for_left_value(owner()); 1675 EffectGraphVisitor for_left_value(owner());
1676 node->left()->Visit(&for_left_value); 1676 node->left()->Visit(&for_left_value);
1677 Append(for_left_value); 1677 Append(for_left_value);
1678 ReturnDefinition(new(I) ConstantInstr(Bool::Get(!negate_result))); 1678 ReturnDefinition(new(Z) ConstantInstr(Bool::Get(!negate_result)));
1679 return; 1679 return;
1680 } 1680 }
1681 ValueGraphVisitor for_left_value(owner()); 1681 ValueGraphVisitor for_left_value(owner());
1682 node->left()->Visit(&for_left_value); 1682 node->left()->Visit(&for_left_value);
1683 Append(for_left_value); 1683 Append(for_left_value);
1684 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1684 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1685 PushArgumentInstr* push_instantiator = NULL; 1685 PushArgumentInstr* push_instantiator = NULL;
1686 PushArgumentInstr* push_type_args = NULL; 1686 PushArgumentInstr* push_type_args = NULL;
1687 if (type.IsInstantiated()) { 1687 if (type.IsInstantiated()) {
1688 push_instantiator = PushArgument(BuildNullValue()); 1688 push_instantiator = PushArgument(BuildNullValue());
1689 push_type_args = PushArgument(BuildNullValue()); 1689 push_type_args = PushArgument(BuildNullValue());
1690 } else { 1690 } else {
1691 BuildTypecheckPushArguments(node->token_pos(), 1691 BuildTypecheckPushArguments(node->token_pos(),
1692 &push_instantiator, 1692 &push_instantiator,
1693 &push_type_args); 1693 &push_type_args);
1694 } 1694 }
1695 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1695 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1696 new(I) ZoneGrowableArray<PushArgumentInstr*>(5); 1696 new(Z) ZoneGrowableArray<PushArgumentInstr*>(5);
1697 arguments->Add(push_left); 1697 arguments->Add(push_left);
1698 arguments->Add(push_instantiator); 1698 arguments->Add(push_instantiator);
1699 arguments->Add(push_type_args); 1699 arguments->Add(push_type_args);
1700 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1700 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1701 Value* type_arg = Bind( 1701 Value* type_arg = Bind(
1702 new(I) ConstantInstr(node->right()->AsTypeNode()->type())); 1702 new(Z) ConstantInstr(node->right()->AsTypeNode()->type()));
1703 arguments->Add(PushArgument(type_arg)); 1703 arguments->Add(PushArgument(type_arg));
1704 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT); 1704 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
1705 Value* negate_arg = Bind(new(I) ConstantInstr(negate)); 1705 Value* negate_arg = Bind(new(Z) ConstantInstr(negate));
1706 arguments->Add(PushArgument(negate_arg)); 1706 arguments->Add(PushArgument(negate_arg));
1707 const intptr_t kNumArgsChecked = 1; 1707 const intptr_t kNumArgsChecked = 1;
1708 InstanceCallInstr* call = new(I) InstanceCallInstr( 1708 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1709 node->token_pos(), 1709 node->token_pos(),
1710 Library::PrivateCoreLibName(Symbols::_instanceOf()), 1710 Library::PrivateCoreLibName(Symbols::_instanceOf()),
1711 node->kind(), 1711 node->kind(),
1712 arguments, 1712 arguments,
1713 Object::null_array(), // No argument names. 1713 Object::null_array(), // No argument names.
1714 kNumArgsChecked, 1714 kNumArgsChecked,
1715 owner()->ic_data_array()); 1715 owner()->ic_data_array());
1716 ReturnDefinition(call); 1716 ReturnDefinition(call);
1717 } 1717 }
1718 1718
1719 1719
1720 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1720 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1721 ASSERT(Token::IsTypeCastOperator(node->kind())); 1721 ASSERT(Token::IsTypeCastOperator(node->kind()));
1722 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1722 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1723 const AbstractType& type = node->right()->AsTypeNode()->type(); 1723 const AbstractType& type = node->right()->AsTypeNode()->type();
1724 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 1724 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
1725 ValueGraphVisitor for_value(owner()); 1725 ValueGraphVisitor for_value(owner());
1726 node->left()->Visit(&for_value); 1726 node->left()->Visit(&for_value);
1727 Append(for_value); 1727 Append(for_value);
1728 const String& dst_name = String::ZoneHandle( 1728 const String& dst_name = String::ZoneHandle(
1729 I, Symbols::New(Exceptions::kCastErrorDstName)); 1729 Z, Symbols::New(Exceptions::kCastErrorDstName));
1730 if (CanSkipTypeCheck(node->token_pos(), 1730 if (CanSkipTypeCheck(node->token_pos(),
1731 for_value.value(), 1731 for_value.value(),
1732 type, 1732 type,
1733 dst_name)) { 1733 dst_name)) {
1734 // Check for javascript compatibility. 1734 // Check for javascript compatibility.
1735 // Do not skip type check if javascript compatibility warning is required. 1735 // Do not skip type check if javascript compatibility warning is required.
1736 if (!FLAG_warn_on_javascript_compatibility || 1736 if (!FLAG_warn_on_javascript_compatibility ||
1737 !owner()->WarnOnJSIntegralNumTypeTest(node->left(), type)) { 1737 !owner()->WarnOnJSIntegralNumTypeTest(node->left(), type)) {
1738 ReturnValue(for_value.value()); 1738 ReturnValue(for_value.value());
1739 return; 1739 return;
1740 } 1740 }
1741 } 1741 }
1742 PushArgumentInstr* push_left = PushArgument(for_value.value()); 1742 PushArgumentInstr* push_left = PushArgument(for_value.value());
1743 PushArgumentInstr* push_instantiator = NULL; 1743 PushArgumentInstr* push_instantiator = NULL;
1744 PushArgumentInstr* push_type_args = NULL; 1744 PushArgumentInstr* push_type_args = NULL;
1745 if (type.IsInstantiated()) { 1745 if (type.IsInstantiated()) {
1746 push_instantiator = PushArgument(BuildNullValue()); 1746 push_instantiator = PushArgument(BuildNullValue());
1747 push_type_args = PushArgument(BuildNullValue()); 1747 push_type_args = PushArgument(BuildNullValue());
1748 } else { 1748 } else {
1749 BuildTypecheckPushArguments(node->token_pos(), 1749 BuildTypecheckPushArguments(node->token_pos(),
1750 &push_instantiator, 1750 &push_instantiator,
1751 &push_type_args); 1751 &push_type_args);
1752 } 1752 }
1753 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1753 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1754 new(I) ZoneGrowableArray<PushArgumentInstr*>(4); 1754 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4);
1755 arguments->Add(push_left); 1755 arguments->Add(push_left);
1756 arguments->Add(push_instantiator); 1756 arguments->Add(push_instantiator);
1757 arguments->Add(push_type_args); 1757 arguments->Add(push_type_args);
1758 Value* type_arg = Bind(new(I) ConstantInstr(type)); 1758 Value* type_arg = Bind(new(Z) ConstantInstr(type));
1759 arguments->Add(PushArgument(type_arg)); 1759 arguments->Add(PushArgument(type_arg));
1760 const intptr_t kNumArgsChecked = 1; 1760 const intptr_t kNumArgsChecked = 1;
1761 InstanceCallInstr* call = new(I) InstanceCallInstr( 1761 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1762 node->token_pos(), 1762 node->token_pos(),
1763 Library::PrivateCoreLibName(Symbols::_as()), 1763 Library::PrivateCoreLibName(Symbols::_as()),
1764 node->kind(), 1764 node->kind(),
1765 arguments, 1765 arguments,
1766 Object::null_array(), // No argument names. 1766 Object::null_array(), // No argument names.
1767 kNumArgsChecked, 1767 kNumArgsChecked,
1768 owner()->ic_data_array()); 1768 owner()->ic_data_array());
1769 ReturnDefinition(call); 1769 ReturnDefinition(call);
1770 } 1770 }
1771 1771
1772 1772
1773 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left, 1773 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left,
1774 AstNode* right, 1774 AstNode* right,
1775 Token::Kind kind, 1775 Token::Kind kind,
1776 intptr_t token_pos) { 1776 intptr_t token_pos) {
1777 ValueGraphVisitor for_left_value(owner()); 1777 ValueGraphVisitor for_left_value(owner());
1778 left->Visit(&for_left_value); 1778 left->Visit(&for_left_value);
1779 Append(for_left_value); 1779 Append(for_left_value);
1780 ValueGraphVisitor for_right_value(owner()); 1780 ValueGraphVisitor for_right_value(owner());
1781 right->Visit(&for_right_value); 1781 right->Visit(&for_right_value);
1782 Append(for_right_value); 1782 Append(for_right_value);
1783 StrictCompareInstr* comp = new(I) StrictCompareInstr(token_pos, 1783 StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos,
1784 kind, 1784 kind,
1785 for_left_value.value(), 1785 for_left_value.value(),
1786 for_right_value.value(), 1786 for_right_value.value(),
1787 true); // Number check. 1787 true); // Number check.
1788 return comp; 1788 return comp;
1789 } 1789 }
1790 1790
1791 1791
1792 // <Expression> :: Comparison { kind: Token::Kind 1792 // <Expression> :: Comparison { kind: Token::Kind
1793 // left: <Expression> 1793 // left: <Expression>
(...skipping 24 matching lines...) Expand all
1818 Token::Kind kind = 1818 Token::Kind kind =
1819 (node->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT; 1819 (node->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT;
1820 StrictCompareInstr* compare = 1820 StrictCompareInstr* compare =
1821 BuildStrictCompare(node->left(), node->right(), 1821 BuildStrictCompare(node->left(), node->right(),
1822 kind, node->token_pos()); 1822 kind, node->token_pos());
1823 ReturnDefinition(compare); 1823 ReturnDefinition(compare);
1824 return; 1824 return;
1825 } 1825 }
1826 1826
1827 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1827 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1828 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 1828 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1829 1829
1830 ValueGraphVisitor for_left_value(owner()); 1830 ValueGraphVisitor for_left_value(owner());
1831 node->left()->Visit(&for_left_value); 1831 node->left()->Visit(&for_left_value);
1832 Append(for_left_value); 1832 Append(for_left_value);
1833 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1833 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1834 arguments->Add(push_left); 1834 arguments->Add(push_left);
1835 1835
1836 ValueGraphVisitor for_right_value(owner()); 1836 ValueGraphVisitor for_right_value(owner());
1837 node->right()->Visit(&for_right_value); 1837 node->right()->Visit(&for_right_value);
1838 Append(for_right_value); 1838 Append(for_right_value);
1839 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1839 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1840 arguments->Add(push_right); 1840 arguments->Add(push_right);
1841 1841
1842 Definition* result = new(I) InstanceCallInstr( 1842 Definition* result = new(Z) InstanceCallInstr(
1843 node->token_pos(), 1843 node->token_pos(),
1844 Symbols::EqualOperator(), 1844 Symbols::EqualOperator(),
1845 Token::kEQ, // Result is negated later for kNE. 1845 Token::kEQ, // Result is negated later for kNE.
1846 arguments, 1846 arguments,
1847 Object::null_array(), 1847 Object::null_array(),
1848 2, 1848 2,
1849 owner()->ic_data_array()); 1849 owner()->ic_data_array());
1850 if (node->kind() == Token::kNE) { 1850 if (node->kind() == Token::kNE) {
1851 if (Isolate::Current()->TypeChecksEnabled() || 1851 if (Isolate::Current()->TypeChecksEnabled() ||
1852 Isolate::Current()->AssertsEnabled()) { 1852 Isolate::Current()->AssertsEnabled()) {
1853 Value* value = Bind(result); 1853 Value* value = Bind(result);
1854 result = new(I) AssertBooleanInstr(node->token_pos(), value); 1854 result = new(Z) AssertBooleanInstr(node->token_pos(), value);
1855 } 1855 }
1856 Value* value = Bind(result); 1856 Value* value = Bind(result);
1857 result = new(I) BooleanNegateInstr(value); 1857 result = new(Z) BooleanNegateInstr(value);
1858 } 1858 }
1859 ReturnDefinition(result); 1859 ReturnDefinition(result);
1860 return; 1860 return;
1861 } 1861 }
1862 1862
1863 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1863 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1864 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 1864 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1865 1865
1866 ValueGraphVisitor for_left_value(owner()); 1866 ValueGraphVisitor for_left_value(owner());
1867 node->left()->Visit(&for_left_value); 1867 node->left()->Visit(&for_left_value);
1868 Append(for_left_value); 1868 Append(for_left_value);
1869 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1869 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1870 arguments->Add(push_left); 1870 arguments->Add(push_left);
1871 1871
1872 ValueGraphVisitor for_right_value(owner()); 1872 ValueGraphVisitor for_right_value(owner());
1873 node->right()->Visit(&for_right_value); 1873 node->right()->Visit(&for_right_value);
1874 Append(for_right_value); 1874 Append(for_right_value);
1875 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1875 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1876 arguments->Add(push_right); 1876 arguments->Add(push_right);
1877 1877
1878 ASSERT(Token::IsRelationalOperator(node->kind())); 1878 ASSERT(Token::IsRelationalOperator(node->kind()));
1879 InstanceCallInstr* comp = new(I) InstanceCallInstr( 1879 InstanceCallInstr* comp = new(Z) InstanceCallInstr(
1880 node->token_pos(), 1880 node->token_pos(),
1881 String::ZoneHandle(I, Symbols::New(node->TokenName())), 1881 String::ZoneHandle(Z, Symbols::New(node->TokenName())),
1882 node->kind(), 1882 node->kind(),
1883 arguments, 1883 arguments,
1884 Object::null_array(), 1884 Object::null_array(),
1885 2, 1885 2,
1886 owner()->ic_data_array()); 1886 owner()->ic_data_array());
1887 ReturnDefinition(comp); 1887 ReturnDefinition(comp);
1888 } 1888 }
1889 1889
1890 1890
1891 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1891 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1892 // "!" cannot be overloaded, therefore do not call operator. 1892 // "!" cannot be overloaded, therefore do not call operator.
1893 if (node->kind() == Token::kNOT) { 1893 if (node->kind() == Token::kNOT) {
1894 ValueGraphVisitor for_value(owner()); 1894 ValueGraphVisitor for_value(owner());
1895 node->operand()->Visit(&for_value); 1895 node->operand()->Visit(&for_value);
1896 Append(for_value); 1896 Append(for_value);
1897 Value* value = for_value.value(); 1897 Value* value = for_value.value();
1898 if (Isolate::Current()->TypeChecksEnabled() || 1898 if (Isolate::Current()->TypeChecksEnabled() ||
1899 Isolate::Current()->AssertsEnabled()) { 1899 Isolate::Current()->AssertsEnabled()) {
1900 value = 1900 value =
1901 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value)); 1901 Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value));
1902 } 1902 }
1903 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value); 1903 BooleanNegateInstr* negate = new(Z) BooleanNegateInstr(value);
1904 ReturnDefinition(negate); 1904 ReturnDefinition(negate);
1905 return; 1905 return;
1906 } 1906 }
1907 1907
1908 ValueGraphVisitor for_value(owner()); 1908 ValueGraphVisitor for_value(owner());
1909 node->operand()->Visit(&for_value); 1909 node->operand()->Visit(&for_value);
1910 Append(for_value); 1910 Append(for_value);
1911 PushArgumentInstr* push_value = PushArgument(for_value.value()); 1911 PushArgumentInstr* push_value = PushArgument(for_value.value());
1912 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1912 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1913 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); 1913 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
1914 arguments->Add(push_value); 1914 arguments->Add(push_value);
1915 InstanceCallInstr* call = new(I) InstanceCallInstr( 1915 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1916 node->token_pos(), 1916 node->token_pos(),
1917 String::ZoneHandle(I, Symbols::New(node->TokenName())), 1917 String::ZoneHandle(Z, Symbols::New(node->TokenName())),
1918 node->kind(), 1918 node->kind(),
1919 arguments, 1919 arguments,
1920 Object::null_array(), 1920 Object::null_array(),
1921 1, 1921 1,
1922 owner()->ic_data_array()); 1922 owner()->ic_data_array());
1923 ReturnDefinition(call); 1923 ReturnDefinition(call);
1924 } 1924 }
1925 1925
1926 1926
1927 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1927 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 // 2008 //
2009 // Note: The specification of switch/case is under discussion and may change 2009 // Note: The specification of switch/case is under discussion and may change
2010 // drastically. 2010 // drastically.
2011 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { 2011 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
2012 const intptr_t len = node->case_expressions()->length(); 2012 const intptr_t len = node->case_expressions()->length();
2013 // Create case statements instructions. 2013 // Create case statements instructions.
2014 EffectGraphVisitor for_case_statements(owner()); 2014 EffectGraphVisitor for_case_statements(owner());
2015 // Compute the start of the statements fragment. 2015 // Compute the start of the statements fragment.
2016 JoinEntryInstr* statement_start = NULL; 2016 JoinEntryInstr* statement_start = NULL;
2017 if (node->label() == NULL) { 2017 if (node->label() == NULL) {
2018 statement_start = new(I) JoinEntryInstr(owner()->AllocateBlockId(), 2018 statement_start = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
2019 owner()->try_index()); 2019 owner()->try_index());
2020 } else { 2020 } else {
2021 // The case nodes are nested inside a SequenceNode that is the body of a 2021 // The case nodes are nested inside a SequenceNode that is the body of a
2022 // SwitchNode. The SwitchNode on the nesting stack contains the 2022 // SwitchNode. The SwitchNode on the nesting stack contains the
2023 // continue labels for all the case clauses. 2023 // continue labels for all the case clauses.
2024 statement_start = 2024 statement_start =
2025 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label()); 2025 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label());
2026 } 2026 }
2027 ASSERT(statement_start != NULL); 2027 ASSERT(statement_start != NULL);
2028 node->statements()->Visit(&for_case_statements); 2028 node->statements()->Visit(&for_case_statements);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2060 // Handle last (or only) case: false goes to exit or to statement if this 2060 // Handle last (or only) case: false goes to exit or to statement if this
2061 // node contains default. 2061 // node contains default.
2062 if (len > 0) { 2062 if (len > 0) {
2063 ASSERT(next_target != NULL); 2063 ASSERT(next_target != NULL);
2064 if (node->contains_default()) { 2064 if (node->contains_default()) {
2065 // True and false go to statement start. 2065 // True and false go to statement start.
2066 next_target->Goto(statement_start); 2066 next_target->Goto(statement_start);
2067 exit_instruction = statement_exit; 2067 exit_instruction = statement_exit;
2068 } else { 2068 } else {
2069 if (statement_exit != NULL) { 2069 if (statement_exit != NULL) {
2070 JoinEntryInstr* join = new(I) JoinEntryInstr(owner()->AllocateBlockId(), 2070 JoinEntryInstr* join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
2071 owner()->try_index()); 2071 owner()->try_index());
2072 statement_exit->Goto(join); 2072 statement_exit->Goto(join);
2073 next_target->Goto(join); 2073 next_target->Goto(join);
2074 exit_instruction = join; 2074 exit_instruction = join;
2075 } else { 2075 } else {
2076 exit_instruction = next_target; 2076 exit_instruction = next_target;
2077 } 2077 }
2078 } 2078 }
2079 } else { 2079 } else {
2080 // A CaseNode without case expressions must contain default. 2080 // A CaseNode without case expressions must contain default.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 // Traverse the body first in order to generate continue and break labels. 2144 // Traverse the body first in order to generate continue and break labels.
2145 EffectGraphVisitor for_body(owner()); 2145 EffectGraphVisitor for_body(owner());
2146 node->body()->Visit(&for_body); 2146 node->body()->Visit(&for_body);
2147 2147
2148 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 2148 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
2149 node->condition()->Visit(&for_test); 2149 node->condition()->Visit(&for_test);
2150 ASSERT(is_open()); 2150 ASSERT(is_open());
2151 2151
2152 // Tie do-while loop (test is after the body). 2152 // Tie do-while loop (test is after the body).
2153 JoinEntryInstr* body_entry_join = 2153 JoinEntryInstr* body_entry_join =
2154 new(I) JoinEntryInstr(owner()->AllocateBlockId(), 2154 new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
2155 owner()->try_index()); 2155 owner()->try_index());
2156 Goto(body_entry_join); 2156 Goto(body_entry_join);
2157 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 2157 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
2158 2158
2159 JoinEntryInstr* join = nested_loop.continue_target(); 2159 JoinEntryInstr* join = nested_loop.continue_target();
2160 if ((body_exit != NULL) || (join != NULL)) { 2160 if ((body_exit != NULL) || (join != NULL)) {
2161 if (join == NULL) { 2161 if (join == NULL) {
2162 join = new(I) JoinEntryInstr(owner()->AllocateBlockId(), 2162 join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
2163 owner()->try_index()); 2163 owner()->try_index());
2164 } 2164 }
2165 CheckStackOverflowInstr* check = new(I) CheckStackOverflowInstr( 2165 CheckStackOverflowInstr* check = new(Z) CheckStackOverflowInstr(
2166 node->token_pos(), owner()->loop_depth()); 2166 node->token_pos(), owner()->loop_depth());
2167 join->LinkTo(check); 2167 join->LinkTo(check);
2168 check->LinkTo(for_test.entry()); 2168 check->LinkTo(for_test.entry());
2169 if (body_exit != NULL) { 2169 if (body_exit != NULL) {
2170 body_exit->Goto(join); 2170 body_exit->Goto(join);
2171 } 2171 }
2172 } 2172 }
2173 2173
2174 for_test.IfTrueGoto(body_entry_join); 2174 for_test.IfTrueGoto(body_entry_join);
2175 join = nested_loop.break_target(); 2175 join = nested_loop.break_target();
(...skipping 29 matching lines...) Expand all
2205 EffectGraphVisitor for_body(owner()); 2205 EffectGraphVisitor for_body(owner());
2206 node->body()->Visit(&for_body); 2206 node->body()->Visit(&for_body);
2207 2207
2208 EffectGraphVisitor for_increment(owner()); 2208 EffectGraphVisitor for_increment(owner());
2209 node->increment()->Visit(&for_increment); 2209 node->increment()->Visit(&for_increment);
2210 2210
2211 // Join the loop body and increment and then tie the loop. 2211 // Join the loop body and increment and then tie the loop.
2212 JoinEntryInstr* continue_join = nested_loop.continue_target(); 2212 JoinEntryInstr* continue_join = nested_loop.continue_target();
2213 if ((continue_join != NULL) || for_body.is_open()) { 2213 if ((continue_join != NULL) || for_body.is_open()) {
2214 JoinEntryInstr* loop_entry = 2214 JoinEntryInstr* loop_entry =
2215 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 2215 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2216 if (continue_join != NULL) { 2216 if (continue_join != NULL) {
2217 if (for_body.is_open()) for_body.Goto(continue_join); 2217 if (for_body.is_open()) for_body.Goto(continue_join);
2218 Instruction* current = AppendFragment(continue_join, for_increment); 2218 Instruction* current = AppendFragment(continue_join, for_increment);
2219 current->Goto(loop_entry); 2219 current->Goto(loop_entry);
2220 } else { 2220 } else {
2221 for_body.Append(for_increment); 2221 for_body.Append(for_increment);
2222 for_body.Goto(loop_entry); 2222 for_body.Goto(loop_entry);
2223 } 2223 }
2224 Goto(loop_entry); 2224 Goto(loop_entry);
2225 exit_ = loop_entry; 2225 exit_ = loop_entry;
2226 AddInstruction( 2226 AddInstruction(
2227 new(I) CheckStackOverflowInstr(node->token_pos(), 2227 new(Z) CheckStackOverflowInstr(node->token_pos(),
2228 owner()->loop_depth())); 2228 owner()->loop_depth()));
2229 } 2229 }
2230 2230
2231 if (node->condition() == NULL) { 2231 if (node->condition() == NULL) {
2232 // Endless loop, no test. 2232 // Endless loop, no test.
2233 Append(for_body); 2233 Append(for_body);
2234 exit_ = nested_loop.break_target(); // May be NULL. 2234 exit_ = nested_loop.break_target(); // May be NULL.
2235 } else { 2235 } else {
2236 EffectGraphVisitor for_test_preamble(owner()); 2236 EffectGraphVisitor for_test_preamble(owner());
2237 if (node->condition_preamble() != NULL) { 2237 if (node->condition_preamble() != NULL) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 LocalVariable* ctx_var = node->scope()->LookupVariable( 2325 LocalVariable* ctx_var = node->scope()->LookupVariable(
2326 Symbols::AwaitContextVar(), false); 2326 Symbols::AwaitContextVar(), false);
2327 ASSERT((jump_var != NULL) && jump_var->is_captured()); 2327 ASSERT((jump_var != NULL) && jump_var->is_captured());
2328 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); 2328 ASSERT((ctx_var != NULL) && ctx_var->is_captured());
2329 const intptr_t jump_count = owner()->next_await_counter(); 2329 const intptr_t jump_count = owner()->next_await_counter();
2330 ASSERT(jump_count >= 0); 2330 ASSERT(jump_count >= 0);
2331 // Sanity check that we always add a JoinEntryInstr before adding a new 2331 // Sanity check that we always add a JoinEntryInstr before adding a new
2332 // state. 2332 // state.
2333 ASSERT(jump_count == owner()->await_joins()->length()); 2333 ASSERT(jump_count == owner()->await_joins()->length());
2334 // Store the counter in :await_jump_var. 2334 // Store the counter in :await_jump_var.
2335 Value* jump_val = Bind(new (I) ConstantInstr( 2335 Value* jump_val = Bind(new(Z) ConstantInstr(
2336 Smi::ZoneHandle(I, Smi::New(jump_count)))); 2336 Smi::ZoneHandle(Z, Smi::New(jump_count))));
2337 Do(BuildStoreLocal(*jump_var, jump_val)); 2337 Do(BuildStoreLocal(*jump_var, jump_val));
2338 // Save the current context for resuming. 2338 // Save the current context for resuming.
2339 BuildSaveContext(*ctx_var); 2339 BuildSaveContext(*ctx_var);
2340 owner()->await_levels()->Add(owner()->context_level()); 2340 owner()->await_levels()->Add(owner()->context_level());
2341 } 2341 }
2342 2342
2343 2343
2344 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { 2344 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const {
2345 return kFirstLocalSlotFromFp 2345 return kFirstLocalSlotFromFp
2346 - owner()->num_stack_locals() 2346 - owner()->num_stack_locals()
2347 - owner()->num_copied_params() 2347 - owner()->num_copied_params()
2348 - owner()->args_pushed() 2348 - owner()->args_pushed()
2349 - owner()->temp_count() + 1; 2349 - owner()->temp_count() + 1;
2350 } 2350 }
2351 2351
2352 2352
2353 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { 2353 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
2354 Do(new(I) PushTempInstr(value)); 2354 Do(new(Z) PushTempInstr(value));
2355 owner()->AllocateTemp(); 2355 owner()->AllocateTemp();
2356 2356
2357 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); 2357 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
2358 intptr_t index = GetCurrentTempLocalIndex(); 2358 intptr_t index = GetCurrentTempLocalIndex();
2359 char name[64]; 2359 char name[64];
2360 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); 2360 OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
2361 LocalVariable* var = 2361 LocalVariable* var =
2362 new(I) LocalVariable(0, 2362 new(Z) LocalVariable(0,
2363 String::ZoneHandle(I, Symbols::New(name)), 2363 String::ZoneHandle(Z, Symbols::New(name)),
2364 *value->Type()->ToAbstractType()); 2364 *value->Type()->ToAbstractType());
2365 var->set_index(index); 2365 var->set_index(index);
2366 return var; 2366 return var;
2367 } 2367 }
2368 2368
2369 2369
2370 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { 2370 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) {
2371 Value* tmp = Bind(new(I) LoadLocalInstr(*var)); 2371 Value* tmp = Bind(new(Z) LoadLocalInstr(*var));
2372 owner()->DeallocateTemps(1); 2372 owner()->DeallocateTemps(1);
2373 ASSERT(GetCurrentTempLocalIndex() == var->index()); 2373 ASSERT(GetCurrentTempLocalIndex() == var->index());
2374 return new(I) DropTempsInstr(1, tmp); 2374 return new(Z) DropTempsInstr(1, tmp);
2375 } 2375 }
2376 2376
2377 2377
2378 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { 2378 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) {
2379 intptr_t num_temps = node->num_temps(); 2379 intptr_t num_temps = node->num_temps();
2380 for (intptr_t i = 0; i < num_temps; ++i) { 2380 for (intptr_t i = 0; i < num_temps; ++i) {
2381 ValueGraphVisitor for_value(owner()); 2381 ValueGraphVisitor for_value(owner());
2382 node->InitializerAt(i)->Visit(&for_value); 2382 node->InitializerAt(i)->Visit(&for_value);
2383 Append(for_value); 2383 Append(for_value);
2384 Value* temp_val = for_value.value(); 2384 Value* temp_val = for_value.value();
2385 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); 2385 node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
2386 Do(new(I) PushTempInstr(temp_val)); 2386 Do(new(Z) PushTempInstr(temp_val));
2387 owner()->AllocateTemp(); 2387 owner()->AllocateTemp();
2388 } 2388 }
2389 } 2389 }
2390 2390
2391 2391
2392 void EffectGraphVisitor::VisitLetNode(LetNode* node) { 2392 void EffectGraphVisitor::VisitLetNode(LetNode* node) {
2393 BuildLetTempExpressions(node); 2393 BuildLetTempExpressions(node);
2394 2394
2395 // Visit body. 2395 // Visit body.
2396 for (intptr_t i = 0; i < node->nodes().length(); ++i) { 2396 for (intptr_t i = 0; i < node->nodes().length(); ++i) {
2397 EffectGraphVisitor for_effect(owner()); 2397 EffectGraphVisitor for_effect(owner());
2398 node->nodes()[i]->Visit(&for_effect); 2398 node->nodes()[i]->Visit(&for_effect);
2399 Append(for_effect); 2399 Append(for_effect);
2400 } 2400 }
2401 2401
2402 intptr_t num_temps = node->num_temps(); 2402 intptr_t num_temps = node->num_temps();
2403 if (num_temps > 0) { 2403 if (num_temps > 0) {
2404 owner()->DeallocateTemps(num_temps); 2404 owner()->DeallocateTemps(num_temps);
2405 Do(new(I) DropTempsInstr(num_temps, NULL)); 2405 Do(new(Z) DropTempsInstr(num_temps, NULL));
2406 } 2406 }
2407 } 2407 }
2408 2408
2409 2409
2410 void ValueGraphVisitor::VisitLetNode(LetNode* node) { 2410 void ValueGraphVisitor::VisitLetNode(LetNode* node) {
2411 BuildLetTempExpressions(node); 2411 BuildLetTempExpressions(node);
2412 2412
2413 // Visit body. 2413 // Visit body.
2414 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { 2414 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) {
2415 EffectGraphVisitor for_effect(owner()); 2415 EffectGraphVisitor for_effect(owner());
2416 node->nodes()[i]->Visit(&for_effect); 2416 node->nodes()[i]->Visit(&for_effect);
2417 Append(for_effect); 2417 Append(for_effect);
2418 } 2418 }
2419 // Visit the last body expression for value. 2419 // Visit the last body expression for value.
2420 ValueGraphVisitor for_value(owner()); 2420 ValueGraphVisitor for_value(owner());
2421 node->nodes().Last()->Visit(&for_value); 2421 node->nodes().Last()->Visit(&for_value);
2422 Append(for_value); 2422 Append(for_value);
2423 Value* result_value = for_value.value(); 2423 Value* result_value = for_value.value();
2424 2424
2425 intptr_t num_temps = node->num_temps(); 2425 intptr_t num_temps = node->num_temps();
2426 if (num_temps > 0) { 2426 if (num_temps > 0) {
2427 owner()->DeallocateTemps(num_temps); 2427 owner()->DeallocateTemps(num_temps);
2428 ReturnDefinition(new(I) DropTempsInstr(num_temps, result_value)); 2428 ReturnDefinition(new(Z) DropTempsInstr(num_temps, result_value));
2429 } else { 2429 } else {
2430 ReturnValue(result_value); 2430 ReturnValue(result_value);
2431 } 2431 }
2432 } 2432 }
2433 2433
2434 2434
2435 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 2435 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
2436 const TypeArguments& type_args = 2436 const TypeArguments& type_args =
2437 TypeArguments::ZoneHandle(I, node->type().arguments()); 2437 TypeArguments::ZoneHandle(Z, node->type().arguments());
2438 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 2438 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
2439 type_args); 2439 type_args);
2440 Value* num_elements = 2440 Value* num_elements =
2441 Bind(new(I) ConstantInstr(Smi::ZoneHandle(I, Smi::New(node->length())))); 2441 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length()))));
2442 CreateArrayInstr* create = new(I) CreateArrayInstr(node->token_pos(), 2442 CreateArrayInstr* create = new(Z) CreateArrayInstr(node->token_pos(),
2443 element_type, 2443 element_type,
2444 num_elements); 2444 num_elements);
2445 Value* array_val = Bind(create); 2445 Value* array_val = Bind(create);
2446 2446
2447 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); 2447 { LocalVariable* tmp_var = EnterTempLocalScope(array_val);
2448 const intptr_t class_id = kArrayCid; 2448 const intptr_t class_id = kArrayCid;
2449 const intptr_t deopt_id = Isolate::kNoDeoptId; 2449 const intptr_t deopt_id = Isolate::kNoDeoptId;
2450 for (int i = 0; i < node->length(); ++i) { 2450 for (int i = 0; i < node->length(); ++i) {
2451 Value* array = Bind(new(I) LoadLocalInstr(*tmp_var)); 2451 Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var));
2452 Value* index = 2452 Value* index =
2453 Bind(new(I) ConstantInstr(Smi::ZoneHandle(I, Smi::New(i)))); 2453 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i))));
2454 ValueGraphVisitor for_value(owner()); 2454 ValueGraphVisitor for_value(owner());
2455 node->ElementAt(i)->Visit(&for_value); 2455 node->ElementAt(i)->Visit(&for_value);
2456 Append(for_value); 2456 Append(for_value);
2457 // No store barrier needed for constants. 2457 // No store barrier needed for constants.
2458 const StoreBarrierType emit_store_barrier = 2458 const StoreBarrierType emit_store_barrier =
2459 for_value.value()->BindsToConstant() 2459 for_value.value()->BindsToConstant()
2460 ? kNoStoreBarrier 2460 ? kNoStoreBarrier
2461 : kEmitStoreBarrier; 2461 : kEmitStoreBarrier;
2462 const intptr_t index_scale = Instance::ElementSizeFor(class_id); 2462 const intptr_t index_scale = Instance::ElementSizeFor(class_id);
2463 StoreIndexedInstr* store = new(I) StoreIndexedInstr( 2463 StoreIndexedInstr* store = new(Z) StoreIndexedInstr(
2464 array, index, for_value.value(), emit_store_barrier, 2464 array, index, for_value.value(), emit_store_barrier,
2465 index_scale, class_id, deopt_id, node->token_pos()); 2465 index_scale, class_id, deopt_id, node->token_pos());
2466 Do(store); 2466 Do(store);
2467 } 2467 }
2468 ReturnDefinition(ExitTempLocalScope(tmp_var)); 2468 ReturnDefinition(ExitTempLocalScope(tmp_var));
2469 } 2469 }
2470 } 2470 }
2471 2471
2472 2472
2473 void EffectGraphVisitor::VisitStringInterpolateNode( 2473 void EffectGraphVisitor::VisitStringInterpolateNode(
2474 StringInterpolateNode* node) { 2474 StringInterpolateNode* node) {
2475 ValueGraphVisitor for_argument(owner()); 2475 ValueGraphVisitor for_argument(owner());
2476 ArrayNode* arguments = node->value(); 2476 ArrayNode* arguments = node->value();
2477 if (arguments->length() == 1) { 2477 if (arguments->length() == 1) {
2478 ZoneGrowableArray<PushArgumentInstr*>* values = 2478 ZoneGrowableArray<PushArgumentInstr*>* values =
2479 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); 2479 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
2480 arguments->ElementAt(0)->Visit(&for_argument); 2480 arguments->ElementAt(0)->Visit(&for_argument);
2481 Append(for_argument); 2481 Append(for_argument);
2482 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 2482 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
2483 values->Add(push_arg); 2483 values->Add(push_arg);
2484 const int kNumberOfArguments = 1; 2484 const int kNumberOfArguments = 1;
2485 const Array& kNoArgumentNames = Object::null_array(); 2485 const Array& kNoArgumentNames = Object::null_array();
2486 const Class& cls = 2486 const Class& cls =
2487 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); 2487 Class::Handle(Library::LookupCoreClass(Symbols::StringBase()));
2488 ASSERT(!cls.IsNull()); 2488 ASSERT(!cls.IsNull());
2489 const Function& function = Function::ZoneHandle( 2489 const Function& function = Function::ZoneHandle(
2490 isolate(), 2490 Z,
2491 Resolver::ResolveStatic( 2491 Resolver::ResolveStatic(
2492 cls, 2492 cls,
2493 Library::PrivateCoreLibName(Symbols::InterpolateSingle()), 2493 Library::PrivateCoreLibName(Symbols::InterpolateSingle()),
2494 kNumberOfArguments, 2494 kNumberOfArguments,
2495 kNoArgumentNames)); 2495 kNoArgumentNames));
2496 StaticCallInstr* call = 2496 StaticCallInstr* call =
2497 new(I) StaticCallInstr(node->token_pos(), 2497 new(Z) StaticCallInstr(node->token_pos(),
2498 function, 2498 function,
2499 kNoArgumentNames, 2499 kNoArgumentNames,
2500 values, 2500 values,
2501 owner()->ic_data_array()); 2501 owner()->ic_data_array());
2502 ReturnDefinition(call); 2502 ReturnDefinition(call);
2503 return; 2503 return;
2504 } 2504 }
2505 arguments->Visit(&for_argument); 2505 arguments->Visit(&for_argument);
2506 Append(for_argument); 2506 Append(for_argument);
2507 StringInterpolateInstr* instr = 2507 StringInterpolateInstr* instr =
2508 new(I) StringInterpolateInstr(for_argument.value(), node->token_pos()); 2508 new(Z) StringInterpolateInstr(for_argument.value(), node->token_pos());
2509 ReturnDefinition(instr); 2509 ReturnDefinition(instr);
2510 } 2510 }
2511 2511
2512 2512
2513 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 2513 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
2514 const Function& function = node->function(); 2514 const Function& function = node->function();
2515 2515
2516 if (function.IsImplicitStaticClosureFunction()) { 2516 if (function.IsImplicitStaticClosureFunction()) {
2517 const Instance& closure = 2517 const Instance& closure =
2518 Instance::ZoneHandle(I, function.ImplicitStaticClosure()); 2518 Instance::ZoneHandle(Z, function.ImplicitStaticClosure());
2519 ReturnDefinition(new(I) ConstantInstr(closure)); 2519 ReturnDefinition(new(Z) ConstantInstr(closure));
2520 return; 2520 return;
2521 } 2521 }
2522 const bool is_implicit = function.IsImplicitInstanceClosureFunction(); 2522 const bool is_implicit = function.IsImplicitInstanceClosureFunction();
2523 ASSERT(is_implicit || function.IsNonImplicitClosureFunction()); 2523 ASSERT(is_implicit || function.IsNonImplicitClosureFunction());
2524 // The context scope may have already been set by the non-optimizing 2524 // The context scope may have already been set by the non-optimizing
2525 // compiler. If it was not, set it here. 2525 // compiler. If it was not, set it here.
2526 if (function.context_scope() == ContextScope::null()) { 2526 if (function.context_scope() == ContextScope::null()) {
2527 ASSERT(!is_implicit); 2527 ASSERT(!is_implicit);
2528 const ContextScope& context_scope = ContextScope::ZoneHandle( 2528 const ContextScope& context_scope = ContextScope::ZoneHandle(
2529 I, node->scope()->PreserveOuterScope(owner()->context_level())); 2529 Z, node->scope()->PreserveOuterScope(owner()->context_level()));
2530 ASSERT(!function.HasCode()); 2530 ASSERT(!function.HasCode());
2531 ASSERT(function.context_scope() == ContextScope::null()); 2531 ASSERT(function.context_scope() == ContextScope::null());
2532 function.set_context_scope(context_scope); 2532 function.set_context_scope(context_scope);
2533 const Class& cls = Class::Handle(I, owner()->function().Owner()); 2533 const Class& cls = Class::Handle(Z, owner()->function().Owner());
2534 // The closure is now properly setup, add it to the lookup table. 2534 // The closure is now properly setup, add it to the lookup table.
2535 // It is possible that the compiler creates more than one function 2535 // It is possible that the compiler creates more than one function
2536 // object for the same closure, e.g. when inlining nodes from 2536 // object for the same closure, e.g. when inlining nodes from
2537 // finally clauses. If we already have a function object for the 2537 // finally clauses. If we already have a function object for the
2538 // same closure, do not add a second one. We compare the origin 2538 // same closure, do not add a second one. We compare the origin
2539 // class, token position, and parent function to detect duplicates. 2539 // class, token position, and parent function to detect duplicates.
2540 // Note that we can have two different closure object for the same 2540 // Note that we can have two different closure object for the same
2541 // source text representation of the closure: one with a non-closurized 2541 // source text representation of the closure: one with a non-closurized
2542 // parent, and one with a closurized parent function. 2542 // parent, and one with a closurized parent function.
2543 2543
2544 const Function& found_func = Function::Handle( 2544 const Function& found_func = Function::Handle(
2545 I, cls.LookupClosureFunction(function.token_pos())); 2545 Z, cls.LookupClosureFunction(function.token_pos()));
2546 2546
2547 if (found_func.IsNull() || 2547 if (found_func.IsNull() ||
2548 (found_func.token_pos() != function.token_pos()) || 2548 (found_func.token_pos() != function.token_pos()) ||
2549 (found_func.script() != function.script()) || 2549 (found_func.script() != function.script()) ||
2550 (found_func.parent_function() != function.parent_function())) { 2550 (found_func.parent_function() != function.parent_function())) {
2551 cls.AddClosureFunction(function); 2551 cls.AddClosureFunction(function);
2552 } 2552 }
2553 } 2553 }
2554 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2554 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2555 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); 2555 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
2556 ASSERT(function.context_scope() != ContextScope::null()); 2556 ASSERT(function.context_scope() != ContextScope::null());
2557 2557
2558 // The function type of a closure may have type arguments. In that case, 2558 // The function type of a closure may have type arguments. In that case,
2559 // pass the type arguments of the instantiator. 2559 // pass the type arguments of the instantiator.
2560 const Class& cls = Class::ZoneHandle(I, function.signature_class()); 2560 const Class& cls = Class::ZoneHandle(Z, function.signature_class());
2561 ASSERT(!cls.IsNull()); 2561 ASSERT(!cls.IsNull());
2562 const bool requires_type_arguments = cls.NumTypeArguments() > 0; 2562 const bool requires_type_arguments = cls.NumTypeArguments() > 0;
2563 Value* type_arguments = NULL; 2563 Value* type_arguments = NULL;
2564 if (requires_type_arguments) { 2564 if (requires_type_arguments) {
2565 ASSERT(cls.type_arguments_field_offset() == 2565 ASSERT(cls.type_arguments_field_offset() ==
2566 Closure::type_arguments_offset()); 2566 Closure::type_arguments_offset());
2567 ASSERT(cls.instance_size() == Closure::InstanceSize()); 2567 ASSERT(cls.instance_size() == Closure::InstanceSize());
2568 const Class& instantiator_class = Class::Handle( 2568 const Class& instantiator_class = Class::Handle(
2569 I, owner()->function().Owner()); 2569 Z, owner()->function().Owner());
2570 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), 2570 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2571 instantiator_class, 2571 instantiator_class,
2572 NULL); 2572 NULL);
2573 arguments->Add(PushArgument(type_arguments)); 2573 arguments->Add(PushArgument(type_arguments));
2574 } 2574 }
2575 AllocateObjectInstr* alloc = new(I) AllocateObjectInstr(node->token_pos(), 2575 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(),
2576 cls, 2576 cls,
2577 arguments); 2577 arguments);
2578 alloc->set_closure_function(function); 2578 alloc->set_closure_function(function);
2579 2579
2580 Value* closure_val = Bind(alloc); 2580 Value* closure_val = Bind(alloc);
2581 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); 2581 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val);
2582 // Store function. 2582 // Store function.
2583 Value* closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var)); 2583 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
2584 Value* func_val = 2584 Value* func_val =
2585 Bind(new(I) ConstantInstr(Function::ZoneHandle(I, function.raw()))); 2585 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw())));
2586 Do(new(I) StoreInstanceFieldInstr(Closure::function_offset(), 2586 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(),
2587 closure_tmp_val, 2587 closure_tmp_val,
2588 func_val, 2588 func_val,
2589 kEmitStoreBarrier, 2589 kEmitStoreBarrier,
2590 node->token_pos())); 2590 node->token_pos()));
2591 if (is_implicit) { 2591 if (is_implicit) {
2592 // Create new context containing the receiver. 2592 // Create new context containing the receiver.
2593 const intptr_t kNumContextVariables = 1; // The receiver. 2593 const intptr_t kNumContextVariables = 1; // The receiver.
2594 Value* allocated_context = 2594 Value* allocated_context =
2595 Bind(new(I) AllocateContextInstr(node->token_pos(), 2595 Bind(new(Z) AllocateContextInstr(node->token_pos(),
2596 kNumContextVariables)); 2596 kNumContextVariables));
2597 { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context); 2597 { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context);
2598 // Store receiver in context. 2598 // Store receiver in context.
2599 Value* context_tmp_val = Bind(new(I) LoadLocalInstr(*context_tmp_var)); 2599 Value* context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var));
2600 ValueGraphVisitor for_receiver(owner()); 2600 ValueGraphVisitor for_receiver(owner());
2601 node->receiver()->Visit(&for_receiver); 2601 node->receiver()->Visit(&for_receiver);
2602 Append(for_receiver); 2602 Append(for_receiver);
2603 Value* receiver = for_receiver.value(); 2603 Value* receiver = for_receiver.value();
2604 Do(new(I) StoreInstanceFieldInstr(Context::variable_offset(0), 2604 Do(new(Z) StoreInstanceFieldInstr(Context::variable_offset(0),
2605 context_tmp_val, 2605 context_tmp_val,
2606 receiver, 2606 receiver,
2607 kEmitStoreBarrier, 2607 kEmitStoreBarrier,
2608 node->token_pos())); 2608 node->token_pos()));
2609 // Store new context in closure. 2609 // Store new context in closure.
2610 closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var)); 2610 closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
2611 context_tmp_val = Bind(new(I) LoadLocalInstr(*context_tmp_var)); 2611 context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var));
2612 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(), 2612 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(),
2613 closure_tmp_val, 2613 closure_tmp_val,
2614 context_tmp_val, 2614 context_tmp_val,
2615 kEmitStoreBarrier, 2615 kEmitStoreBarrier,
2616 node->token_pos())); 2616 node->token_pos()));
2617 Do(ExitTempLocalScope(context_tmp_var)); 2617 Do(ExitTempLocalScope(context_tmp_var));
2618 } 2618 }
2619 } else { 2619 } else {
2620 // Store current context in closure. 2620 // Store current context in closure.
2621 closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var)); 2621 closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
2622 Value* context = Bind(BuildCurrentContext()); 2622 Value* context = Bind(BuildCurrentContext());
2623 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(), 2623 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(),
2624 closure_tmp_val, 2624 closure_tmp_val,
2625 context, 2625 context,
2626 kEmitStoreBarrier, 2626 kEmitStoreBarrier,
2627 node->token_pos())); 2627 node->token_pos()));
2628 } 2628 }
2629 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); 2629 ReturnDefinition(ExitTempLocalScope(closure_tmp_var));
2630 } 2630 }
2631 } 2631 }
2632 2632
2633 2633
2634 void EffectGraphVisitor::BuildPushArguments( 2634 void EffectGraphVisitor::BuildPushArguments(
2635 const ArgumentListNode& node, 2635 const ArgumentListNode& node,
2636 ZoneGrowableArray<PushArgumentInstr*>* values) { 2636 ZoneGrowableArray<PushArgumentInstr*>* values) {
2637 for (intptr_t i = 0; i < node.length(); ++i) { 2637 for (intptr_t i = 0; i < node.length(); ++i) {
2638 ValueGraphVisitor for_argument(owner()); 2638 ValueGraphVisitor for_argument(owner());
2639 node.NodeAt(i)->Visit(&for_argument); 2639 node.NodeAt(i)->Visit(&for_argument);
2640 Append(for_argument); 2640 Append(for_argument);
2641 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 2641 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
2642 values->Add(push_arg); 2642 values->Add(push_arg);
2643 } 2643 }
2644 } 2644 }
2645 2645
2646 2646
2647 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 2647 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
2648 ValueGraphVisitor for_receiver(owner()); 2648 ValueGraphVisitor for_receiver(owner());
2649 node->receiver()->Visit(&for_receiver); 2649 node->receiver()->Visit(&for_receiver);
2650 Append(for_receiver); 2650 Append(for_receiver);
2651 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2651 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2652 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2652 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2653 new(I) ZoneGrowableArray<PushArgumentInstr*>( 2653 new(Z) ZoneGrowableArray<PushArgumentInstr*>(
2654 node->arguments()->length() + 1); 2654 node->arguments()->length() + 1);
2655 arguments->Add(push_receiver); 2655 arguments->Add(push_receiver);
2656 2656
2657 BuildPushArguments(*node->arguments(), arguments); 2657 BuildPushArguments(*node->arguments(), arguments);
2658 InstanceCallInstr* call = new(I) InstanceCallInstr( 2658 InstanceCallInstr* call = new(Z) InstanceCallInstr(
2659 node->token_pos(), 2659 node->token_pos(),
2660 node->function_name(), 2660 node->function_name(),
2661 Token::kILLEGAL, 2661 Token::kILLEGAL,
2662 arguments, 2662 arguments,
2663 node->arguments()->names(), 2663 node->arguments()->names(),
2664 1, 2664 1,
2665 owner()->ic_data_array()); 2665 owner()->ic_data_array());
2666 ReturnDefinition(call); 2666 ReturnDefinition(call);
2667 } 2667 }
2668 2668
(...skipping 25 matching lines...) Expand all
2694 } 2694 }
2695 } 2695 }
2696 return kDynamicCid; 2696 return kDynamicCid;
2697 } 2697 }
2698 2698
2699 2699
2700 // <Expression> ::= StaticCall { function: Function 2700 // <Expression> ::= StaticCall { function: Function
2701 // arguments: <ArgumentList> } 2701 // arguments: <ArgumentList> }
2702 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 2702 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
2703 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2703 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2704 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 2704 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
2705 BuildPushArguments(*node->arguments(), arguments); 2705 BuildPushArguments(*node->arguments(), arguments);
2706 StaticCallInstr* call = 2706 StaticCallInstr* call =
2707 new(I) StaticCallInstr(node->token_pos(), 2707 new(Z) StaticCallInstr(node->token_pos(),
2708 node->function(), 2708 node->function(),
2709 node->arguments()->names(), 2709 node->arguments()->names(),
2710 arguments, 2710 arguments,
2711 owner()->ic_data_array()); 2711 owner()->ic_data_array());
2712 if (node->function().is_native()) { 2712 if (node->function().is_native()) {
2713 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function()); 2713 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function());
2714 if (result_cid != kDynamicCid) { 2714 if (result_cid != kDynamicCid) {
2715 call->set_result_cid(result_cid); 2715 call->set_result_cid(result_cid);
2716 call->set_is_native_list_factory(true); 2716 call->set_is_native_list_factory(true);
2717 } 2717 }
2718 } 2718 }
2719 ReturnDefinition(call); 2719 ReturnDefinition(call);
2720 } 2720 }
2721 2721
2722 2722
2723 void EffectGraphVisitor::BuildClosureCall( 2723 void EffectGraphVisitor::BuildClosureCall(
2724 ClosureCallNode* node, bool result_needed) { 2724 ClosureCallNode* node, bool result_needed) {
2725 ValueGraphVisitor for_closure(owner()); 2725 ValueGraphVisitor for_closure(owner());
2726 node->closure()->Visit(&for_closure); 2726 node->closure()->Visit(&for_closure);
2727 Append(for_closure); 2727 Append(for_closure);
2728 2728
2729 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value()); 2729 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value());
2730 2730
2731 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2731 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2732 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 2732 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
2733 Value* closure_val = Bind(new(I) LoadLocalInstr(*tmp_var)); 2733 Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
2734 PushArgumentInstr* push_closure = PushArgument(closure_val); 2734 PushArgumentInstr* push_closure = PushArgument(closure_val);
2735 arguments->Add(push_closure); 2735 arguments->Add(push_closure);
2736 BuildPushArguments(*node->arguments(), arguments); 2736 BuildPushArguments(*node->arguments(), arguments);
2737 2737
2738 closure_val = Bind(new(I) LoadLocalInstr(*tmp_var)); 2738 closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
2739 LoadFieldInstr* function_load = new(I) LoadFieldInstr( 2739 LoadFieldInstr* function_load = new(Z) LoadFieldInstr(
2740 closure_val, 2740 closure_val,
2741 Closure::function_offset(), 2741 Closure::function_offset(),
2742 AbstractType::ZoneHandle(I, AbstractType::null()), 2742 AbstractType::ZoneHandle(Z, AbstractType::null()),
2743 node->token_pos()); 2743 node->token_pos());
2744 function_load->set_is_immutable(true); 2744 function_load->set_is_immutable(true);
2745 Value* function_val = Bind(function_load); 2745 Value* function_val = Bind(function_load);
2746 2746
2747 Definition* closure_call = 2747 Definition* closure_call =
2748 new(I) ClosureCallInstr(function_val, node, arguments); 2748 new(Z) ClosureCallInstr(function_val, node, arguments);
2749 if (result_needed) { 2749 if (result_needed) {
2750 Value* result = Bind(closure_call); 2750 Value* result = Bind(closure_call);
2751 Do(new(I) StoreLocalInstr(*tmp_var, result)); 2751 Do(new(Z) StoreLocalInstr(*tmp_var, result));
2752 } else { 2752 } else {
2753 Do(closure_call); 2753 Do(closure_call);
2754 } 2754 }
2755 ReturnDefinition(ExitTempLocalScope(tmp_var)); 2755 ReturnDefinition(ExitTempLocalScope(tmp_var));
2756 } 2756 }
2757 2757
2758 2758
2759 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2759 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2760 BuildClosureCall(node, false); 2760 BuildClosureCall(node, false);
2761 } 2761 }
2762 2762
2763 2763
2764 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2764 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2765 BuildClosureCall(node, true); 2765 BuildClosureCall(node, true);
2766 } 2766 }
2767 2767
2768 2768
2769 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { 2769 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
2770 Value* field = Bind(new(I) ConstantInstr(node->field())); 2770 Value* field = Bind(new(Z) ConstantInstr(node->field()));
2771 AddInstruction(new(I) InitStaticFieldInstr(field, node->field())); 2771 AddInstruction(new(Z) InitStaticFieldInstr(field, node->field()));
2772 } 2772 }
2773 2773
2774 2774
2775 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 2775 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
2776 Value* context = Bind(BuildCurrentContext()); 2776 Value* context = Bind(BuildCurrentContext());
2777 Value* clone = Bind(new(I) CloneContextInstr(node->token_pos(), context)); 2777 Value* clone = Bind(new(Z) CloneContextInstr(node->token_pos(), context));
2778 Do(BuildStoreContext(clone)); 2778 Do(BuildStoreContext(clone));
2779 } 2779 }
2780 2780
2781 2781
2782 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { 2782 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
2783 const Class& cls = Class::ZoneHandle(I, node->constructor().Owner()); 2783 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner());
2784 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; 2784 const bool cls_is_parameterized = cls.NumTypeArguments() > 0;
2785 2785
2786 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = 2786 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2787 new(I) ZoneGrowableArray<PushArgumentInstr*>( 2787 new(Z) ZoneGrowableArray<PushArgumentInstr*>(
2788 cls_is_parameterized ? 1 : 0); 2788 cls_is_parameterized ? 1 : 0);
2789 if (cls_is_parameterized) { 2789 if (cls_is_parameterized) {
2790 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(), 2790 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(),
2791 node->type_arguments()); 2791 node->type_arguments());
2792 allocate_arguments->Add(PushArgument(type_args)); 2792 allocate_arguments->Add(PushArgument(type_args));
2793 } 2793 }
2794 2794
2795 Definition* allocation = new(I) AllocateObjectInstr( 2795 Definition* allocation = new(Z) AllocateObjectInstr(
2796 node->token_pos(), 2796 node->token_pos(),
2797 Class::ZoneHandle(I, node->constructor().Owner()), 2797 Class::ZoneHandle(Z, node->constructor().Owner()),
2798 allocate_arguments); 2798 allocate_arguments);
2799 2799
2800 return Bind(allocation); 2800 return Bind(allocation);
2801 } 2801 }
2802 2802
2803 2803
2804 void EffectGraphVisitor::BuildConstructorCall( 2804 void EffectGraphVisitor::BuildConstructorCall(
2805 ConstructorCallNode* node, 2805 ConstructorCallNode* node,
2806 PushArgumentInstr* push_alloc_value) { 2806 PushArgumentInstr* push_alloc_value) {
2807 Value* ctor_arg = Bind(new(I) ConstantInstr( 2807 Value* ctor_arg = Bind(new(Z) ConstantInstr(
2808 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll)))); 2808 Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))));
2809 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); 2809 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
2810 2810
2811 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2811 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2812 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 2812 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
2813 arguments->Add(push_alloc_value); 2813 arguments->Add(push_alloc_value);
2814 arguments->Add(push_ctor_arg); 2814 arguments->Add(push_ctor_arg);
2815 2815
2816 BuildPushArguments(*node->arguments(), arguments); 2816 BuildPushArguments(*node->arguments(), arguments);
2817 Do(new(I) StaticCallInstr(node->token_pos(), 2817 Do(new(Z) StaticCallInstr(node->token_pos(),
2818 node->constructor(), 2818 node->constructor(),
2819 node->arguments()->names(), 2819 node->arguments()->names(),
2820 arguments, 2820 arguments,
2821 owner()->ic_data_array())); 2821 owner()->ic_data_array()));
2822 } 2822 }
2823 2823
2824 2824
2825 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { 2825 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) {
2826 const Function& function = node->constructor(); 2826 const Function& function = node->constructor();
2827 const Class& function_class = Class::Handle(function.Owner()); 2827 const Class& function_class = Class::Handle(function.Owner());
(...skipping 14 matching lines...) Expand all
2842 } 2842 }
2843 return FactoryRecognizer::ResultCid(function); 2843 return FactoryRecognizer::ResultCid(function);
2844 } 2844 }
2845 return kDynamicCid; // Not a known list constructor. 2845 return kDynamicCid; // Not a known list constructor.
2846 } 2846 }
2847 2847
2848 2848
2849 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2849 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2850 if (node->constructor().IsFactory()) { 2850 if (node->constructor().IsFactory()) {
2851 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2851 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2852 new(I) ZoneGrowableArray<PushArgumentInstr*>(); 2852 new(Z) ZoneGrowableArray<PushArgumentInstr*>();
2853 PushArgumentInstr* push_type_arguments = PushArgument( 2853 PushArgumentInstr* push_type_arguments = PushArgument(
2854 BuildInstantiatedTypeArguments(node->token_pos(), 2854 BuildInstantiatedTypeArguments(node->token_pos(),
2855 node->type_arguments())); 2855 node->type_arguments()));
2856 arguments->Add(push_type_arguments); 2856 arguments->Add(push_type_arguments);
2857 ASSERT(arguments->length() == 1); 2857 ASSERT(arguments->length() == 1);
2858 BuildPushArguments(*node->arguments(), arguments); 2858 BuildPushArguments(*node->arguments(), arguments);
2859 StaticCallInstr* call = 2859 StaticCallInstr* call =
2860 new(I) StaticCallInstr(node->token_pos(), 2860 new(Z) StaticCallInstr(node->token_pos(),
2861 node->constructor(), 2861 node->constructor(),
2862 node->arguments()->names(), 2862 node->arguments()->names(),
2863 arguments, 2863 arguments,
2864 owner()->ic_data_array()); 2864 owner()->ic_data_array());
2865 const intptr_t result_cid = GetResultCidOfListFactory(node); 2865 const intptr_t result_cid = GetResultCidOfListFactory(node);
2866 if (result_cid != kDynamicCid) { 2866 if (result_cid != kDynamicCid) {
2867 call->set_result_cid(result_cid); 2867 call->set_result_cid(result_cid);
2868 call->set_is_known_list_constructor(true); 2868 call->set_is_known_list_constructor(true);
2869 // Recognized fixed length array factory must have two arguments: 2869 // Recognized fixed length array factory must have two arguments:
2870 // (0) type-arguments, (1) length. 2870 // (0) type-arguments, (1) length.
(...skipping 10 matching lines...) Expand all
2881 // StaticCall(constructor, t_n+1, t_n+2, ...) 2881 // StaticCall(constructor, t_n+1, t_n+2, ...)
2882 // No need to preserve allocated value (simpler than in ValueGraphVisitor). 2882 // No need to preserve allocated value (simpler than in ValueGraphVisitor).
2883 Value* allocated_value = BuildObjectAllocation(node); 2883 Value* allocated_value = BuildObjectAllocation(node);
2884 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 2884 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
2885 BuildConstructorCall(node, push_allocated_value); 2885 BuildConstructorCall(node, push_allocated_value);
2886 } 2886 }
2887 2887
2888 2888
2889 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { 2889 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) {
2890 ASSERT(instantiator_class.NumTypeParameters() > 0); 2890 ASSERT(instantiator_class.NumTypeParameters() > 0);
2891 Function& outer_function = Function::Handle(I, owner()->function().raw()); 2891 Function& outer_function = Function::Handle(Z, owner()->function().raw());
2892 while (outer_function.IsLocalFunction()) { 2892 while (outer_function.IsLocalFunction()) {
2893 outer_function = outer_function.parent_function(); 2893 outer_function = outer_function.parent_function();
2894 } 2894 }
2895 if (outer_function.IsFactory()) { 2895 if (outer_function.IsFactory()) {
2896 return NULL; 2896 return NULL;
2897 } 2897 }
2898 2898
2899 LocalVariable* instantiator = owner()->parsed_function().instantiator(); 2899 LocalVariable* instantiator = owner()->parsed_function().instantiator();
2900 ASSERT(instantiator != NULL); 2900 ASSERT(instantiator != NULL);
2901 Value* result = Bind(BuildLoadLocal(*instantiator)); 2901 Value* result = Bind(BuildLoadLocal(*instantiator));
2902 return result; 2902 return result;
2903 } 2903 }
2904 2904
2905 2905
2906 // 'expression_temp_var' may not be used inside this method if 'instantiator' 2906 // 'expression_temp_var' may not be used inside this method if 'instantiator'
2907 // is not NULL. 2907 // is not NULL.
2908 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 2908 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
2909 intptr_t token_pos, 2909 intptr_t token_pos,
2910 const Class& instantiator_class, 2910 const Class& instantiator_class,
2911 Value* instantiator) { 2911 Value* instantiator) {
2912 if (instantiator_class.NumTypeParameters() == 0) { 2912 if (instantiator_class.NumTypeParameters() == 0) {
2913 // The type arguments are compile time constants. 2913 // The type arguments are compile time constants.
2914 TypeArguments& type_arguments = 2914 TypeArguments& type_arguments =
2915 TypeArguments::ZoneHandle(I, TypeArguments::null()); 2915 TypeArguments::ZoneHandle(Z, TypeArguments::null());
2916 // Type is temporary. Only its type arguments are preserved. 2916 // Type is temporary. Only its type arguments are preserved.
2917 Type& type = Type::Handle( 2917 Type& type = Type::Handle(
2918 I, 2918 Z,
2919 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2919 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
2920 type ^= ClassFinalizer::FinalizeType( 2920 type ^= ClassFinalizer::FinalizeType(
2921 instantiator_class, type, ClassFinalizer::kFinalize); 2921 instantiator_class, type, ClassFinalizer::kFinalize);
2922 ASSERT(!type.IsMalformedOrMalbounded()); 2922 ASSERT(!type.IsMalformedOrMalbounded());
2923 type_arguments = type.arguments(); 2923 type_arguments = type.arguments();
2924 type_arguments = type_arguments.Canonicalize(); 2924 type_arguments = type_arguments.Canonicalize();
2925 return Bind(new(I) ConstantInstr(type_arguments)); 2925 return Bind(new(Z) ConstantInstr(type_arguments));
2926 } 2926 }
2927 Function& outer_function = Function::Handle(I, owner()->function().raw()); 2927 Function& outer_function = Function::Handle(Z, owner()->function().raw());
2928 while (outer_function.IsLocalFunction()) { 2928 while (outer_function.IsLocalFunction()) {
2929 outer_function = outer_function.parent_function(); 2929 outer_function = outer_function.parent_function();
2930 } 2930 }
2931 if (outer_function.IsFactory()) { 2931 if (outer_function.IsFactory()) {
2932 // No instantiator for factories. 2932 // No instantiator for factories.
2933 ASSERT(instantiator == NULL); 2933 ASSERT(instantiator == NULL);
2934 LocalVariable* instantiator_var = 2934 LocalVariable* instantiator_var =
2935 owner()->parsed_function().instantiator(); 2935 owner()->parsed_function().instantiator();
2936 ASSERT(instantiator_var != NULL); 2936 ASSERT(instantiator_var != NULL);
2937 return Bind(BuildLoadLocal(*instantiator_var)); 2937 return Bind(BuildLoadLocal(*instantiator_var));
2938 } 2938 }
2939 if (instantiator == NULL) { 2939 if (instantiator == NULL) {
2940 instantiator = BuildInstantiator(instantiator_class); 2940 instantiator = BuildInstantiator(instantiator_class);
2941 } 2941 }
2942 // The instantiator is the receiver of the caller, which is not a factory. 2942 // The instantiator is the receiver of the caller, which is not a factory.
2943 // The receiver cannot be null; extract its TypeArguments object. 2943 // The receiver cannot be null; extract its TypeArguments object.
2944 // Note that in the factory case, the instantiator is the first parameter 2944 // Note that in the factory case, the instantiator is the first parameter
2945 // of the factory, i.e. already a TypeArguments object. 2945 // of the factory, i.e. already a TypeArguments object.
2946 intptr_t type_arguments_field_offset = 2946 intptr_t type_arguments_field_offset =
2947 instantiator_class.type_arguments_field_offset(); 2947 instantiator_class.type_arguments_field_offset();
2948 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2948 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2949 2949
2950 return Bind(new(I) LoadFieldInstr( 2950 return Bind(new(Z) LoadFieldInstr(
2951 instantiator, 2951 instantiator,
2952 type_arguments_field_offset, 2952 type_arguments_field_offset,
2953 Type::ZoneHandle(I, Type::null()), // Not an instance, no type. 2953 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type.
2954 Scanner::kNoSourcePos)); 2954 Scanner::kNoSourcePos));
2955 } 2955 }
2956 2956
2957 2957
2958 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2958 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2959 intptr_t token_pos, 2959 intptr_t token_pos,
2960 const TypeArguments& type_arguments) { 2960 const TypeArguments& type_arguments) {
2961 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2961 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2962 return Bind(new(I) ConstantInstr(type_arguments)); 2962 return Bind(new(Z) ConstantInstr(type_arguments));
2963 } 2963 }
2964 // The type arguments are uninstantiated. 2964 // The type arguments are uninstantiated.
2965 const Class& instantiator_class = Class::ZoneHandle( 2965 const Class& instantiator_class = Class::ZoneHandle(
2966 I, owner()->function().Owner()); 2966 Z, owner()->function().Owner());
2967 Value* instantiator_value = 2967 Value* instantiator_value =
2968 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 2968 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2969 const bool use_instantiator_type_args = 2969 const bool use_instantiator_type_args =
2970 type_arguments.IsUninstantiatedIdentity() || 2970 type_arguments.IsUninstantiatedIdentity() ||
2971 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); 2971 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class);
2972 if (use_instantiator_type_args) { 2972 if (use_instantiator_type_args) {
2973 return instantiator_value; 2973 return instantiator_value;
2974 } else { 2974 } else {
2975 return Bind(new(I) InstantiateTypeArgumentsInstr(token_pos, 2975 return Bind(new(Z) InstantiateTypeArgumentsInstr(token_pos,
2976 type_arguments, 2976 type_arguments,
2977 instantiator_class, 2977 instantiator_class,
2978 instantiator_value)); 2978 instantiator_value));
2979 } 2979 }
2980 } 2980 }
2981 2981
2982 2982
2983 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2983 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2984 if (node->constructor().IsFactory()) { 2984 if (node->constructor().IsFactory()) {
2985 EffectGraphVisitor::VisitConstructorCallNode(node); 2985 EffectGraphVisitor::VisitConstructorCallNode(node);
2986 return; 2986 return;
2987 } 2987 }
2988 2988
2989 // t_n contains the allocated and initialized object. 2989 // t_n contains the allocated and initialized object.
2990 // t_n <- AllocateObject(class) 2990 // t_n <- AllocateObject(class)
2991 // t_n <- StoreLocal(temp, t_n); 2991 // t_n <- StoreLocal(temp, t_n);
2992 // t_n+1 <- ctor-arg 2992 // t_n+1 <- ctor-arg
2993 // t_n+2... <- constructor arguments start here 2993 // t_n+2... <- constructor arguments start here
2994 // StaticCall(constructor, t_n, t_n+1, ...) 2994 // StaticCall(constructor, t_n, t_n+1, ...)
2995 // tn <- LoadLocal(temp) 2995 // tn <- LoadLocal(temp)
2996 2996
2997 Value* allocate = BuildObjectAllocation(node); 2997 Value* allocate = BuildObjectAllocation(node);
2998 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); 2998 { LocalVariable* tmp_var = EnterTempLocalScope(allocate);
2999 Value* allocated_tmp = Bind(new(I) LoadLocalInstr(*tmp_var)); 2999 Value* allocated_tmp = Bind(new(Z) LoadLocalInstr(*tmp_var));
3000 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); 3000 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
3001 BuildConstructorCall(node, push_allocated_value); 3001 BuildConstructorCall(node, push_allocated_value);
3002 ReturnDefinition(ExitTempLocalScope(tmp_var)); 3002 ReturnDefinition(ExitTempLocalScope(tmp_var));
3003 } 3003 }
3004 } 3004 }
3005 3005
3006 3006
3007 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 3007 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
3008 ValueGraphVisitor for_receiver(owner()); 3008 ValueGraphVisitor for_receiver(owner());
3009 node->receiver()->Visit(&for_receiver); 3009 node->receiver()->Visit(&for_receiver);
3010 Append(for_receiver); 3010 Append(for_receiver);
3011 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 3011 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
3012 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3012 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3013 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); 3013 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
3014 arguments->Add(push_receiver); 3014 arguments->Add(push_receiver);
3015 const String& name = 3015 const String& name =
3016 String::ZoneHandle(I, Field::GetterSymbol(node->field_name())); 3016 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
3017 InstanceCallInstr* call = new(I) InstanceCallInstr( 3017 InstanceCallInstr* call = new(Z) InstanceCallInstr(
3018 node->token_pos(), 3018 node->token_pos(),
3019 name, 3019 name,
3020 Token::kGET, 3020 Token::kGET,
3021 arguments, Object::null_array(), 3021 arguments, Object::null_array(),
3022 1, 3022 1,
3023 owner()->ic_data_array()); 3023 owner()->ic_data_array());
3024 ReturnDefinition(call); 3024 ReturnDefinition(call);
3025 } 3025 }
3026 3026
3027 3027
(...skipping 15 matching lines...) Expand all
3043 value = Bind(BuildStoreExprTemp(for_value.value())); 3043 value = Bind(BuildStoreExprTemp(for_value.value()));
3044 } else { 3044 } else {
3045 value = for_value.value(); 3045 value = for_value.value();
3046 } 3046 }
3047 arguments->Add(PushArgument(value)); 3047 arguments->Add(PushArgument(value));
3048 } 3048 }
3049 3049
3050 3050
3051 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 3051 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
3052 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3052 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3053 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 3053 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3054 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); 3054 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
3055 const String& name = 3055 const String& name =
3056 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); 3056 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3057 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(), 3057 InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
3058 name, 3058 name,
3059 Token::kSET, 3059 Token::kSET,
3060 arguments, 3060 arguments,
3061 Object::null_array(), 3061 Object::null_array(),
3062 2, // Checked arg count. 3062 2, // Checked arg count.
3063 owner()->ic_data_array()); 3063 owner()->ic_data_array());
3064 ReturnDefinition(call); 3064 ReturnDefinition(call);
3065 } 3065 }
3066 3066
3067 3067
3068 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 3068 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
3069 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3069 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3070 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 3070 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3071 BuildInstanceSetterArguments(node, arguments, kResultNeeded); 3071 BuildInstanceSetterArguments(node, arguments, kResultNeeded);
3072 const String& name = 3072 const String& name =
3073 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); 3073 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3074 Do(new(I) InstanceCallInstr(node->token_pos(), 3074 Do(new(Z) InstanceCallInstr(node->token_pos(),
3075 name, 3075 name,
3076 Token::kSET, 3076 Token::kSET,
3077 arguments, 3077 arguments,
3078 Object::null_array(), 3078 Object::null_array(),
3079 2, // Checked argument count. 3079 2, // Checked argument count.
3080 owner()->ic_data_array())); 3080 owner()->ic_data_array()));
3081 ReturnDefinition(BuildLoadExprTemp()); 3081 ReturnDefinition(BuildLoadExprTemp());
3082 } 3082 }
3083 3083
3084 3084
3085 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { 3085 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
3086 const String& getter_name = 3086 const String& getter_name =
3087 String::ZoneHandle(I, Field::GetterSymbol(node->field_name())); 3087 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
3088 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3088 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3089 new(I) ZoneGrowableArray<PushArgumentInstr*>(); 3089 new(Z) ZoneGrowableArray<PushArgumentInstr*>();
3090 Function& getter_function = Function::ZoneHandle(I, Function::null()); 3090 Function& getter_function = Function::ZoneHandle(Z, Function::null());
3091 if (node->is_super_getter()) { 3091 if (node->is_super_getter()) {
3092 // Statically resolved instance getter, i.e. "super getter". 3092 // Statically resolved instance getter, i.e. "super getter".
3093 ASSERT(node->receiver() != NULL); 3093 ASSERT(node->receiver() != NULL);
3094 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); 3094 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
3095 if (getter_function.IsNull()) { 3095 if (getter_function.IsNull()) {
3096 // Resolve and call noSuchMethod. 3096 // Resolve and call noSuchMethod.
3097 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos()); 3097 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
3098 arguments->Add(node->receiver()); 3098 arguments->Add(node->receiver());
3099 StaticCallInstr* call = 3099 StaticCallInstr* call =
3100 BuildStaticNoSuchMethodCall(node->cls(), 3100 BuildStaticNoSuchMethodCall(node->cls(),
3101 node->receiver(), 3101 node->receiver(),
3102 getter_name, 3102 getter_name,
3103 arguments, 3103 arguments,
3104 false, // Don't save last argument. 3104 false, // Don't save last argument.
3105 true); // Super invocation. 3105 true); // Super invocation.
3106 ReturnDefinition(call); 3106 ReturnDefinition(call);
3107 return; 3107 return;
(...skipping 29 matching lines...) Expand all
3137 InvocationMirror::EncodeType( 3137 InvocationMirror::EncodeType(
3138 node->cls().IsTopLevel() ? 3138 node->cls().IsTopLevel() ?
3139 InvocationMirror::kTopLevel : 3139 InvocationMirror::kTopLevel :
3140 InvocationMirror::kStatic, 3140 InvocationMirror::kStatic,
3141 InvocationMirror::kGetter)); 3141 InvocationMirror::kGetter));
3142 ReturnDefinition(call); 3142 ReturnDefinition(call);
3143 return; 3143 return;
3144 } 3144 }
3145 } 3145 }
3146 ASSERT(!getter_function.IsNull()); 3146 ASSERT(!getter_function.IsNull());
3147 StaticCallInstr* call = new(I) StaticCallInstr( 3147 StaticCallInstr* call = new(Z) StaticCallInstr(
3148 node->token_pos(), 3148 node->token_pos(),
3149 getter_function, 3149 getter_function,
3150 Object::null_array(), // No names 3150 Object::null_array(), // No names
3151 arguments, 3151 arguments,
3152 owner()->ic_data_array()); 3152 owner()->ic_data_array());
3153 ReturnDefinition(call); 3153 ReturnDefinition(call);
3154 } 3154 }
3155 3155
3156 3156
3157 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, 3157 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
3158 bool result_is_needed) { 3158 bool result_is_needed) {
3159 const String& setter_name = 3159 const String& setter_name =
3160 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); 3160 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3161 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3161 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3162 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); 3162 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
3163 // A super setter is an instance setter whose setter function is 3163 // A super setter is an instance setter whose setter function is
3164 // resolved at compile time (in the caller instance getter's super class). 3164 // resolved at compile time (in the caller instance getter's super class).
3165 // Unlike a static getter, a super getter has a receiver parameter. 3165 // Unlike a static getter, a super getter has a receiver parameter.
3166 const bool is_super_setter = (node->receiver() != NULL); 3166 const bool is_super_setter = (node->receiver() != NULL);
3167 Function& setter_function = 3167 Function& setter_function =
3168 Function::ZoneHandle(I, is_super_setter 3168 Function::ZoneHandle(Z, is_super_setter
3169 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) 3169 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name)
3170 : node->cls().LookupStaticFunction(setter_name)); 3170 : node->cls().LookupStaticFunction(setter_name));
3171 StaticCallInstr* call; 3171 StaticCallInstr* call;
3172 if (setter_function.IsNull()) { 3172 if (setter_function.IsNull()) {
3173 if (is_super_setter) { 3173 if (is_super_setter) {
3174 ASSERT(node->receiver() != NULL); 3174 ASSERT(node->receiver() != NULL);
3175 // Resolve and call noSuchMethod. 3175 // Resolve and call noSuchMethod.
3176 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos()); 3176 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
3177 arguments->Add(node->receiver()); 3177 arguments->Add(node->receiver());
3178 arguments->Add(node->value()); 3178 arguments->Add(node->value());
3179 call = BuildStaticNoSuchMethodCall( 3179 call = BuildStaticNoSuchMethodCall(
3180 node->cls(), 3180 node->cls(),
3181 node->receiver(), 3181 node->receiver(),
3182 setter_name, 3182 setter_name,
3183 arguments, 3183 arguments,
3184 result_is_needed, // Save last arg if result is needed. 3184 result_is_needed, // Save last arg if result is needed.
3185 true); // Super invocation. 3185 true); // Super invocation.
3186 } else { 3186 } else {
3187 // Throw a NoSuchMethodError. 3187 // Throw a NoSuchMethodError.
3188 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos()); 3188 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
3189 arguments->Add(node->value()); 3189 arguments->Add(node->value());
3190 call = BuildThrowNoSuchMethodError( 3190 call = BuildThrowNoSuchMethodError(
3191 node->token_pos(), 3191 node->token_pos(),
3192 node->cls(), 3192 node->cls(),
3193 setter_name, 3193 setter_name,
3194 arguments, // Argument is the value passed to the setter. 3194 arguments, // Argument is the value passed to the setter.
3195 InvocationMirror::EncodeType( 3195 InvocationMirror::EncodeType(
3196 node->cls().IsTopLevel() ? 3196 node->cls().IsTopLevel() ?
3197 InvocationMirror::kTopLevel : 3197 InvocationMirror::kTopLevel :
3198 InvocationMirror::kStatic, 3198 InvocationMirror::kStatic,
(...skipping 11 matching lines...) Expand all
3210 node->value()->Visit(&for_value); 3210 node->value()->Visit(&for_value);
3211 Append(for_value); 3211 Append(for_value);
3212 Value* value = NULL; 3212 Value* value = NULL;
3213 if (result_is_needed) { 3213 if (result_is_needed) {
3214 value = Bind(BuildStoreExprTemp(for_value.value())); 3214 value = Bind(BuildStoreExprTemp(for_value.value()));
3215 } else { 3215 } else {
3216 value = for_value.value(); 3216 value = for_value.value();
3217 } 3217 }
3218 arguments->Add(PushArgument(value)); 3218 arguments->Add(PushArgument(value));
3219 3219
3220 call = new(I) StaticCallInstr(node->token_pos(), 3220 call = new(Z) StaticCallInstr(node->token_pos(),
3221 setter_function, 3221 setter_function,
3222 Object::null_array(), // No names. 3222 Object::null_array(), // No names.
3223 arguments, 3223 arguments,
3224 owner()->ic_data_array()); 3224 owner()->ic_data_array());
3225 } 3225 }
3226 if (result_is_needed) { 3226 if (result_is_needed) {
3227 Do(call); 3227 Do(call);
3228 ReturnDefinition(BuildLoadExprTemp()); 3228 ReturnDefinition(BuildLoadExprTemp());
3229 } else { 3229 } else {
3230 ReturnDefinition(call); 3230 ReturnDefinition(call);
(...skipping 26 matching lines...) Expand all
3257 default: 3257 default:
3258 UNREACHABLE(); 3258 UNREACHABLE();
3259 return 0; 3259 return 0;
3260 } 3260 }
3261 } 3261 }
3262 3262
3263 3263
3264 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) { 3264 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) {
3265 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), 3265 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
3266 true); // Test only. 3266 true); // Test only.
3267 return new(I) LoadLocalInstr(*receiver_var); 3267 return new(Z) LoadLocalInstr(*receiver_var);
3268 } 3268 }
3269 3269
3270 3270
3271 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { 3271 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
3272 const Function& function = owner()->function(); 3272 const Function& function = owner()->function();
3273 if (!function.IsClosureFunction()) { 3273 if (!function.IsClosureFunction()) {
3274 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 3274 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
3275 switch (kind) { 3275 switch (kind) {
3276 case MethodRecognizer::kObjectEquals: { 3276 case MethodRecognizer::kObjectEquals: {
3277 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3277 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3278 LocalVariable* other_var = 3278 LocalVariable* other_var =
3279 node->scope()->LookupVariable(Symbols::Other(), 3279 node->scope()->LookupVariable(Symbols::Other(),
3280 true); // Test only. 3280 true); // Test only.
3281 Value* other = Bind(new(I) LoadLocalInstr(*other_var)); 3281 Value* other = Bind(new(Z) LoadLocalInstr(*other_var));
3282 // Receiver is not a number because numbers override equality. 3282 // Receiver is not a number because numbers override equality.
3283 const bool kNoNumberCheck = false; 3283 const bool kNoNumberCheck = false;
3284 StrictCompareInstr* compare = 3284 StrictCompareInstr* compare =
3285 new(I) StrictCompareInstr(node->token_pos(), 3285 new(Z) StrictCompareInstr(node->token_pos(),
3286 Token::kEQ_STRICT, 3286 Token::kEQ_STRICT,
3287 receiver, 3287 receiver,
3288 other, 3288 other,
3289 kNoNumberCheck); 3289 kNoNumberCheck);
3290 return ReturnDefinition(compare); 3290 return ReturnDefinition(compare);
3291 } 3291 }
3292 case MethodRecognizer::kStringBaseLength: 3292 case MethodRecognizer::kStringBaseLength:
3293 case MethodRecognizer::kStringBaseIsEmpty: { 3293 case MethodRecognizer::kStringBaseIsEmpty: {
3294 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3294 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3295 // Treat length loads as mutable (i.e. affected by side effects) to 3295 // Treat length loads as mutable (i.e. affected by side effects) to
3296 // avoid hoisting them since we can't hoist the preceding class-check. 3296 // avoid hoisting them since we can't hoist the preceding class-check.
3297 // This is because of externalization of strings that affects their 3297 // This is because of externalization of strings that affects their
3298 // class-id. 3298 // class-id.
3299 LoadFieldInstr* load = new(I) LoadFieldInstr( 3299 LoadFieldInstr* load = new(Z) LoadFieldInstr(
3300 receiver, 3300 receiver,
3301 String::length_offset(), 3301 String::length_offset(),
3302 Type::ZoneHandle(I, Type::SmiType()), 3302 Type::ZoneHandle(Z, Type::SmiType()),
3303 node->token_pos()); 3303 node->token_pos());
3304 load->set_result_cid(kSmiCid); 3304 load->set_result_cid(kSmiCid);
3305 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); 3305 load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
3306 if (kind == MethodRecognizer::kStringBaseLength) { 3306 if (kind == MethodRecognizer::kStringBaseLength) {
3307 return ReturnDefinition(load); 3307 return ReturnDefinition(load);
3308 } 3308 }
3309 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); 3309 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty);
3310 Value* zero_val = Bind(new(I) ConstantInstr( 3310 Value* zero_val = Bind(new(Z) ConstantInstr(
3311 Smi::ZoneHandle(I, Smi::New(0)))); 3311 Smi::ZoneHandle(Z, Smi::New(0))));
3312 Value* load_val = Bind(load); 3312 Value* load_val = Bind(load);
3313 StrictCompareInstr* compare = 3313 StrictCompareInstr* compare =
3314 new(I) StrictCompareInstr(node->token_pos(), 3314 new(Z) StrictCompareInstr(node->token_pos(),
3315 Token::kEQ_STRICT, 3315 Token::kEQ_STRICT,
3316 load_val, 3316 load_val,
3317 zero_val, 3317 zero_val,
3318 false); // No number check. 3318 false); // No number check.
3319 return ReturnDefinition(compare); 3319 return ReturnDefinition(compare);
3320 } 3320 }
3321 case MethodRecognizer::kGrowableArrayLength: 3321 case MethodRecognizer::kGrowableArrayLength:
3322 case MethodRecognizer::kObjectArrayLength: 3322 case MethodRecognizer::kObjectArrayLength:
3323 case MethodRecognizer::kImmutableArrayLength: 3323 case MethodRecognizer::kImmutableArrayLength:
3324 case MethodRecognizer::kTypedDataLength: { 3324 case MethodRecognizer::kTypedDataLength: {
3325 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3325 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3326 LoadFieldInstr* load = new(I) LoadFieldInstr( 3326 LoadFieldInstr* load = new(Z) LoadFieldInstr(
3327 receiver, 3327 receiver,
3328 OffsetForLengthGetter(kind), 3328 OffsetForLengthGetter(kind),
3329 Type::ZoneHandle(I, Type::SmiType()), 3329 Type::ZoneHandle(Z, Type::SmiType()),
3330 node->token_pos()); 3330 node->token_pos());
3331 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); 3331 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength);
3332 load->set_result_cid(kSmiCid); 3332 load->set_result_cid(kSmiCid);
3333 load->set_recognized_kind(kind); 3333 load->set_recognized_kind(kind);
3334 return ReturnDefinition(load); 3334 return ReturnDefinition(load);
3335 } 3335 }
3336 case MethodRecognizer::kClassIDgetID: { 3336 case MethodRecognizer::kClassIDgetID: {
3337 LocalVariable* value_var = 3337 LocalVariable* value_var =
3338 node->scope()->LookupVariable(Symbols::Value(), true); 3338 node->scope()->LookupVariable(Symbols::Value(), true);
3339 Value* value = Bind(new(I) LoadLocalInstr(*value_var)); 3339 Value* value = Bind(new(Z) LoadLocalInstr(*value_var));
3340 LoadClassIdInstr* load = new(I) LoadClassIdInstr(value); 3340 LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value);
3341 return ReturnDefinition(load); 3341 return ReturnDefinition(load);
3342 } 3342 }
3343 case MethodRecognizer::kGrowableArrayCapacity: { 3343 case MethodRecognizer::kGrowableArrayCapacity: {
3344 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3344 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3345 LoadFieldInstr* data_load = new(I) LoadFieldInstr( 3345 LoadFieldInstr* data_load = new(Z) LoadFieldInstr(
3346 receiver, 3346 receiver,
3347 Array::data_offset(), 3347 Array::data_offset(),
3348 Type::ZoneHandle(I, Type::DynamicType()), 3348 Type::ZoneHandle(Z, Type::DynamicType()),
3349 node->token_pos()); 3349 node->token_pos());
3350 data_load->set_result_cid(kArrayCid); 3350 data_load->set_result_cid(kArrayCid);
3351 Value* data = Bind(data_load); 3351 Value* data = Bind(data_load);
3352 LoadFieldInstr* length_load = new(I) LoadFieldInstr( 3352 LoadFieldInstr* length_load = new(Z) LoadFieldInstr(
3353 data, 3353 data,
3354 Array::length_offset(), 3354 Array::length_offset(),
3355 Type::ZoneHandle(I, Type::SmiType()), 3355 Type::ZoneHandle(Z, Type::SmiType()),
3356 node->token_pos()); 3356 node->token_pos());
3357 length_load->set_result_cid(kSmiCid); 3357 length_load->set_result_cid(kSmiCid);
3358 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); 3358 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
3359 return ReturnDefinition(length_load); 3359 return ReturnDefinition(length_load);
3360 } 3360 }
3361 case MethodRecognizer::kObjectArrayAllocate: { 3361 case MethodRecognizer::kObjectArrayAllocate: {
3362 LocalVariable* type_args_parameter = 3362 LocalVariable* type_args_parameter =
3363 node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(), 3363 node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(),
3364 true); 3364 true);
3365 Value* element_type = Bind(new(I) LoadLocalInstr(*type_args_parameter)); 3365 Value* element_type = Bind(new(Z) LoadLocalInstr(*type_args_parameter));
3366 LocalVariable* length_parameter = 3366 LocalVariable* length_parameter =
3367 node->scope()->LookupVariable(Symbols::Length(), true); 3367 node->scope()->LookupVariable(Symbols::Length(), true);
3368 Value* length = Bind(new(I) LoadLocalInstr(*length_parameter)); 3368 Value* length = Bind(new(Z) LoadLocalInstr(*length_parameter));
3369 CreateArrayInstr* create_array = 3369 CreateArrayInstr* create_array =
3370 new CreateArrayInstr(node->token_pos(), element_type, length); 3370 new CreateArrayInstr(node->token_pos(), element_type, length);
3371 return ReturnDefinition(create_array); 3371 return ReturnDefinition(create_array);
3372 } 3372 }
3373 case MethodRecognizer::kBigint_getDigits: { 3373 case MethodRecognizer::kBigint_getDigits: {
3374 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3374 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3375 LoadFieldInstr* load = new(I) LoadFieldInstr( 3375 LoadFieldInstr* load = new(Z) LoadFieldInstr(
3376 receiver, 3376 receiver,
3377 Bigint::digits_offset(), 3377 Bigint::digits_offset(),
3378 Type::ZoneHandle(I, Type::DynamicType()), 3378 Type::ZoneHandle(Z, Type::DynamicType()),
3379 node->token_pos()); 3379 node->token_pos());
3380 load->set_result_cid(kTypedDataUint32ArrayCid); 3380 load->set_result_cid(kTypedDataUint32ArrayCid);
3381 load->set_recognized_kind(kind); 3381 load->set_recognized_kind(kind);
3382 return ReturnDefinition(load); 3382 return ReturnDefinition(load);
3383 } 3383 }
3384 case MethodRecognizer::kBigint_getUsed: { 3384 case MethodRecognizer::kBigint_getUsed: {
3385 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3385 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3386 LoadFieldInstr* load = new(I) LoadFieldInstr( 3386 LoadFieldInstr* load = new(Z) LoadFieldInstr(
3387 receiver, 3387 receiver,
3388 Bigint::used_offset(), 3388 Bigint::used_offset(),
3389 Type::ZoneHandle(I, Type::SmiType()), 3389 Type::ZoneHandle(Z, Type::SmiType()),
3390 node->token_pos()); 3390 node->token_pos());
3391 load->set_result_cid(kSmiCid); 3391 load->set_result_cid(kSmiCid);
3392 load->set_recognized_kind(kind); 3392 load->set_recognized_kind(kind);
3393 return ReturnDefinition(load); 3393 return ReturnDefinition(load);
3394 } 3394 }
3395 case MethodRecognizer::kBigint_getNeg: { 3395 case MethodRecognizer::kBigint_getNeg: {
3396 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3396 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3397 LoadFieldInstr* load = new(I) LoadFieldInstr( 3397 LoadFieldInstr* load = new(Z) LoadFieldInstr(
3398 receiver, 3398 receiver,
3399 Bigint::neg_offset(), 3399 Bigint::neg_offset(),
3400 Type::ZoneHandle(I, Type::BoolType()), 3400 Type::ZoneHandle(Z, Type::BoolType()),
3401 node->token_pos()); 3401 node->token_pos());
3402 load->set_result_cid(kBoolCid); 3402 load->set_result_cid(kBoolCid);
3403 load->set_recognized_kind(kind); 3403 load->set_recognized_kind(kind);
3404 return ReturnDefinition(load); 3404 return ReturnDefinition(load);
3405 } 3405 }
3406 default: 3406 default:
3407 break; 3407 break;
3408 } 3408 }
3409 } 3409 }
3410 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); 3410 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
3411 NativeCallInstr* native_call = new(I) NativeCallInstr(node); 3411 NativeCallInstr* native_call = new(Z) NativeCallInstr(node);
3412 ReturnDefinition(native_call); 3412 ReturnDefinition(native_call);
3413 } 3413 }
3414 3414
3415 3415
3416 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { 3416 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
3417 // PrimaryNodes are temporary during parsing. 3417 // PrimaryNodes are temporary during parsing.
3418 UNREACHABLE(); 3418 UNREACHABLE();
3419 } 3419 }
3420 3420
3421 3421
(...skipping 11 matching lines...) Expand all
3433 3433
3434 // <Expression> ::= StoreLocal { local: LocalVariable 3434 // <Expression> ::= StoreLocal { local: LocalVariable
3435 // value: <Expression> } 3435 // value: <Expression> }
3436 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 3436 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
3437 // If the right hand side is an expression that does not contain 3437 // If the right hand side is an expression that does not contain
3438 // a safe point for the debugger to stop, add an explicit stub 3438 // a safe point for the debugger to stop, add an explicit stub
3439 // call. 3439 // call.
3440 if (node->value()->IsLiteralNode() || 3440 if (node->value()->IsLiteralNode() ||
3441 node->value()->IsLoadLocalNode() || 3441 node->value()->IsLoadLocalNode() ||
3442 node->value()->IsClosureNode()) { 3442 node->value()->IsClosureNode()) {
3443 AddInstruction(new(I) DebugStepCheckInstr( 3443 AddInstruction(new(Z) DebugStepCheckInstr(
3444 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 3444 node->token_pos(), RawPcDescriptors::kRuntimeCall));
3445 } 3445 }
3446 3446
3447 ValueGraphVisitor for_value(owner()); 3447 ValueGraphVisitor for_value(owner());
3448 node->value()->Visit(&for_value); 3448 node->value()->Visit(&for_value);
3449 Append(for_value); 3449 Append(for_value);
3450 Value* store_value = for_value.value(); 3450 Value* store_value = for_value.value();
3451 if (Isolate::Current()->TypeChecksEnabled()) { 3451 if (Isolate::Current()->TypeChecksEnabled()) {
3452 store_value = BuildAssignableValue(node->value()->token_pos(), 3452 store_value = BuildAssignableValue(node->value()->token_pos(),
3453 store_value, 3453 store_value,
3454 node->local().type(), 3454 node->local().type(),
3455 node->local().name()); 3455 node->local().name());
3456 } 3456 }
3457 Definition* store = BuildStoreLocal(node->local(), store_value); 3457 Definition* store = BuildStoreLocal(node->local(), store_value);
3458 ReturnDefinition(store); 3458 ReturnDefinition(store);
3459 } 3459 }
3460 3460
3461 3461
3462 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 3462 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
3463 LoadInstanceFieldNode* node) { 3463 LoadInstanceFieldNode* node) {
3464 ValueGraphVisitor for_instance(owner()); 3464 ValueGraphVisitor for_instance(owner());
3465 node->instance()->Visit(&for_instance); 3465 node->instance()->Visit(&for_instance);
3466 Append(for_instance); 3466 Append(for_instance);
3467 LoadFieldInstr* load = new(I) LoadFieldInstr( 3467 LoadFieldInstr* load = new(Z) LoadFieldInstr(
3468 for_instance.value(), 3468 for_instance.value(),
3469 &node->field(), 3469 &node->field(),
3470 AbstractType::ZoneHandle(I, node->field().type()), 3470 AbstractType::ZoneHandle(Z, node->field().type()),
3471 node->token_pos()); 3471 node->token_pos());
3472 if (node->field().guarded_cid() != kIllegalCid) { 3472 if (node->field().guarded_cid() != kIllegalCid) {
3473 if (!node->field().is_nullable() || 3473 if (!node->field().is_nullable() ||
3474 (node->field().guarded_cid() == kNullCid)) { 3474 (node->field().guarded_cid() == kNullCid)) {
3475 load->set_result_cid(node->field().guarded_cid()); 3475 load->set_result_cid(node->field().guarded_cid());
3476 } 3476 }
3477 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); 3477 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field());
3478 } 3478 }
3479 ReturnDefinition(load); 3479 ReturnDefinition(load);
3480 } 3480 }
3481 3481
3482 3482
3483 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 3483 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
3484 StoreInstanceFieldNode* node) { 3484 StoreInstanceFieldNode* node) {
3485 ValueGraphVisitor for_instance(owner()); 3485 ValueGraphVisitor for_instance(owner());
3486 node->instance()->Visit(&for_instance); 3486 node->instance()->Visit(&for_instance);
3487 Append(for_instance); 3487 Append(for_instance);
3488 ValueGraphVisitor for_value(owner()); 3488 ValueGraphVisitor for_value(owner());
3489 node->value()->Visit(&for_value); 3489 node->value()->Visit(&for_value);
3490 Append(for_value); 3490 Append(for_value);
3491 Value* store_value = for_value.value(); 3491 Value* store_value = for_value.value();
3492 if (Isolate::Current()->TypeChecksEnabled()) { 3492 if (Isolate::Current()->TypeChecksEnabled()) {
3493 const AbstractType& type = 3493 const AbstractType& type =
3494 AbstractType::ZoneHandle(I, node->field().type()); 3494 AbstractType::ZoneHandle(Z, node->field().type());
3495 const String& dst_name = String::ZoneHandle(I, node->field().name()); 3495 const String& dst_name = String::ZoneHandle(Z, node->field().name());
3496 store_value = BuildAssignableValue(node->value()->token_pos(), 3496 store_value = BuildAssignableValue(node->value()->token_pos(),
3497 store_value, 3497 store_value,
3498 type, 3498 type,
3499 dst_name); 3499 dst_name);
3500 } 3500 }
3501 3501
3502 store_value = Bind(BuildStoreExprTemp(store_value)); 3502 store_value = Bind(BuildStoreExprTemp(store_value));
3503 GuardFieldClassInstr* guard_field_class = 3503 GuardFieldClassInstr* guard_field_class =
3504 new(I) GuardFieldClassInstr(store_value, 3504 new(Z) GuardFieldClassInstr(store_value,
3505 node->field(), 3505 node->field(),
3506 I->GetNextDeoptId()); 3506 isolate()->GetNextDeoptId());
3507 AddInstruction(guard_field_class); 3507 AddInstruction(guard_field_class);
3508 3508
3509 store_value = Bind(BuildLoadExprTemp()); 3509 store_value = Bind(BuildLoadExprTemp());
3510 GuardFieldLengthInstr* guard_field_length = 3510 GuardFieldLengthInstr* guard_field_length =
3511 new(I) GuardFieldLengthInstr(store_value, 3511 new(Z) GuardFieldLengthInstr(store_value,
3512 node->field(), 3512 node->field(),
3513 I->GetNextDeoptId()); 3513 isolate()->GetNextDeoptId());
3514 AddInstruction(guard_field_length); 3514 AddInstruction(guard_field_length);
3515 3515
3516 store_value = Bind(BuildLoadExprTemp()); 3516 store_value = Bind(BuildLoadExprTemp());
3517 StoreInstanceFieldInstr* store = 3517 StoreInstanceFieldInstr* store =
3518 new(I) StoreInstanceFieldInstr(node->field(), 3518 new(Z) StoreInstanceFieldInstr(node->field(),
3519 for_instance.value(), 3519 for_instance.value(),
3520 store_value, 3520 store_value,
3521 kEmitStoreBarrier, 3521 kEmitStoreBarrier,
3522 node->token_pos()); 3522 node->token_pos());
3523 // Maybe initializing unboxed store. 3523 // Maybe initializing unboxed store.
3524 store->set_is_potential_unboxed_initialization(true); 3524 store->set_is_potential_unboxed_initialization(true);
3525 ReturnDefinition(store); 3525 ReturnDefinition(store);
3526 } 3526 }
3527 3527
3528 3528
3529 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 3529 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
3530 if (node->field().is_const()) { 3530 if (node->field().is_const()) {
3531 ASSERT(node->field().value() != Object::sentinel().raw()); 3531 ASSERT(node->field().value() != Object::sentinel().raw());
3532 ASSERT(node->field().value() != Object::transition_sentinel().raw()); 3532 ASSERT(node->field().value() != Object::transition_sentinel().raw());
3533 Definition* result = 3533 Definition* result =
3534 new(I) ConstantInstr(Instance::ZoneHandle(I, node->field().value())); 3534 new(Z) ConstantInstr(Instance::ZoneHandle(Z, node->field().value()));
3535 return ReturnDefinition(result); 3535 return ReturnDefinition(result);
3536 } 3536 }
3537 Value* field_value = Bind(new(I) ConstantInstr(node->field())); 3537 Value* field_value = Bind(new(Z) ConstantInstr(node->field()));
3538 LoadStaticFieldInstr* load = new(I) LoadStaticFieldInstr(field_value); 3538 LoadStaticFieldInstr* load = new(Z) LoadStaticFieldInstr(field_value);
3539 ReturnDefinition(load); 3539 ReturnDefinition(load);
3540 } 3540 }
3541 3541
3542 3542
3543 Definition* EffectGraphVisitor::BuildStoreStaticField( 3543 Definition* EffectGraphVisitor::BuildStoreStaticField(
3544 StoreStaticFieldNode* node, bool result_is_needed) { 3544 StoreStaticFieldNode* node, bool result_is_needed) {
3545 ValueGraphVisitor for_value(owner()); 3545 ValueGraphVisitor for_value(owner());
3546 node->value()->Visit(&for_value); 3546 node->value()->Visit(&for_value);
3547 Append(for_value); 3547 Append(for_value);
3548 Value* store_value = NULL; 3548 Value* store_value = NULL;
3549 if (result_is_needed) { 3549 if (result_is_needed) {
3550 store_value = Bind(BuildStoreExprTemp(for_value.value())); 3550 store_value = Bind(BuildStoreExprTemp(for_value.value()));
3551 } else { 3551 } else {
3552 store_value = for_value.value(); 3552 store_value = for_value.value();
3553 } 3553 }
3554 StoreStaticFieldInstr* store = 3554 StoreStaticFieldInstr* store =
3555 new(I) StoreStaticFieldInstr(node->field(), store_value); 3555 new(Z) StoreStaticFieldInstr(node->field(), store_value);
3556 3556
3557 if (result_is_needed) { 3557 if (result_is_needed) {
3558 Do(store); 3558 Do(store);
3559 return BuildLoadExprTemp(); 3559 return BuildLoadExprTemp();
3560 } else { 3560 } else {
3561 return store; 3561 return store;
3562 } 3562 }
3563 } 3563 }
3564 3564
3565 3565
3566 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 3566 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
3567 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded)); 3567 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded));
3568 } 3568 }
3569 3569
3570 3570
3571 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 3571 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
3572 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); 3572 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded));
3573 } 3573 }
3574 3574
3575 3575
3576 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { 3576 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
3577 Function* super_function = NULL; 3577 Function* super_function = NULL;
3578 if (node->IsSuperLoad()) { 3578 if (node->IsSuperLoad()) {
3579 // Resolve the load indexed operator in the super class. 3579 // Resolve the load indexed operator in the super class.
3580 super_function = &Function::ZoneHandle( 3580 super_function = &Function::ZoneHandle(
3581 I, Resolver::ResolveDynamicAnyArgs(node->super_class(), 3581 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(),
3582 Symbols::IndexToken())); 3582 Symbols::IndexToken()));
3583 if (super_function->IsNull()) { 3583 if (super_function->IsNull()) {
3584 // Could not resolve super operator. Generate call noSuchMethod() of the 3584 // Could not resolve super operator. Generate call noSuchMethod() of the
3585 // super class instead. 3585 // super class instead.
3586 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos()); 3586 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
3587 arguments->Add(node->array()); 3587 arguments->Add(node->array());
3588 arguments->Add(node->index_expr()); 3588 arguments->Add(node->index_expr());
3589 StaticCallInstr* call = 3589 StaticCallInstr* call =
3590 BuildStaticNoSuchMethodCall(node->super_class(), 3590 BuildStaticNoSuchMethodCall(node->super_class(),
3591 node->array(), 3591 node->array(),
3592 Symbols::IndexToken(), 3592 Symbols::IndexToken(),
3593 arguments, 3593 arguments,
3594 false, // Don't save last arg. 3594 false, // Don't save last arg.
3595 true); // Super invocation. 3595 true); // Super invocation.
3596 ReturnDefinition(call); 3596 ReturnDefinition(call);
3597 return; 3597 return;
3598 } 3598 }
3599 } 3599 }
3600 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3600 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3601 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 3601 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3602 ValueGraphVisitor for_array(owner()); 3602 ValueGraphVisitor for_array(owner());
3603 node->array()->Visit(&for_array); 3603 node->array()->Visit(&for_array);
3604 Append(for_array); 3604 Append(for_array);
3605 arguments->Add(PushArgument(for_array.value())); 3605 arguments->Add(PushArgument(for_array.value()));
3606 3606
3607 ValueGraphVisitor for_index(owner()); 3607 ValueGraphVisitor for_index(owner());
3608 node->index_expr()->Visit(&for_index); 3608 node->index_expr()->Visit(&for_index);
3609 Append(for_index); 3609 Append(for_index);
3610 arguments->Add(PushArgument(for_index.value())); 3610 arguments->Add(PushArgument(for_index.value()));
3611 3611
3612 if (super_function != NULL) { 3612 if (super_function != NULL) {
3613 // Generate static call to super operator. 3613 // Generate static call to super operator.
3614 StaticCallInstr* load = new(I) StaticCallInstr(node->token_pos(), 3614 StaticCallInstr* load = new(Z) StaticCallInstr(node->token_pos(),
3615 *super_function, 3615 *super_function,
3616 Object::null_array(), 3616 Object::null_array(),
3617 arguments, 3617 arguments,
3618 owner()->ic_data_array()); 3618 owner()->ic_data_array());
3619 ReturnDefinition(load); 3619 ReturnDefinition(load);
3620 } else { 3620 } else {
3621 // Generate dynamic call to index operator. 3621 // Generate dynamic call to index operator.
3622 const intptr_t checked_argument_count = 1; 3622 const intptr_t checked_argument_count = 1;
3623 InstanceCallInstr* load = new(I) InstanceCallInstr( 3623 InstanceCallInstr* load = new(Z) InstanceCallInstr(
3624 node->token_pos(), 3624 node->token_pos(),
3625 Symbols::IndexToken(), 3625 Symbols::IndexToken(),
3626 Token::kINDEX, 3626 Token::kINDEX,
3627 arguments, 3627 arguments,
3628 Object::null_array(), 3628 Object::null_array(),
3629 checked_argument_count, 3629 checked_argument_count,
3630 owner()->ic_data_array()); 3630 owner()->ic_data_array());
3631 ReturnDefinition(load); 3631 ReturnDefinition(load);
3632 } 3632 }
3633 } 3633 }
3634 3634
3635 3635
3636 Definition* EffectGraphVisitor::BuildStoreIndexedValues( 3636 Definition* EffectGraphVisitor::BuildStoreIndexedValues(
3637 StoreIndexedNode* node, 3637 StoreIndexedNode* node,
3638 bool result_is_needed) { 3638 bool result_is_needed) {
3639 Function* super_function = NULL; 3639 Function* super_function = NULL;
3640 if (node->IsSuperStore()) { 3640 if (node->IsSuperStore()) {
3641 // Resolve the store indexed operator in the super class. 3641 // Resolve the store indexed operator in the super class.
3642 super_function = &Function::ZoneHandle( 3642 super_function = &Function::ZoneHandle(
3643 I, Resolver::ResolveDynamicAnyArgs(node->super_class(), 3643 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(),
3644 Symbols::AssignIndexToken())); 3644 Symbols::AssignIndexToken()));
3645 if (super_function->IsNull()) { 3645 if (super_function->IsNull()) {
3646 // Could not resolve super operator. Generate call noSuchMethod() of the 3646 // Could not resolve super operator. Generate call noSuchMethod() of the
3647 // super class instead. 3647 // super class instead.
3648 ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos()); 3648 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
3649 arguments->Add(node->array()); 3649 arguments->Add(node->array());
3650 arguments->Add(node->index_expr()); 3650 arguments->Add(node->index_expr());
3651 arguments->Add(node->value()); 3651 arguments->Add(node->value());
3652 StaticCallInstr* call = BuildStaticNoSuchMethodCall( 3652 StaticCallInstr* call = BuildStaticNoSuchMethodCall(
3653 node->super_class(), 3653 node->super_class(),
3654 node->array(), 3654 node->array(),
3655 Symbols::AssignIndexToken(), 3655 Symbols::AssignIndexToken(),
3656 arguments, 3656 arguments,
3657 result_is_needed, // Save last arg if result is needed. 3657 result_is_needed, // Save last arg if result is needed.
3658 true); // Super invocation. 3658 true); // Super invocation.
3659 if (result_is_needed) { 3659 if (result_is_needed) {
3660 Do(call); 3660 Do(call);
3661 // BuildStaticNoSuchMethodCall stores the value in expression_temp. 3661 // BuildStaticNoSuchMethodCall stores the value in expression_temp.
3662 return BuildLoadExprTemp(); 3662 return BuildLoadExprTemp();
3663 } else { 3663 } else {
3664 return call; 3664 return call;
3665 } 3665 }
3666 } 3666 }
3667 } 3667 }
3668 3668
3669 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3669 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3670 new(I) ZoneGrowableArray<PushArgumentInstr*>(3); 3670 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3);
3671 ValueGraphVisitor for_array(owner()); 3671 ValueGraphVisitor for_array(owner());
3672 node->array()->Visit(&for_array); 3672 node->array()->Visit(&for_array);
3673 Append(for_array); 3673 Append(for_array);
3674 arguments->Add(PushArgument(for_array.value())); 3674 arguments->Add(PushArgument(for_array.value()));
3675 3675
3676 ValueGraphVisitor for_index(owner()); 3676 ValueGraphVisitor for_index(owner());
3677 node->index_expr()->Visit(&for_index); 3677 node->index_expr()->Visit(&for_index);
3678 Append(for_index); 3678 Append(for_index);
3679 arguments->Add(PushArgument(for_index.value())); 3679 arguments->Add(PushArgument(for_index.value()));
3680 3680
3681 ValueGraphVisitor for_value(owner()); 3681 ValueGraphVisitor for_value(owner());
3682 node->value()->Visit(&for_value); 3682 node->value()->Visit(&for_value);
3683 Append(for_value); 3683 Append(for_value);
3684 Value* value = NULL; 3684 Value* value = NULL;
3685 if (result_is_needed) { 3685 if (result_is_needed) {
3686 value = Bind(BuildStoreExprTemp(for_value.value())); 3686 value = Bind(BuildStoreExprTemp(for_value.value()));
3687 } else { 3687 } else {
3688 value = for_value.value(); 3688 value = for_value.value();
3689 } 3689 }
3690 arguments->Add(PushArgument(value)); 3690 arguments->Add(PushArgument(value));
3691 3691
3692 if (super_function != NULL) { 3692 if (super_function != NULL) {
3693 // Generate static call to super operator []=. 3693 // Generate static call to super operator []=.
3694 3694
3695 StaticCallInstr* store = 3695 StaticCallInstr* store =
3696 new(I) StaticCallInstr(node->token_pos(), 3696 new(Z) StaticCallInstr(node->token_pos(),
3697 *super_function, 3697 *super_function,
3698 Object::null_array(), 3698 Object::null_array(),
3699 arguments, 3699 arguments,
3700 owner()->ic_data_array()); 3700 owner()->ic_data_array());
3701 if (result_is_needed) { 3701 if (result_is_needed) {
3702 Do(store); 3702 Do(store);
3703 return BuildLoadExprTemp(); 3703 return BuildLoadExprTemp();
3704 } else { 3704 } else {
3705 return store; 3705 return store;
3706 } 3706 }
3707 } else { 3707 } else {
3708 // Generate dynamic call to operator []=. 3708 // Generate dynamic call to operator []=.
3709 const intptr_t checked_argument_count = 3; 3709 const intptr_t checked_argument_count = 3;
3710 const String& name = 3710 const String& name =
3711 String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); 3711 String::ZoneHandle(Z, Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
3712 InstanceCallInstr* store = 3712 InstanceCallInstr* store =
3713 new(I) InstanceCallInstr(node->token_pos(), 3713 new(Z) InstanceCallInstr(node->token_pos(),
3714 name, 3714 name,
3715 Token::kASSIGN_INDEX, 3715 Token::kASSIGN_INDEX,
3716 arguments, 3716 arguments,
3717 Object::null_array(), 3717 Object::null_array(),
3718 checked_argument_count, 3718 checked_argument_count,
3719 owner()->ic_data_array()); 3719 owner()->ic_data_array());
3720 if (result_is_needed) { 3720 if (result_is_needed) {
3721 Do(store); 3721 Do(store);
3722 return BuildLoadExprTemp(); 3722 return BuildLoadExprTemp();
3723 } else { 3723 } else {
(...skipping 18 matching lines...) Expand all
3742 owner()->function().context_scope()); 3742 owner()->function().context_scope());
3743 return !context_scope.IsNull() && (context_scope.num_variables() > 0); 3743 return !context_scope.IsNull() && (context_scope.num_variables() > 0);
3744 } 3744 }
3745 3745
3746 3746
3747 void EffectGraphVisitor::UnchainContexts(intptr_t n) { 3747 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
3748 if (n > 0) { 3748 if (n > 0) {
3749 Value* context = Bind(BuildCurrentContext()); 3749 Value* context = Bind(BuildCurrentContext());
3750 while (n-- > 0) { 3750 while (n-- > 0) {
3751 context = Bind( 3751 context = Bind(
3752 new(I) LoadFieldInstr(context, 3752 new(Z) LoadFieldInstr(context,
3753 Context::parent_offset(), 3753 Context::parent_offset(),
3754 // Not an instance, no type. 3754 // Not an instance, no type.
3755 Type::ZoneHandle(I, Type::null()), 3755 Type::ZoneHandle(Z, Type::null()),
3756 Scanner::kNoSourcePos)); 3756 Scanner::kNoSourcePos));
3757 } 3757 }
3758 Do(BuildStoreContext(context)); 3758 Do(BuildStoreContext(context));
3759 } 3759 }
3760 } 3760 }
3761 3761
3762 3762
3763 // <Statement> ::= Sequence { scope: LocalScope 3763 // <Statement> ::= Sequence { scope: LocalScope
3764 // nodes: <Statement>* 3764 // nodes: <Statement>*
3765 // label: SourceLabel } 3765 // label: SourceLabel }
3766 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { 3766 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
3767 LocalScope* scope = node->scope(); 3767 LocalScope* scope = node->scope();
3768 const Function& function = owner()->function(); 3768 const Function& function = owner()->function();
3769 const intptr_t num_context_variables = 3769 const intptr_t num_context_variables =
3770 (scope != NULL) ? scope->num_context_variables() : 0; 3770 (scope != NULL) ? scope->num_context_variables() : 0;
3771 const bool is_top_level_sequence = 3771 const bool is_top_level_sequence =
3772 node == owner()->parsed_function().node_sequence(); 3772 node == owner()->parsed_function().node_sequence();
3773 // The outermost function sequence cannot contain a label. 3773 // The outermost function sequence cannot contain a label.
3774 ASSERT((node->label() == NULL) || !is_top_level_sequence); 3774 ASSERT((node->label() == NULL) || !is_top_level_sequence);
3775 NestedBlock nested_block(owner(), node); 3775 NestedBlock nested_block(owner(), node);
3776 3776
3777 if (num_context_variables > 0) { 3777 if (num_context_variables > 0) {
3778 // The local scope declares variables that are captured. 3778 // The local scope declares variables that are captured.
3779 // Allocate and chain a new context (Except don't chain when at the function 3779 // Allocate and chain a new context (Except don't chain when at the function
3780 // entry if the function does not capture any variables from outer scopes). 3780 // entry if the function does not capture any variables from outer scopes).
3781 Value* allocated_context = 3781 Value* allocated_context =
3782 Bind(new(I) AllocateContextInstr(node->token_pos(), 3782 Bind(new(Z) AllocateContextInstr(node->token_pos(),
3783 num_context_variables)); 3783 num_context_variables));
3784 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); 3784 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
3785 if (HasContextScope() || !is_top_level_sequence) { 3785 if (HasContextScope() || !is_top_level_sequence) {
3786 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); 3786 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
3787 Value* parent_context = Bind(BuildCurrentContext()); 3787 Value* parent_context = Bind(BuildCurrentContext());
3788 Do(new(I) StoreInstanceFieldInstr(Context::parent_offset(), 3788 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(),
3789 tmp_val, 3789 tmp_val,
3790 parent_context, 3790 parent_context,
3791 kEmitStoreBarrier, 3791 kEmitStoreBarrier,
3792 Scanner::kNoSourcePos)); 3792 Scanner::kNoSourcePos));
3793 } 3793 }
3794 Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var)))); 3794 Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var))));
3795 } 3795 }
3796 3796
3797 // If this node_sequence is the body of the function being compiled, copy 3797 // If this node_sequence is the body of the function being compiled, copy
3798 // the captured parameters from the frame into the context. 3798 // the captured parameters from the frame into the context.
3799 if (is_top_level_sequence) { 3799 if (is_top_level_sequence) {
3800 ASSERT(scope->context_level() == 1); 3800 ASSERT(scope->context_level() == 1);
3801 const int num_params = function.NumParameters(); 3801 const int num_params = function.NumParameters();
3802 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 3802 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
3803 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; 3803 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp;
3804 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 3804 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
3805 const LocalVariable& parameter = *scope->VariableAt(pos); 3805 const LocalVariable& parameter = *scope->VariableAt(pos);
3806 ASSERT(parameter.owner() == scope); 3806 ASSERT(parameter.owner() == scope);
3807 if (parameter.is_captured()) { 3807 if (parameter.is_captured()) {
3808 // Create a temporary local describing the original position. 3808 // Create a temporary local describing the original position.
3809 const String& temp_name = Symbols::TempParam(); 3809 const String& temp_name = Symbols::TempParam();
3810 LocalVariable* temp_local = new(I) LocalVariable( 3810 LocalVariable* temp_local = new(Z) LocalVariable(
3811 0, // Token index. 3811 0, // Token index.
3812 temp_name, 3812 temp_name,
3813 Type::ZoneHandle(I, Type::DynamicType())); // Type. 3813 Type::ZoneHandle(Z, Type::DynamicType())); // Type.
3814 temp_local->set_index(param_frame_index); 3814 temp_local->set_index(param_frame_index);
3815 3815
3816 // Mark this local as captured parameter so that the optimizer 3816 // Mark this local as captured parameter so that the optimizer
3817 // correctly handles these when compiling try-catch: Captured 3817 // correctly handles these when compiling try-catch: Captured
3818 // parameters are not in the stack environment, therefore they 3818 // parameters are not in the stack environment, therefore they
3819 // must be skipped when emitting sync-code in try-blocks. 3819 // must be skipped when emitting sync-code in try-blocks.
3820 temp_local->set_is_captured_parameter(true); 3820 temp_local->set_is_captured_parameter(true);
3821 3821
3822 // Copy parameter from local frame to current context. 3822 // Copy parameter from local frame to current context.
3823 Value* load = Bind(BuildLoadLocal(*temp_local)); 3823 Value* load = Bind(BuildLoadLocal(*temp_local));
3824 Do(BuildStoreLocal(parameter, load)); 3824 Do(BuildStoreLocal(parameter, load));
3825 // Write NULL to the source location to detect buggy accesses and 3825 // Write NULL to the source location to detect buggy accesses and
3826 // allow GC of passed value if it gets overwritten by a new value in 3826 // allow GC of passed value if it gets overwritten by a new value in
3827 // the function. 3827 // the function.
3828 Value* null_constant = Bind(new(I) ConstantInstr( 3828 Value* null_constant = Bind(new(Z) ConstantInstr(
3829 Object::ZoneHandle(I, Object::null()))); 3829 Object::ZoneHandle(Z, Object::null())));
3830 Do(BuildStoreLocal(*temp_local, null_constant)); 3830 Do(BuildStoreLocal(*temp_local, null_constant));
3831 } 3831 }
3832 } 3832 }
3833 } 3833 }
3834 } 3834 }
3835 3835
3836 // This check may be deleted if the generated code is leaf. 3836 // This check may be deleted if the generated code is leaf.
3837 // Native functions don't need a stack check at entry. 3837 // Native functions don't need a stack check at entry.
3838 if (is_top_level_sequence && !function.is_native()) { 3838 if (is_top_level_sequence && !function.is_native()) {
3839 // Always allocate CheckOverflowInstr so that deopt-ids match regardless 3839 // Always allocate CheckOverflowInstr so that deopt-ids match regardless
3840 // if we inline or not. 3840 // if we inline or not.
3841 if (!function.IsImplicitGetterFunction() && 3841 if (!function.IsImplicitGetterFunction() &&
3842 !function.IsImplicitSetterFunction()) { 3842 !function.IsImplicitSetterFunction()) {
3843 CheckStackOverflowInstr* check = 3843 CheckStackOverflowInstr* check =
3844 new(I) CheckStackOverflowInstr(function.token_pos(), 0); 3844 new(Z) CheckStackOverflowInstr(function.token_pos(), 0);
3845 // If we are inlining don't actually attach the stack check. We must still 3845 // If we are inlining don't actually attach the stack check. We must still
3846 // create the stack check in order to allocate a deopt id. 3846 // create the stack check in order to allocate a deopt id.
3847 if (!owner()->IsInlining()) { 3847 if (!owner()->IsInlining()) {
3848 AddInstruction(check); 3848 AddInstruction(check);
3849 } 3849 }
3850 } 3850 }
3851 } 3851 }
3852 3852
3853 if (Isolate::Current()->TypeChecksEnabled() && is_top_level_sequence) { 3853 if (Isolate::Current()->TypeChecksEnabled() && is_top_level_sequence) {
3854 const int num_params = function.NumParameters(); 3854 const int num_params = function.NumParameters();
(...skipping 25 matching lines...) Expand all
3880 3880
3881 // Continuation part: 3881 // Continuation part:
3882 // If this node sequence is the body of a function with continuations, 3882 // If this node sequence is the body of a function with continuations,
3883 // leave room for a preamble. 3883 // leave room for a preamble.
3884 // The preamble is generated after visiting the body. 3884 // The preamble is generated after visiting the body.
3885 GotoInstr* preamble_start = NULL; 3885 GotoInstr* preamble_start = NULL;
3886 if (is_top_level_sequence && 3886 if (is_top_level_sequence &&
3887 (function.IsAsyncClosure() || 3887 (function.IsAsyncClosure() ||
3888 function.IsSyncGenClosure() || 3888 function.IsSyncGenClosure() ||
3889 function.IsAsyncGenClosure())) { 3889 function.IsAsyncGenClosure())) {
3890 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr( 3890 JoinEntryInstr* preamble_end = new(Z) JoinEntryInstr(
3891 owner()->AllocateBlockId(), owner()->try_index()); 3891 owner()->AllocateBlockId(), owner()->try_index());
3892 ASSERT(exit() != NULL); 3892 ASSERT(exit() != NULL);
3893 exit()->Goto(preamble_end); 3893 exit()->Goto(preamble_end);
3894 ASSERT(exit()->next()->IsGoto()); 3894 ASSERT(exit()->next()->IsGoto());
3895 preamble_start = exit()->next()->AsGoto(); 3895 preamble_start = exit()->next()->AsGoto();
3896 ASSERT(preamble_start->IsGoto()); 3896 ASSERT(preamble_start->IsGoto());
3897 exit_ = preamble_end; 3897 exit_ = preamble_end;
3898 } 3898 }
3899 3899
3900 intptr_t i = 0; 3900 intptr_t i = 0;
(...skipping 19 matching lines...) Expand all
3920 LocalScope* top_scope = node->scope(); 3920 LocalScope* top_scope = node->scope();
3921 LocalVariable* jump_var = top_scope->LookupVariable( 3921 LocalVariable* jump_var = top_scope->LookupVariable(
3922 Symbols::AwaitJumpVar(), false); 3922 Symbols::AwaitJumpVar(), false);
3923 ASSERT(jump_var != NULL && jump_var->is_captured()); 3923 ASSERT(jump_var != NULL && jump_var->is_captured());
3924 Instruction* saved_entry = entry_; 3924 Instruction* saved_entry = entry_;
3925 Instruction* saved_exit = exit_; 3925 Instruction* saved_exit = exit_;
3926 entry_ = NULL; 3926 entry_ = NULL;
3927 exit_ = NULL; 3927 exit_ = NULL;
3928 3928
3929 LoadLocalNode* load_jump_count = 3929 LoadLocalNode* load_jump_count =
3930 new(I) LoadLocalNode(Scanner::kNoSourcePos, jump_var); 3930 new(Z) LoadLocalNode(Scanner::kNoSourcePos, jump_var);
3931 ComparisonNode* check_jump_count; 3931 ComparisonNode* check_jump_count;
3932 const intptr_t num_await_states = owner()->await_joins()->length(); 3932 const intptr_t num_await_states = owner()->await_joins()->length();
3933 3933
3934 LocalVariable* old_context = top_scope->LookupVariable( 3934 LocalVariable* old_context = top_scope->LookupVariable(
3935 Symbols::AwaitContextVar(), false); 3935 Symbols::AwaitContextVar(), false);
3936 for (intptr_t i = 0; i < num_await_states; i++) { 3936 for (intptr_t i = 0; i < num_await_states; i++) {
3937 check_jump_count = new(I) ComparisonNode( 3937 check_jump_count = new(Z) ComparisonNode(
3938 Scanner::kNoSourcePos, 3938 Scanner::kNoSourcePos,
3939 Token::kEQ, 3939 Token::kEQ,
3940 load_jump_count, 3940 load_jump_count,
3941 new(I) LiteralNode( 3941 new(Z) LiteralNode(
3942 Scanner::kNoSourcePos, Smi::ZoneHandle(I, Smi::New(i)))); 3942 Scanner::kNoSourcePos, Smi::ZoneHandle(Z, Smi::New(i))));
3943 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); 3943 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
3944 check_jump_count->Visit(&for_test); 3944 check_jump_count->Visit(&for_test);
3945 EffectGraphVisitor for_true(owner()); 3945 EffectGraphVisitor for_true(owner());
3946 EffectGraphVisitor for_false(owner()); 3946 EffectGraphVisitor for_false(owner());
3947 3947
3948 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { 3948 if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
3949 LocalVariable* result_param = 3949 LocalVariable* result_param =
3950 top_scope->LookupVariable(Symbols::AsyncOperationParam(), false); 3950 top_scope->LookupVariable(Symbols::AsyncOperationParam(), false);
3951 LocalVariable* error_param = 3951 LocalVariable* error_param =
3952 top_scope->LookupVariable(Symbols::AsyncOperationErrorParam(), 3952 top_scope->LookupVariable(Symbols::AsyncOperationErrorParam(),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4023 owner()->set_try_index(try_handler_index); 4023 owner()->set_try_index(try_handler_index);
4024 4024
4025 // Preserve current context into local variable ':saved_try_context_var'. 4025 // Preserve current context into local variable ':saved_try_context_var'.
4026 BuildSaveContext(node->context_var()); 4026 BuildSaveContext(node->context_var());
4027 4027
4028 EffectGraphVisitor for_try(owner()); 4028 EffectGraphVisitor for_try(owner());
4029 node->try_block()->Visit(&for_try); 4029 node->try_block()->Visit(&for_try);
4030 4030
4031 if (for_try.is_open()) { 4031 if (for_try.is_open()) {
4032 JoinEntryInstr* after_try = 4032 JoinEntryInstr* after_try =
4033 new(I) JoinEntryInstr(owner()->AllocateBlockId(), 4033 new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
4034 original_handler_index); 4034 original_handler_index);
4035 for_try.Goto(after_try); 4035 for_try.Goto(after_try);
4036 for_try.exit_ = after_try; 4036 for_try.exit_ = after_try;
4037 } 4037 }
4038 4038
4039 JoinEntryInstr* try_entry = 4039 JoinEntryInstr* try_entry =
4040 new(I) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index); 4040 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
4041 4041
4042 Goto(try_entry); 4042 Goto(try_entry);
4043 AppendFragment(try_entry, for_try); 4043 AppendFragment(try_entry, for_try);
4044 exit_ = for_try.exit_; 4044 exit_ = for_try.exit_;
4045 4045
4046 // We are done generating code for the try block. 4046 // We are done generating code for the try block.
4047 owner()->set_try_index(original_handler_index); 4047 owner()->set_try_index(original_handler_index);
4048 4048
4049 CatchClauseNode* catch_block = node->catch_block(); 4049 CatchClauseNode* catch_block = node->catch_block();
4050 SequenceNode* finally_block = node->finally_block(); 4050 SequenceNode* finally_block = node->finally_block();
(...skipping 12 matching lines...) Expand all
4063 catch_block->Visit(&for_catch); 4063 catch_block->Visit(&for_catch);
4064 owner()->set_catch_try_index(prev_catch_try_index); 4064 owner()->set_catch_try_index(prev_catch_try_index);
4065 4065
4066 // NOTE: The implicit variables ':saved_try_context_var', ':exception_var' 4066 // NOTE: The implicit variables ':saved_try_context_var', ':exception_var'
4067 // and ':stack_trace_var' can never be captured variables. 4067 // and ':stack_trace_var' can never be captured variables.
4068 ASSERT(!catch_block->context_var().is_captured()); 4068 ASSERT(!catch_block->context_var().is_captured());
4069 ASSERT(!catch_block->exception_var().is_captured()); 4069 ASSERT(!catch_block->exception_var().is_captured());
4070 ASSERT(!catch_block->stacktrace_var().is_captured()); 4070 ASSERT(!catch_block->stacktrace_var().is_captured());
4071 4071
4072 CatchBlockEntryInstr* catch_entry = 4072 CatchBlockEntryInstr* catch_entry =
4073 new(I) CatchBlockEntryInstr(owner()->AllocateBlockId(), 4073 new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
4074 catch_handler_index, 4074 catch_handler_index,
4075 catch_block->handler_types(), 4075 catch_block->handler_types(),
4076 try_handler_index, 4076 try_handler_index,
4077 catch_block->exception_var(), 4077 catch_block->exception_var(),
4078 catch_block->stacktrace_var(), 4078 catch_block->stacktrace_var(),
4079 catch_block->needs_stacktrace()); 4079 catch_block->needs_stacktrace());
4080 owner()->AddCatchEntry(catch_entry); 4080 owner()->AddCatchEntry(catch_entry);
4081 AppendFragment(catch_entry, for_catch); 4081 AppendFragment(catch_entry, for_catch);
4082 4082
4083 if (for_catch.is_open()) { 4083 if (for_catch.is_open()) {
4084 JoinEntryInstr* join = new(I) JoinEntryInstr(owner()->AllocateBlockId(), 4084 JoinEntryInstr* join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
4085 original_handler_index); 4085 original_handler_index);
4086 for_catch.Goto(join); 4086 for_catch.Goto(join);
4087 if (is_open()) Goto(join); 4087 if (is_open()) Goto(join);
4088 exit_ = join; 4088 exit_ = join;
4089 } 4089 }
4090 4090
4091 if (finally_block != NULL) { 4091 if (finally_block != NULL) {
4092 // Create a handler for the code in the catch block, containing the 4092 // Create a handler for the code in the catch block, containing the
4093 // code in the finally block. 4093 // code in the finally block.
4094 owner()->set_try_index(original_handler_index); 4094 owner()->set_try_index(original_handler_index);
4095 EffectGraphVisitor for_finally(owner()); 4095 EffectGraphVisitor for_finally(owner());
4096 for_finally.BuildRestoreContext(catch_block->context_var()); 4096 for_finally.BuildRestoreContext(catch_block->context_var());
4097 4097
4098 finally_block->Visit(&for_finally); 4098 finally_block->Visit(&for_finally);
4099 if (for_finally.is_open()) { 4099 if (for_finally.is_open()) {
4100 // Rethrow the exception. Manually build the graph for rethrow. 4100 // Rethrow the exception. Manually build the graph for rethrow.
4101 Value* exception = for_finally.Bind( 4101 Value* exception = for_finally.Bind(
4102 for_finally.BuildLoadLocal(catch_block->rethrow_exception_var())); 4102 for_finally.BuildLoadLocal(catch_block->rethrow_exception_var()));
4103 for_finally.PushArgument(exception); 4103 for_finally.PushArgument(exception);
4104 Value* stacktrace = for_finally.Bind( 4104 Value* stacktrace = for_finally.Bind(
4105 for_finally.BuildLoadLocal(catch_block->rethrow_stacktrace_var())); 4105 for_finally.BuildLoadLocal(catch_block->rethrow_stacktrace_var()));
4106 for_finally.PushArgument(stacktrace); 4106 for_finally.PushArgument(stacktrace);
4107 for_finally.AddInstruction( 4107 for_finally.AddInstruction(
4108 new(I) ReThrowInstr(catch_block->token_pos(), catch_handler_index)); 4108 new(Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
4109 for_finally.CloseFragment(); 4109 for_finally.CloseFragment();
4110 } 4110 }
4111 ASSERT(!for_finally.is_open()); 4111 ASSERT(!for_finally.is_open());
4112 4112
4113 const Array& types = Array::ZoneHandle(I, Array::New(1, Heap::kOld)); 4113 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
4114 types.SetAt(0, Type::Handle(I, Type::DynamicType())); 4114 types.SetAt(0, Type::Handle(Z, Type::DynamicType()));
4115 CatchBlockEntryInstr* finally_entry = 4115 CatchBlockEntryInstr* finally_entry =
4116 new(I) CatchBlockEntryInstr(owner()->AllocateBlockId(), 4116 new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
4117 original_handler_index, 4117 original_handler_index,
4118 types, 4118 types,
4119 catch_handler_index, 4119 catch_handler_index,
4120 catch_block->exception_var(), 4120 catch_block->exception_var(),
4121 catch_block->stacktrace_var(), 4121 catch_block->stacktrace_var(),
4122 catch_block->needs_stacktrace()); 4122 catch_block->needs_stacktrace());
4123 owner()->AddCatchEntry(finally_entry); 4123 owner()->AddCatchEntry(finally_entry);
4124 AppendFragment(finally_entry, for_finally); 4124 AppendFragment(finally_entry, for_finally);
4125 } 4125 }
4126 4126
(...skipping 19 matching lines...) Expand all
4146 LocalVariable* temp = NULL; 4146 LocalVariable* temp = NULL;
4147 if (save_last_arg) { 4147 if (save_last_arg) {
4148 temp = owner()->parsed_function().expression_temp_var(); 4148 temp = owner()->parsed_function().expression_temp_var();
4149 } 4149 }
4150 ArgumentListNode* args = 4150 ArgumentListNode* args =
4151 Parser::BuildNoSuchMethodArguments(args_pos, 4151 Parser::BuildNoSuchMethodArguments(args_pos,
4152 method_name, 4152 method_name,
4153 *method_arguments, 4153 *method_arguments,
4154 temp, 4154 temp,
4155 is_super_invocation); 4155 is_super_invocation);
4156 const Function& no_such_method_func = Function::ZoneHandle(I, 4156 const Function& no_such_method_func = Function::ZoneHandle(Z,
4157 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); 4157 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod()));
4158 // We are guaranteed to find noSuchMethod of class Object. 4158 // We are guaranteed to find noSuchMethod of class Object.
4159 ASSERT(!no_such_method_func.IsNull()); 4159 ASSERT(!no_such_method_func.IsNull());
4160 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = 4160 ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
4161 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); 4161 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
4162 BuildPushArguments(*args, push_arguments); 4162 BuildPushArguments(*args, push_arguments);
4163 return new(I) StaticCallInstr(args_pos, 4163 return new(Z) StaticCallInstr(args_pos,
4164 no_such_method_func, 4164 no_such_method_func,
4165 Object::null_array(), 4165 Object::null_array(),
4166 push_arguments, 4166 push_arguments,
4167 owner()->ic_data_array()); 4167 owner()->ic_data_array());
4168 } 4168 }
4169 4169
4170 4170
4171 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( 4171 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
4172 intptr_t token_pos, 4172 intptr_t token_pos,
4173 const Class& function_class, 4173 const Class& function_class,
4174 const String& function_name, 4174 const String& function_name,
4175 ArgumentListNode* function_arguments, 4175 ArgumentListNode* function_arguments,
4176 int invocation_type) { 4176 int invocation_type) {
4177 ZoneGrowableArray<PushArgumentInstr*>* arguments = 4177 ZoneGrowableArray<PushArgumentInstr*>* arguments =
4178 new(I) ZoneGrowableArray<PushArgumentInstr*>(); 4178 new(Z) ZoneGrowableArray<PushArgumentInstr*>();
4179 // Object receiver, actually a class literal of the unresolved method's owner. 4179 // Object receiver, actually a class literal of the unresolved method's owner.
4180 Type& type = Type::ZoneHandle( 4180 Type& type = Type::ZoneHandle(
4181 I, 4181 Z,
4182 Type::New(function_class, 4182 Type::New(function_class,
4183 TypeArguments::Handle(I, TypeArguments::null()), 4183 TypeArguments::Handle(Z, TypeArguments::null()),
4184 token_pos, 4184 token_pos,
4185 Heap::kOld)); 4185 Heap::kOld));
4186 type ^= ClassFinalizer::FinalizeType( 4186 type ^= ClassFinalizer::FinalizeType(
4187 function_class, type, ClassFinalizer::kCanonicalize); 4187 function_class, type, ClassFinalizer::kCanonicalize);
4188 Value* receiver_value = Bind(new(I) ConstantInstr(type)); 4188 Value* receiver_value = Bind(new(Z) ConstantInstr(type));
4189 arguments->Add(PushArgument(receiver_value)); 4189 arguments->Add(PushArgument(receiver_value));
4190 // String memberName. 4190 // String memberName.
4191 const String& member_name = 4191 const String& member_name =
4192 String::ZoneHandle(I, Symbols::New(function_name)); 4192 String::ZoneHandle(Z, Symbols::New(function_name));
4193 Value* member_name_value = Bind(new(I) ConstantInstr(member_name)); 4193 Value* member_name_value = Bind(new(Z) ConstantInstr(member_name));
4194 arguments->Add(PushArgument(member_name_value)); 4194 arguments->Add(PushArgument(member_name_value));
4195 // Smi invocation_type. 4195 // Smi invocation_type.
4196 Value* invocation_type_value = Bind(new(I) ConstantInstr( 4196 Value* invocation_type_value = Bind(new(Z) ConstantInstr(
4197 Smi::ZoneHandle(I, Smi::New(invocation_type)))); 4197 Smi::ZoneHandle(Z, Smi::New(invocation_type))));
4198 arguments->Add(PushArgument(invocation_type_value)); 4198 arguments->Add(PushArgument(invocation_type_value));
4199 // List arguments. 4199 // List arguments.
4200 if (function_arguments == NULL) { 4200 if (function_arguments == NULL) {
4201 Value* arguments_value = Bind( 4201 Value* arguments_value = Bind(
4202 new(I) ConstantInstr(Array::ZoneHandle(I, Array::null()))); 4202 new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null())));
4203 arguments->Add(PushArgument(arguments_value)); 4203 arguments->Add(PushArgument(arguments_value));
4204 } else { 4204 } else {
4205 ValueGraphVisitor array_val(owner()); 4205 ValueGraphVisitor array_val(owner());
4206 ArrayNode* array = 4206 ArrayNode* array =
4207 new(I) ArrayNode(token_pos, Type::ZoneHandle(I, Type::ArrayType()), 4207 new(Z) ArrayNode(token_pos, Type::ZoneHandle(Z, Type::ArrayType()),
4208 function_arguments->nodes()); 4208 function_arguments->nodes());
4209 array->Visit(&array_val); 4209 array->Visit(&array_val);
4210 Append(array_val); 4210 Append(array_val);
4211 arguments->Add(PushArgument(array_val.value())); 4211 arguments->Add(PushArgument(array_val.value()));
4212 } 4212 }
4213 // List argumentNames. 4213 // List argumentNames.
4214 ConstantInstr* cinstr = new(I) ConstantInstr( 4214 ConstantInstr* cinstr = new(Z) ConstantInstr(
4215 (function_arguments == NULL) ? Array::ZoneHandle(I, Array::null()) 4215 (function_arguments == NULL) ? Array::ZoneHandle(Z, Array::null())
4216 : function_arguments->names()); 4216 : function_arguments->names());
4217 Value* argument_names_value = Bind(cinstr); 4217 Value* argument_names_value = Bind(cinstr);
4218 arguments->Add(PushArgument(argument_names_value)); 4218 arguments->Add(PushArgument(argument_names_value));
4219 4219
4220 // List existingArgumentNames. 4220 // List existingArgumentNames.
4221 Value* existing_argument_names_value = 4221 Value* existing_argument_names_value =
4222 Bind(new(I) ConstantInstr(Array::ZoneHandle(I, Array::null()))); 4222 Bind(new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null())));
4223 arguments->Add(PushArgument(existing_argument_names_value)); 4223 arguments->Add(PushArgument(existing_argument_names_value));
4224 // Resolve and call NoSuchMethodError._throwNew. 4224 // Resolve and call NoSuchMethodError._throwNew.
4225 const Library& core_lib = Library::Handle(I, Library::CoreLibrary()); 4225 const Library& core_lib = Library::Handle(Z, Library::CoreLibrary());
4226 const Class& cls = Class::Handle( 4226 const Class& cls = Class::Handle(
4227 I, core_lib.LookupClass(Symbols::NoSuchMethodError())); 4227 Z, core_lib.LookupClass(Symbols::NoSuchMethodError()));
4228 ASSERT(!cls.IsNull()); 4228 ASSERT(!cls.IsNull());
4229 const Function& func = Function::ZoneHandle( 4229 const Function& func = Function::ZoneHandle(
4230 I, 4230 Z,
4231 Resolver::ResolveStatic(cls, 4231 Resolver::ResolveStatic(cls,
4232 Library::PrivateCoreLibName(Symbols::ThrowNew()), 4232 Library::PrivateCoreLibName(Symbols::ThrowNew()),
4233 arguments->length(), 4233 arguments->length(),
4234 Object::null_array())); 4234 Object::null_array()));
4235 ASSERT(!func.IsNull()); 4235 ASSERT(!func.IsNull());
4236 return new(I) StaticCallInstr(token_pos, 4236 return new(Z) StaticCallInstr(token_pos,
4237 func, 4237 func,
4238 Object::null_array(), // No names. 4238 Object::null_array(), // No names.
4239 arguments, 4239 arguments,
4240 owner()->ic_data_array()); 4240 owner()->ic_data_array());
4241 } 4241 }
4242 4242
4243 4243
4244 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 4244 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
4245 if (node->exception()->IsLiteralNode() || 4245 if (node->exception()->IsLiteralNode() ||
4246 node->exception()->IsLoadLocalNode() || 4246 node->exception()->IsLoadLocalNode() ||
4247 node->exception()->IsClosureNode()) { 4247 node->exception()->IsClosureNode()) {
4248 AddInstruction(new(I) DebugStepCheckInstr( 4248 AddInstruction(new(Z) DebugStepCheckInstr(
4249 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 4249 node->token_pos(), RawPcDescriptors::kRuntimeCall));
4250 } 4250 }
4251 ValueGraphVisitor for_exception(owner()); 4251 ValueGraphVisitor for_exception(owner());
4252 node->exception()->Visit(&for_exception); 4252 node->exception()->Visit(&for_exception);
4253 Append(for_exception); 4253 Append(for_exception);
4254 PushArgument(for_exception.value()); 4254 PushArgument(for_exception.value());
4255 Instruction* instr = NULL; 4255 Instruction* instr = NULL;
4256 if (node->stacktrace() == NULL) { 4256 if (node->stacktrace() == NULL) {
4257 instr = new(I) ThrowInstr(node->token_pos()); 4257 instr = new(Z) ThrowInstr(node->token_pos());
4258 } else { 4258 } else {
4259 ValueGraphVisitor for_stack_trace(owner()); 4259 ValueGraphVisitor for_stack_trace(owner());
4260 node->stacktrace()->Visit(&for_stack_trace); 4260 node->stacktrace()->Visit(&for_stack_trace);
4261 Append(for_stack_trace); 4261 Append(for_stack_trace);
4262 PushArgument(for_stack_trace.value()); 4262 PushArgument(for_stack_trace.value());
4263 instr = new(I) ReThrowInstr(node->token_pos(), owner()->catch_try_index()); 4263 instr = new(Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index());
4264 } 4264 }
4265 AddInstruction(instr); 4265 AddInstruction(instr);
4266 } 4266 }
4267 4267
4268 4268
4269 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 4269 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
4270 BuildThrowNode(node); 4270 BuildThrowNode(node);
4271 CloseFragment(); 4271 CloseFragment();
4272 } 4272 }
4273 4273
4274 4274
4275 // A throw cannot be part of an expression, however, the parser may replace 4275 // A throw cannot be part of an expression, however, the parser may replace
4276 // certain expression nodes with a throw. In that case generate a literal null 4276 // certain expression nodes with a throw. In that case generate a literal null
4277 // so that the fragment is not closed in the middle of an expression. 4277 // so that the fragment is not closed in the middle of an expression.
4278 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { 4278 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
4279 BuildThrowNode(node); 4279 BuildThrowNode(node);
4280 ReturnDefinition(new(I) ConstantInstr( 4280 ReturnDefinition(new(Z) ConstantInstr(
4281 Instance::ZoneHandle(I, Instance::null()))); 4281 Instance::ZoneHandle(Z, Instance::null())));
4282 } 4282 }
4283 4283
4284 4284
4285 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 4285 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
4286 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); 4286 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)");
4287 const intptr_t try_index = owner()->try_index(); 4287 const intptr_t try_index = owner()->try_index();
4288 if (try_index >= 0) { 4288 if (try_index >= 0) {
4289 // We are about to generate code for an inlined finally block. Exceptions 4289 // We are about to generate code for an inlined finally block. Exceptions
4290 // thrown in this block of code should be treated as though they are 4290 // thrown in this block of code should be treated as though they are
4291 // thrown not from the current try block but the outer try block if any. 4291 // thrown not from the current try block but the outer try block if any.
4292 intptr_t outer_try_index = node->try_index(); 4292 intptr_t outer_try_index = node->try_index();
4293 owner()->set_try_index(outer_try_index); 4293 owner()->set_try_index(outer_try_index);
4294 } 4294 }
4295 BuildRestoreContext(node->context_var()); 4295 BuildRestoreContext(node->context_var());
4296 4296
4297 JoinEntryInstr* finally_entry = 4297 JoinEntryInstr* finally_entry =
4298 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 4298 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
4299 EffectGraphVisitor for_finally_block(owner()); 4299 EffectGraphVisitor for_finally_block(owner());
4300 node->finally_block()->Visit(&for_finally_block); 4300 node->finally_block()->Visit(&for_finally_block);
4301 4301
4302 if (try_index >= 0) { 4302 if (try_index >= 0) {
4303 owner()->set_try_index(try_index); 4303 owner()->set_try_index(try_index);
4304 } 4304 }
4305 4305
4306 if (for_finally_block.is_open()) { 4306 if (for_finally_block.is_open()) {
4307 JoinEntryInstr* after_finally = 4307 JoinEntryInstr* after_finally =
4308 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 4308 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
4309 for_finally_block.Goto(after_finally); 4309 for_finally_block.Goto(after_finally);
4310 for_finally_block.exit_ = after_finally; 4310 for_finally_block.exit_ = after_finally;
4311 } 4311 }
4312 4312
4313 Goto(finally_entry); 4313 Goto(finally_entry);
4314 AppendFragment(finally_entry, for_finally_block); 4314 AppendFragment(finally_entry, for_finally_block);
4315 exit_ = for_finally_block.exit_; 4315 exit_ = for_finally_block.exit_;
4316 } 4316 }
4317 4317
4318 4318
4319 FlowGraph* FlowGraphBuilder::BuildGraph() { 4319 FlowGraph* FlowGraphBuilder::BuildGraph() {
4320 if (FLAG_print_ast) { 4320 if (FLAG_print_ast) {
4321 // Print the function ast before IL generation. 4321 // Print the function ast before IL generation.
4322 AstPrinter::PrintFunctionNodes(parsed_function()); 4322 AstPrinter::PrintFunctionNodes(parsed_function());
4323 } 4323 }
4324 if (FLAG_print_scopes) { 4324 if (FLAG_print_scopes) {
4325 AstPrinter::PrintFunctionScope(parsed_function()); 4325 AstPrinter::PrintFunctionScope(parsed_function());
4326 } 4326 }
4327 TargetEntryInstr* normal_entry = 4327 TargetEntryInstr* normal_entry =
4328 new(I) TargetEntryInstr(AllocateBlockId(), 4328 new(Z) TargetEntryInstr(AllocateBlockId(),
4329 CatchClauseNode::kInvalidTryIndex); 4329 CatchClauseNode::kInvalidTryIndex);
4330 graph_entry_ = 4330 graph_entry_ =
4331 new(I) GraphEntryInstr(parsed_function(), normal_entry, osr_id_); 4331 new(Z) GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
4332 EffectGraphVisitor for_effect(this); 4332 EffectGraphVisitor for_effect(this);
4333 parsed_function().node_sequence()->Visit(&for_effect); 4333 parsed_function().node_sequence()->Visit(&for_effect);
4334 AppendFragment(normal_entry, for_effect); 4334 AppendFragment(normal_entry, for_effect);
4335 // Check that the graph is properly terminated. 4335 // Check that the graph is properly terminated.
4336 ASSERT(!for_effect.is_open()); 4336 ASSERT(!for_effect.is_open());
4337 4337
4338 // When compiling for OSR, use a depth first search to prune instructions 4338 // When compiling for OSR, use a depth first search to prune instructions
4339 // unreachable from the OSR entry. Catch entries are always considered 4339 // unreachable from the OSR entry. Catch entries are always considered
4340 // reachable, even if they become unreachable after OSR. 4340 // reachable, even if they become unreachable after OSR.
4341 if (osr_id_ != Isolate::kNoDeoptId) { 4341 if (osr_id_ != Isolate::kNoDeoptId) {
4342 PruneUnreachable(); 4342 PruneUnreachable();
4343 } 4343 }
4344 4344
4345 FlowGraph* graph = 4345 FlowGraph* graph =
4346 new(I) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_); 4346 new(Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_);
4347 return graph; 4347 return graph;
4348 } 4348 }
4349 4349
4350 4350
4351 void FlowGraphBuilder::PruneUnreachable() { 4351 void FlowGraphBuilder::PruneUnreachable() {
4352 ASSERT(osr_id_ != Isolate::kNoDeoptId); 4352 ASSERT(osr_id_ != Isolate::kNoDeoptId);
4353 Zone* zone = parsed_function().zone(); 4353 BitVector* block_marks = new(Z) BitVector(Z, last_used_block_id_ + 1);
4354 BitVector* block_marks = new(zone) BitVector(zone, last_used_block_id_ + 1);
4355 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_, 4354 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_,
4356 block_marks); 4355 block_marks);
4357 ASSERT(found); 4356 ASSERT(found);
4358 } 4357 }
4359 4358
4360 4359
4361 void FlowGraphBuilder::Bailout(const char* reason) const { 4360 void FlowGraphBuilder::Bailout(const char* reason) const {
4362 const Function& function = parsed_function_.function(); 4361 const Function& function = parsed_function_.function();
4363 Report::MessageF(Report::kBailout, 4362 Report::MessageF(Report::kBailout,
4364 Script::Handle(function.script()), 4363 Script::Handle(function.script()),
4365 function.token_pos(), 4364 function.token_pos(),
4366 "FlowGraphBuilder Bailout: %s %s", 4365 "FlowGraphBuilder Bailout: %s %s",
4367 String::Handle(function.name()).ToCString(), 4366 String::Handle(function.name()).ToCString(),
4368 reason); 4367 reason);
4369 UNREACHABLE(); 4368 UNREACHABLE();
4370 } 4369 }
4371 4370
4372 } // namespace dart 4371 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698