| 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 |