OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 25 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |