| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 #else | 48 #else |
| 49 #error Unsupported target architecture. | 49 #error Unsupported target architecture. |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 namespace v8 { | 52 namespace v8 { |
| 53 namespace internal { | 53 namespace internal { |
| 54 | 54 |
| 55 HBasicBlock::HBasicBlock(HGraph* graph) | 55 HBasicBlock::HBasicBlock(HGraph* graph) |
| 56 : block_id_(graph->GetNextBlockID()), | 56 : block_id_(graph->GetNextBlockID()), |
| 57 graph_(graph), | 57 graph_(graph), |
| 58 phis_(4), | 58 phis_(4, graph->zone()), |
| 59 first_(NULL), | 59 first_(NULL), |
| 60 last_(NULL), | 60 last_(NULL), |
| 61 end_(NULL), | 61 end_(NULL), |
| 62 loop_information_(NULL), | 62 loop_information_(NULL), |
| 63 predecessors_(2), | 63 predecessors_(2, graph->zone()), |
| 64 dominator_(NULL), | 64 dominator_(NULL), |
| 65 dominated_blocks_(4), | 65 dominated_blocks_(4, graph->zone()), |
| 66 last_environment_(NULL), | 66 last_environment_(NULL), |
| 67 argument_count_(-1), | 67 argument_count_(-1), |
| 68 first_instruction_index_(-1), | 68 first_instruction_index_(-1), |
| 69 last_instruction_index_(-1), | 69 last_instruction_index_(-1), |
| 70 deleted_phis_(4), | 70 deleted_phis_(4, graph->zone()), |
| 71 parent_loop_header_(NULL), | 71 parent_loop_header_(NULL), |
| 72 is_inline_return_target_(false), | 72 is_inline_return_target_(false), |
| 73 is_deoptimizing_(false), | 73 is_deoptimizing_(false), |
| 74 dominates_loop_successors_(false) { } | 74 dominates_loop_successors_(false) { } |
| 75 | 75 |
| 76 | 76 |
| 77 void HBasicBlock::AttachLoopInformation() { | 77 void HBasicBlock::AttachLoopInformation() { |
| 78 ASSERT(!IsLoopHeader()); | 78 ASSERT(!IsLoopHeader()); |
| 79 loop_information_ = new(zone()) HLoopInformation(this); | 79 loop_information_ = new(zone()) HLoopInformation(this, zone()); |
| 80 } | 80 } |
| 81 | 81 |
| 82 | 82 |
| 83 void HBasicBlock::DetachLoopInformation() { | 83 void HBasicBlock::DetachLoopInformation() { |
| 84 ASSERT(IsLoopHeader()); | 84 ASSERT(IsLoopHeader()); |
| 85 loop_information_ = NULL; | 85 loop_information_ = NULL; |
| 86 } | 86 } |
| 87 | 87 |
| 88 | 88 |
| 89 void HBasicBlock::AddPhi(HPhi* phi) { | 89 void HBasicBlock::AddPhi(HPhi* phi) { |
| 90 ASSERT(!IsStartBlock()); | 90 ASSERT(!IsStartBlock()); |
| 91 phis_.Add(phi); | 91 phis_.Add(phi, zone()); |
| 92 phi->SetBlock(this); | 92 phi->SetBlock(this); |
| 93 } | 93 } |
| 94 | 94 |
| 95 | 95 |
| 96 void HBasicBlock::RemovePhi(HPhi* phi) { | 96 void HBasicBlock::RemovePhi(HPhi* phi) { |
| 97 ASSERT(phi->block() == this); | 97 ASSERT(phi->block() == this); |
| 98 ASSERT(phis_.Contains(phi)); | 98 ASSERT(phis_.Contains(phi)); |
| 99 ASSERT(phi->HasNoUses() || !phi->is_live()); | 99 ASSERT(phi->HasNoUses() || !phi->is_live()); |
| 100 phi->Kill(); | 100 phi->Kill(); |
| 101 phis_.RemoveElement(phi); | 101 phis_.RemoveElement(phi); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 112 entry->InitializeAsFirst(this); | 112 entry->InitializeAsFirst(this); |
| 113 first_ = last_ = entry; | 113 first_ = last_ = entry; |
| 114 } | 114 } |
| 115 instr->InsertAfter(last_); | 115 instr->InsertAfter(last_); |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 HDeoptimize* HBasicBlock::CreateDeoptimize( | 119 HDeoptimize* HBasicBlock::CreateDeoptimize( |
| 120 HDeoptimize::UseEnvironment has_uses) { | 120 HDeoptimize::UseEnvironment has_uses) { |
| 121 ASSERT(HasEnvironment()); | 121 ASSERT(HasEnvironment()); |
| 122 if (has_uses == HDeoptimize::kNoUses) return new(zone()) HDeoptimize(0); | 122 if (has_uses == HDeoptimize::kNoUses) |
| 123 return new(zone()) HDeoptimize(0, zone()); |
| 123 | 124 |
| 124 HEnvironment* environment = last_environment(); | 125 HEnvironment* environment = last_environment(); |
| 125 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length()); | 126 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length(), zone()); |
| 126 for (int i = 0; i < environment->length(); i++) { | 127 for (int i = 0; i < environment->length(); i++) { |
| 127 HValue* val = environment->values()->at(i); | 128 HValue* val = environment->values()->at(i); |
| 128 instr->AddEnvironmentValue(val); | 129 instr->AddEnvironmentValue(val, zone()); |
| 129 } | 130 } |
| 130 | 131 |
| 131 return instr; | 132 return instr; |
| 132 } | 133 } |
| 133 | 134 |
| 134 | 135 |
| 135 HSimulate* HBasicBlock::CreateSimulate(int ast_id) { | 136 HSimulate* HBasicBlock::CreateSimulate(int ast_id) { |
| 136 ASSERT(HasEnvironment()); | 137 ASSERT(HasEnvironment()); |
| 137 HEnvironment* environment = last_environment(); | 138 HEnvironment* environment = last_environment(); |
| 138 ASSERT(ast_id == AstNode::kNoNumber || | 139 ASSERT(ast_id == AstNode::kNoNumber || |
| 139 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 140 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
| 140 | 141 |
| 141 int push_count = environment->push_count(); | 142 int push_count = environment->push_count(); |
| 142 int pop_count = environment->pop_count(); | 143 int pop_count = environment->pop_count(); |
| 143 | 144 |
| 144 HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count); | 145 HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count, zone()); |
| 145 for (int i = push_count - 1; i >= 0; --i) { | 146 for (int i = push_count - 1; i >= 0; --i) { |
| 146 instr->AddPushedValue(environment->ExpressionStackAt(i)); | 147 instr->AddPushedValue(environment->ExpressionStackAt(i)); |
| 147 } | 148 } |
| 148 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { | 149 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { |
| 149 int index = environment->assigned_variables()->at(i); | 150 int index = environment->assigned_variables()->at(i); |
| 150 instr->AddAssignedValue(index, environment->Lookup(index)); | 151 instr->AddAssignedValue(index, environment->Lookup(index)); |
| 151 } | 152 } |
| 152 environment->ClearHistory(); | 153 environment->ClearHistory(); |
| 153 return instr; | 154 return instr; |
| 154 } | 155 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 phis_[i]->AddInput(incoming_env->values()->at(i)); | 272 phis_[i]->AddInput(incoming_env->values()->at(i)); |
| 272 } | 273 } |
| 273 } else { | 274 } else { |
| 274 last_environment()->AddIncomingEdge(this, pred->last_environment()); | 275 last_environment()->AddIncomingEdge(this, pred->last_environment()); |
| 275 } | 276 } |
| 276 } else if (!HasEnvironment() && !IsFinished()) { | 277 } else if (!HasEnvironment() && !IsFinished()) { |
| 277 ASSERT(!IsLoopHeader()); | 278 ASSERT(!IsLoopHeader()); |
| 278 SetInitialEnvironment(pred->last_environment()->Copy()); | 279 SetInitialEnvironment(pred->last_environment()->Copy()); |
| 279 } | 280 } |
| 280 | 281 |
| 281 predecessors_.Add(pred); | 282 predecessors_.Add(pred, zone()); |
| 282 } | 283 } |
| 283 | 284 |
| 284 | 285 |
| 285 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { | 286 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { |
| 286 ASSERT(!dominated_blocks_.Contains(block)); | 287 ASSERT(!dominated_blocks_.Contains(block)); |
| 287 // Keep the list of dominated blocks sorted such that if there is two | 288 // Keep the list of dominated blocks sorted such that if there is two |
| 288 // succeeding block in this list, the predecessor is before the successor. | 289 // succeeding block in this list, the predecessor is before the successor. |
| 289 int index = 0; | 290 int index = 0; |
| 290 while (index < dominated_blocks_.length() && | 291 while (index < dominated_blocks_.length() && |
| 291 dominated_blocks_[index]->block_id() < block->block_id()) { | 292 dominated_blocks_[index]->block_id() < block->block_id()) { |
| 292 ++index; | 293 ++index; |
| 293 } | 294 } |
| 294 dominated_blocks_.InsertAt(index, block); | 295 dominated_blocks_.InsertAt(index, block, zone()); |
| 295 } | 296 } |
| 296 | 297 |
| 297 | 298 |
| 298 void HBasicBlock::AssignCommonDominator(HBasicBlock* other) { | 299 void HBasicBlock::AssignCommonDominator(HBasicBlock* other) { |
| 299 if (dominator_ == NULL) { | 300 if (dominator_ == NULL) { |
| 300 dominator_ = other; | 301 dominator_ = other; |
| 301 other->AddDominatedBlock(this); | 302 other->AddDominatedBlock(this); |
| 302 } else if (other->dominator() != NULL) { | 303 } else if (other->dominator() != NULL) { |
| 303 HBasicBlock* first = dominator_; | 304 HBasicBlock* first = dominator_; |
| 304 HBasicBlock* second = other; | 305 HBasicBlock* second = other; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 if (predecessors_.length() > 1) { | 398 if (predecessors_.length() > 1) { |
| 398 for (int i = 0; i < predecessors_.length(); ++i) { | 399 for (int i = 0; i < predecessors_.length(); ++i) { |
| 399 ASSERT(predecessors_[i]->end()->SecondSuccessor() == NULL); | 400 ASSERT(predecessors_[i]->end()->SecondSuccessor() == NULL); |
| 400 } | 401 } |
| 401 } | 402 } |
| 402 } | 403 } |
| 403 #endif | 404 #endif |
| 404 | 405 |
| 405 | 406 |
| 406 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) { | 407 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) { |
| 407 this->back_edges_.Add(block); | 408 this->back_edges_.Add(block, block->zone()); |
| 408 AddBlock(block); | 409 AddBlock(block); |
| 409 } | 410 } |
| 410 | 411 |
| 411 | 412 |
| 412 HBasicBlock* HLoopInformation::GetLastBackEdge() const { | 413 HBasicBlock* HLoopInformation::GetLastBackEdge() const { |
| 413 int max_id = -1; | 414 int max_id = -1; |
| 414 HBasicBlock* result = NULL; | 415 HBasicBlock* result = NULL; |
| 415 for (int i = 0; i < back_edges_.length(); ++i) { | 416 for (int i = 0; i < back_edges_.length(); ++i) { |
| 416 HBasicBlock* cur = back_edges_[i]; | 417 HBasicBlock* cur = back_edges_[i]; |
| 417 if (cur->block_id() > max_id) { | 418 if (cur->block_id() > max_id) { |
| 418 max_id = cur->block_id(); | 419 max_id = cur->block_id(); |
| 419 result = cur; | 420 result = cur; |
| 420 } | 421 } |
| 421 } | 422 } |
| 422 return result; | 423 return result; |
| 423 } | 424 } |
| 424 | 425 |
| 425 | 426 |
| 426 void HLoopInformation::AddBlock(HBasicBlock* block) { | 427 void HLoopInformation::AddBlock(HBasicBlock* block) { |
| 427 if (block == loop_header()) return; | 428 if (block == loop_header()) return; |
| 428 if (block->parent_loop_header() == loop_header()) return; | 429 if (block->parent_loop_header() == loop_header()) return; |
| 429 if (block->parent_loop_header() != NULL) { | 430 if (block->parent_loop_header() != NULL) { |
| 430 AddBlock(block->parent_loop_header()); | 431 AddBlock(block->parent_loop_header()); |
| 431 } else { | 432 } else { |
| 432 block->set_parent_loop_header(loop_header()); | 433 block->set_parent_loop_header(loop_header()); |
| 433 blocks_.Add(block); | 434 blocks_.Add(block, block->zone()); |
| 434 for (int i = 0; i < block->predecessors()->length(); ++i) { | 435 for (int i = 0; i < block->predecessors()->length(); ++i) { |
| 435 AddBlock(block->predecessors()->at(i)); | 436 AddBlock(block->predecessors()->at(i)); |
| 436 } | 437 } |
| 437 } | 438 } |
| 438 } | 439 } |
| 439 | 440 |
| 440 | 441 |
| 441 #ifdef DEBUG | 442 #ifdef DEBUG |
| 442 | 443 |
| 443 // Checks reachability of the blocks in this graph and stores a bit in | 444 // Checks reachability of the blocks in this graph and stores a bit in |
| 444 // the BitVector "reachable()" for every block that can be reached | 445 // the BitVector "reachable()" for every block that can be reached |
| 445 // from the start block of the graph. If "dont_visit" is non-null, the given | 446 // from the start block of the graph. If "dont_visit" is non-null, the given |
| 446 // block is treated as if it would not be part of the graph. "visited_count()" | 447 // block is treated as if it would not be part of the graph. "visited_count()" |
| 447 // returns the number of reachable blocks. | 448 // returns the number of reachable blocks. |
| 448 class ReachabilityAnalyzer BASE_EMBEDDED { | 449 class ReachabilityAnalyzer BASE_EMBEDDED { |
| 449 public: | 450 public: |
| 450 ReachabilityAnalyzer(HBasicBlock* entry_block, | 451 ReachabilityAnalyzer(HBasicBlock* entry_block, |
| 451 int block_count, | 452 int block_count, |
| 452 HBasicBlock* dont_visit) | 453 HBasicBlock* dont_visit) |
| 453 : visited_count_(0), | 454 : visited_count_(0), |
| 454 stack_(16), | 455 stack_(16, entry_block->zone()), |
| 455 reachable_(block_count, ZONE), | 456 reachable_(block_count, entry_block->zone()), |
| 456 dont_visit_(dont_visit) { | 457 dont_visit_(dont_visit) { |
| 457 PushBlock(entry_block); | 458 PushBlock(entry_block); |
| 458 Analyze(); | 459 Analyze(); |
| 459 } | 460 } |
| 460 | 461 |
| 461 int visited_count() const { return visited_count_; } | 462 int visited_count() const { return visited_count_; } |
| 462 const BitVector* reachable() const { return &reachable_; } | 463 const BitVector* reachable() const { return &reachable_; } |
| 463 | 464 |
| 464 private: | 465 private: |
| 465 void PushBlock(HBasicBlock* block) { | 466 void PushBlock(HBasicBlock* block) { |
| 466 if (block != NULL && block != dont_visit_ && | 467 if (block != NULL && block != dont_visit_ && |
| 467 !reachable_.Contains(block->block_id())) { | 468 !reachable_.Contains(block->block_id())) { |
| 468 reachable_.Add(block->block_id()); | 469 reachable_.Add(block->block_id()); |
| 469 stack_.Add(block); | 470 stack_.Add(block, block->zone()); |
| 470 visited_count_++; | 471 visited_count_++; |
| 471 } | 472 } |
| 472 } | 473 } |
| 473 | 474 |
| 474 void Analyze() { | 475 void Analyze() { |
| 475 while (!stack_.is_empty()) { | 476 while (!stack_.is_empty()) { |
| 476 HControlInstruction* end = stack_.RemoveLast()->end(); | 477 HControlInstruction* end = stack_.RemoveLast()->end(); |
| 477 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { | 478 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { |
| 478 PushBlock(it.Current()); | 479 PushBlock(it.Current()); |
| 479 } | 480 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 return GetConstant(&constant_false_, isolate()->heap()->false_value()); | 598 return GetConstant(&constant_false_, isolate()->heap()->false_value()); |
| 598 } | 599 } |
| 599 | 600 |
| 600 | 601 |
| 601 HConstant* HGraph::GetConstantHole() { | 602 HConstant* HGraph::GetConstantHole() { |
| 602 return GetConstant(&constant_hole_, isolate()->heap()->the_hole_value()); | 603 return GetConstant(&constant_hole_, isolate()->heap()->the_hole_value()); |
| 603 } | 604 } |
| 604 | 605 |
| 605 | 606 |
| 606 HGraphBuilder::HGraphBuilder(CompilationInfo* info, | 607 HGraphBuilder::HGraphBuilder(CompilationInfo* info, |
| 607 TypeFeedbackOracle* oracle) | 608 TypeFeedbackOracle* oracle, |
| 609 Zone* zone) |
| 608 : function_state_(NULL), | 610 : function_state_(NULL), |
| 609 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 611 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
| 610 ast_context_(NULL), | 612 ast_context_(NULL), |
| 611 break_scope_(NULL), | 613 break_scope_(NULL), |
| 612 graph_(NULL), | 614 graph_(NULL), |
| 613 current_block_(NULL), | 615 current_block_(NULL), |
| 614 inlined_count_(0), | 616 inlined_count_(0), |
| 615 globals_(10), | 617 globals_(10, zone), |
| 616 zone_(info->isolate()->zone()), | 618 zone_(zone), |
| 617 inline_bailout_(false) { | 619 inline_bailout_(false) { |
| 618 // This is not initialized in the initializer list because the | 620 // This is not initialized in the initializer list because the |
| 619 // constructor for the initial state relies on function_state_ == NULL | 621 // constructor for the initial state relies on function_state_ == NULL |
| 620 // to know it's the initial state. | 622 // to know it's the initial state. |
| 621 function_state_= &initial_function_state_; | 623 function_state_= &initial_function_state_; |
| 622 } | 624 } |
| 623 | 625 |
| 624 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, | 626 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, |
| 625 HBasicBlock* second, | 627 HBasicBlock* second, |
| 626 int join_id) { | 628 int join_id) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 return loop_successor; | 667 return loop_successor; |
| 666 } | 668 } |
| 667 | 669 |
| 668 | 670 |
| 669 void HBasicBlock::FinishExit(HControlInstruction* instruction) { | 671 void HBasicBlock::FinishExit(HControlInstruction* instruction) { |
| 670 Finish(instruction); | 672 Finish(instruction); |
| 671 ClearEnvironment(); | 673 ClearEnvironment(); |
| 672 } | 674 } |
| 673 | 675 |
| 674 | 676 |
| 675 HGraph::HGraph(CompilationInfo* info) | 677 HGraph::HGraph(CompilationInfo* info, Zone* zone) |
| 676 : isolate_(info->isolate()), | 678 : isolate_(info->isolate()), |
| 677 next_block_id_(0), | 679 next_block_id_(0), |
| 678 entry_block_(NULL), | 680 entry_block_(NULL), |
| 679 blocks_(8), | 681 blocks_(8, zone), |
| 680 values_(16), | 682 values_(16, zone), |
| 681 phi_list_(NULL) { | 683 phi_list_(NULL), |
| 684 zone_(zone) { |
| 682 start_environment_ = | 685 start_environment_ = |
| 683 new(zone()) HEnvironment(NULL, info->scope(), info->closure()); | 686 new(zone) HEnvironment(NULL, info->scope(), info->closure(), zone); |
| 684 start_environment_->set_ast_id(AstNode::kFunctionEntryId); | 687 start_environment_->set_ast_id(AstNode::kFunctionEntryId); |
| 685 entry_block_ = CreateBasicBlock(); | 688 entry_block_ = CreateBasicBlock(); |
| 686 entry_block_->SetInitialEnvironment(start_environment_); | 689 entry_block_->SetInitialEnvironment(start_environment_); |
| 687 } | 690 } |
| 688 | 691 |
| 689 | 692 |
| 690 Handle<Code> HGraph::Compile(CompilationInfo* info, Zone* zone) { | 693 Handle<Code> HGraph::Compile(CompilationInfo* info, Zone* zone) { |
| 691 int values = GetMaximumValueID(); | 694 int values = GetMaximumValueID(); |
| 692 if (values > LUnallocated::kMaxVirtualRegisters) { | 695 if (values > LUnallocated::kMaxVirtualRegisters) { |
| 693 if (FLAG_trace_bailout) { | 696 if (FLAG_trace_bailout) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 723 generator.FinishCode(code); | 726 generator.FinishCode(code); |
| 724 CodeGenerator::PrintCode(code, info); | 727 CodeGenerator::PrintCode(code, info); |
| 725 return code; | 728 return code; |
| 726 } | 729 } |
| 727 return Handle<Code>::null(); | 730 return Handle<Code>::null(); |
| 728 } | 731 } |
| 729 | 732 |
| 730 | 733 |
| 731 HBasicBlock* HGraph::CreateBasicBlock() { | 734 HBasicBlock* HGraph::CreateBasicBlock() { |
| 732 HBasicBlock* result = new(zone()) HBasicBlock(this); | 735 HBasicBlock* result = new(zone()) HBasicBlock(this); |
| 733 blocks_.Add(result); | 736 blocks_.Add(result, zone()); |
| 734 return result; | 737 return result; |
| 735 } | 738 } |
| 736 | 739 |
| 737 | 740 |
| 738 void HGraph::Canonicalize() { | 741 void HGraph::Canonicalize() { |
| 739 if (!FLAG_use_canonicalizing) return; | 742 if (!FLAG_use_canonicalizing) return; |
| 740 HPhase phase("H_Canonicalize", this); | 743 HPhase phase("H_Canonicalize", this); |
| 741 for (int i = 0; i < blocks()->length(); ++i) { | 744 for (int i = 0; i < blocks()->length(); ++i) { |
| 742 HInstruction* instr = blocks()->at(i)->first(); | 745 HInstruction* instr = blocks()->at(i)->first(); |
| 743 while (instr != NULL) { | 746 while (instr != NULL) { |
| 744 HValue* value = instr->Canonicalize(); | 747 HValue* value = instr->Canonicalize(); |
| 745 if (value != instr) instr->DeleteAndReplaceWith(value); | 748 if (value != instr) instr->DeleteAndReplaceWith(value); |
| 746 instr = instr->next(); | 749 instr = instr->next(); |
| 747 } | 750 } |
| 748 } | 751 } |
| 749 } | 752 } |
| 750 | 753 |
| 751 | 754 |
| 752 void HGraph::OrderBlocks() { | 755 void HGraph::OrderBlocks() { |
| 753 HPhase phase("H_Block ordering"); | 756 HPhase phase("H_Block ordering"); |
| 754 BitVector visited(blocks_.length(), zone()); | 757 BitVector visited(blocks_.length(), zone()); |
| 755 | 758 |
| 756 ZoneList<HBasicBlock*> reverse_result(8); | 759 ZoneList<HBasicBlock*> reverse_result(8, zone()); |
| 757 HBasicBlock* start = blocks_[0]; | 760 HBasicBlock* start = blocks_[0]; |
| 758 Postorder(start, &visited, &reverse_result, NULL); | 761 Postorder(start, &visited, &reverse_result, NULL); |
| 759 | 762 |
| 760 blocks_.Rewind(0); | 763 blocks_.Rewind(0); |
| 761 int index = 0; | 764 int index = 0; |
| 762 for (int i = reverse_result.length() - 1; i >= 0; --i) { | 765 for (int i = reverse_result.length() - 1; i >= 0; --i) { |
| 763 HBasicBlock* b = reverse_result[i]; | 766 HBasicBlock* b = reverse_result[i]; |
| 764 blocks_.Add(b); | 767 blocks_.Add(b, zone()); |
| 765 b->set_block_id(index++); | 768 b->set_block_id(index++); |
| 766 } | 769 } |
| 767 } | 770 } |
| 768 | 771 |
| 769 | 772 |
| 770 void HGraph::PostorderLoopBlocks(HLoopInformation* loop, | 773 void HGraph::PostorderLoopBlocks(HLoopInformation* loop, |
| 771 BitVector* visited, | 774 BitVector* visited, |
| 772 ZoneList<HBasicBlock*>* order, | 775 ZoneList<HBasicBlock*>* order, |
| 773 HBasicBlock* loop_header) { | 776 HBasicBlock* loop_header) { |
| 774 for (int i = 0; i < loop->blocks()->length(); ++i) { | 777 for (int i = 0; i < loop->blocks()->length(); ++i) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 800 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) { | 803 for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) { |
| 801 Postorder(it.Current(), visited, order, loop_header); | 804 Postorder(it.Current(), visited, order, loop_header); |
| 802 } | 805 } |
| 803 } | 806 } |
| 804 ASSERT(block->end()->FirstSuccessor() == NULL || | 807 ASSERT(block->end()->FirstSuccessor() == NULL || |
| 805 order->Contains(block->end()->FirstSuccessor()) || | 808 order->Contains(block->end()->FirstSuccessor()) || |
| 806 block->end()->FirstSuccessor()->IsLoopHeader()); | 809 block->end()->FirstSuccessor()->IsLoopHeader()); |
| 807 ASSERT(block->end()->SecondSuccessor() == NULL || | 810 ASSERT(block->end()->SecondSuccessor() == NULL || |
| 808 order->Contains(block->end()->SecondSuccessor()) || | 811 order->Contains(block->end()->SecondSuccessor()) || |
| 809 block->end()->SecondSuccessor()->IsLoopHeader()); | 812 block->end()->SecondSuccessor()->IsLoopHeader()); |
| 810 order->Add(block); | 813 order->Add(block, zone()); |
| 811 } | 814 } |
| 812 | 815 |
| 813 | 816 |
| 814 void HGraph::AssignDominators() { | 817 void HGraph::AssignDominators() { |
| 815 HPhase phase("H_Assign dominators", this); | 818 HPhase phase("H_Assign dominators", this); |
| 816 for (int i = 0; i < blocks_.length(); ++i) { | 819 for (int i = 0; i < blocks_.length(); ++i) { |
| 817 HBasicBlock* block = blocks_[i]; | 820 HBasicBlock* block = blocks_[i]; |
| 818 if (block->IsLoopHeader()) { | 821 if (block->IsLoopHeader()) { |
| 819 // Only the first predecessor of a loop header is from outside the loop. | 822 // Only the first predecessor of a loop header is from outside the loop. |
| 820 // All others are back edges, and thus cannot dominate the loop header. | 823 // All others are back edges, and thus cannot dominate the loop header. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 842 MarkAsDeoptimizingRecursively(dominated); | 845 MarkAsDeoptimizingRecursively(dominated); |
| 843 } | 846 } |
| 844 } | 847 } |
| 845 | 848 |
| 846 void HGraph::EliminateRedundantPhis() { | 849 void HGraph::EliminateRedundantPhis() { |
| 847 HPhase phase("H_Redundant phi elimination", this); | 850 HPhase phase("H_Redundant phi elimination", this); |
| 848 | 851 |
| 849 // Worklist of phis that can potentially be eliminated. Initialized with | 852 // Worklist of phis that can potentially be eliminated. Initialized with |
| 850 // all phi nodes. When elimination of a phi node modifies another phi node | 853 // all phi nodes. When elimination of a phi node modifies another phi node |
| 851 // the modified phi node is added to the worklist. | 854 // the modified phi node is added to the worklist. |
| 852 ZoneList<HPhi*> worklist(blocks_.length()); | 855 ZoneList<HPhi*> worklist(blocks_.length(), zone()); |
| 853 for (int i = 0; i < blocks_.length(); ++i) { | 856 for (int i = 0; i < blocks_.length(); ++i) { |
| 854 worklist.AddAll(*blocks_[i]->phis()); | 857 worklist.AddAll(*blocks_[i]->phis(), zone()); |
| 855 } | 858 } |
| 856 | 859 |
| 857 while (!worklist.is_empty()) { | 860 while (!worklist.is_empty()) { |
| 858 HPhi* phi = worklist.RemoveLast(); | 861 HPhi* phi = worklist.RemoveLast(); |
| 859 HBasicBlock* block = phi->block(); | 862 HBasicBlock* block = phi->block(); |
| 860 | 863 |
| 861 // Skip phi node if it was already replaced. | 864 // Skip phi node if it was already replaced. |
| 862 if (block == NULL) continue; | 865 if (block == NULL) continue; |
| 863 | 866 |
| 864 // Get replacement value if phi is redundant. | 867 // Get replacement value if phi is redundant. |
| 865 HValue* replacement = phi->GetRedundantReplacement(); | 868 HValue* replacement = phi->GetRedundantReplacement(); |
| 866 | 869 |
| 867 if (replacement != NULL) { | 870 if (replacement != NULL) { |
| 868 // Iterate through the uses and replace them all. | 871 // Iterate through the uses and replace them all. |
| 869 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { | 872 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
| 870 HValue* value = it.value(); | 873 HValue* value = it.value(); |
| 871 value->SetOperandAt(it.index(), replacement); | 874 value->SetOperandAt(it.index(), replacement); |
| 872 if (value->IsPhi()) worklist.Add(HPhi::cast(value)); | 875 if (value->IsPhi()) worklist.Add(HPhi::cast(value), zone()); |
| 873 } | 876 } |
| 874 block->RemovePhi(phi); | 877 block->RemovePhi(phi); |
| 875 } | 878 } |
| 876 } | 879 } |
| 877 } | 880 } |
| 878 | 881 |
| 879 | 882 |
| 880 void HGraph::EliminateUnreachablePhis() { | 883 void HGraph::EliminateUnreachablePhis() { |
| 881 HPhase phase("H_Unreachable phi elimination", this); | 884 HPhase phase("H_Unreachable phi elimination", this); |
| 882 | 885 |
| 883 // Initialize worklist. | 886 // Initialize worklist. |
| 884 ZoneList<HPhi*> phi_list(blocks_.length()); | 887 ZoneList<HPhi*> phi_list(blocks_.length(), zone()); |
| 885 ZoneList<HPhi*> worklist(blocks_.length()); | 888 ZoneList<HPhi*> worklist(blocks_.length(), zone()); |
| 886 for (int i = 0; i < blocks_.length(); ++i) { | 889 for (int i = 0; i < blocks_.length(); ++i) { |
| 887 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { | 890 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { |
| 888 HPhi* phi = blocks_[i]->phis()->at(j); | 891 HPhi* phi = blocks_[i]->phis()->at(j); |
| 889 phi_list.Add(phi); | 892 phi_list.Add(phi, zone()); |
| 890 // We can't eliminate phis in the receiver position in the environment | 893 // We can't eliminate phis in the receiver position in the environment |
| 891 // because in case of throwing an error we need this value to | 894 // because in case of throwing an error we need this value to |
| 892 // construct a stack trace. | 895 // construct a stack trace. |
| 893 if (phi->HasRealUses() || phi->IsReceiver()) { | 896 if (phi->HasRealUses() || phi->IsReceiver()) { |
| 894 phi->set_is_live(true); | 897 phi->set_is_live(true); |
| 895 worklist.Add(phi); | 898 worklist.Add(phi, zone()); |
| 896 } | 899 } |
| 897 } | 900 } |
| 898 } | 901 } |
| 899 | 902 |
| 900 // Iteratively mark live phis. | 903 // Iteratively mark live phis. |
| 901 while (!worklist.is_empty()) { | 904 while (!worklist.is_empty()) { |
| 902 HPhi* phi = worklist.RemoveLast(); | 905 HPhi* phi = worklist.RemoveLast(); |
| 903 for (int i = 0; i < phi->OperandCount(); i++) { | 906 for (int i = 0; i < phi->OperandCount(); i++) { |
| 904 HValue* operand = phi->OperandAt(i); | 907 HValue* operand = phi->OperandAt(i); |
| 905 if (operand->IsPhi() && !HPhi::cast(operand)->is_live()) { | 908 if (operand->IsPhi() && !HPhi::cast(operand)->is_live()) { |
| 906 HPhi::cast(operand)->set_is_live(true); | 909 HPhi::cast(operand)->set_is_live(true); |
| 907 worklist.Add(HPhi::cast(operand)); | 910 worklist.Add(HPhi::cast(operand), zone()); |
| 908 } | 911 } |
| 909 } | 912 } |
| 910 } | 913 } |
| 911 | 914 |
| 912 // Remove unreachable phis. | 915 // Remove unreachable phis. |
| 913 for (int i = 0; i < phi_list.length(); i++) { | 916 for (int i = 0; i < phi_list.length(); i++) { |
| 914 HPhi* phi = phi_list[i]; | 917 HPhi* phi = phi_list[i]; |
| 915 if (!phi->is_live()) { | 918 if (!phi->is_live()) { |
| 916 HBasicBlock* block = phi->block(); | 919 HBasicBlock* block = phi->block(); |
| 917 block->RemovePhi(phi); | 920 block->RemovePhi(phi); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 944 if (phi->OperandAt(k) == GetConstantHole()) return false; | 947 if (phi->OperandAt(k) == GetConstantHole()) return false; |
| 945 } | 948 } |
| 946 } | 949 } |
| 947 } | 950 } |
| 948 return true; | 951 return true; |
| 949 } | 952 } |
| 950 | 953 |
| 951 | 954 |
| 952 void HGraph::CollectPhis() { | 955 void HGraph::CollectPhis() { |
| 953 int block_count = blocks_.length(); | 956 int block_count = blocks_.length(); |
| 954 phi_list_ = new ZoneList<HPhi*>(block_count); | 957 phi_list_ = new(zone()) ZoneList<HPhi*>(block_count, zone()); |
| 955 for (int i = 0; i < block_count; ++i) { | 958 for (int i = 0; i < block_count; ++i) { |
| 956 for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { | 959 for (int j = 0; j < blocks_[i]->phis()->length(); ++j) { |
| 957 HPhi* phi = blocks_[i]->phis()->at(j); | 960 HPhi* phi = blocks_[i]->phis()->at(j); |
| 958 phi_list_->Add(phi); | 961 phi_list_->Add(phi, zone()); |
| 959 } | 962 } |
| 960 } | 963 } |
| 961 } | 964 } |
| 962 | 965 |
| 963 | 966 |
| 964 void HGraph::InferTypes(ZoneList<HValue*>* worklist) { | 967 void HGraph::InferTypes(ZoneList<HValue*>* worklist) { |
| 965 BitVector in_worklist(GetMaximumValueID(), zone()); | 968 BitVector in_worklist(GetMaximumValueID(), zone()); |
| 966 for (int i = 0; i < worklist->length(); ++i) { | 969 for (int i = 0; i < worklist->length(); ++i) { |
| 967 ASSERT(!in_worklist.Contains(worklist->at(i)->id())); | 970 ASSERT(!in_worklist.Contains(worklist->at(i)->id())); |
| 968 in_worklist.Add(worklist->at(i)->id()); | 971 in_worklist.Add(worklist->at(i)->id()); |
| 969 } | 972 } |
| 970 | 973 |
| 971 while (!worklist->is_empty()) { | 974 while (!worklist->is_empty()) { |
| 972 HValue* current = worklist->RemoveLast(); | 975 HValue* current = worklist->RemoveLast(); |
| 973 in_worklist.Remove(current->id()); | 976 in_worklist.Remove(current->id()); |
| 974 if (current->UpdateInferredType()) { | 977 if (current->UpdateInferredType()) { |
| 975 for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) { | 978 for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) { |
| 976 HValue* use = it.value(); | 979 HValue* use = it.value(); |
| 977 if (!in_worklist.Contains(use->id())) { | 980 if (!in_worklist.Contains(use->id())) { |
| 978 in_worklist.Add(use->id()); | 981 in_worklist.Add(use->id()); |
| 979 worklist->Add(use); | 982 worklist->Add(use, zone()); |
| 980 } | 983 } |
| 981 } | 984 } |
| 982 } | 985 } |
| 983 } | 986 } |
| 984 } | 987 } |
| 985 | 988 |
| 986 | 989 |
| 987 class HRangeAnalysis BASE_EMBEDDED { | 990 class HRangeAnalysis BASE_EMBEDDED { |
| 988 public: | 991 public: |
| 989 explicit HRangeAnalysis(HGraph* graph) : | 992 explicit HRangeAnalysis(HGraph* graph) : |
| 990 graph_(graph), zone_(graph->isolate()->zone()), changed_ranges_(16) { } | 993 graph_(graph), zone_(graph->zone()), changed_ranges_(16, zone_) { } |
| 991 | 994 |
| 992 void Analyze(); | 995 void Analyze(); |
| 993 | 996 |
| 994 private: | 997 private: |
| 995 void TraceRange(const char* msg, ...); | 998 void TraceRange(const char* msg, ...); |
| 996 void Analyze(HBasicBlock* block); | 999 void Analyze(HBasicBlock* block); |
| 997 void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest); | 1000 void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest); |
| 998 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other); | 1001 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other); |
| 999 void InferRange(HValue* value); | 1002 void InferRange(HValue* value); |
| 1000 void RollBackTo(int index); | 1003 void RollBackTo(int index); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 for (int i = index + 1; i < changed_ranges_.length(); ++i) { | 1128 for (int i = index + 1; i < changed_ranges_.length(); ++i) { |
| 1126 changed_ranges_[i]->RemoveLastAddedRange(); | 1129 changed_ranges_[i]->RemoveLastAddedRange(); |
| 1127 } | 1130 } |
| 1128 changed_ranges_.Rewind(index + 1); | 1131 changed_ranges_.Rewind(index + 1); |
| 1129 } | 1132 } |
| 1130 | 1133 |
| 1131 | 1134 |
| 1132 void HRangeAnalysis::AddRange(HValue* value, Range* range) { | 1135 void HRangeAnalysis::AddRange(HValue* value, Range* range) { |
| 1133 Range* original_range = value->range(); | 1136 Range* original_range = value->range(); |
| 1134 value->AddNewRange(range, zone_); | 1137 value->AddNewRange(range, zone_); |
| 1135 changed_ranges_.Add(value); | 1138 changed_ranges_.Add(value, zone_); |
| 1136 Range* new_range = value->range(); | 1139 Range* new_range = value->range(); |
| 1137 TraceRange("Updated range of %d set to [%d,%d]\n", | 1140 TraceRange("Updated range of %d set to [%d,%d]\n", |
| 1138 value->id(), | 1141 value->id(), |
| 1139 new_range->lower(), | 1142 new_range->lower(), |
| 1140 new_range->upper()); | 1143 new_range->upper()); |
| 1141 if (original_range != NULL) { | 1144 if (original_range != NULL) { |
| 1142 TraceRange("Original range was [%d,%d]\n", | 1145 TraceRange("Original range was [%d,%d]\n", |
| 1143 original_range->lower(), | 1146 original_range->lower(), |
| 1144 original_range->upper()); | 1147 original_range->upper()); |
| 1145 } | 1148 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1253 int next = array_[pos].next; | 1256 int next = array_[pos].next; |
| 1254 while (next != kNil) { | 1257 while (next != kNil) { |
| 1255 if (lists_[next].value->Equals(value)) return lists_[next].value; | 1258 if (lists_[next].value->Equals(value)) return lists_[next].value; |
| 1256 next = lists_[next].next; | 1259 next = lists_[next].next; |
| 1257 } | 1260 } |
| 1258 } | 1261 } |
| 1259 return NULL; | 1262 return NULL; |
| 1260 } | 1263 } |
| 1261 | 1264 |
| 1262 | 1265 |
| 1263 void HValueMap::Resize(int new_size) { | 1266 void HValueMap::Resize(int new_size, Zone* zone) { |
| 1264 ASSERT(new_size > count_); | 1267 ASSERT(new_size > count_); |
| 1265 // Hashing the values into the new array has no more collisions than in the | 1268 // Hashing the values into the new array has no more collisions than in the |
| 1266 // old hash map, so we can use the existing lists_ array, if we are careful. | 1269 // old hash map, so we can use the existing lists_ array, if we are careful. |
| 1267 | 1270 |
| 1268 // Make sure we have at least one free element. | 1271 // Make sure we have at least one free element. |
| 1269 if (free_list_head_ == kNil) { | 1272 if (free_list_head_ == kNil) { |
| 1270 ResizeLists(lists_size_ << 1); | 1273 ResizeLists(lists_size_ << 1, zone); |
| 1271 } | 1274 } |
| 1272 | 1275 |
| 1273 HValueMapListElement* new_array = | 1276 HValueMapListElement* new_array = |
| 1274 ZONE->NewArray<HValueMapListElement>(new_size); | 1277 zone->NewArray<HValueMapListElement>(new_size); |
| 1275 memset(new_array, 0, sizeof(HValueMapListElement) * new_size); | 1278 memset(new_array, 0, sizeof(HValueMapListElement) * new_size); |
| 1276 | 1279 |
| 1277 HValueMapListElement* old_array = array_; | 1280 HValueMapListElement* old_array = array_; |
| 1278 int old_size = array_size_; | 1281 int old_size = array_size_; |
| 1279 | 1282 |
| 1280 int old_count = count_; | 1283 int old_count = count_; |
| 1281 count_ = 0; | 1284 count_ = 0; |
| 1282 // Do not modify present_flags_. It is currently correct. | 1285 // Do not modify present_flags_. It is currently correct. |
| 1283 array_size_ = new_size; | 1286 array_size_ = new_size; |
| 1284 array_ = new_array; | 1287 array_ = new_array; |
| 1285 | 1288 |
| 1286 if (old_array != NULL) { | 1289 if (old_array != NULL) { |
| 1287 // Iterate over all the elements in lists, rehashing them. | 1290 // Iterate over all the elements in lists, rehashing them. |
| 1288 for (int i = 0; i < old_size; ++i) { | 1291 for (int i = 0; i < old_size; ++i) { |
| 1289 if (old_array[i].value != NULL) { | 1292 if (old_array[i].value != NULL) { |
| 1290 int current = old_array[i].next; | 1293 int current = old_array[i].next; |
| 1291 while (current != kNil) { | 1294 while (current != kNil) { |
| 1292 Insert(lists_[current].value); | 1295 Insert(lists_[current].value, zone); |
| 1293 int next = lists_[current].next; | 1296 int next = lists_[current].next; |
| 1294 lists_[current].next = free_list_head_; | 1297 lists_[current].next = free_list_head_; |
| 1295 free_list_head_ = current; | 1298 free_list_head_ = current; |
| 1296 current = next; | 1299 current = next; |
| 1297 } | 1300 } |
| 1298 // Rehash the directly stored value. | 1301 // Rehash the directly stored value. |
| 1299 Insert(old_array[i].value); | 1302 Insert(old_array[i].value, zone); |
| 1300 } | 1303 } |
| 1301 } | 1304 } |
| 1302 } | 1305 } |
| 1303 USE(old_count); | 1306 USE(old_count); |
| 1304 ASSERT(count_ == old_count); | 1307 ASSERT(count_ == old_count); |
| 1305 } | 1308 } |
| 1306 | 1309 |
| 1307 | 1310 |
| 1308 void HValueMap::ResizeLists(int new_size) { | 1311 void HValueMap::ResizeLists(int new_size, Zone* zone) { |
| 1309 ASSERT(new_size > lists_size_); | 1312 ASSERT(new_size > lists_size_); |
| 1310 | 1313 |
| 1311 HValueMapListElement* new_lists = | 1314 HValueMapListElement* new_lists = |
| 1312 ZONE->NewArray<HValueMapListElement>(new_size); | 1315 zone->NewArray<HValueMapListElement>(new_size); |
| 1313 memset(new_lists, 0, sizeof(HValueMapListElement) * new_size); | 1316 memset(new_lists, 0, sizeof(HValueMapListElement) * new_size); |
| 1314 | 1317 |
| 1315 HValueMapListElement* old_lists = lists_; | 1318 HValueMapListElement* old_lists = lists_; |
| 1316 int old_size = lists_size_; | 1319 int old_size = lists_size_; |
| 1317 | 1320 |
| 1318 lists_size_ = new_size; | 1321 lists_size_ = new_size; |
| 1319 lists_ = new_lists; | 1322 lists_ = new_lists; |
| 1320 | 1323 |
| 1321 if (old_lists != NULL) { | 1324 if (old_lists != NULL) { |
| 1322 memcpy(lists_, old_lists, old_size * sizeof(HValueMapListElement)); | 1325 memcpy(lists_, old_lists, old_size * sizeof(HValueMapListElement)); |
| 1323 } | 1326 } |
| 1324 for (int i = old_size; i < lists_size_; ++i) { | 1327 for (int i = old_size; i < lists_size_; ++i) { |
| 1325 lists_[i].next = free_list_head_; | 1328 lists_[i].next = free_list_head_; |
| 1326 free_list_head_ = i; | 1329 free_list_head_ = i; |
| 1327 } | 1330 } |
| 1328 } | 1331 } |
| 1329 | 1332 |
| 1330 | 1333 |
| 1331 void HValueMap::Insert(HValue* value) { | 1334 void HValueMap::Insert(HValue* value, Zone* zone) { |
| 1332 ASSERT(value != NULL); | 1335 ASSERT(value != NULL); |
| 1333 // Resizing when half of the hashtable is filled up. | 1336 // Resizing when half of the hashtable is filled up. |
| 1334 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1); | 1337 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1, zone); |
| 1335 ASSERT(count_ < array_size_); | 1338 ASSERT(count_ < array_size_); |
| 1336 count_++; | 1339 count_++; |
| 1337 uint32_t pos = Bound(static_cast<uint32_t>(value->Hashcode())); | 1340 uint32_t pos = Bound(static_cast<uint32_t>(value->Hashcode())); |
| 1338 if (array_[pos].value == NULL) { | 1341 if (array_[pos].value == NULL) { |
| 1339 array_[pos].value = value; | 1342 array_[pos].value = value; |
| 1340 array_[pos].next = kNil; | 1343 array_[pos].next = kNil; |
| 1341 } else { | 1344 } else { |
| 1342 if (free_list_head_ == kNil) { | 1345 if (free_list_head_ == kNil) { |
| 1343 ResizeLists(lists_size_ << 1); | 1346 ResizeLists(lists_size_ << 1, zone); |
| 1344 } | 1347 } |
| 1345 int new_element_pos = free_list_head_; | 1348 int new_element_pos = free_list_head_; |
| 1346 ASSERT(new_element_pos != kNil); | 1349 ASSERT(new_element_pos != kNil); |
| 1347 free_list_head_ = lists_[free_list_head_].next; | 1350 free_list_head_ = lists_[free_list_head_].next; |
| 1348 lists_[new_element_pos].value = value; | 1351 lists_[new_element_pos].value = value; |
| 1349 lists_[new_element_pos].next = array_[pos].next; | 1352 lists_[new_element_pos].next = array_[pos].next; |
| 1350 ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL); | 1353 ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL); |
| 1351 array_[pos].next = new_element_pos; | 1354 array_[pos].next = new_element_pos; |
| 1352 } | 1355 } |
| 1353 } | 1356 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 DISALLOW_COPY_AND_ASSIGN(SparseSet); | 1474 DISALLOW_COPY_AND_ASSIGN(SparseSet); |
| 1472 }; | 1475 }; |
| 1473 | 1476 |
| 1474 | 1477 |
| 1475 class HGlobalValueNumberer BASE_EMBEDDED { | 1478 class HGlobalValueNumberer BASE_EMBEDDED { |
| 1476 public: | 1479 public: |
| 1477 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) | 1480 explicit HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) |
| 1478 : graph_(graph), | 1481 : graph_(graph), |
| 1479 info_(info), | 1482 info_(info), |
| 1480 removed_side_effects_(false), | 1483 removed_side_effects_(false), |
| 1481 block_side_effects_(graph->blocks()->length()), | 1484 block_side_effects_(graph->blocks()->length(), graph->zone()), |
| 1482 loop_side_effects_(graph->blocks()->length()), | 1485 loop_side_effects_(graph->blocks()->length(), graph->zone()), |
| 1483 visited_on_paths_(graph->zone(), graph->blocks()->length()) { | 1486 visited_on_paths_(graph->zone(), graph->blocks()->length()) { |
| 1484 ASSERT(info->isolate()->heap()->allow_allocation(false)); | 1487 ASSERT(info->isolate()->heap()->allow_allocation(false)); |
| 1485 block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length()); | 1488 block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(), |
| 1486 loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length()); | 1489 graph_->zone()); |
| 1490 loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(), |
| 1491 graph_->zone()); |
| 1487 } | 1492 } |
| 1488 ~HGlobalValueNumberer() { | 1493 ~HGlobalValueNumberer() { |
| 1489 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); | 1494 ASSERT(!info_->isolate()->heap()->allow_allocation(true)); |
| 1490 } | 1495 } |
| 1491 | 1496 |
| 1492 // Returns true if values with side effects are removed. | 1497 // Returns true if values with side effects are removed. |
| 1493 bool Analyze(); | 1498 bool Analyze(); |
| 1494 | 1499 |
| 1495 private: | 1500 private: |
| 1496 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( | 1501 GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock( |
| 1497 HBasicBlock* dominator, | 1502 HBasicBlock* dominator, |
| 1498 HBasicBlock* dominated); | 1503 HBasicBlock* dominated); |
| 1499 void AnalyzeGraph(); | 1504 void AnalyzeGraph(); |
| 1500 void ComputeBlockSideEffects(); | 1505 void ComputeBlockSideEffects(); |
| 1501 void LoopInvariantCodeMotion(); | 1506 void LoopInvariantCodeMotion(); |
| 1502 void ProcessLoopBlock(HBasicBlock* block, | 1507 void ProcessLoopBlock(HBasicBlock* block, |
| 1503 HBasicBlock* before_loop, | 1508 HBasicBlock* before_loop, |
| 1504 GVNFlagSet loop_kills, | 1509 GVNFlagSet loop_kills, |
| 1505 GVNFlagSet* accumulated_first_time_depends, | 1510 GVNFlagSet* accumulated_first_time_depends, |
| 1506 GVNFlagSet* accumulated_first_time_changes); | 1511 GVNFlagSet* accumulated_first_time_changes); |
| 1507 bool AllowCodeMotion(); | 1512 bool AllowCodeMotion(); |
| 1508 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); | 1513 bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); |
| 1509 | 1514 |
| 1510 HGraph* graph() { return graph_; } | 1515 HGraph* graph() { return graph_; } |
| 1511 CompilationInfo* info() { return info_; } | 1516 CompilationInfo* info() { return info_; } |
| 1512 Zone* zone() { return graph_->zone(); } | 1517 Zone* zone() const { return graph_->zone(); } |
| 1513 | 1518 |
| 1514 HGraph* graph_; | 1519 HGraph* graph_; |
| 1515 CompilationInfo* info_; | 1520 CompilationInfo* info_; |
| 1516 bool removed_side_effects_; | 1521 bool removed_side_effects_; |
| 1517 | 1522 |
| 1518 // A map of block IDs to their side effects. | 1523 // A map of block IDs to their side effects. |
| 1519 ZoneList<GVNFlagSet> block_side_effects_; | 1524 ZoneList<GVNFlagSet> block_side_effects_; |
| 1520 | 1525 |
| 1521 // A map of loop header block IDs to their loop's side effects. | 1526 // A map of loop header block IDs to their loop's side effects. |
| 1522 ZoneList<GVNFlagSet> loop_side_effects_; | 1527 ZoneList<GVNFlagSet> loop_side_effects_; |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1942 int dominated_index_; | 1947 int dominated_index_; |
| 1943 int length_; | 1948 int length_; |
| 1944 }; | 1949 }; |
| 1945 | 1950 |
| 1946 // This is a recursive traversal of the dominator tree but it has been turned | 1951 // This is a recursive traversal of the dominator tree but it has been turned |
| 1947 // into a loop to avoid stack overflows. | 1952 // into a loop to avoid stack overflows. |
| 1948 // The logical "stack frames" of the recursion are kept in a list of | 1953 // The logical "stack frames" of the recursion are kept in a list of |
| 1949 // GvnBasicBlockState instances. | 1954 // GvnBasicBlockState instances. |
| 1950 void HGlobalValueNumberer::AnalyzeGraph() { | 1955 void HGlobalValueNumberer::AnalyzeGraph() { |
| 1951 HBasicBlock* entry_block = graph_->entry_block(); | 1956 HBasicBlock* entry_block = graph_->entry_block(); |
| 1952 HValueMap* entry_map = new(zone()) HValueMap(); | 1957 HValueMap* entry_map = new(zone()) HValueMap(zone()); |
| 1953 GvnBasicBlockState* current = | 1958 GvnBasicBlockState* current = |
| 1954 GvnBasicBlockState::CreateEntry(zone(), entry_block, entry_map); | 1959 GvnBasicBlockState::CreateEntry(zone(), entry_block, entry_map); |
| 1955 | 1960 |
| 1956 while (current != NULL) { | 1961 while (current != NULL) { |
| 1957 HBasicBlock* block = current->block(); | 1962 HBasicBlock* block = current->block(); |
| 1958 HValueMap* map = current->map(); | 1963 HValueMap* map = current->map(); |
| 1959 HSideEffectMap* dominators = current->dominators(); | 1964 HSideEffectMap* dominators = current->dominators(); |
| 1960 | 1965 |
| 1961 TRACE_GVN_2("Analyzing block B%d%s\n", | 1966 TRACE_GVN_2("Analyzing block B%d%s\n", |
| 1962 block->block_id(), | 1967 block->block_id(), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1986 if (other != NULL) { | 1991 if (other != NULL) { |
| 1987 ASSERT(instr->Equals(other) && other->Equals(instr)); | 1992 ASSERT(instr->Equals(other) && other->Equals(instr)); |
| 1988 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", | 1993 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", |
| 1989 instr->id(), | 1994 instr->id(), |
| 1990 instr->Mnemonic(), | 1995 instr->Mnemonic(), |
| 1991 other->id(), | 1996 other->id(), |
| 1992 other->Mnemonic()); | 1997 other->Mnemonic()); |
| 1993 if (instr->HasSideEffects()) removed_side_effects_ = true; | 1998 if (instr->HasSideEffects()) removed_side_effects_ = true; |
| 1994 instr->DeleteAndReplaceWith(other); | 1999 instr->DeleteAndReplaceWith(other); |
| 1995 } else { | 2000 } else { |
| 1996 map->Add(instr); | 2001 map->Add(instr, zone()); |
| 1997 } | 2002 } |
| 1998 } | 2003 } |
| 1999 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { | 2004 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { |
| 2000 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { | 2005 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { |
| 2001 HValue* other = dominators->at(i); | 2006 HValue* other = dominators->at(i); |
| 2002 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); | 2007 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); |
| 2003 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); | 2008 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); |
| 2004 if (instr->DependsOnFlags().Contains(depends_on_flag) && | 2009 if (instr->DependsOnFlags().Contains(depends_on_flag) && |
| 2005 (other != NULL)) { | 2010 (other != NULL)) { |
| 2006 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", | 2011 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2042 } | 2047 } |
| 2043 current = next; | 2048 current = next; |
| 2044 } | 2049 } |
| 2045 } | 2050 } |
| 2046 | 2051 |
| 2047 | 2052 |
| 2048 class HInferRepresentation BASE_EMBEDDED { | 2053 class HInferRepresentation BASE_EMBEDDED { |
| 2049 public: | 2054 public: |
| 2050 explicit HInferRepresentation(HGraph* graph) | 2055 explicit HInferRepresentation(HGraph* graph) |
| 2051 : graph_(graph), | 2056 : graph_(graph), |
| 2052 worklist_(8), | 2057 worklist_(8, graph->zone()), |
| 2053 in_worklist_(graph->GetMaximumValueID(), graph->zone()) { } | 2058 in_worklist_(graph->GetMaximumValueID(), graph->zone()) { } |
| 2054 | 2059 |
| 2055 void Analyze(); | 2060 void Analyze(); |
| 2056 | 2061 |
| 2057 private: | 2062 private: |
| 2058 Representation TryChange(HValue* current); | 2063 Representation TryChange(HValue* current); |
| 2059 void AddToWorklist(HValue* current); | 2064 void AddToWorklist(HValue* current); |
| 2060 void InferBasedOnInputs(HValue* current); | 2065 void InferBasedOnInputs(HValue* current); |
| 2061 void AddDependantsToWorklist(HValue* current); | 2066 void AddDependantsToWorklist(HValue* current); |
| 2062 void InferBasedOnUses(HValue* current); | 2067 void InferBasedOnUses(HValue* current); |
| 2063 | 2068 |
| 2064 Zone* zone() { return graph_->zone(); } | 2069 Zone* zone() const { return graph_->zone(); } |
| 2065 | 2070 |
| 2066 HGraph* graph_; | 2071 HGraph* graph_; |
| 2067 ZoneList<HValue*> worklist_; | 2072 ZoneList<HValue*> worklist_; |
| 2068 BitVector in_worklist_; | 2073 BitVector in_worklist_; |
| 2069 }; | 2074 }; |
| 2070 | 2075 |
| 2071 | 2076 |
| 2072 void HInferRepresentation::AddToWorklist(HValue* current) { | 2077 void HInferRepresentation::AddToWorklist(HValue* current) { |
| 2073 if (current->representation().IsSpecialization()) return; | 2078 if (current->representation().IsSpecialization()) return; |
| 2074 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return; | 2079 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return; |
| 2075 if (in_worklist_.Contains(current->id())) return; | 2080 if (in_worklist_.Contains(current->id())) return; |
| 2076 worklist_.Add(current); | 2081 worklist_.Add(current, zone()); |
| 2077 in_worklist_.Add(current->id()); | 2082 in_worklist_.Add(current->id()); |
| 2078 } | 2083 } |
| 2079 | 2084 |
| 2080 | 2085 |
| 2081 // This method tries to specialize the representation type of the value | 2086 // This method tries to specialize the representation type of the value |
| 2082 // given as a parameter. The value is asked to infer its representation type | 2087 // given as a parameter. The value is asked to infer its representation type |
| 2083 // based on its inputs. If the inferred type is more specialized, then this | 2088 // based on its inputs. If the inferred type is more specialized, then this |
| 2084 // becomes the new representation type of the node. | 2089 // becomes the new representation type of the node. |
| 2085 void HInferRepresentation::InferBasedOnInputs(HValue* current) { | 2090 void HInferRepresentation::InferBasedOnInputs(HValue* current) { |
| 2086 Representation r = current->representation(); | 2091 Representation r = current->representation(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2177 } | 2182 } |
| 2178 | 2183 |
| 2179 | 2184 |
| 2180 void HInferRepresentation::Analyze() { | 2185 void HInferRepresentation::Analyze() { |
| 2181 HPhase phase("H_Infer representations", graph_); | 2186 HPhase phase("H_Infer representations", graph_); |
| 2182 | 2187 |
| 2183 // (1) Initialize bit vectors and count real uses. Each phi gets a | 2188 // (1) Initialize bit vectors and count real uses. Each phi gets a |
| 2184 // bit-vector of length <number of phis>. | 2189 // bit-vector of length <number of phis>. |
| 2185 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); | 2190 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); |
| 2186 int phi_count = phi_list->length(); | 2191 int phi_count = phi_list->length(); |
| 2187 ZoneList<BitVector*> connected_phis(phi_count); | 2192 ZoneList<BitVector*> connected_phis(phi_count, graph_->zone()); |
| 2188 for (int i = 0; i < phi_count; ++i) { | 2193 for (int i = 0; i < phi_count; ++i) { |
| 2189 phi_list->at(i)->InitRealUses(i); | 2194 phi_list->at(i)->InitRealUses(i); |
| 2190 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); | 2195 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); |
| 2191 connected_set->Add(i); | 2196 connected_set->Add(i); |
| 2192 connected_phis.Add(connected_set); | 2197 connected_phis.Add(connected_set, zone()); |
| 2193 } | 2198 } |
| 2194 | 2199 |
| 2195 // (2) Do a fixed point iteration to find the set of connected phis. A | 2200 // (2) Do a fixed point iteration to find the set of connected phis. A |
| 2196 // phi is connected to another phi if its value is used either directly or | 2201 // phi is connected to another phi if its value is used either directly or |
| 2197 // indirectly through a transitive closure of the def-use relation. | 2202 // indirectly through a transitive closure of the def-use relation. |
| 2198 bool change = true; | 2203 bool change = true; |
| 2199 while (change) { | 2204 while (change) { |
| 2200 change = false; | 2205 change = false; |
| 2201 // We normally have far more "forward edges" than "backward edges", | 2206 // We normally have far more "forward edges" than "backward edges", |
| 2202 // so we terminate faster when we walk backwards. | 2207 // so we terminate faster when we walk backwards. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2291 } | 2296 } |
| 2292 | 2297 |
| 2293 if (block->IsLoopHeader()) { | 2298 if (block->IsLoopHeader()) { |
| 2294 HBasicBlock* last_back_edge = | 2299 HBasicBlock* last_back_edge = |
| 2295 block->loop_information()->GetLastBackEdge(); | 2300 block->loop_information()->GetLastBackEdge(); |
| 2296 InitializeInferredTypes(i + 1, last_back_edge->block_id()); | 2301 InitializeInferredTypes(i + 1, last_back_edge->block_id()); |
| 2297 // Skip all blocks already processed by the recursive call. | 2302 // Skip all blocks already processed by the recursive call. |
| 2298 i = last_back_edge->block_id(); | 2303 i = last_back_edge->block_id(); |
| 2299 // Update phis of the loop header now after the whole loop body is | 2304 // Update phis of the loop header now after the whole loop body is |
| 2300 // guaranteed to be processed. | 2305 // guaranteed to be processed. |
| 2301 ZoneList<HValue*> worklist(block->phis()->length()); | 2306 ZoneList<HValue*> worklist(block->phis()->length(), zone()); |
| 2302 for (int j = 0; j < block->phis()->length(); ++j) { | 2307 for (int j = 0; j < block->phis()->length(); ++j) { |
| 2303 worklist.Add(block->phis()->at(j)); | 2308 worklist.Add(block->phis()->at(j), zone()); |
| 2304 } | 2309 } |
| 2305 InferTypes(&worklist); | 2310 InferTypes(&worklist); |
| 2306 } | 2311 } |
| 2307 } | 2312 } |
| 2308 } | 2313 } |
| 2309 | 2314 |
| 2310 | 2315 |
| 2311 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { | 2316 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { |
| 2312 HValue* current = value; | 2317 HValue* current = value; |
| 2313 while (current != NULL) { | 2318 while (current != NULL) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2360 // information we treat constants like normal instructions and insert the | 2365 // information we treat constants like normal instructions and insert the |
| 2361 // change instructions for them. | 2366 // change instructions for them. |
| 2362 HInstruction* new_value = NULL; | 2367 HInstruction* new_value = NULL; |
| 2363 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | 2368 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
| 2364 bool deoptimize_on_undefined = | 2369 bool deoptimize_on_undefined = |
| 2365 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); | 2370 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); |
| 2366 if (value->IsConstant()) { | 2371 if (value->IsConstant()) { |
| 2367 HConstant* constant = HConstant::cast(value); | 2372 HConstant* constant = HConstant::cast(value); |
| 2368 // Try to create a new copy of the constant with the new representation. | 2373 // Try to create a new copy of the constant with the new representation. |
| 2369 new_value = is_truncating | 2374 new_value = is_truncating |
| 2370 ? constant->CopyToTruncatedInt32() | 2375 ? constant->CopyToTruncatedInt32(zone()) |
| 2371 : constant->CopyToRepresentation(to); | 2376 : constant->CopyToRepresentation(to, zone()); |
| 2372 } | 2377 } |
| 2373 | 2378 |
| 2374 if (new_value == NULL) { | 2379 if (new_value == NULL) { |
| 2375 new_value = new(zone()) HChange(value, to, | 2380 new_value = new(zone()) HChange(value, to, |
| 2376 is_truncating, deoptimize_on_undefined); | 2381 is_truncating, deoptimize_on_undefined); |
| 2377 } | 2382 } |
| 2378 | 2383 |
| 2379 new_value->InsertBefore(next); | 2384 new_value->InsertBefore(next); |
| 2380 use_value->SetOperandAt(use_index, new_value); | 2385 use_value->SetOperandAt(use_index, new_value); |
| 2381 } | 2386 } |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2780 | 2785 |
| 2781 | 2786 |
| 2782 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { | 2787 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { |
| 2783 for (int i = 0; i < exprs->length(); ++i) { | 2788 for (int i = 0; i < exprs->length(); ++i) { |
| 2784 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 2789 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
| 2785 } | 2790 } |
| 2786 } | 2791 } |
| 2787 | 2792 |
| 2788 | 2793 |
| 2789 HGraph* HGraphBuilder::CreateGraph() { | 2794 HGraph* HGraphBuilder::CreateGraph() { |
| 2790 graph_ = new(zone()) HGraph(info()); | 2795 graph_ = new(zone()) HGraph(info(), zone()); |
| 2791 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 2796 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); |
| 2792 | 2797 |
| 2793 { | 2798 { |
| 2794 HPhase phase("H_Block building"); | 2799 HPhase phase("H_Block building"); |
| 2795 current_block_ = graph()->entry_block(); | 2800 current_block_ = graph()->entry_block(); |
| 2796 | 2801 |
| 2797 Scope* scope = info()->scope(); | 2802 Scope* scope = info()->scope(); |
| 2798 if (scope->HasIllegalRedeclaration()) { | 2803 if (scope->HasIllegalRedeclaration()) { |
| 2799 Bailout("function with illegal redeclaration"); | 2804 Bailout("function with illegal redeclaration"); |
| 2800 return NULL; | 2805 return NULL; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3131 | 3136 |
| 3132 static bool BoundsCheckKeyMatch(void* key1, void* key2) { | 3137 static bool BoundsCheckKeyMatch(void* key1, void* key2) { |
| 3133 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); | 3138 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); |
| 3134 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); | 3139 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); |
| 3135 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); | 3140 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); |
| 3136 } | 3141 } |
| 3137 | 3142 |
| 3138 | 3143 |
| 3139 class BoundsCheckTable : private ZoneHashMap { | 3144 class BoundsCheckTable : private ZoneHashMap { |
| 3140 public: | 3145 public: |
| 3141 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key) { | 3146 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key, Zone* zone) { |
| 3142 return reinterpret_cast<BoundsCheckBbData**>( | 3147 return reinterpret_cast<BoundsCheckBbData**>( |
| 3143 &(Lookup(key, key->Hash(), true)->value)); | 3148 &(Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value)); |
| 3144 } | 3149 } |
| 3145 | 3150 |
| 3146 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data) { | 3151 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data, Zone* zone) { |
| 3147 Lookup(key, key->Hash(), true)->value = data; | 3152 Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value = data; |
| 3148 } | 3153 } |
| 3149 | 3154 |
| 3150 void Delete(BoundsCheckKey* key) { | 3155 void Delete(BoundsCheckKey* key) { |
| 3151 Remove(key, key->Hash()); | 3156 Remove(key, key->Hash()); |
| 3152 } | 3157 } |
| 3153 | 3158 |
| 3154 BoundsCheckTable() : ZoneHashMap(BoundsCheckKeyMatch) { } | 3159 explicit BoundsCheckTable(Zone* zone) |
| 3160 : ZoneHashMap(BoundsCheckKeyMatch, ZoneHashMap::kDefaultHashMapCapacity, |
| 3161 ZoneAllocationPolicy(zone)) { } |
| 3155 }; | 3162 }; |
| 3156 | 3163 |
| 3157 | 3164 |
| 3158 // Eliminates checks in bb and recursively in the dominated blocks. | 3165 // Eliminates checks in bb and recursively in the dominated blocks. |
| 3159 // Also replace the results of check instructions with the original value, if | 3166 // Also replace the results of check instructions with the original value, if |
| 3160 // the result is used. This is safe now, since we don't do code motion after | 3167 // the result is used. This is safe now, since we don't do code motion after |
| 3161 // this point. It enables better register allocation since the value produced | 3168 // this point. It enables better register allocation since the value produced |
| 3162 // by check instructions is really a copy of the original value. | 3169 // by check instructions is really a copy of the original value. |
| 3163 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, | 3170 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
| 3164 BoundsCheckTable* table) { | 3171 BoundsCheckTable* table) { |
| 3165 BoundsCheckBbData* bb_data_list = NULL; | 3172 BoundsCheckBbData* bb_data_list = NULL; |
| 3166 | 3173 |
| 3167 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { | 3174 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
| 3168 if (!i->IsBoundsCheck()) continue; | 3175 if (!i->IsBoundsCheck()) continue; |
| 3169 | 3176 |
| 3170 HBoundsCheck* check = HBoundsCheck::cast(i); | 3177 HBoundsCheck* check = HBoundsCheck::cast(i); |
| 3171 check->ReplaceAllUsesWith(check->index()); | 3178 check->ReplaceAllUsesWith(check->index()); |
| 3172 | 3179 |
| 3173 if (!FLAG_array_bounds_checks_elimination) continue; | 3180 if (!FLAG_array_bounds_checks_elimination) continue; |
| 3174 | 3181 |
| 3175 int32_t offset; | 3182 int32_t offset; |
| 3176 BoundsCheckKey* key = | 3183 BoundsCheckKey* key = |
| 3177 BoundsCheckKey::Create(bb->zone(), check, &offset); | 3184 BoundsCheckKey::Create(zone(), check, &offset); |
| 3178 BoundsCheckBbData** data_p = table->LookupOrInsert(key); | 3185 BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone()); |
| 3179 BoundsCheckBbData* data = *data_p; | 3186 BoundsCheckBbData* data = *data_p; |
| 3180 if (data == NULL) { | 3187 if (data == NULL) { |
| 3181 bb_data_list = new(zone()) BoundsCheckBbData(key, | 3188 bb_data_list = new(zone()) BoundsCheckBbData(key, |
| 3182 offset, | 3189 offset, |
| 3183 offset, | 3190 offset, |
| 3184 bb, | 3191 bb, |
| 3185 check, | 3192 check, |
| 3186 bb_data_list, | 3193 bb_data_list, |
| 3187 NULL); | 3194 NULL); |
| 3188 *data_p = bb_data_list; | 3195 *data_p = bb_data_list; |
| 3189 } else if (data->OffsetIsCovered(offset)) { | 3196 } else if (data->OffsetIsCovered(offset)) { |
| 3190 check->DeleteAndReplaceWith(NULL); | 3197 check->DeleteAndReplaceWith(NULL); |
| 3191 } else if (data->BasicBlock() == bb) { | 3198 } else if (data->BasicBlock() == bb) { |
| 3192 data->CoverCheck(check, offset); | 3199 data->CoverCheck(check, offset); |
| 3193 } else { | 3200 } else { |
| 3194 int32_t new_lower_offset = offset < data->LowerOffset() | 3201 int32_t new_lower_offset = offset < data->LowerOffset() |
| 3195 ? offset | 3202 ? offset |
| 3196 : data->LowerOffset(); | 3203 : data->LowerOffset(); |
| 3197 int32_t new_upper_offset = offset > data->UpperOffset() | 3204 int32_t new_upper_offset = offset > data->UpperOffset() |
| 3198 ? offset | 3205 ? offset |
| 3199 : data->UpperOffset(); | 3206 : data->UpperOffset(); |
| 3200 bb_data_list = new(bb->zone()) BoundsCheckBbData(key, | 3207 bb_data_list = new(zone()) BoundsCheckBbData(key, |
| 3201 new_lower_offset, | 3208 new_lower_offset, |
| 3202 new_upper_offset, | 3209 new_upper_offset, |
| 3203 bb, | 3210 bb, |
| 3204 check, | 3211 check, |
| 3205 bb_data_list, | 3212 bb_data_list, |
| 3206 data); | 3213 data); |
| 3207 table->Insert(key, bb_data_list); | 3214 table->Insert(key, bb_data_list, zone()); |
| 3208 } | 3215 } |
| 3209 } | 3216 } |
| 3210 | 3217 |
| 3211 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { | 3218 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { |
| 3212 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); | 3219 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); |
| 3213 } | 3220 } |
| 3214 | 3221 |
| 3215 for (BoundsCheckBbData* data = bb_data_list; | 3222 for (BoundsCheckBbData* data = bb_data_list; |
| 3216 data != NULL; | 3223 data != NULL; |
| 3217 data = data->NextInBasicBlock()) { | 3224 data = data->NextInBasicBlock()) { |
| 3218 data->RemoveZeroOperations(); | 3225 data->RemoveZeroOperations(); |
| 3219 if (data->FatherInDominatorTree()) { | 3226 if (data->FatherInDominatorTree()) { |
| 3220 table->Insert(data->Key(), data->FatherInDominatorTree()); | 3227 table->Insert(data->Key(), data->FatherInDominatorTree(), zone()); |
| 3221 } else { | 3228 } else { |
| 3222 table->Delete(data->Key()); | 3229 table->Delete(data->Key()); |
| 3223 } | 3230 } |
| 3224 } | 3231 } |
| 3225 } | 3232 } |
| 3226 | 3233 |
| 3227 | 3234 |
| 3228 void HGraph::EliminateRedundantBoundsChecks() { | 3235 void HGraph::EliminateRedundantBoundsChecks() { |
| 3229 HPhase phase("H_Eliminate bounds checks", this); | 3236 HPhase phase("H_Eliminate bounds checks", this); |
| 3230 AssertNoAllocation no_gc; | 3237 AssertNoAllocation no_gc; |
| 3231 BoundsCheckTable checks_table; | 3238 BoundsCheckTable checks_table(zone()); |
| 3232 EliminateRedundantBoundsChecks(entry_block(), &checks_table); | 3239 EliminateRedundantBoundsChecks(entry_block(), &checks_table); |
| 3233 } | 3240 } |
| 3234 | 3241 |
| 3235 | 3242 |
| 3236 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { | 3243 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
| 3237 HValue* index = array_operation->GetKey(); | 3244 HValue* index = array_operation->GetKey(); |
| 3238 | 3245 |
| 3239 HConstant* constant; | 3246 HConstant* constant; |
| 3240 HValue* subexpression; | 3247 HValue* subexpression; |
| 3241 int32_t sign; | 3248 int32_t sign; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3341 | 3348 |
| 3342 void HGraphBuilder::PushAndAdd(HInstruction* instr) { | 3349 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
| 3343 Push(instr); | 3350 Push(instr); |
| 3344 AddInstruction(instr); | 3351 AddInstruction(instr); |
| 3345 } | 3352 } |
| 3346 | 3353 |
| 3347 | 3354 |
| 3348 template <class Instruction> | 3355 template <class Instruction> |
| 3349 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { | 3356 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { |
| 3350 int count = call->argument_count(); | 3357 int count = call->argument_count(); |
| 3351 ZoneList<HValue*> arguments(count); | 3358 ZoneList<HValue*> arguments(count, zone()); |
| 3352 for (int i = 0; i < count; ++i) { | 3359 for (int i = 0; i < count; ++i) { |
| 3353 arguments.Add(Pop()); | 3360 arguments.Add(Pop(), zone()); |
| 3354 } | 3361 } |
| 3355 | 3362 |
| 3356 while (!arguments.is_empty()) { | 3363 while (!arguments.is_empty()) { |
| 3357 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 3364 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
| 3358 } | 3365 } |
| 3359 return call; | 3366 return call; |
| 3360 } | 3367 } |
| 3361 | 3368 |
| 3362 | 3369 |
| 3363 void HGraphBuilder::SetUpScope(Scope* scope) { | 3370 void HGraphBuilder::SetUpScope(Scope* scope) { |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3843 current_block()->Finish(test); | 3850 current_block()->Finish(test); |
| 3844 | 3851 |
| 3845 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 3852 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
| 3846 non_osr_entry->Goto(loop_predecessor); | 3853 non_osr_entry->Goto(loop_predecessor); |
| 3847 | 3854 |
| 3848 set_current_block(osr_entry); | 3855 set_current_block(osr_entry); |
| 3849 int osr_entry_id = statement->OsrEntryId(); | 3856 int osr_entry_id = statement->OsrEntryId(); |
| 3850 int first_expression_index = environment()->first_expression_index(); | 3857 int first_expression_index = environment()->first_expression_index(); |
| 3851 int length = environment()->length(); | 3858 int length = environment()->length(); |
| 3852 ZoneList<HUnknownOSRValue*>* osr_values = | 3859 ZoneList<HUnknownOSRValue*>* osr_values = |
| 3853 new(zone()) ZoneList<HUnknownOSRValue*>(length); | 3860 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); |
| 3854 | 3861 |
| 3855 for (int i = 0; i < first_expression_index; ++i) { | 3862 for (int i = 0; i < first_expression_index; ++i) { |
| 3856 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3863 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
| 3857 AddInstruction(osr_value); | 3864 AddInstruction(osr_value); |
| 3858 environment()->Bind(i, osr_value); | 3865 environment()->Bind(i, osr_value); |
| 3859 osr_values->Add(osr_value); | 3866 osr_values->Add(osr_value, zone()); |
| 3860 } | 3867 } |
| 3861 | 3868 |
| 3862 if (first_expression_index != length) { | 3869 if (first_expression_index != length) { |
| 3863 environment()->Drop(length - first_expression_index); | 3870 environment()->Drop(length - first_expression_index); |
| 3864 for (int i = first_expression_index; i < length; ++i) { | 3871 for (int i = first_expression_index; i < length; ++i) { |
| 3865 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3872 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
| 3866 AddInstruction(osr_value); | 3873 AddInstruction(osr_value); |
| 3867 environment()->Push(osr_value); | 3874 environment()->Push(osr_value); |
| 3868 osr_values->Add(osr_value); | 3875 osr_values->Add(osr_value, zone()); |
| 3869 } | 3876 } |
| 3870 } | 3877 } |
| 3871 | 3878 |
| 3872 graph()->set_osr_values(osr_values); | 3879 graph()->set_osr_values(osr_values); |
| 3873 | 3880 |
| 3874 AddSimulate(osr_entry_id); | 3881 AddSimulate(osr_entry_id); |
| 3875 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 3882 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
| 3876 HContext* context = new(zone()) HContext; | 3883 HContext* context = new(zone()) HContext; |
| 3877 AddInstruction(context); | 3884 AddInstruction(context); |
| 3878 environment()->BindContext(context); | 3885 environment()->BindContext(context); |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4486 expr->fast_elements(), | 4493 expr->fast_elements(), |
| 4487 expr->literal_index(), | 4494 expr->literal_index(), |
| 4488 expr->depth(), | 4495 expr->depth(), |
| 4489 expr->has_function()); | 4496 expr->has_function()); |
| 4490 } | 4497 } |
| 4491 | 4498 |
| 4492 // The object is expected in the bailout environment during computation | 4499 // The object is expected in the bailout environment during computation |
| 4493 // of the property values and is the value of the entire expression. | 4500 // of the property values and is the value of the entire expression. |
| 4494 PushAndAdd(literal); | 4501 PushAndAdd(literal); |
| 4495 | 4502 |
| 4496 expr->CalculateEmitStore(); | 4503 expr->CalculateEmitStore(zone()); |
| 4497 | 4504 |
| 4498 for (int i = 0; i < expr->properties()->length(); i++) { | 4505 for (int i = 0; i < expr->properties()->length(); i++) { |
| 4499 ObjectLiteral::Property* property = expr->properties()->at(i); | 4506 ObjectLiteral::Property* property = expr->properties()->at(i); |
| 4500 if (property->IsCompileTimeValue()) continue; | 4507 if (property->IsCompileTimeValue()) continue; |
| 4501 | 4508 |
| 4502 Literal* key = property->key(); | 4509 Literal* key = property->key(); |
| 4503 Expression* value = property->value(); | 4510 Expression* value = property->value(); |
| 4504 | 4511 |
| 4505 switch (property->kind()) { | 4512 switch (property->kind()) { |
| 4506 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 4513 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4676 | 4683 |
| 4677 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 4684 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
| 4678 Handle<String> name, | 4685 Handle<String> name, |
| 4679 HValue* value, | 4686 HValue* value, |
| 4680 Handle<Map> type, | 4687 Handle<Map> type, |
| 4681 LookupResult* lookup, | 4688 LookupResult* lookup, |
| 4682 bool smi_and_map_check) { | 4689 bool smi_and_map_check) { |
| 4683 ASSERT(lookup->IsFound()); | 4690 ASSERT(lookup->IsFound()); |
| 4684 if (smi_and_map_check) { | 4691 if (smi_and_map_check) { |
| 4685 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4692 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 4686 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 4693 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
| 4687 } | 4694 } |
| 4688 | 4695 |
| 4689 // If the property does not exist yet, we have to check that it wasn't made | 4696 // If the property does not exist yet, we have to check that it wasn't made |
| 4690 // readonly or turned into a setter by some meanwhile modifications on the | 4697 // readonly or turned into a setter by some meanwhile modifications on the |
| 4691 // prototype chain. | 4698 // prototype chain. |
| 4692 if (!lookup->IsProperty()) { | 4699 if (!lookup->IsProperty()) { |
| 4693 Object* proto = type->prototype(); | 4700 Object* proto = type->prototype(); |
| 4694 // First check that the prototype chain isn't affected already. | 4701 // First check that the prototype chain isn't affected already. |
| 4695 LookupResult proto_result(isolate()); | 4702 LookupResult proto_result(isolate()); |
| 4696 proto->Lookup(*name, &proto_result); | 4703 proto->Lookup(*name, &proto_result); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4821 (is_in_object == previous_field_is_in_object); | 4828 (is_in_object == previous_field_is_in_object); |
| 4822 } | 4829 } |
| 4823 ++count; | 4830 ++count; |
| 4824 } | 4831 } |
| 4825 } | 4832 } |
| 4826 | 4833 |
| 4827 // Use monomorphic load if property lookup results in the same field index | 4834 // Use monomorphic load if property lookup results in the same field index |
| 4828 // for all maps. Requires special map check on the set of all handled maps. | 4835 // for all maps. Requires special map check on the set of all handled maps. |
| 4829 HInstruction* instr; | 4836 HInstruction* instr; |
| 4830 if (count == types->length() && is_monomorphic_field) { | 4837 if (count == types->length() && is_monomorphic_field) { |
| 4831 AddInstruction(new(zone()) HCheckMaps(object, types)); | 4838 AddInstruction(new(zone()) HCheckMaps(object, types, zone())); |
| 4832 instr = BuildLoadNamedField(object, expr, map, &lookup, false); | 4839 instr = BuildLoadNamedField(object, expr, map, &lookup, false); |
| 4833 } else { | 4840 } else { |
| 4834 HValue* context = environment()->LookupContext(); | 4841 HValue* context = environment()->LookupContext(); |
| 4835 instr = new(zone()) HLoadNamedFieldPolymorphic(context, | 4842 instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
| 4836 object, | 4843 object, |
| 4837 types, | 4844 types, |
| 4838 name); | 4845 name, |
| 4846 zone()); |
| 4839 } | 4847 } |
| 4840 | 4848 |
| 4841 instr->set_position(expr->position()); | 4849 instr->set_position(expr->position()); |
| 4842 return ast_context()->ReturnInstruction(instr, expr->id()); | 4850 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 4843 } | 4851 } |
| 4844 | 4852 |
| 4845 | 4853 |
| 4846 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 4854 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
| 4847 HValue* object, | 4855 HValue* object, |
| 4848 HValue* value, | 4856 HValue* value, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4915 ASSERT(join != NULL); | 4923 ASSERT(join != NULL); |
| 4916 join->SetJoinId(expr->id()); | 4924 join->SetJoinId(expr->id()); |
| 4917 set_current_block(join); | 4925 set_current_block(join); |
| 4918 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 4926 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
| 4919 } | 4927 } |
| 4920 | 4928 |
| 4921 | 4929 |
| 4922 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 4930 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
| 4923 Property* prop = expr->target()->AsProperty(); | 4931 Property* prop = expr->target()->AsProperty(); |
| 4924 ASSERT(prop != NULL); | 4932 ASSERT(prop != NULL); |
| 4925 expr->RecordTypeFeedback(oracle()); | 4933 expr->RecordTypeFeedback(oracle(), zone()); |
| 4926 CHECK_ALIVE(VisitForValue(prop->obj())); | 4934 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 4927 | 4935 |
| 4928 HValue* value = NULL; | 4936 HValue* value = NULL; |
| 4929 HInstruction* instr = NULL; | 4937 HInstruction* instr = NULL; |
| 4930 | 4938 |
| 4931 if (prop->key()->IsPropertyName()) { | 4939 if (prop->key()->IsPropertyName()) { |
| 4932 // Named store. | 4940 // Named store. |
| 4933 CHECK_ALIVE(VisitForValue(expr->value())); | 4941 CHECK_ALIVE(VisitForValue(expr->value())); |
| 4934 value = Pop(); | 4942 value = Pop(); |
| 4935 HValue* object = Pop(); | 4943 HValue* object = Pop(); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5086 } | 5094 } |
| 5087 break; | 5095 break; |
| 5088 } | 5096 } |
| 5089 | 5097 |
| 5090 case Variable::LOOKUP: | 5098 case Variable::LOOKUP: |
| 5091 return Bailout("compound assignment to lookup slot"); | 5099 return Bailout("compound assignment to lookup slot"); |
| 5092 } | 5100 } |
| 5093 return ast_context()->ReturnValue(Pop()); | 5101 return ast_context()->ReturnValue(Pop()); |
| 5094 | 5102 |
| 5095 } else if (prop != NULL) { | 5103 } else if (prop != NULL) { |
| 5096 prop->RecordTypeFeedback(oracle()); | 5104 prop->RecordTypeFeedback(oracle(), zone()); |
| 5097 | 5105 |
| 5098 if (prop->key()->IsPropertyName()) { | 5106 if (prop->key()->IsPropertyName()) { |
| 5099 // Named property. | 5107 // Named property. |
| 5100 CHECK_ALIVE(VisitForValue(prop->obj())); | 5108 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5101 HValue* obj = Top(); | 5109 HValue* obj = Top(); |
| 5102 | 5110 |
| 5103 HInstruction* load = NULL; | 5111 HInstruction* load = NULL; |
| 5104 if (prop->IsMonomorphic()) { | 5112 if (prop->IsMonomorphic()) { |
| 5105 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5113 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 5106 Handle<Map> map = prop->GetReceiverTypes()->first(); | 5114 Handle<Map> map = prop->GetReceiverTypes()->first(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5145 | 5153 |
| 5146 | 5154 |
| 5147 CHECK_ALIVE(VisitForValue(expr->value())); | 5155 CHECK_ALIVE(VisitForValue(expr->value())); |
| 5148 HValue* right = Pop(); | 5156 HValue* right = Pop(); |
| 5149 HValue* left = Pop(); | 5157 HValue* left = Pop(); |
| 5150 | 5158 |
| 5151 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5159 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 5152 PushAndAdd(instr); | 5160 PushAndAdd(instr); |
| 5153 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5161 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| 5154 | 5162 |
| 5155 expr->RecordTypeFeedback(oracle()); | 5163 expr->RecordTypeFeedback(oracle(), zone()); |
| 5156 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 5164 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
| 5157 RelocInfo::kNoPosition, | 5165 RelocInfo::kNoPosition, |
| 5158 true, // is_store | 5166 true, // is_store |
| 5159 &has_side_effects); | 5167 &has_side_effects); |
| 5160 | 5168 |
| 5161 // Drop the simulated receiver, key, and value. Return the value. | 5169 // Drop the simulated receiver, key, and value. Return the value. |
| 5162 Drop(3); | 5170 Drop(3); |
| 5163 Push(instr); | 5171 Push(instr); |
| 5164 ASSERT(has_side_effects); // Stores always have side effects. | 5172 ASSERT(has_side_effects); // Stores always have side effects. |
| 5165 AddSimulate(expr->AssignmentId()); | 5173 AddSimulate(expr->AssignmentId()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 5193 if (var->mode() == CONST) { | 5201 if (var->mode() == CONST) { |
| 5194 if (expr->op() != Token::INIT_CONST) { | 5202 if (expr->op() != Token::INIT_CONST) { |
| 5195 CHECK_ALIVE(VisitForValue(expr->value())); | 5203 CHECK_ALIVE(VisitForValue(expr->value())); |
| 5196 return ast_context()->ReturnValue(Pop()); | 5204 return ast_context()->ReturnValue(Pop()); |
| 5197 } | 5205 } |
| 5198 | 5206 |
| 5199 if (var->IsStackAllocated()) { | 5207 if (var->IsStackAllocated()) { |
| 5200 // We insert a use of the old value to detect unsupported uses of const | 5208 // We insert a use of the old value to detect unsupported uses of const |
| 5201 // variables (e.g. initialization inside a loop). | 5209 // variables (e.g. initialization inside a loop). |
| 5202 HValue* old_value = environment()->Lookup(var); | 5210 HValue* old_value = environment()->Lookup(var); |
| 5203 AddInstruction(new HUseConst(old_value)); | 5211 AddInstruction(new(zone()) HUseConst(old_value)); |
| 5204 } | 5212 } |
| 5205 } else if (var->mode() == CONST_HARMONY) { | 5213 } else if (var->mode() == CONST_HARMONY) { |
| 5206 if (expr->op() != Token::INIT_CONST_HARMONY) { | 5214 if (expr->op() != Token::INIT_CONST_HARMONY) { |
| 5207 return Bailout("non-initializer assignment to const"); | 5215 return Bailout("non-initializer assignment to const"); |
| 5208 } | 5216 } |
| 5209 } | 5217 } |
| 5210 | 5218 |
| 5211 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 5219 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
| 5212 | 5220 |
| 5213 // Handle the assignment. | 5221 // Handle the assignment. |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5320 } | 5328 } |
| 5321 | 5329 |
| 5322 | 5330 |
| 5323 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 5331 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
| 5324 Property* expr, | 5332 Property* expr, |
| 5325 Handle<Map> type, | 5333 Handle<Map> type, |
| 5326 LookupResult* lookup, | 5334 LookupResult* lookup, |
| 5327 bool smi_and_map_check) { | 5335 bool smi_and_map_check) { |
| 5328 if (smi_and_map_check) { | 5336 if (smi_and_map_check) { |
| 5329 AddInstruction(new(zone()) HCheckNonSmi(object)); | 5337 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 5330 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 5338 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
| 5331 } | 5339 } |
| 5332 | 5340 |
| 5333 int index = lookup->GetLocalFieldIndexFromMap(*type); | 5341 int index = lookup->GetLocalFieldIndexFromMap(*type); |
| 5334 if (index < 0) { | 5342 if (index < 0) { |
| 5335 // Negative property indices are in-object properties, indexed | 5343 // Negative property indices are in-object properties, indexed |
| 5336 // from the end of the fixed part of the object. | 5344 // from the end of the fixed part of the object. |
| 5337 int offset = (index * kPointerSize) + type->instance_size(); | 5345 int offset = (index * kPointerSize) + type->instance_size(); |
| 5338 return new(zone()) HLoadNamedField(object, true, offset); | 5346 return new(zone()) HLoadNamedField(object, true, offset); |
| 5339 } else { | 5347 } else { |
| 5340 // Non-negative property indices are in the properties array. | 5348 // Non-negative property indices are in the properties array. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5364 LookupResult lookup(isolate()); | 5372 LookupResult lookup(isolate()); |
| 5365 map->LookupInDescriptors(NULL, *name, &lookup); | 5373 map->LookupInDescriptors(NULL, *name, &lookup); |
| 5366 if (lookup.IsFound() && lookup.type() == FIELD) { | 5374 if (lookup.IsFound() && lookup.type() == FIELD) { |
| 5367 return BuildLoadNamedField(obj, | 5375 return BuildLoadNamedField(obj, |
| 5368 expr, | 5376 expr, |
| 5369 map, | 5377 map, |
| 5370 &lookup, | 5378 &lookup, |
| 5371 true); | 5379 true); |
| 5372 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { | 5380 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { |
| 5373 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 5381 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
| 5374 AddInstruction(HCheckMaps::NewWithTransitions(obj, map)); | 5382 AddInstruction(HCheckMaps::NewWithTransitions(obj, map, zone())); |
| 5375 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 5383 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
| 5376 return new(zone()) HConstant(function, Representation::Tagged()); | 5384 return new(zone()) HConstant(function, Representation::Tagged()); |
| 5377 } else { | 5385 } else { |
| 5378 return BuildLoadNamedGeneric(obj, expr); | 5386 return BuildLoadNamedGeneric(obj, expr); |
| 5379 } | 5387 } |
| 5380 } | 5388 } |
| 5381 | 5389 |
| 5382 | 5390 |
| 5383 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 5391 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
| 5384 HValue* key) { | 5392 HValue* key) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5477 } | 5485 } |
| 5478 | 5486 |
| 5479 | 5487 |
| 5480 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 5488 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
| 5481 HValue* key, | 5489 HValue* key, |
| 5482 HValue* val, | 5490 HValue* val, |
| 5483 HValue* dependency, | 5491 HValue* dependency, |
| 5484 Handle<Map> map, | 5492 Handle<Map> map, |
| 5485 bool is_store) { | 5493 bool is_store) { |
| 5486 HInstruction* mapcheck = | 5494 HInstruction* mapcheck = |
| 5487 AddInstruction(new(zone()) HCheckMaps(object, map, dependency)); | 5495 AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency)); |
| 5488 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 5496 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
| 5489 // on a HElementsTransition instruction. The flag can also be removed if the | 5497 // on a HElementsTransition instruction. The flag can also be removed if the |
| 5490 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 5498 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
| 5491 // ElementsKind transitions. Finally, the dependency can be removed for stores | 5499 // ElementsKind transitions. Finally, the dependency can be removed for stores |
| 5492 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 5500 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
| 5493 // generated store code. | 5501 // generated store code. |
| 5494 if (dependency || | 5502 if (dependency || |
| 5495 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || | 5503 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || |
| 5496 (map->elements_kind() == FAST_ELEMENTS && is_store)) { | 5504 (map->elements_kind() == FAST_ELEMENTS && is_store)) { |
| 5497 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 5505 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| 5498 } | 5506 } |
| 5499 bool fast_smi_only_elements = map->has_fast_smi_elements(); | 5507 bool fast_smi_only_elements = map->has_fast_smi_elements(); |
| 5500 bool fast_elements = map->has_fast_object_elements(); | 5508 bool fast_elements = map->has_fast_object_elements(); |
| 5501 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5509 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 5502 if (is_store && (fast_elements || fast_smi_only_elements)) { | 5510 if (is_store && (fast_elements || fast_smi_only_elements)) { |
| 5503 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( | 5511 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( |
| 5504 elements, isolate()->factory()->fixed_array_map()); | 5512 elements, isolate()->factory()->fixed_array_map(), zone()); |
| 5505 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 5513 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 5506 AddInstruction(check_cow_map); | 5514 AddInstruction(check_cow_map); |
| 5507 } | 5515 } |
| 5508 HInstruction* length = NULL; | 5516 HInstruction* length = NULL; |
| 5509 HInstruction* checked_key = NULL; | 5517 HInstruction* checked_key = NULL; |
| 5510 if (map->has_external_array_elements()) { | 5518 if (map->has_external_array_elements()) { |
| 5511 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 5519 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 5512 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 5520 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 5513 HLoadExternalArrayPointer* external_elements = | 5521 HLoadExternalArrayPointer* external_elements = |
| 5514 new(zone()) HLoadExternalArrayPointer(elements); | 5522 new(zone()) HLoadExternalArrayPointer(elements); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5601 : BuildLoadKeyedGeneric(object, key)); | 5609 : BuildLoadKeyedGeneric(object, key)); |
| 5602 } else { | 5610 } else { |
| 5603 instr = AddInstruction(BuildMonomorphicElementAccess( | 5611 instr = AddInstruction(BuildMonomorphicElementAccess( |
| 5604 object, key, val, transition, untransitionable_map, is_store)); | 5612 object, key, val, transition, untransitionable_map, is_store)); |
| 5605 } | 5613 } |
| 5606 *has_side_effects |= instr->HasObservableSideEffects(); | 5614 *has_side_effects |= instr->HasObservableSideEffects(); |
| 5607 instr->set_position(position); | 5615 instr->set_position(position); |
| 5608 return is_store ? NULL : instr; | 5616 return is_store ? NULL : instr; |
| 5609 } | 5617 } |
| 5610 | 5618 |
| 5611 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 5619 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); |
| 5612 HBasicBlock* join = graph()->CreateBasicBlock(); | 5620 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 5613 | 5621 |
| 5614 HInstruction* elements_kind_instr = | 5622 HInstruction* elements_kind_instr = |
| 5615 AddInstruction(new(zone()) HElementsKind(object)); | 5623 AddInstruction(new(zone()) HElementsKind(object)); |
| 5616 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 5624 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
| 5617 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5625 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 5618 HLoadExternalArrayPointer* external_elements = NULL; | 5626 HLoadExternalArrayPointer* external_elements = NULL; |
| 5619 HInstruction* checked_key = NULL; | 5627 HInstruction* checked_key = NULL; |
| 5620 | 5628 |
| 5621 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds | 5629 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5648 elements_kind_branch->SetSuccessorAt(0, if_true); | 5656 elements_kind_branch->SetSuccessorAt(0, if_true); |
| 5649 elements_kind_branch->SetSuccessorAt(1, if_false); | 5657 elements_kind_branch->SetSuccessorAt(1, if_false); |
| 5650 current_block()->Finish(elements_kind_branch); | 5658 current_block()->Finish(elements_kind_branch); |
| 5651 | 5659 |
| 5652 set_current_block(if_true); | 5660 set_current_block(if_true); |
| 5653 HInstruction* access; | 5661 HInstruction* access; |
| 5654 if (IsFastElementsKind(elements_kind)) { | 5662 if (IsFastElementsKind(elements_kind)) { |
| 5655 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 5663 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
| 5656 AddInstruction(new(zone()) HCheckMaps( | 5664 AddInstruction(new(zone()) HCheckMaps( |
| 5657 elements, isolate()->factory()->fixed_array_map(), | 5665 elements, isolate()->factory()->fixed_array_map(), |
| 5658 elements_kind_branch)); | 5666 zone(), elements_kind_branch)); |
| 5659 } | 5667 } |
| 5660 // TODO(jkummerow): The need for these two blocks could be avoided | 5668 // TODO(jkummerow): The need for these two blocks could be avoided |
| 5661 // in one of two ways: | 5669 // in one of two ways: |
| 5662 // (1) Introduce ElementsKinds for JSArrays that are distinct from | 5670 // (1) Introduce ElementsKinds for JSArrays that are distinct from |
| 5663 // those for fast objects. | 5671 // those for fast objects. |
| 5664 // (2) Put the common instructions into a third "join" block. This | 5672 // (2) Put the common instructions into a third "join" block. This |
| 5665 // requires additional AST IDs that we can deopt to from inside | 5673 // requires additional AST IDs that we can deopt to from inside |
| 5666 // that join block. They must be added to the Property class (when | 5674 // that join block. They must be added to the Property class (when |
| 5667 // it's a keyed property) and registered in the full codegen. | 5675 // it's a keyed property) and registered in the full codegen. |
| 5668 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 5676 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5855 } | 5863 } |
| 5856 ast_context()->ReturnInstruction(result, expr->id()); | 5864 ast_context()->ReturnInstruction(result, expr->id()); |
| 5857 return true; | 5865 return true; |
| 5858 } | 5866 } |
| 5859 | 5867 |
| 5860 | 5868 |
| 5861 void HGraphBuilder::VisitProperty(Property* expr) { | 5869 void HGraphBuilder::VisitProperty(Property* expr) { |
| 5862 ASSERT(!HasStackOverflow()); | 5870 ASSERT(!HasStackOverflow()); |
| 5863 ASSERT(current_block() != NULL); | 5871 ASSERT(current_block() != NULL); |
| 5864 ASSERT(current_block()->HasPredecessor()); | 5872 ASSERT(current_block()->HasPredecessor()); |
| 5865 expr->RecordTypeFeedback(oracle()); | 5873 expr->RecordTypeFeedback(oracle(), zone()); |
| 5866 | 5874 |
| 5867 if (TryArgumentsAccess(expr)) return; | 5875 if (TryArgumentsAccess(expr)) return; |
| 5868 | 5876 |
| 5869 CHECK_ALIVE(VisitForValue(expr->obj())); | 5877 CHECK_ALIVE(VisitForValue(expr->obj())); |
| 5870 | 5878 |
| 5871 HInstruction* instr = NULL; | 5879 HInstruction* instr = NULL; |
| 5872 if (expr->AsProperty()->IsArrayLength()) { | 5880 if (expr->AsProperty()->IsArrayLength()) { |
| 5873 HValue* array = Pop(); | 5881 HValue* array = Pop(); |
| 5874 AddInstruction(new(zone()) HCheckNonSmi(array)); | 5882 AddInstruction(new(zone()) HCheckNonSmi(array)); |
| 5875 HInstruction* mapcheck = | 5883 HInstruction* mapcheck = |
| 5876 AddInstruction(HCheckInstanceType::NewIsJSArray(array)); | 5884 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); |
| 5877 instr = new(zone()) HJSArrayLength(array, mapcheck); | 5885 instr = new(zone()) HJSArrayLength(array, mapcheck); |
| 5878 | 5886 |
| 5879 } else if (expr->IsStringLength()) { | 5887 } else if (expr->IsStringLength()) { |
| 5880 HValue* string = Pop(); | 5888 HValue* string = Pop(); |
| 5881 AddInstruction(new(zone()) HCheckNonSmi(string)); | 5889 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 5882 AddInstruction(HCheckInstanceType::NewIsString(string)); | 5890 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 5883 instr = new(zone()) HStringLength(string); | 5891 instr = new(zone()) HStringLength(string); |
| 5884 } else if (expr->IsStringAccess()) { | 5892 } else if (expr->IsStringAccess()) { |
| 5885 CHECK_ALIVE(VisitForValue(expr->key())); | 5893 CHECK_ALIVE(VisitForValue(expr->key())); |
| 5886 HValue* index = Pop(); | 5894 HValue* index = Pop(); |
| 5887 HValue* string = Pop(); | 5895 HValue* string = Pop(); |
| 5888 HValue* context = environment()->LookupContext(); | 5896 HValue* context = environment()->LookupContext(); |
| 5889 HStringCharCodeAt* char_code = | 5897 HStringCharCodeAt* char_code = |
| 5890 BuildStringCharCodeAt(context, string, index); | 5898 BuildStringCharCodeAt(context, string, index); |
| 5891 AddInstruction(char_code); | 5899 AddInstruction(char_code); |
| 5892 instr = new(zone()) HStringCharFromCode(context, char_code); | 5900 instr = new(zone()) HStringCharFromCode(context, char_code); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5940 | 5948 |
| 5941 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 5949 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
| 5942 HValue* receiver, | 5950 HValue* receiver, |
| 5943 Handle<Map> receiver_map, | 5951 Handle<Map> receiver_map, |
| 5944 bool smi_and_map_check) { | 5952 bool smi_and_map_check) { |
| 5945 // Constant functions have the nice property that the map will change if they | 5953 // Constant functions have the nice property that the map will change if they |
| 5946 // are overwritten. Therefore it is enough to check the map of the holder and | 5954 // are overwritten. Therefore it is enough to check the map of the holder and |
| 5947 // its prototypes. | 5955 // its prototypes. |
| 5948 if (smi_and_map_check) { | 5956 if (smi_and_map_check) { |
| 5949 AddInstruction(new(zone()) HCheckNonSmi(receiver)); | 5957 AddInstruction(new(zone()) HCheckNonSmi(receiver)); |
| 5950 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map)); | 5958 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map, |
| 5959 zone())); |
| 5951 } | 5960 } |
| 5952 if (!expr->holder().is_null()) { | 5961 if (!expr->holder().is_null()) { |
| 5953 AddInstruction(new(zone()) HCheckPrototypeMaps( | 5962 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 5954 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), | 5963 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), |
| 5955 expr->holder())); | 5964 expr->holder())); |
| 5956 } | 5965 } |
| 5957 } | 5966 } |
| 5958 | 5967 |
| 5959 | 5968 |
| 5960 class FunctionSorter { | 5969 class FunctionSorter { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6275 // generating the optimized inline code. | 6284 // generating the optimized inline code. |
| 6276 target_info.EnableDeoptimizationSupport(); | 6285 target_info.EnableDeoptimizationSupport(); |
| 6277 if (!FullCodeGenerator::MakeCode(&target_info)) { | 6286 if (!FullCodeGenerator::MakeCode(&target_info)) { |
| 6278 TraceInline(target, caller, "could not generate deoptimization info"); | 6287 TraceInline(target, caller, "could not generate deoptimization info"); |
| 6279 return false; | 6288 return false; |
| 6280 } | 6289 } |
| 6281 if (target_shared->scope_info() == ScopeInfo::Empty()) { | 6290 if (target_shared->scope_info() == ScopeInfo::Empty()) { |
| 6282 // The scope info might not have been set if a lazily compiled | 6291 // The scope info might not have been set if a lazily compiled |
| 6283 // function is inlined before being called for the first time. | 6292 // function is inlined before being called for the first time. |
| 6284 Handle<ScopeInfo> target_scope_info = | 6293 Handle<ScopeInfo> target_scope_info = |
| 6285 ScopeInfo::Create(target_info.scope()); | 6294 ScopeInfo::Create(target_info.scope(), zone()); |
| 6286 target_shared->set_scope_info(*target_scope_info); | 6295 target_shared->set_scope_info(*target_scope_info); |
| 6287 } | 6296 } |
| 6288 target_shared->EnableDeoptimizationSupport(*target_info.code()); | 6297 target_shared->EnableDeoptimizationSupport(*target_info.code()); |
| 6289 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, | 6298 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, |
| 6290 &target_info, | 6299 &target_info, |
| 6291 target_shared); | 6300 target_shared); |
| 6292 } | 6301 } |
| 6293 | 6302 |
| 6294 // ---------------------------------------------------------------- | 6303 // ---------------------------------------------------------------- |
| 6295 // After this point, we've made a decision to inline this function (so | 6304 // After this point, we've made a decision to inline this function (so |
| 6296 // TryInline should always return true). | 6305 // TryInline should always return true). |
| 6297 | 6306 |
| 6298 // Save the pending call context and type feedback oracle. Set up new ones | 6307 // Save the pending call context and type feedback oracle. Set up new ones |
| 6299 // for the inlined function. | 6308 // for the inlined function. |
| 6300 ASSERT(target_shared->has_deoptimization_support()); | 6309 ASSERT(target_shared->has_deoptimization_support()); |
| 6301 TypeFeedbackOracle target_oracle( | 6310 TypeFeedbackOracle target_oracle( |
| 6302 Handle<Code>(target_shared->code()), | 6311 Handle<Code>(target_shared->code()), |
| 6303 Handle<Context>(target->context()->global_context()), | 6312 Handle<Context>(target->context()->global_context()), |
| 6304 isolate()); | 6313 isolate(), |
| 6314 zone()); |
| 6305 // The function state is new-allocated because we need to delete it | 6315 // The function state is new-allocated because we need to delete it |
| 6306 // in two different places. | 6316 // in two different places. |
| 6307 FunctionState* target_state = new FunctionState( | 6317 FunctionState* target_state = new FunctionState( |
| 6308 this, &target_info, &target_oracle, return_handling); | 6318 this, &target_info, &target_oracle, return_handling); |
| 6309 | 6319 |
| 6310 HConstant* undefined = graph()->GetConstantUndefined(); | 6320 HConstant* undefined = graph()->GetConstantUndefined(); |
| 6311 HEnvironment* inner_env = | 6321 HEnvironment* inner_env = |
| 6312 environment()->CopyForInlining(target, | 6322 environment()->CopyForInlining(target, |
| 6313 arguments->length(), | 6323 arguments->length(), |
| 6314 function, | 6324 function, |
| 6315 undefined, | 6325 undefined, |
| 6316 call_kind, | 6326 call_kind, |
| 6317 function_state()->is_construct()); | 6327 function_state()->is_construct()); |
| 6318 #ifdef V8_TARGET_ARCH_IA32 | 6328 #ifdef V8_TARGET_ARCH_IA32 |
| 6319 // IA32 only, overwrite the caller's context in the deoptimization | 6329 // IA32 only, overwrite the caller's context in the deoptimization |
| 6320 // environment with the correct one. | 6330 // environment with the correct one. |
| 6321 // | 6331 // |
| 6322 // TODO(kmillikin): implement the same inlining on other platforms so we | 6332 // TODO(kmillikin): implement the same inlining on other platforms so we |
| 6323 // can remove the unsightly ifdefs in this function. | 6333 // can remove the unsightly ifdefs in this function. |
| 6324 HConstant* context = new HConstant(Handle<Context>(target->context()), | 6334 HConstant* context = |
| 6325 Representation::Tagged()); | 6335 new(zone()) HConstant(Handle<Context>(target->context()), |
| 6336 Representation::Tagged()); |
| 6326 AddInstruction(context); | 6337 AddInstruction(context); |
| 6327 inner_env->BindContext(context); | 6338 inner_env->BindContext(context); |
| 6328 #endif | 6339 #endif |
| 6329 | 6340 |
| 6330 AddSimulate(return_id); | 6341 AddSimulate(return_id); |
| 6331 current_block()->UpdateEnvironment(inner_env); | 6342 current_block()->UpdateEnvironment(inner_env); |
| 6332 | 6343 |
| 6333 ZoneList<HValue*>* arguments_values = NULL; | 6344 ZoneList<HValue*>* arguments_values = NULL; |
| 6334 | 6345 |
| 6335 // If the function uses arguments copy current arguments values | 6346 // If the function uses arguments copy current arguments values |
| 6336 // to use them for materialization. | 6347 // to use them for materialization. |
| 6337 if (function->scope()->arguments() != NULL) { | 6348 if (function->scope()->arguments() != NULL) { |
| 6338 HEnvironment* arguments_env = inner_env->arguments_environment(); | 6349 HEnvironment* arguments_env = inner_env->arguments_environment(); |
| 6339 int arguments_count = arguments_env->parameter_count(); | 6350 int arguments_count = arguments_env->parameter_count(); |
| 6340 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count); | 6351 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
| 6341 for (int i = 0; i < arguments_count; i++) { | 6352 for (int i = 0; i < arguments_count; i++) { |
| 6342 arguments_values->Add(arguments_env->Lookup(i)); | 6353 arguments_values->Add(arguments_env->Lookup(i), zone()); |
| 6343 } | 6354 } |
| 6344 } | 6355 } |
| 6345 | 6356 |
| 6346 HEnterInlined* enter_inlined = | 6357 HEnterInlined* enter_inlined = |
| 6347 new(zone()) HEnterInlined(target, | 6358 new(zone()) HEnterInlined(target, |
| 6348 arguments->length(), | 6359 arguments->length(), |
| 6349 function, | 6360 function, |
| 6350 call_kind, | 6361 call_kind, |
| 6351 function_state()->is_construct(), | 6362 function_state()->is_construct(), |
| 6352 function->scope()->arguments(), | 6363 function->scope()->arguments(), |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6927 Drop(argument_count); | 6938 Drop(argument_count); |
| 6928 } | 6939 } |
| 6929 | 6940 |
| 6930 } else if (expr->IsMonomorphic()) { | 6941 } else if (expr->IsMonomorphic()) { |
| 6931 // The function is on the stack in the unoptimized code during | 6942 // The function is on the stack in the unoptimized code during |
| 6932 // evaluation of the arguments. | 6943 // evaluation of the arguments. |
| 6933 CHECK_ALIVE(VisitForValue(expr->expression())); | 6944 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 6934 HValue* function = Top(); | 6945 HValue* function = Top(); |
| 6935 HValue* context = environment()->LookupContext(); | 6946 HValue* context = environment()->LookupContext(); |
| 6936 HGlobalObject* global = new(zone()) HGlobalObject(context); | 6947 HGlobalObject* global = new(zone()) HGlobalObject(context); |
| 6948 AddInstruction(global); |
| 6937 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); | 6949 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
| 6938 AddInstruction(global); | |
| 6939 PushAndAdd(receiver); | 6950 PushAndAdd(receiver); |
| 6940 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 6951 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 6941 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 6952 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); |
| 6942 | 6953 |
| 6943 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 6954 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
| 6944 if (FLAG_trace_inlining) { | 6955 if (FLAG_trace_inlining) { |
| 6945 PrintF("Inlining builtin "); | 6956 PrintF("Inlining builtin "); |
| 6946 expr->target()->ShortPrint(); | 6957 expr->target()->ShortPrint(); |
| 6947 PrintF("\n"); | 6958 PrintF("\n"); |
| 6948 } | 6959 } |
| 6949 return; | 6960 return; |
| 6950 } | 6961 } |
| 6951 | 6962 |
| 6952 if (TryInlineCall(expr, true)) { // Drop function from environment. | 6963 if (TryInlineCall(expr, true)) { // Drop function from environment. |
| 6953 return; | 6964 return; |
| 6954 } else { | 6965 } else { |
| 6955 call = PreProcessCall( | 6966 call = PreProcessCall( |
| 6956 new(zone()) HInvokeFunction(context, | 6967 new(zone()) HInvokeFunction(context, |
| 6957 function, | 6968 function, |
| 6958 expr->target(), | 6969 expr->target(), |
| 6959 argument_count)); | 6970 argument_count)); |
| 6960 Drop(1); // The function. | 6971 Drop(1); // The function. |
| 6961 } | 6972 } |
| 6962 | 6973 |
| 6963 } else { | 6974 } else { |
| 6964 CHECK_ALIVE(VisitForValue(expr->expression())); | 6975 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 6965 HValue* function = Top(); | 6976 HValue* function = Top(); |
| 6966 HValue* context = environment()->LookupContext(); | 6977 HValue* context = environment()->LookupContext(); |
| 6967 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6978 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 6979 AddInstruction(global_object); |
| 6968 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); | 6980 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
| 6969 AddInstruction(global_object); | |
| 6970 AddInstruction(receiver); | 6981 AddInstruction(receiver); |
| 6971 PushAndAdd(new(zone()) HPushArgument(receiver)); | 6982 PushAndAdd(new(zone()) HPushArgument(receiver)); |
| 6972 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 6983 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 6973 | 6984 |
| 6974 call = new(zone()) HCallFunction(context, function, argument_count); | 6985 call = new(zone()) HCallFunction(context, function, argument_count); |
| 6975 Drop(argument_count + 1); | 6986 Drop(argument_count + 1); |
| 6976 } | 6987 } |
| 6977 } | 6988 } |
| 6978 | 6989 |
| 6979 call->set_position(expr->position()); | 6990 call->set_position(expr->position()); |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7365 break; | 7376 break; |
| 7366 } | 7377 } |
| 7367 | 7378 |
| 7368 case Variable::LOOKUP: | 7379 case Variable::LOOKUP: |
| 7369 return Bailout("lookup variable in count operation"); | 7380 return Bailout("lookup variable in count operation"); |
| 7370 } | 7381 } |
| 7371 | 7382 |
| 7372 } else { | 7383 } else { |
| 7373 // Argument of the count operation is a property. | 7384 // Argument of the count operation is a property. |
| 7374 ASSERT(prop != NULL); | 7385 ASSERT(prop != NULL); |
| 7375 prop->RecordTypeFeedback(oracle()); | 7386 prop->RecordTypeFeedback(oracle(), zone()); |
| 7376 | 7387 |
| 7377 if (prop->key()->IsPropertyName()) { | 7388 if (prop->key()->IsPropertyName()) { |
| 7378 // Named property. | 7389 // Named property. |
| 7379 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 7390 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
| 7380 | 7391 |
| 7381 CHECK_ALIVE(VisitForValue(prop->obj())); | 7392 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7382 HValue* obj = Top(); | 7393 HValue* obj = Top(); |
| 7383 | 7394 |
| 7384 HInstruction* load = NULL; | 7395 HInstruction* load = NULL; |
| 7385 if (prop->IsMonomorphic()) { | 7396 if (prop->IsMonomorphic()) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7419 HValue* load = HandleKeyedElementAccess( | 7430 HValue* load = HandleKeyedElementAccess( |
| 7420 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, | 7431 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, |
| 7421 false, // is_store | 7432 false, // is_store |
| 7422 &has_side_effects); | 7433 &has_side_effects); |
| 7423 Push(load); | 7434 Push(load); |
| 7424 if (has_side_effects) AddSimulate(expr->CountId()); | 7435 if (has_side_effects) AddSimulate(expr->CountId()); |
| 7425 | 7436 |
| 7426 after = BuildIncrement(returns_original_input, expr); | 7437 after = BuildIncrement(returns_original_input, expr); |
| 7427 input = Pop(); | 7438 input = Pop(); |
| 7428 | 7439 |
| 7429 expr->RecordTypeFeedback(oracle()); | 7440 expr->RecordTypeFeedback(oracle(), zone()); |
| 7430 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), | 7441 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), |
| 7431 RelocInfo::kNoPosition, | 7442 RelocInfo::kNoPosition, |
| 7432 true, // is_store | 7443 true, // is_store |
| 7433 &has_side_effects); | 7444 &has_side_effects); |
| 7434 | 7445 |
| 7435 // Drop the key from the bailout environment. Overwrite the receiver | 7446 // Drop the key from the bailout environment. Overwrite the receiver |
| 7436 // with the result of the operation, and the placeholder with the | 7447 // with the result of the operation, and the placeholder with the |
| 7437 // original value if necessary. | 7448 // original value if necessary. |
| 7438 Drop(1); | 7449 Drop(1); |
| 7439 environment()->SetExpressionStackAt(0, after); | 7450 environment()->SetExpressionStackAt(0, after); |
| 7440 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 7451 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
| 7441 ASSERT(has_side_effects); // Stores always have side effects. | 7452 ASSERT(has_side_effects); // Stores always have side effects. |
| 7442 AddSimulate(expr->AssignmentId()); | 7453 AddSimulate(expr->AssignmentId()); |
| 7443 } | 7454 } |
| 7444 } | 7455 } |
| 7445 | 7456 |
| 7446 Drop(returns_original_input ? 2 : 1); | 7457 Drop(returns_original_input ? 2 : 1); |
| 7447 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 7458 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
| 7448 } | 7459 } |
| 7449 | 7460 |
| 7450 | 7461 |
| 7451 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, | 7462 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, |
| 7452 HValue* string, | 7463 HValue* string, |
| 7453 HValue* index) { | 7464 HValue* index) { |
| 7454 AddInstruction(new(zone()) HCheckNonSmi(string)); | 7465 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 7455 AddInstruction(HCheckInstanceType::NewIsString(string)); | 7466 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 7456 HStringLength* length = new(zone()) HStringLength(string); | 7467 HStringLength* length = new(zone()) HStringLength(string); |
| 7457 AddInstruction(length); | 7468 AddInstruction(length); |
| 7458 HInstruction* checked_index = | 7469 HInstruction* checked_index = |
| 7459 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 7470 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
| 7460 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 7471 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 7461 } | 7472 } |
| 7462 | 7473 |
| 7463 | 7474 |
| 7464 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 7475 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
| 7465 HValue* left, | 7476 HValue* left, |
| 7466 HValue* right) { | 7477 HValue* right) { |
| 7467 HValue* context = environment()->LookupContext(); | 7478 HValue* context = environment()->LookupContext(); |
| 7468 TypeInfo info = oracle()->BinaryType(expr); | 7479 TypeInfo info = oracle()->BinaryType(expr); |
| 7469 if (info.IsUninitialized()) { | 7480 if (info.IsUninitialized()) { |
| 7470 AddInstruction(new(zone()) HSoftDeoptimize); | 7481 AddInstruction(new(zone()) HSoftDeoptimize); |
| 7471 current_block()->MarkAsDeoptimizing(); | 7482 current_block()->MarkAsDeoptimizing(); |
| 7472 info = TypeInfo::Unknown(); | 7483 info = TypeInfo::Unknown(); |
| 7473 } | 7484 } |
| 7474 HInstruction* instr = NULL; | 7485 HInstruction* instr = NULL; |
| 7475 switch (expr->op()) { | 7486 switch (expr->op()) { |
| 7476 case Token::ADD: | 7487 case Token::ADD: |
| 7477 if (info.IsString()) { | 7488 if (info.IsString()) { |
| 7478 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7489 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7479 AddInstruction(HCheckInstanceType::NewIsString(left)); | 7490 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
| 7480 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7491 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7481 AddInstruction(HCheckInstanceType::NewIsString(right)); | 7492 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
| 7482 instr = new(zone()) HStringAdd(context, left, right); | 7493 instr = new(zone()) HStringAdd(context, left, right); |
| 7483 } else { | 7494 } else { |
| 7484 instr = HAdd::NewHAdd(zone(), context, left, right); | 7495 instr = HAdd::NewHAdd(zone(), context, left, right); |
| 7485 } | 7496 } |
| 7486 break; | 7497 break; |
| 7487 case Token::SUB: | 7498 case Token::SUB: |
| 7488 instr = HSub::NewHSub(zone(), context, left, right); | 7499 instr = HSub::NewHSub(zone(), context, left, right); |
| 7489 break; | 7500 break; |
| 7490 case Token::MUL: | 7501 case Token::MUL: |
| 7491 instr = HMul::NewHMul(zone(), context, left, right); | 7502 instr = HMul::NewHMul(zone(), context, left, right); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7873 result->set_position(expr->position()); | 7884 result->set_position(expr->position()); |
| 7874 return ast_context()->ReturnInstruction(result, expr->id()); | 7885 return ast_context()->ReturnInstruction(result, expr->id()); |
| 7875 } else if (type_info.IsNonPrimitive()) { | 7886 } else if (type_info.IsNonPrimitive()) { |
| 7876 switch (op) { | 7887 switch (op) { |
| 7877 case Token::EQ: | 7888 case Token::EQ: |
| 7878 case Token::EQ_STRICT: { | 7889 case Token::EQ_STRICT: { |
| 7879 // Can we get away with map check and not instance type check? | 7890 // Can we get away with map check and not instance type check? |
| 7880 Handle<Map> map = oracle()->GetCompareMap(expr); | 7891 Handle<Map> map = oracle()->GetCompareMap(expr); |
| 7881 if (!map.is_null()) { | 7892 if (!map.is_null()) { |
| 7882 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7893 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7883 AddInstruction(HCheckMaps::NewWithTransitions(left, map)); | 7894 AddInstruction(HCheckMaps::NewWithTransitions(left, map, zone())); |
| 7884 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7895 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7885 AddInstruction(HCheckMaps::NewWithTransitions(right, map)); | 7896 AddInstruction(HCheckMaps::NewWithTransitions(right, map, zone())); |
| 7886 HCompareObjectEqAndBranch* result = | 7897 HCompareObjectEqAndBranch* result = |
| 7887 new(zone()) HCompareObjectEqAndBranch(left, right); | 7898 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 7888 result->set_position(expr->position()); | 7899 result->set_position(expr->position()); |
| 7889 return ast_context()->ReturnControl(result, expr->id()); | 7900 return ast_context()->ReturnControl(result, expr->id()); |
| 7890 } else { | 7901 } else { |
| 7891 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7902 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7892 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 7903 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
| 7893 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7904 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7894 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 7905 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
| 7895 HCompareObjectEqAndBranch* result = | 7906 HCompareObjectEqAndBranch* result = |
| 7896 new(zone()) HCompareObjectEqAndBranch(left, right); | 7907 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 7897 result->set_position(expr->position()); | 7908 result->set_position(expr->position()); |
| 7898 return ast_context()->ReturnControl(result, expr->id()); | 7909 return ast_context()->ReturnControl(result, expr->id()); |
| 7899 } | 7910 } |
| 7900 } | 7911 } |
| 7901 default: | 7912 default: |
| 7902 return Bailout("Unsupported non-primitive compare"); | 7913 return Bailout("Unsupported non-primitive compare"); |
| 7903 } | 7914 } |
| 7904 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && | 7915 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && |
| 7905 (op == Token::EQ || op == Token::EQ_STRICT)) { | 7916 (op == Token::EQ || op == Token::EQ_STRICT)) { |
| 7906 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7917 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7907 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); | 7918 AddInstruction(HCheckInstanceType::NewIsSymbol(left, zone())); |
| 7908 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7919 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7909 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); | 7920 AddInstruction(HCheckInstanceType::NewIsSymbol(right, zone())); |
| 7910 HCompareObjectEqAndBranch* result = | 7921 HCompareObjectEqAndBranch* result = |
| 7911 new(zone()) HCompareObjectEqAndBranch(left, right); | 7922 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 7912 result->set_position(expr->position()); | 7923 result->set_position(expr->position()); |
| 7913 return ast_context()->ReturnControl(result, expr->id()); | 7924 return ast_context()->ReturnControl(result, expr->id()); |
| 7914 } else { | 7925 } else { |
| 7915 Representation r = ToRepresentation(type_info); | 7926 Representation r = ToRepresentation(type_info); |
| 7916 if (r.IsTagged()) { | 7927 if (r.IsTagged()) { |
| 7917 HCompareGeneric* result = | 7928 HCompareGeneric* result = |
| 7918 new(zone()) HCompareGeneric(context, left, right, op); | 7929 new(zone()) HCompareGeneric(context, left, right, op); |
| 7919 result->set_position(expr->position()); | 7930 result->set_position(expr->position()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7971 } | 7982 } |
| 7972 | 7983 |
| 7973 | 7984 |
| 7974 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { | 7985 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { |
| 7975 VariableProxy* proxy = declaration->proxy(); | 7986 VariableProxy* proxy = declaration->proxy(); |
| 7976 VariableMode mode = declaration->mode(); | 7987 VariableMode mode = declaration->mode(); |
| 7977 Variable* variable = proxy->var(); | 7988 Variable* variable = proxy->var(); |
| 7978 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 7989 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
| 7979 switch (variable->location()) { | 7990 switch (variable->location()) { |
| 7980 case Variable::UNALLOCATED: | 7991 case Variable::UNALLOCATED: |
| 7981 globals_.Add(variable->name()); | 7992 globals_.Add(variable->name(), zone()); |
| 7982 globals_.Add(variable->binding_needs_init() | 7993 globals_.Add(variable->binding_needs_init() |
| 7983 ? isolate()->factory()->the_hole_value() | 7994 ? isolate()->factory()->the_hole_value() |
| 7984 : isolate()->factory()->undefined_value()); | 7995 : isolate()->factory()->undefined_value(), zone()); |
| 7985 return; | 7996 return; |
| 7986 case Variable::PARAMETER: | 7997 case Variable::PARAMETER: |
| 7987 case Variable::LOCAL: | 7998 case Variable::LOCAL: |
| 7988 if (hole_init) { | 7999 if (hole_init) { |
| 7989 HValue* value = graph()->GetConstantHole(); | 8000 HValue* value = graph()->GetConstantHole(); |
| 7990 environment()->Bind(variable, value); | 8001 environment()->Bind(variable, value); |
| 7991 } | 8002 } |
| 7992 break; | 8003 break; |
| 7993 case Variable::CONTEXT: | 8004 case Variable::CONTEXT: |
| 7994 if (hole_init) { | 8005 if (hole_init) { |
| 7995 HValue* value = graph()->GetConstantHole(); | 8006 HValue* value = graph()->GetConstantHole(); |
| 7996 HValue* context = environment()->LookupContext(); | 8007 HValue* context = environment()->LookupContext(); |
| 7997 HStoreContextSlot* store = new HStoreContextSlot( | 8008 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
| 7998 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 8009 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 7999 AddInstruction(store); | 8010 AddInstruction(store); |
| 8000 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 8011 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
| 8001 } | 8012 } |
| 8002 break; | 8013 break; |
| 8003 case Variable::LOOKUP: | 8014 case Variable::LOOKUP: |
| 8004 return Bailout("unsupported lookup slot in declaration"); | 8015 return Bailout("unsupported lookup slot in declaration"); |
| 8005 } | 8016 } |
| 8006 } | 8017 } |
| 8007 | 8018 |
| 8008 | 8019 |
| 8009 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { | 8020 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { |
| 8010 VariableProxy* proxy = declaration->proxy(); | 8021 VariableProxy* proxy = declaration->proxy(); |
| 8011 Variable* variable = proxy->var(); | 8022 Variable* variable = proxy->var(); |
| 8012 switch (variable->location()) { | 8023 switch (variable->location()) { |
| 8013 case Variable::UNALLOCATED: { | 8024 case Variable::UNALLOCATED: { |
| 8014 globals_.Add(variable->name()); | 8025 globals_.Add(variable->name(), zone()); |
| 8015 Handle<SharedFunctionInfo> function = | 8026 Handle<SharedFunctionInfo> function = |
| 8016 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 8027 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); |
| 8017 // Check for stack-overflow exception. | 8028 // Check for stack-overflow exception. |
| 8018 if (function.is_null()) return SetStackOverflow(); | 8029 if (function.is_null()) return SetStackOverflow(); |
| 8019 globals_.Add(function); | 8030 globals_.Add(function, zone()); |
| 8020 return; | 8031 return; |
| 8021 } | 8032 } |
| 8022 case Variable::PARAMETER: | 8033 case Variable::PARAMETER: |
| 8023 case Variable::LOCAL: { | 8034 case Variable::LOCAL: { |
| 8024 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8035 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 8025 HValue* value = Pop(); | 8036 HValue* value = Pop(); |
| 8026 environment()->Bind(variable, value); | 8037 environment()->Bind(variable, value); |
| 8027 break; | 8038 break; |
| 8028 } | 8039 } |
| 8029 case Variable::CONTEXT: { | 8040 case Variable::CONTEXT: { |
| 8030 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8041 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 8031 HValue* value = Pop(); | 8042 HValue* value = Pop(); |
| 8032 HValue* context = environment()->LookupContext(); | 8043 HValue* context = environment()->LookupContext(); |
| 8033 HStoreContextSlot* store = new HStoreContextSlot( | 8044 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
| 8034 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 8045 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 8035 AddInstruction(store); | 8046 AddInstruction(store); |
| 8036 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 8047 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
| 8037 break; | 8048 break; |
| 8038 } | 8049 } |
| 8039 case Variable::LOOKUP: | 8050 case Variable::LOOKUP: |
| 8040 return Bailout("unsupported lookup slot in declaration"); | 8051 return Bailout("unsupported lookup slot in declaration"); |
| 8041 } | 8052 } |
| 8042 } | 8053 } |
| 8043 | 8054 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8269 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 8280 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
| 8270 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 8281 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
| 8271 typecheck->SetSuccessorAt(0, if_js_value); | 8282 typecheck->SetSuccessorAt(0, if_js_value); |
| 8272 typecheck->SetSuccessorAt(1, not_js_value); | 8283 typecheck->SetSuccessorAt(1, not_js_value); |
| 8273 current_block()->Finish(typecheck); | 8284 current_block()->Finish(typecheck); |
| 8274 not_js_value->Goto(join); | 8285 not_js_value->Goto(join); |
| 8275 | 8286 |
| 8276 // Create in-object property store to kValueOffset. | 8287 // Create in-object property store to kValueOffset. |
| 8277 set_current_block(if_js_value); | 8288 set_current_block(if_js_value); |
| 8278 Handle<String> name = isolate()->factory()->undefined_symbol(); | 8289 Handle<String> name = isolate()->factory()->undefined_symbol(); |
| 8279 AddInstruction(new HStoreNamedField(object, | 8290 AddInstruction(new(zone()) HStoreNamedField(object, |
| 8280 name, | 8291 name, |
| 8281 value, | 8292 value, |
| 8282 true, // in-object store. | 8293 true, // in-object store. |
| 8283 JSValue::kValueOffset)); | 8294 JSValue::kValueOffset)); |
| 8284 if_js_value->Goto(join); | 8295 if_js_value->Goto(join); |
| 8285 join->SetJoinId(call->id()); | 8296 join->SetJoinId(call->id()); |
| 8286 set_current_block(join); | 8297 set_current_block(join); |
| 8287 return ast_context()->ReturnValue(value); | 8298 return ast_context()->ReturnValue(value); |
| 8288 } | 8299 } |
| 8289 | 8300 |
| 8290 | 8301 |
| 8291 // Fast support for charCodeAt(n). | 8302 // Fast support for charCodeAt(n). |
| 8292 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 8303 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
| 8293 ASSERT(call->arguments()->length() == 2); | 8304 ASSERT(call->arguments()->length() == 2); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8561 return Bailout("inlined runtime function: FastAsciiArrayJoin"); | 8572 return Bailout("inlined runtime function: FastAsciiArrayJoin"); |
| 8562 } | 8573 } |
| 8563 | 8574 |
| 8564 | 8575 |
| 8565 #undef CHECK_BAILOUT | 8576 #undef CHECK_BAILOUT |
| 8566 #undef CHECK_ALIVE | 8577 #undef CHECK_ALIVE |
| 8567 | 8578 |
| 8568 | 8579 |
| 8569 HEnvironment::HEnvironment(HEnvironment* outer, | 8580 HEnvironment::HEnvironment(HEnvironment* outer, |
| 8570 Scope* scope, | 8581 Scope* scope, |
| 8571 Handle<JSFunction> closure) | 8582 Handle<JSFunction> closure, |
| 8583 Zone* zone) |
| 8572 : closure_(closure), | 8584 : closure_(closure), |
| 8573 values_(0), | 8585 values_(0, zone), |
| 8574 assigned_variables_(4), | 8586 assigned_variables_(4, zone), |
| 8575 frame_type_(JS_FUNCTION), | 8587 frame_type_(JS_FUNCTION), |
| 8576 parameter_count_(0), | 8588 parameter_count_(0), |
| 8577 specials_count_(1), | 8589 specials_count_(1), |
| 8578 local_count_(0), | 8590 local_count_(0), |
| 8579 outer_(outer), | 8591 outer_(outer), |
| 8580 pop_count_(0), | 8592 pop_count_(0), |
| 8581 push_count_(0), | 8593 push_count_(0), |
| 8582 ast_id_(AstNode::kNoNumber) { | 8594 ast_id_(AstNode::kNoNumber), |
| 8595 zone_(zone) { |
| 8583 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 8596 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
| 8584 } | 8597 } |
| 8585 | 8598 |
| 8586 | 8599 |
| 8587 HEnvironment::HEnvironment(const HEnvironment* other) | 8600 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
| 8588 : values_(0), | 8601 : values_(0, zone), |
| 8589 assigned_variables_(0), | 8602 assigned_variables_(0, zone), |
| 8590 frame_type_(JS_FUNCTION), | 8603 frame_type_(JS_FUNCTION), |
| 8591 parameter_count_(0), | 8604 parameter_count_(0), |
| 8592 specials_count_(1), | 8605 specials_count_(1), |
| 8593 local_count_(0), | 8606 local_count_(0), |
| 8594 outer_(NULL), | 8607 outer_(NULL), |
| 8595 pop_count_(0), | 8608 pop_count_(0), |
| 8596 push_count_(0), | 8609 push_count_(0), |
| 8597 ast_id_(other->ast_id()) { | 8610 ast_id_(other->ast_id()), |
| 8611 zone_(zone) { |
| 8598 Initialize(other); | 8612 Initialize(other); |
| 8599 } | 8613 } |
| 8600 | 8614 |
| 8601 | 8615 |
| 8602 HEnvironment::HEnvironment(HEnvironment* outer, | 8616 HEnvironment::HEnvironment(HEnvironment* outer, |
| 8603 Handle<JSFunction> closure, | 8617 Handle<JSFunction> closure, |
| 8604 FrameType frame_type, | 8618 FrameType frame_type, |
| 8605 int arguments) | 8619 int arguments, |
| 8620 Zone* zone) |
| 8606 : closure_(closure), | 8621 : closure_(closure), |
| 8607 values_(arguments), | 8622 values_(arguments, zone), |
| 8608 assigned_variables_(0), | 8623 assigned_variables_(0, zone), |
| 8609 frame_type_(frame_type), | 8624 frame_type_(frame_type), |
| 8610 parameter_count_(arguments), | 8625 parameter_count_(arguments), |
| 8611 local_count_(0), | 8626 local_count_(0), |
| 8612 outer_(outer), | 8627 outer_(outer), |
| 8613 pop_count_(0), | 8628 pop_count_(0), |
| 8614 push_count_(0), | 8629 push_count_(0), |
| 8615 ast_id_(AstNode::kNoNumber) { | 8630 ast_id_(AstNode::kNoNumber), |
| 8631 zone_(zone) { |
| 8616 } | 8632 } |
| 8617 | 8633 |
| 8618 | 8634 |
| 8619 void HEnvironment::Initialize(int parameter_count, | 8635 void HEnvironment::Initialize(int parameter_count, |
| 8620 int local_count, | 8636 int local_count, |
| 8621 int stack_height) { | 8637 int stack_height) { |
| 8622 parameter_count_ = parameter_count; | 8638 parameter_count_ = parameter_count; |
| 8623 local_count_ = local_count; | 8639 local_count_ = local_count; |
| 8624 | 8640 |
| 8625 // Avoid reallocating the temporaries' backing store on the first Push. | 8641 // Avoid reallocating the temporaries' backing store on the first Push. |
| 8626 int total = parameter_count + specials_count_ + local_count + stack_height; | 8642 int total = parameter_count + specials_count_ + local_count + stack_height; |
| 8627 values_.Initialize(total + 4); | 8643 values_.Initialize(total + 4, zone()); |
| 8628 for (int i = 0; i < total; ++i) values_.Add(NULL); | 8644 for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); |
| 8629 } | 8645 } |
| 8630 | 8646 |
| 8631 | 8647 |
| 8632 void HEnvironment::Initialize(const HEnvironment* other) { | 8648 void HEnvironment::Initialize(const HEnvironment* other) { |
| 8633 closure_ = other->closure(); | 8649 closure_ = other->closure(); |
| 8634 values_.AddAll(other->values_); | 8650 values_.AddAll(other->values_, zone()); |
| 8635 assigned_variables_.AddAll(other->assigned_variables_); | 8651 assigned_variables_.AddAll(other->assigned_variables_, zone()); |
| 8636 frame_type_ = other->frame_type_; | 8652 frame_type_ = other->frame_type_; |
| 8637 parameter_count_ = other->parameter_count_; | 8653 parameter_count_ = other->parameter_count_; |
| 8638 local_count_ = other->local_count_; | 8654 local_count_ = other->local_count_; |
| 8639 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 8655 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
| 8640 pop_count_ = other->pop_count_; | 8656 pop_count_ = other->pop_count_; |
| 8641 push_count_ = other->push_count_; | 8657 push_count_ = other->push_count_; |
| 8642 ast_id_ = other->ast_id_; | 8658 ast_id_ = other->ast_id_; |
| 8643 } | 8659 } |
| 8644 | 8660 |
| 8645 | 8661 |
| 8646 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 8662 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
| 8647 ASSERT(!block->IsLoopHeader()); | 8663 ASSERT(!block->IsLoopHeader()); |
| 8648 ASSERT(values_.length() == other->values_.length()); | 8664 ASSERT(values_.length() == other->values_.length()); |
| 8649 | 8665 |
| 8650 int length = values_.length(); | 8666 int length = values_.length(); |
| 8651 for (int i = 0; i < length; ++i) { | 8667 for (int i = 0; i < length; ++i) { |
| 8652 HValue* value = values_[i]; | 8668 HValue* value = values_[i]; |
| 8653 if (value != NULL && value->IsPhi() && value->block() == block) { | 8669 if (value != NULL && value->IsPhi() && value->block() == block) { |
| 8654 // There is already a phi for the i'th value. | 8670 // There is already a phi for the i'th value. |
| 8655 HPhi* phi = HPhi::cast(value); | 8671 HPhi* phi = HPhi::cast(value); |
| 8656 // Assert index is correct and that we haven't missed an incoming edge. | 8672 // Assert index is correct and that we haven't missed an incoming edge. |
| 8657 ASSERT(phi->merged_index() == i); | 8673 ASSERT(phi->merged_index() == i); |
| 8658 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 8674 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
| 8659 phi->AddInput(other->values_[i]); | 8675 phi->AddInput(other->values_[i]); |
| 8660 } else if (values_[i] != other->values_[i]) { | 8676 } else if (values_[i] != other->values_[i]) { |
| 8661 // There is a fresh value on the incoming edge, a phi is needed. | 8677 // There is a fresh value on the incoming edge, a phi is needed. |
| 8662 ASSERT(values_[i] != NULL && other->values_[i] != NULL); | 8678 ASSERT(values_[i] != NULL && other->values_[i] != NULL); |
| 8663 HPhi* phi = new(block->zone()) HPhi(i); | 8679 HPhi* phi = new(zone()) HPhi(i, zone()); |
| 8664 HValue* old_value = values_[i]; | 8680 HValue* old_value = values_[i]; |
| 8665 for (int j = 0; j < block->predecessors()->length(); j++) { | 8681 for (int j = 0; j < block->predecessors()->length(); j++) { |
| 8666 phi->AddInput(old_value); | 8682 phi->AddInput(old_value); |
| 8667 } | 8683 } |
| 8668 phi->AddInput(other->values_[i]); | 8684 phi->AddInput(other->values_[i]); |
| 8669 this->values_[i] = phi; | 8685 this->values_[i] = phi; |
| 8670 block->AddPhi(phi); | 8686 block->AddPhi(phi); |
| 8671 } | 8687 } |
| 8672 } | 8688 } |
| 8673 } | 8689 } |
| 8674 | 8690 |
| 8675 | 8691 |
| 8676 void HEnvironment::Bind(int index, HValue* value) { | 8692 void HEnvironment::Bind(int index, HValue* value) { |
| 8677 ASSERT(value != NULL); | 8693 ASSERT(value != NULL); |
| 8678 if (!assigned_variables_.Contains(index)) { | 8694 if (!assigned_variables_.Contains(index)) { |
| 8679 assigned_variables_.Add(index); | 8695 assigned_variables_.Add(index, zone()); |
| 8680 } | 8696 } |
| 8681 values_[index] = value; | 8697 values_[index] = value; |
| 8682 } | 8698 } |
| 8683 | 8699 |
| 8684 | 8700 |
| 8685 bool HEnvironment::HasExpressionAt(int index) const { | 8701 bool HEnvironment::HasExpressionAt(int index) const { |
| 8686 return index >= parameter_count_ + specials_count_ + local_count_; | 8702 return index >= parameter_count_ + specials_count_ + local_count_; |
| 8687 } | 8703 } |
| 8688 | 8704 |
| 8689 | 8705 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8709 | 8725 |
| 8710 | 8726 |
| 8711 void HEnvironment::Drop(int count) { | 8727 void HEnvironment::Drop(int count) { |
| 8712 for (int i = 0; i < count; ++i) { | 8728 for (int i = 0; i < count; ++i) { |
| 8713 Pop(); | 8729 Pop(); |
| 8714 } | 8730 } |
| 8715 } | 8731 } |
| 8716 | 8732 |
| 8717 | 8733 |
| 8718 HEnvironment* HEnvironment::Copy() const { | 8734 HEnvironment* HEnvironment::Copy() const { |
| 8719 return new(closure()->GetIsolate()->zone()) HEnvironment(this); | 8735 return new(zone()) HEnvironment(this, zone()); |
| 8720 } | 8736 } |
| 8721 | 8737 |
| 8722 | 8738 |
| 8723 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 8739 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
| 8724 HEnvironment* result = Copy(); | 8740 HEnvironment* result = Copy(); |
| 8725 result->ClearHistory(); | 8741 result->ClearHistory(); |
| 8726 return result; | 8742 return result; |
| 8727 } | 8743 } |
| 8728 | 8744 |
| 8729 | 8745 |
| 8730 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { | 8746 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { |
| 8731 HEnvironment* new_env = Copy(); | 8747 HEnvironment* new_env = Copy(); |
| 8732 for (int i = 0; i < values_.length(); ++i) { | 8748 for (int i = 0; i < values_.length(); ++i) { |
| 8733 HPhi* phi = new(loop_header->zone()) HPhi(i); | 8749 HPhi* phi = new(zone()) HPhi(i, zone()); |
| 8734 phi->AddInput(values_[i]); | 8750 phi->AddInput(values_[i]); |
| 8735 new_env->values_[i] = phi; | 8751 new_env->values_[i] = phi; |
| 8736 loop_header->AddPhi(phi); | 8752 loop_header->AddPhi(phi); |
| 8737 } | 8753 } |
| 8738 new_env->ClearHistory(); | 8754 new_env->ClearHistory(); |
| 8739 return new_env; | 8755 return new_env; |
| 8740 } | 8756 } |
| 8741 | 8757 |
| 8742 | 8758 |
| 8743 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, | 8759 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
| 8744 Handle<JSFunction> target, | 8760 Handle<JSFunction> target, |
| 8745 FrameType frame_type, | 8761 FrameType frame_type, |
| 8746 int arguments) const { | 8762 int arguments) const { |
| 8747 HEnvironment* new_env = new(closure()->GetIsolate()->zone()) | 8763 HEnvironment* new_env = |
| 8748 HEnvironment(outer, target, frame_type, arguments + 1); | 8764 new(zone()) HEnvironment(outer, target, frame_type, |
| 8765 arguments + 1, zone()); |
| 8749 for (int i = 0; i <= arguments; ++i) { // Include receiver. | 8766 for (int i = 0; i <= arguments; ++i) { // Include receiver. |
| 8750 new_env->Push(ExpressionStackAt(arguments - i)); | 8767 new_env->Push(ExpressionStackAt(arguments - i)); |
| 8751 } | 8768 } |
| 8752 new_env->ClearHistory(); | 8769 new_env->ClearHistory(); |
| 8753 return new_env; | 8770 return new_env; |
| 8754 } | 8771 } |
| 8755 | 8772 |
| 8756 | 8773 |
| 8757 HEnvironment* HEnvironment::CopyForInlining( | 8774 HEnvironment* HEnvironment::CopyForInlining( |
| 8758 Handle<JSFunction> target, | 8775 Handle<JSFunction> target, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8778 // object instead, DoComputeConstructStubFrame() relies on that. | 8795 // object instead, DoComputeConstructStubFrame() relies on that. |
| 8779 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); | 8796 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); |
| 8780 } | 8797 } |
| 8781 | 8798 |
| 8782 if (arity != arguments) { | 8799 if (arity != arguments) { |
| 8783 // Create artificial arguments adaptation environment. | 8800 // Create artificial arguments adaptation environment. |
| 8784 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); | 8801 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); |
| 8785 } | 8802 } |
| 8786 | 8803 |
| 8787 HEnvironment* inner = | 8804 HEnvironment* inner = |
| 8788 new(zone) HEnvironment(outer, function->scope(), target); | 8805 new(zone) HEnvironment(outer, function->scope(), target, zone); |
| 8789 // Get the argument values from the original environment. | 8806 // Get the argument values from the original environment. |
| 8790 for (int i = 0; i <= arity; ++i) { // Include receiver. | 8807 for (int i = 0; i <= arity; ++i) { // Include receiver. |
| 8791 HValue* push = (i <= arguments) ? | 8808 HValue* push = (i <= arguments) ? |
| 8792 ExpressionStackAt(arguments - i) : undefined; | 8809 ExpressionStackAt(arguments - i) : undefined; |
| 8793 inner->SetValueAt(i, push); | 8810 inner->SetValueAt(i, push); |
| 8794 } | 8811 } |
| 8795 // If the function we are inlining is a strict mode function or a | 8812 // If the function we are inlining is a strict mode function or a |
| 8796 // builtin function, pass undefined as the receiver for function | 8813 // builtin function, pass undefined as the receiver for function |
| 8797 // calls (instead of the global receiver). | 8814 // calls (instead of the global receiver). |
| 8798 if ((target->shared()->native() || !function->is_classic_mode()) && | 8815 if ((target->shared()->native() || !function->is_classic_mode()) && |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8968 } | 8985 } |
| 8969 } | 8986 } |
| 8970 | 8987 |
| 8971 | 8988 |
| 8972 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { | 8989 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { |
| 8973 Tag tag(this, "intervals"); | 8990 Tag tag(this, "intervals"); |
| 8974 PrintStringProperty("name", name); | 8991 PrintStringProperty("name", name); |
| 8975 | 8992 |
| 8976 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); | 8993 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); |
| 8977 for (int i = 0; i < fixed_d->length(); ++i) { | 8994 for (int i = 0; i < fixed_d->length(); ++i) { |
| 8978 TraceLiveRange(fixed_d->at(i), "fixed"); | 8995 TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); |
| 8979 } | 8996 } |
| 8980 | 8997 |
| 8981 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); | 8998 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); |
| 8982 for (int i = 0; i < fixed->length(); ++i) { | 8999 for (int i = 0; i < fixed->length(); ++i) { |
| 8983 TraceLiveRange(fixed->at(i), "fixed"); | 9000 TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); |
| 8984 } | 9001 } |
| 8985 | 9002 |
| 8986 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); | 9003 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); |
| 8987 for (int i = 0; i < live_ranges->length(); ++i) { | 9004 for (int i = 0; i < live_ranges->length(); ++i) { |
| 8988 TraceLiveRange(live_ranges->at(i), "object"); | 9005 TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); |
| 8989 } | 9006 } |
| 8990 } | 9007 } |
| 8991 | 9008 |
| 8992 | 9009 |
| 8993 void HTracer::TraceLiveRange(LiveRange* range, const char* type) { | 9010 void HTracer::TraceLiveRange(LiveRange* range, const char* type, |
| 9011 Zone* zone) { |
| 8994 if (range != NULL && !range->IsEmpty()) { | 9012 if (range != NULL && !range->IsEmpty()) { |
| 8995 PrintIndent(); | 9013 PrintIndent(); |
| 8996 trace_.Add("%d %s", range->id(), type); | 9014 trace_.Add("%d %s", range->id(), type); |
| 8997 if (range->HasRegisterAssigned()) { | 9015 if (range->HasRegisterAssigned()) { |
| 8998 LOperand* op = range->CreateAssignedOperand(ZONE); | 9016 LOperand* op = range->CreateAssignedOperand(zone); |
| 8999 int assigned_reg = op->index(); | 9017 int assigned_reg = op->index(); |
| 9000 if (op->IsDoubleRegister()) { | 9018 if (op->IsDoubleRegister()) { |
| 9001 trace_.Add(" \"%s\"", | 9019 trace_.Add(" \"%s\"", |
| 9002 DoubleRegister::AllocationIndexToString(assigned_reg)); | 9020 DoubleRegister::AllocationIndexToString(assigned_reg)); |
| 9003 } else { | 9021 } else { |
| 9004 ASSERT(op->IsRegister()); | 9022 ASSERT(op->IsRegister()); |
| 9005 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); | 9023 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); |
| 9006 } | 9024 } |
| 9007 } else if (range->IsSpilled()) { | 9025 } else if (range->IsSpilled()) { |
| 9008 LOperand* op = range->TopLevel()->GetSpillOperand(); | 9026 LOperand* op = range->TopLevel()->GetSpillOperand(); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9150 } | 9168 } |
| 9151 } | 9169 } |
| 9152 | 9170 |
| 9153 #ifdef DEBUG | 9171 #ifdef DEBUG |
| 9154 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9172 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 9155 if (allocator_ != NULL) allocator_->Verify(); | 9173 if (allocator_ != NULL) allocator_->Verify(); |
| 9156 #endif | 9174 #endif |
| 9157 } | 9175 } |
| 9158 | 9176 |
| 9159 } } // namespace v8::internal | 9177 } } // namespace v8::internal |
| OLD | NEW |