| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2169 } | 2174 } |
| 2170 | 2175 |
| 2171 | 2176 |
| 2172 void HInferRepresentation::Analyze() { | 2177 void HInferRepresentation::Analyze() { |
| 2173 HPhase phase("H_Infer representations", graph_); | 2178 HPhase phase("H_Infer representations", graph_); |
| 2174 | 2179 |
| 2175 // (1) Initialize bit vectors and count real uses. Each phi gets a | 2180 // (1) Initialize bit vectors and count real uses. Each phi gets a |
| 2176 // bit-vector of length <number of phis>. | 2181 // bit-vector of length <number of phis>. |
| 2177 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); | 2182 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); |
| 2178 int phi_count = phi_list->length(); | 2183 int phi_count = phi_list->length(); |
| 2179 ZoneList<BitVector*> connected_phis(phi_count); | 2184 ZoneList<BitVector*> connected_phis(phi_count, graph_->zone()); |
| 2180 for (int i = 0; i < phi_count; ++i) { | 2185 for (int i = 0; i < phi_count; ++i) { |
| 2181 phi_list->at(i)->InitRealUses(i); | 2186 phi_list->at(i)->InitRealUses(i); |
| 2182 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); | 2187 BitVector* connected_set = new(zone()) BitVector(phi_count, graph_->zone()); |
| 2183 connected_set->Add(i); | 2188 connected_set->Add(i); |
| 2184 connected_phis.Add(connected_set); | 2189 connected_phis.Add(connected_set, zone()); |
| 2185 } | 2190 } |
| 2186 | 2191 |
| 2187 // (2) Do a fixed point iteration to find the set of connected phis. A | 2192 // (2) Do a fixed point iteration to find the set of connected phis. A |
| 2188 // phi is connected to another phi if its value is used either directly or | 2193 // phi is connected to another phi if its value is used either directly or |
| 2189 // indirectly through a transitive closure of the def-use relation. | 2194 // indirectly through a transitive closure of the def-use relation. |
| 2190 bool change = true; | 2195 bool change = true; |
| 2191 while (change) { | 2196 while (change) { |
| 2192 change = false; | 2197 change = false; |
| 2193 // We normally have far more "forward edges" than "backward edges", | 2198 // We normally have far more "forward edges" than "backward edges", |
| 2194 // so we terminate faster when we walk backwards. | 2199 // so we terminate faster when we walk backwards. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2270 } | 2275 } |
| 2271 | 2276 |
| 2272 if (block->IsLoopHeader()) { | 2277 if (block->IsLoopHeader()) { |
| 2273 HBasicBlock* last_back_edge = | 2278 HBasicBlock* last_back_edge = |
| 2274 block->loop_information()->GetLastBackEdge(); | 2279 block->loop_information()->GetLastBackEdge(); |
| 2275 InitializeInferredTypes(i + 1, last_back_edge->block_id()); | 2280 InitializeInferredTypes(i + 1, last_back_edge->block_id()); |
| 2276 // Skip all blocks already processed by the recursive call. | 2281 // Skip all blocks already processed by the recursive call. |
| 2277 i = last_back_edge->block_id(); | 2282 i = last_back_edge->block_id(); |
| 2278 // Update phis of the loop header now after the whole loop body is | 2283 // Update phis of the loop header now after the whole loop body is |
| 2279 // guaranteed to be processed. | 2284 // guaranteed to be processed. |
| 2280 ZoneList<HValue*> worklist(block->phis()->length()); | 2285 ZoneList<HValue*> worklist(block->phis()->length(), zone()); |
| 2281 for (int j = 0; j < block->phis()->length(); ++j) { | 2286 for (int j = 0; j < block->phis()->length(); ++j) { |
| 2282 worklist.Add(block->phis()->at(j)); | 2287 worklist.Add(block->phis()->at(j), zone()); |
| 2283 } | 2288 } |
| 2284 InferTypes(&worklist); | 2289 InferTypes(&worklist); |
| 2285 } | 2290 } |
| 2286 } | 2291 } |
| 2287 } | 2292 } |
| 2288 | 2293 |
| 2289 | 2294 |
| 2290 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { | 2295 void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { |
| 2291 HValue* current = value; | 2296 HValue* current = value; |
| 2292 while (current != NULL) { | 2297 while (current != NULL) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2339 // information we treat constants like normal instructions and insert the | 2344 // information we treat constants like normal instructions and insert the |
| 2340 // change instructions for them. | 2345 // change instructions for them. |
| 2341 HInstruction* new_value = NULL; | 2346 HInstruction* new_value = NULL; |
| 2342 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); | 2347 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
| 2343 bool deoptimize_on_undefined = | 2348 bool deoptimize_on_undefined = |
| 2344 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); | 2349 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); |
| 2345 if (value->IsConstant()) { | 2350 if (value->IsConstant()) { |
| 2346 HConstant* constant = HConstant::cast(value); | 2351 HConstant* constant = HConstant::cast(value); |
| 2347 // Try to create a new copy of the constant with the new representation. | 2352 // Try to create a new copy of the constant with the new representation. |
| 2348 new_value = is_truncating | 2353 new_value = is_truncating |
| 2349 ? constant->CopyToTruncatedInt32() | 2354 ? constant->CopyToTruncatedInt32(zone()) |
| 2350 : constant->CopyToRepresentation(to); | 2355 : constant->CopyToRepresentation(to, zone()); |
| 2351 } | 2356 } |
| 2352 | 2357 |
| 2353 if (new_value == NULL) { | 2358 if (new_value == NULL) { |
| 2354 new_value = new(zone()) HChange(value, to, | 2359 new_value = new(zone()) HChange(value, to, |
| 2355 is_truncating, deoptimize_on_undefined); | 2360 is_truncating, deoptimize_on_undefined); |
| 2356 } | 2361 } |
| 2357 | 2362 |
| 2358 new_value->InsertBefore(next); | 2363 new_value->InsertBefore(next); |
| 2359 use_value->SetOperandAt(use_index, new_value); | 2364 use_value->SetOperandAt(use_index, new_value); |
| 2360 } | 2365 } |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2759 | 2764 |
| 2760 | 2765 |
| 2761 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { | 2766 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { |
| 2762 for (int i = 0; i < exprs->length(); ++i) { | 2767 for (int i = 0; i < exprs->length(); ++i) { |
| 2763 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 2768 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
| 2764 } | 2769 } |
| 2765 } | 2770 } |
| 2766 | 2771 |
| 2767 | 2772 |
| 2768 HGraph* HGraphBuilder::CreateGraph() { | 2773 HGraph* HGraphBuilder::CreateGraph() { |
| 2769 graph_ = new(zone()) HGraph(info()); | 2774 graph_ = new(zone()) HGraph(info(), zone()); |
| 2770 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 2775 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); |
| 2771 | 2776 |
| 2772 { | 2777 { |
| 2773 HPhase phase("H_Block building"); | 2778 HPhase phase("H_Block building"); |
| 2774 current_block_ = graph()->entry_block(); | 2779 current_block_ = graph()->entry_block(); |
| 2775 | 2780 |
| 2776 Scope* scope = info()->scope(); | 2781 Scope* scope = info()->scope(); |
| 2777 if (scope->HasIllegalRedeclaration()) { | 2782 if (scope->HasIllegalRedeclaration()) { |
| 2778 Bailout("function with illegal redeclaration"); | 2783 Bailout("function with illegal redeclaration"); |
| 2779 return NULL; | 2784 return NULL; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3110 | 3115 |
| 3111 static bool BoundsCheckKeyMatch(void* key1, void* key2) { | 3116 static bool BoundsCheckKeyMatch(void* key1, void* key2) { |
| 3112 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); | 3117 BoundsCheckKey* k1 = static_cast<BoundsCheckKey*>(key1); |
| 3113 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); | 3118 BoundsCheckKey* k2 = static_cast<BoundsCheckKey*>(key2); |
| 3114 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); | 3119 return k1->IndexBase() == k2->IndexBase() && k1->Length() == k2->Length(); |
| 3115 } | 3120 } |
| 3116 | 3121 |
| 3117 | 3122 |
| 3118 class BoundsCheckTable : private ZoneHashMap { | 3123 class BoundsCheckTable : private ZoneHashMap { |
| 3119 public: | 3124 public: |
| 3120 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key) { | 3125 BoundsCheckBbData** LookupOrInsert(BoundsCheckKey* key, Zone* zone) { |
| 3121 return reinterpret_cast<BoundsCheckBbData**>( | 3126 return reinterpret_cast<BoundsCheckBbData**>( |
| 3122 &(Lookup(key, key->Hash(), true)->value)); | 3127 &(Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value)); |
| 3123 } | 3128 } |
| 3124 | 3129 |
| 3125 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data) { | 3130 void Insert(BoundsCheckKey* key, BoundsCheckBbData* data, Zone* zone) { |
| 3126 Lookup(key, key->Hash(), true)->value = data; | 3131 Lookup(key, key->Hash(), true, ZoneAllocationPolicy(zone))->value = data; |
| 3127 } | 3132 } |
| 3128 | 3133 |
| 3129 void Delete(BoundsCheckKey* key) { | 3134 void Delete(BoundsCheckKey* key) { |
| 3130 Remove(key, key->Hash()); | 3135 Remove(key, key->Hash()); |
| 3131 } | 3136 } |
| 3132 | 3137 |
| 3133 BoundsCheckTable() : ZoneHashMap(BoundsCheckKeyMatch) { } | 3138 explicit BoundsCheckTable(Zone* zone) |
| 3139 : ZoneHashMap(BoundsCheckKeyMatch, ZoneHashMap::kDefaultHashMapCapacity, |
| 3140 ZoneAllocationPolicy(zone)) { } |
| 3134 }; | 3141 }; |
| 3135 | 3142 |
| 3136 | 3143 |
| 3137 // Eliminates checks in bb and recursively in the dominated blocks. | 3144 // Eliminates checks in bb and recursively in the dominated blocks. |
| 3138 // Also replace the results of check instructions with the original value, if | 3145 // Also replace the results of check instructions with the original value, if |
| 3139 // the result is used. This is safe now, since we don't do code motion after | 3146 // the result is used. This is safe now, since we don't do code motion after |
| 3140 // this point. It enables better register allocation since the value produced | 3147 // this point. It enables better register allocation since the value produced |
| 3141 // by check instructions is really a copy of the original value. | 3148 // by check instructions is really a copy of the original value. |
| 3142 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, | 3149 void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb, |
| 3143 BoundsCheckTable* table) { | 3150 BoundsCheckTable* table) { |
| 3144 BoundsCheckBbData* bb_data_list = NULL; | 3151 BoundsCheckBbData* bb_data_list = NULL; |
| 3145 | 3152 |
| 3146 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { | 3153 for (HInstruction* i = bb->first(); i != NULL; i = i->next()) { |
| 3147 if (!i->IsBoundsCheck()) continue; | 3154 if (!i->IsBoundsCheck()) continue; |
| 3148 | 3155 |
| 3149 HBoundsCheck* check = HBoundsCheck::cast(i); | 3156 HBoundsCheck* check = HBoundsCheck::cast(i); |
| 3150 check->ReplaceAllUsesWith(check->index()); | 3157 check->ReplaceAllUsesWith(check->index()); |
| 3151 | 3158 |
| 3152 if (!FLAG_array_bounds_checks_elimination) continue; | 3159 if (!FLAG_array_bounds_checks_elimination) continue; |
| 3153 | 3160 |
| 3154 int32_t offset; | 3161 int32_t offset; |
| 3155 BoundsCheckKey* key = | 3162 BoundsCheckKey* key = |
| 3156 BoundsCheckKey::Create(bb->zone(), check, &offset); | 3163 BoundsCheckKey::Create(zone(), check, &offset); |
| 3157 BoundsCheckBbData** data_p = table->LookupOrInsert(key); | 3164 BoundsCheckBbData** data_p = table->LookupOrInsert(key, zone()); |
| 3158 BoundsCheckBbData* data = *data_p; | 3165 BoundsCheckBbData* data = *data_p; |
| 3159 if (data == NULL) { | 3166 if (data == NULL) { |
| 3160 bb_data_list = new(zone()) BoundsCheckBbData(key, | 3167 bb_data_list = new(zone()) BoundsCheckBbData(key, |
| 3161 offset, | 3168 offset, |
| 3162 offset, | 3169 offset, |
| 3163 bb, | 3170 bb, |
| 3164 check, | 3171 check, |
| 3165 bb_data_list, | 3172 bb_data_list, |
| 3166 NULL); | 3173 NULL); |
| 3167 *data_p = bb_data_list; | 3174 *data_p = bb_data_list; |
| 3168 } else if (data->OffsetIsCovered(offset)) { | 3175 } else if (data->OffsetIsCovered(offset)) { |
| 3169 check->DeleteAndReplaceWith(NULL); | 3176 check->DeleteAndReplaceWith(NULL); |
| 3170 } else if (data->BasicBlock() == bb) { | 3177 } else if (data->BasicBlock() == bb) { |
| 3171 data->CoverCheck(check, offset); | 3178 data->CoverCheck(check, offset); |
| 3172 } else { | 3179 } else { |
| 3173 int32_t new_lower_offset = offset < data->LowerOffset() | 3180 int32_t new_lower_offset = offset < data->LowerOffset() |
| 3174 ? offset | 3181 ? offset |
| 3175 : data->LowerOffset(); | 3182 : data->LowerOffset(); |
| 3176 int32_t new_upper_offset = offset > data->UpperOffset() | 3183 int32_t new_upper_offset = offset > data->UpperOffset() |
| 3177 ? offset | 3184 ? offset |
| 3178 : data->UpperOffset(); | 3185 : data->UpperOffset(); |
| 3179 bb_data_list = new(bb->zone()) BoundsCheckBbData(key, | 3186 bb_data_list = new(zone()) BoundsCheckBbData(key, |
| 3180 new_lower_offset, | 3187 new_lower_offset, |
| 3181 new_upper_offset, | 3188 new_upper_offset, |
| 3182 bb, | 3189 bb, |
| 3183 check, | 3190 check, |
| 3184 bb_data_list, | 3191 bb_data_list, |
| 3185 data); | 3192 data); |
| 3186 table->Insert(key, bb_data_list); | 3193 table->Insert(key, bb_data_list, zone()); |
| 3187 } | 3194 } |
| 3188 } | 3195 } |
| 3189 | 3196 |
| 3190 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { | 3197 for (int i = 0; i < bb->dominated_blocks()->length(); ++i) { |
| 3191 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); | 3198 EliminateRedundantBoundsChecks(bb->dominated_blocks()->at(i), table); |
| 3192 } | 3199 } |
| 3193 | 3200 |
| 3194 for (BoundsCheckBbData* data = bb_data_list; | 3201 for (BoundsCheckBbData* data = bb_data_list; |
| 3195 data != NULL; | 3202 data != NULL; |
| 3196 data = data->NextInBasicBlock()) { | 3203 data = data->NextInBasicBlock()) { |
| 3197 data->RemoveZeroOperations(); | 3204 data->RemoveZeroOperations(); |
| 3198 if (data->FatherInDominatorTree()) { | 3205 if (data->FatherInDominatorTree()) { |
| 3199 table->Insert(data->Key(), data->FatherInDominatorTree()); | 3206 table->Insert(data->Key(), data->FatherInDominatorTree(), zone()); |
| 3200 } else { | 3207 } else { |
| 3201 table->Delete(data->Key()); | 3208 table->Delete(data->Key()); |
| 3202 } | 3209 } |
| 3203 } | 3210 } |
| 3204 } | 3211 } |
| 3205 | 3212 |
| 3206 | 3213 |
| 3207 void HGraph::EliminateRedundantBoundsChecks() { | 3214 void HGraph::EliminateRedundantBoundsChecks() { |
| 3208 HPhase phase("H_Eliminate bounds checks", this); | 3215 HPhase phase("H_Eliminate bounds checks", this); |
| 3209 AssertNoAllocation no_gc; | 3216 AssertNoAllocation no_gc; |
| 3210 BoundsCheckTable checks_table; | 3217 BoundsCheckTable checks_table(zone()); |
| 3211 EliminateRedundantBoundsChecks(entry_block(), &checks_table); | 3218 EliminateRedundantBoundsChecks(entry_block(), &checks_table); |
| 3212 } | 3219 } |
| 3213 | 3220 |
| 3214 | 3221 |
| 3215 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { | 3222 static void DehoistArrayIndex(ArrayInstructionInterface* array_operation) { |
| 3216 HValue* index = array_operation->GetKey(); | 3223 HValue* index = array_operation->GetKey(); |
| 3217 | 3224 |
| 3218 HConstant* constant; | 3225 HConstant* constant; |
| 3219 HValue* subexpression; | 3226 HValue* subexpression; |
| 3220 int32_t sign; | 3227 int32_t sign; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3320 | 3327 |
| 3321 void HGraphBuilder::PushAndAdd(HInstruction* instr) { | 3328 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
| 3322 Push(instr); | 3329 Push(instr); |
| 3323 AddInstruction(instr); | 3330 AddInstruction(instr); |
| 3324 } | 3331 } |
| 3325 | 3332 |
| 3326 | 3333 |
| 3327 template <class Instruction> | 3334 template <class Instruction> |
| 3328 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { | 3335 HInstruction* HGraphBuilder::PreProcessCall(Instruction* call) { |
| 3329 int count = call->argument_count(); | 3336 int count = call->argument_count(); |
| 3330 ZoneList<HValue*> arguments(count); | 3337 ZoneList<HValue*> arguments(count, zone()); |
| 3331 for (int i = 0; i < count; ++i) { | 3338 for (int i = 0; i < count; ++i) { |
| 3332 arguments.Add(Pop()); | 3339 arguments.Add(Pop(), zone()); |
| 3333 } | 3340 } |
| 3334 | 3341 |
| 3335 while (!arguments.is_empty()) { | 3342 while (!arguments.is_empty()) { |
| 3336 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); | 3343 AddInstruction(new(zone()) HPushArgument(arguments.RemoveLast())); |
| 3337 } | 3344 } |
| 3338 return call; | 3345 return call; |
| 3339 } | 3346 } |
| 3340 | 3347 |
| 3341 | 3348 |
| 3342 void HGraphBuilder::SetUpScope(Scope* scope) { | 3349 void HGraphBuilder::SetUpScope(Scope* scope) { |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3822 current_block()->Finish(test); | 3829 current_block()->Finish(test); |
| 3823 | 3830 |
| 3824 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 3831 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
| 3825 non_osr_entry->Goto(loop_predecessor); | 3832 non_osr_entry->Goto(loop_predecessor); |
| 3826 | 3833 |
| 3827 set_current_block(osr_entry); | 3834 set_current_block(osr_entry); |
| 3828 int osr_entry_id = statement->OsrEntryId(); | 3835 int osr_entry_id = statement->OsrEntryId(); |
| 3829 int first_expression_index = environment()->first_expression_index(); | 3836 int first_expression_index = environment()->first_expression_index(); |
| 3830 int length = environment()->length(); | 3837 int length = environment()->length(); |
| 3831 ZoneList<HUnknownOSRValue*>* osr_values = | 3838 ZoneList<HUnknownOSRValue*>* osr_values = |
| 3832 new(zone()) ZoneList<HUnknownOSRValue*>(length); | 3839 new(zone()) ZoneList<HUnknownOSRValue*>(length, zone()); |
| 3833 | 3840 |
| 3834 for (int i = 0; i < first_expression_index; ++i) { | 3841 for (int i = 0; i < first_expression_index; ++i) { |
| 3835 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3842 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
| 3836 AddInstruction(osr_value); | 3843 AddInstruction(osr_value); |
| 3837 environment()->Bind(i, osr_value); | 3844 environment()->Bind(i, osr_value); |
| 3838 osr_values->Add(osr_value); | 3845 osr_values->Add(osr_value, zone()); |
| 3839 } | 3846 } |
| 3840 | 3847 |
| 3841 if (first_expression_index != length) { | 3848 if (first_expression_index != length) { |
| 3842 environment()->Drop(length - first_expression_index); | 3849 environment()->Drop(length - first_expression_index); |
| 3843 for (int i = first_expression_index; i < length; ++i) { | 3850 for (int i = first_expression_index; i < length; ++i) { |
| 3844 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; | 3851 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
| 3845 AddInstruction(osr_value); | 3852 AddInstruction(osr_value); |
| 3846 environment()->Push(osr_value); | 3853 environment()->Push(osr_value); |
| 3847 osr_values->Add(osr_value); | 3854 osr_values->Add(osr_value, zone()); |
| 3848 } | 3855 } |
| 3849 } | 3856 } |
| 3850 | 3857 |
| 3851 graph()->set_osr_values(osr_values); | 3858 graph()->set_osr_values(osr_values); |
| 3852 | 3859 |
| 3853 AddSimulate(osr_entry_id); | 3860 AddSimulate(osr_entry_id); |
| 3854 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 3861 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
| 3855 HContext* context = new(zone()) HContext; | 3862 HContext* context = new(zone()) HContext; |
| 3856 AddInstruction(context); | 3863 AddInstruction(context); |
| 3857 environment()->BindContext(context); | 3864 environment()->BindContext(context); |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4465 expr->fast_elements(), | 4472 expr->fast_elements(), |
| 4466 expr->literal_index(), | 4473 expr->literal_index(), |
| 4467 expr->depth(), | 4474 expr->depth(), |
| 4468 expr->has_function()); | 4475 expr->has_function()); |
| 4469 } | 4476 } |
| 4470 | 4477 |
| 4471 // The object is expected in the bailout environment during computation | 4478 // The object is expected in the bailout environment during computation |
| 4472 // of the property values and is the value of the entire expression. | 4479 // of the property values and is the value of the entire expression. |
| 4473 PushAndAdd(literal); | 4480 PushAndAdd(literal); |
| 4474 | 4481 |
| 4475 expr->CalculateEmitStore(); | 4482 expr->CalculateEmitStore(zone()); |
| 4476 | 4483 |
| 4477 for (int i = 0; i < expr->properties()->length(); i++) { | 4484 for (int i = 0; i < expr->properties()->length(); i++) { |
| 4478 ObjectLiteral::Property* property = expr->properties()->at(i); | 4485 ObjectLiteral::Property* property = expr->properties()->at(i); |
| 4479 if (property->IsCompileTimeValue()) continue; | 4486 if (property->IsCompileTimeValue()) continue; |
| 4480 | 4487 |
| 4481 Literal* key = property->key(); | 4488 Literal* key = property->key(); |
| 4482 Expression* value = property->value(); | 4489 Expression* value = property->value(); |
| 4483 | 4490 |
| 4484 switch (property->kind()) { | 4491 switch (property->kind()) { |
| 4485 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 4492 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4655 | 4662 |
| 4656 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 4663 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
| 4657 Handle<String> name, | 4664 Handle<String> name, |
| 4658 HValue* value, | 4665 HValue* value, |
| 4659 Handle<Map> type, | 4666 Handle<Map> type, |
| 4660 LookupResult* lookup, | 4667 LookupResult* lookup, |
| 4661 bool smi_and_map_check) { | 4668 bool smi_and_map_check) { |
| 4662 ASSERT(lookup->IsFound()); | 4669 ASSERT(lookup->IsFound()); |
| 4663 if (smi_and_map_check) { | 4670 if (smi_and_map_check) { |
| 4664 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4671 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 4665 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 4672 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
| 4666 } | 4673 } |
| 4667 | 4674 |
| 4668 // If the property does not exist yet, we have to check that it wasn't made | 4675 // If the property does not exist yet, we have to check that it wasn't made |
| 4669 // readonly or turned into a setter by some meanwhile modifications on the | 4676 // readonly or turned into a setter by some meanwhile modifications on the |
| 4670 // prototype chain. | 4677 // prototype chain. |
| 4671 if (!lookup->IsProperty()) { | 4678 if (!lookup->IsProperty()) { |
| 4672 Object* proto = type->prototype(); | 4679 Object* proto = type->prototype(); |
| 4673 // First check that the prototype chain isn't affected already. | 4680 // First check that the prototype chain isn't affected already. |
| 4674 LookupResult proto_result(isolate()); | 4681 LookupResult proto_result(isolate()); |
| 4675 proto->Lookup(*name, &proto_result); | 4682 proto->Lookup(*name, &proto_result); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4799 (is_in_object == previous_field_is_in_object); | 4806 (is_in_object == previous_field_is_in_object); |
| 4800 } | 4807 } |
| 4801 ++count; | 4808 ++count; |
| 4802 } | 4809 } |
| 4803 } | 4810 } |
| 4804 | 4811 |
| 4805 // Use monomorphic load if property lookup results in the same field index | 4812 // Use monomorphic load if property lookup results in the same field index |
| 4806 // for all maps. Requires special map check on the set of all handled maps. | 4813 // for all maps. Requires special map check on the set of all handled maps. |
| 4807 HInstruction* instr; | 4814 HInstruction* instr; |
| 4808 if (count == types->length() && is_monomorphic_field) { | 4815 if (count == types->length() && is_monomorphic_field) { |
| 4809 AddInstruction(new(zone()) HCheckMaps(object, types)); | 4816 AddInstruction(new(zone()) HCheckMaps(object, types, zone())); |
| 4810 instr = BuildLoadNamedField(object, expr, map, &lookup, false); | 4817 instr = BuildLoadNamedField(object, expr, map, &lookup, false); |
| 4811 } else { | 4818 } else { |
| 4812 HValue* context = environment()->LookupContext(); | 4819 HValue* context = environment()->LookupContext(); |
| 4813 instr = new(zone()) HLoadNamedFieldPolymorphic(context, | 4820 instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
| 4814 object, | 4821 object, |
| 4815 types, | 4822 types, |
| 4816 name); | 4823 name, |
| 4824 zone()); |
| 4817 } | 4825 } |
| 4818 | 4826 |
| 4819 instr->set_position(expr->position()); | 4827 instr->set_position(expr->position()); |
| 4820 return ast_context()->ReturnInstruction(instr, expr->id()); | 4828 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 4821 } | 4829 } |
| 4822 | 4830 |
| 4823 | 4831 |
| 4824 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 4832 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
| 4825 HValue* object, | 4833 HValue* object, |
| 4826 HValue* value, | 4834 HValue* value, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4893 ASSERT(join != NULL); | 4901 ASSERT(join != NULL); |
| 4894 join->SetJoinId(expr->id()); | 4902 join->SetJoinId(expr->id()); |
| 4895 set_current_block(join); | 4903 set_current_block(join); |
| 4896 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); | 4904 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); |
| 4897 } | 4905 } |
| 4898 | 4906 |
| 4899 | 4907 |
| 4900 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 4908 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
| 4901 Property* prop = expr->target()->AsProperty(); | 4909 Property* prop = expr->target()->AsProperty(); |
| 4902 ASSERT(prop != NULL); | 4910 ASSERT(prop != NULL); |
| 4903 expr->RecordTypeFeedback(oracle()); | 4911 expr->RecordTypeFeedback(oracle(), zone()); |
| 4904 CHECK_ALIVE(VisitForValue(prop->obj())); | 4912 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 4905 | 4913 |
| 4906 HValue* value = NULL; | 4914 HValue* value = NULL; |
| 4907 HInstruction* instr = NULL; | 4915 HInstruction* instr = NULL; |
| 4908 | 4916 |
| 4909 if (prop->key()->IsPropertyName()) { | 4917 if (prop->key()->IsPropertyName()) { |
| 4910 // Named store. | 4918 // Named store. |
| 4911 CHECK_ALIVE(VisitForValue(expr->value())); | 4919 CHECK_ALIVE(VisitForValue(expr->value())); |
| 4912 value = Pop(); | 4920 value = Pop(); |
| 4913 HValue* object = Pop(); | 4921 HValue* object = Pop(); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5064 } | 5072 } |
| 5065 break; | 5073 break; |
| 5066 } | 5074 } |
| 5067 | 5075 |
| 5068 case Variable::LOOKUP: | 5076 case Variable::LOOKUP: |
| 5069 return Bailout("compound assignment to lookup slot"); | 5077 return Bailout("compound assignment to lookup slot"); |
| 5070 } | 5078 } |
| 5071 return ast_context()->ReturnValue(Pop()); | 5079 return ast_context()->ReturnValue(Pop()); |
| 5072 | 5080 |
| 5073 } else if (prop != NULL) { | 5081 } else if (prop != NULL) { |
| 5074 prop->RecordTypeFeedback(oracle()); | 5082 prop->RecordTypeFeedback(oracle(), zone()); |
| 5075 | 5083 |
| 5076 if (prop->key()->IsPropertyName()) { | 5084 if (prop->key()->IsPropertyName()) { |
| 5077 // Named property. | 5085 // Named property. |
| 5078 CHECK_ALIVE(VisitForValue(prop->obj())); | 5086 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5079 HValue* obj = Top(); | 5087 HValue* obj = Top(); |
| 5080 | 5088 |
| 5081 HInstruction* load = NULL; | 5089 HInstruction* load = NULL; |
| 5082 if (prop->IsMonomorphic()) { | 5090 if (prop->IsMonomorphic()) { |
| 5083 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 5091 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 5084 Handle<Map> map = prop->GetReceiverTypes()->first(); | 5092 Handle<Map> map = prop->GetReceiverTypes()->first(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5123 | 5131 |
| 5124 | 5132 |
| 5125 CHECK_ALIVE(VisitForValue(expr->value())); | 5133 CHECK_ALIVE(VisitForValue(expr->value())); |
| 5126 HValue* right = Pop(); | 5134 HValue* right = Pop(); |
| 5127 HValue* left = Pop(); | 5135 HValue* left = Pop(); |
| 5128 | 5136 |
| 5129 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5137 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 5130 PushAndAdd(instr); | 5138 PushAndAdd(instr); |
| 5131 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5139 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
| 5132 | 5140 |
| 5133 expr->RecordTypeFeedback(oracle()); | 5141 expr->RecordTypeFeedback(oracle(), zone()); |
| 5134 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), | 5142 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), |
| 5135 RelocInfo::kNoPosition, | 5143 RelocInfo::kNoPosition, |
| 5136 true, // is_store | 5144 true, // is_store |
| 5137 &has_side_effects); | 5145 &has_side_effects); |
| 5138 | 5146 |
| 5139 // Drop the simulated receiver, key, and value. Return the value. | 5147 // Drop the simulated receiver, key, and value. Return the value. |
| 5140 Drop(3); | 5148 Drop(3); |
| 5141 Push(instr); | 5149 Push(instr); |
| 5142 ASSERT(has_side_effects); // Stores always have side effects. | 5150 ASSERT(has_side_effects); // Stores always have side effects. |
| 5143 AddSimulate(expr->AssignmentId()); | 5151 AddSimulate(expr->AssignmentId()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 5171 if (var->mode() == CONST) { | 5179 if (var->mode() == CONST) { |
| 5172 if (expr->op() != Token::INIT_CONST) { | 5180 if (expr->op() != Token::INIT_CONST) { |
| 5173 CHECK_ALIVE(VisitForValue(expr->value())); | 5181 CHECK_ALIVE(VisitForValue(expr->value())); |
| 5174 return ast_context()->ReturnValue(Pop()); | 5182 return ast_context()->ReturnValue(Pop()); |
| 5175 } | 5183 } |
| 5176 | 5184 |
| 5177 if (var->IsStackAllocated()) { | 5185 if (var->IsStackAllocated()) { |
| 5178 // We insert a use of the old value to detect unsupported uses of const | 5186 // We insert a use of the old value to detect unsupported uses of const |
| 5179 // variables (e.g. initialization inside a loop). | 5187 // variables (e.g. initialization inside a loop). |
| 5180 HValue* old_value = environment()->Lookup(var); | 5188 HValue* old_value = environment()->Lookup(var); |
| 5181 AddInstruction(new HUseConst(old_value)); | 5189 AddInstruction(new(zone()) HUseConst(old_value)); |
| 5182 } | 5190 } |
| 5183 } else if (var->mode() == CONST_HARMONY) { | 5191 } else if (var->mode() == CONST_HARMONY) { |
| 5184 if (expr->op() != Token::INIT_CONST_HARMONY) { | 5192 if (expr->op() != Token::INIT_CONST_HARMONY) { |
| 5185 return Bailout("non-initializer assignment to const"); | 5193 return Bailout("non-initializer assignment to const"); |
| 5186 } | 5194 } |
| 5187 } | 5195 } |
| 5188 | 5196 |
| 5189 if (proxy->IsArguments()) return Bailout("assignment to arguments"); | 5197 if (proxy->IsArguments()) return Bailout("assignment to arguments"); |
| 5190 | 5198 |
| 5191 // Handle the assignment. | 5199 // Handle the assignment. |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5298 } | 5306 } |
| 5299 | 5307 |
| 5300 | 5308 |
| 5301 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 5309 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
| 5302 Property* expr, | 5310 Property* expr, |
| 5303 Handle<Map> type, | 5311 Handle<Map> type, |
| 5304 LookupResult* lookup, | 5312 LookupResult* lookup, |
| 5305 bool smi_and_map_check) { | 5313 bool smi_and_map_check) { |
| 5306 if (smi_and_map_check) { | 5314 if (smi_and_map_check) { |
| 5307 AddInstruction(new(zone()) HCheckNonSmi(object)); | 5315 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 5308 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 5316 AddInstruction(HCheckMaps::NewWithTransitions(object, type, zone())); |
| 5309 } | 5317 } |
| 5310 | 5318 |
| 5311 int index = lookup->GetLocalFieldIndexFromMap(*type); | 5319 int index = lookup->GetLocalFieldIndexFromMap(*type); |
| 5312 if (index < 0) { | 5320 if (index < 0) { |
| 5313 // Negative property indices are in-object properties, indexed | 5321 // Negative property indices are in-object properties, indexed |
| 5314 // from the end of the fixed part of the object. | 5322 // from the end of the fixed part of the object. |
| 5315 int offset = (index * kPointerSize) + type->instance_size(); | 5323 int offset = (index * kPointerSize) + type->instance_size(); |
| 5316 return new(zone()) HLoadNamedField(object, true, offset); | 5324 return new(zone()) HLoadNamedField(object, true, offset); |
| 5317 } else { | 5325 } else { |
| 5318 // Non-negative property indices are in the properties array. | 5326 // Non-negative property indices are in the properties array. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5342 LookupResult lookup(isolate()); | 5350 LookupResult lookup(isolate()); |
| 5343 map->LookupInDescriptors(NULL, *name, &lookup); | 5351 map->LookupInDescriptors(NULL, *name, &lookup); |
| 5344 if (lookup.IsFound() && lookup.type() == FIELD) { | 5352 if (lookup.IsFound() && lookup.type() == FIELD) { |
| 5345 return BuildLoadNamedField(obj, | 5353 return BuildLoadNamedField(obj, |
| 5346 expr, | 5354 expr, |
| 5347 map, | 5355 map, |
| 5348 &lookup, | 5356 &lookup, |
| 5349 true); | 5357 true); |
| 5350 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { | 5358 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { |
| 5351 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 5359 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
| 5352 AddInstruction(HCheckMaps::NewWithTransitions(obj, map)); | 5360 AddInstruction(HCheckMaps::NewWithTransitions(obj, map, zone())); |
| 5353 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 5361 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
| 5354 return new(zone()) HConstant(function, Representation::Tagged()); | 5362 return new(zone()) HConstant(function, Representation::Tagged()); |
| 5355 } else { | 5363 } else { |
| 5356 return BuildLoadNamedGeneric(obj, expr); | 5364 return BuildLoadNamedGeneric(obj, expr); |
| 5357 } | 5365 } |
| 5358 } | 5366 } |
| 5359 | 5367 |
| 5360 | 5368 |
| 5361 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 5369 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
| 5362 HValue* key) { | 5370 HValue* key) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5455 } | 5463 } |
| 5456 | 5464 |
| 5457 | 5465 |
| 5458 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 5466 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
| 5459 HValue* key, | 5467 HValue* key, |
| 5460 HValue* val, | 5468 HValue* val, |
| 5461 HValue* dependency, | 5469 HValue* dependency, |
| 5462 Handle<Map> map, | 5470 Handle<Map> map, |
| 5463 bool is_store) { | 5471 bool is_store) { |
| 5464 HInstruction* mapcheck = | 5472 HInstruction* mapcheck = |
| 5465 AddInstruction(new(zone()) HCheckMaps(object, map, dependency)); | 5473 AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency)); |
| 5466 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 5474 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
| 5467 // on a HElementsTransition instruction. The flag can also be removed if the | 5475 // on a HElementsTransition instruction. The flag can also be removed if the |
| 5468 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 5476 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
| 5469 // ElementsKind transitions. Finally, the dependency can be removed for stores | 5477 // ElementsKind transitions. Finally, the dependency can be removed for stores |
| 5470 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 5478 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
| 5471 // generated store code. | 5479 // generated store code. |
| 5472 if (dependency || | 5480 if (dependency || |
| 5473 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || | 5481 (map->elements_kind() == FAST_HOLEY_ELEMENTS) || |
| 5474 (map->elements_kind() == FAST_ELEMENTS && is_store)) { | 5482 (map->elements_kind() == FAST_ELEMENTS && is_store)) { |
| 5475 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 5483 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| 5476 } | 5484 } |
| 5477 bool fast_smi_only_elements = map->has_fast_smi_elements(); | 5485 bool fast_smi_only_elements = map->has_fast_smi_elements(); |
| 5478 bool fast_elements = map->has_fast_object_elements(); | 5486 bool fast_elements = map->has_fast_object_elements(); |
| 5479 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5487 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 5480 if (is_store && (fast_elements || fast_smi_only_elements)) { | 5488 if (is_store && (fast_elements || fast_smi_only_elements)) { |
| 5481 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( | 5489 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( |
| 5482 elements, isolate()->factory()->fixed_array_map()); | 5490 elements, isolate()->factory()->fixed_array_map(), zone()); |
| 5483 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 5491 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| 5484 AddInstruction(check_cow_map); | 5492 AddInstruction(check_cow_map); |
| 5485 } | 5493 } |
| 5486 HInstruction* length = NULL; | 5494 HInstruction* length = NULL; |
| 5487 HInstruction* checked_key = NULL; | 5495 HInstruction* checked_key = NULL; |
| 5488 if (map->has_external_array_elements()) { | 5496 if (map->has_external_array_elements()) { |
| 5489 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 5497 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 5490 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 5498 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 5491 HLoadExternalArrayPointer* external_elements = | 5499 HLoadExternalArrayPointer* external_elements = |
| 5492 new(zone()) HLoadExternalArrayPointer(elements); | 5500 new(zone()) HLoadExternalArrayPointer(elements); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5579 : BuildLoadKeyedGeneric(object, key)); | 5587 : BuildLoadKeyedGeneric(object, key)); |
| 5580 } else { | 5588 } else { |
| 5581 instr = AddInstruction(BuildMonomorphicElementAccess( | 5589 instr = AddInstruction(BuildMonomorphicElementAccess( |
| 5582 object, key, val, transition, untransitionable_map, is_store)); | 5590 object, key, val, transition, untransitionable_map, is_store)); |
| 5583 } | 5591 } |
| 5584 *has_side_effects |= instr->HasObservableSideEffects(); | 5592 *has_side_effects |= instr->HasObservableSideEffects(); |
| 5585 instr->set_position(position); | 5593 instr->set_position(position); |
| 5586 return is_store ? NULL : instr; | 5594 return is_store ? NULL : instr; |
| 5587 } | 5595 } |
| 5588 | 5596 |
| 5589 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 5597 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); |
| 5590 HBasicBlock* join = graph()->CreateBasicBlock(); | 5598 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 5591 | 5599 |
| 5592 HInstruction* elements_kind_instr = | 5600 HInstruction* elements_kind_instr = |
| 5593 AddInstruction(new(zone()) HElementsKind(object)); | 5601 AddInstruction(new(zone()) HElementsKind(object)); |
| 5594 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 5602 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
| 5595 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 5603 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 5596 HLoadExternalArrayPointer* external_elements = NULL; | 5604 HLoadExternalArrayPointer* external_elements = NULL; |
| 5597 HInstruction* checked_key = NULL; | 5605 HInstruction* checked_key = NULL; |
| 5598 | 5606 |
| 5599 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds | 5607 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5626 elements_kind_branch->SetSuccessorAt(0, if_true); | 5634 elements_kind_branch->SetSuccessorAt(0, if_true); |
| 5627 elements_kind_branch->SetSuccessorAt(1, if_false); | 5635 elements_kind_branch->SetSuccessorAt(1, if_false); |
| 5628 current_block()->Finish(elements_kind_branch); | 5636 current_block()->Finish(elements_kind_branch); |
| 5629 | 5637 |
| 5630 set_current_block(if_true); | 5638 set_current_block(if_true); |
| 5631 HInstruction* access; | 5639 HInstruction* access; |
| 5632 if (IsFastElementsKind(elements_kind)) { | 5640 if (IsFastElementsKind(elements_kind)) { |
| 5633 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 5641 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
| 5634 AddInstruction(new(zone()) HCheckMaps( | 5642 AddInstruction(new(zone()) HCheckMaps( |
| 5635 elements, isolate()->factory()->fixed_array_map(), | 5643 elements, isolate()->factory()->fixed_array_map(), |
| 5636 elements_kind_branch)); | 5644 zone(), elements_kind_branch)); |
| 5637 } | 5645 } |
| 5638 // TODO(jkummerow): The need for these two blocks could be avoided | 5646 // TODO(jkummerow): The need for these two blocks could be avoided |
| 5639 // in one of two ways: | 5647 // in one of two ways: |
| 5640 // (1) Introduce ElementsKinds for JSArrays that are distinct from | 5648 // (1) Introduce ElementsKinds for JSArrays that are distinct from |
| 5641 // those for fast objects. | 5649 // those for fast objects. |
| 5642 // (2) Put the common instructions into a third "join" block. This | 5650 // (2) Put the common instructions into a third "join" block. This |
| 5643 // requires additional AST IDs that we can deopt to from inside | 5651 // requires additional AST IDs that we can deopt to from inside |
| 5644 // that join block. They must be added to the Property class (when | 5652 // that join block. They must be added to the Property class (when |
| 5645 // it's a keyed property) and registered in the full codegen. | 5653 // it's a keyed property) and registered in the full codegen. |
| 5646 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 5654 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5833 } | 5841 } |
| 5834 ast_context()->ReturnInstruction(result, expr->id()); | 5842 ast_context()->ReturnInstruction(result, expr->id()); |
| 5835 return true; | 5843 return true; |
| 5836 } | 5844 } |
| 5837 | 5845 |
| 5838 | 5846 |
| 5839 void HGraphBuilder::VisitProperty(Property* expr) { | 5847 void HGraphBuilder::VisitProperty(Property* expr) { |
| 5840 ASSERT(!HasStackOverflow()); | 5848 ASSERT(!HasStackOverflow()); |
| 5841 ASSERT(current_block() != NULL); | 5849 ASSERT(current_block() != NULL); |
| 5842 ASSERT(current_block()->HasPredecessor()); | 5850 ASSERT(current_block()->HasPredecessor()); |
| 5843 expr->RecordTypeFeedback(oracle()); | 5851 expr->RecordTypeFeedback(oracle(), zone()); |
| 5844 | 5852 |
| 5845 if (TryArgumentsAccess(expr)) return; | 5853 if (TryArgumentsAccess(expr)) return; |
| 5846 | 5854 |
| 5847 CHECK_ALIVE(VisitForValue(expr->obj())); | 5855 CHECK_ALIVE(VisitForValue(expr->obj())); |
| 5848 | 5856 |
| 5849 HInstruction* instr = NULL; | 5857 HInstruction* instr = NULL; |
| 5850 if (expr->AsProperty()->IsArrayLength()) { | 5858 if (expr->AsProperty()->IsArrayLength()) { |
| 5851 HValue* array = Pop(); | 5859 HValue* array = Pop(); |
| 5852 AddInstruction(new(zone()) HCheckNonSmi(array)); | 5860 AddInstruction(new(zone()) HCheckNonSmi(array)); |
| 5853 HInstruction* mapcheck = | 5861 HInstruction* mapcheck = |
| 5854 AddInstruction(HCheckInstanceType::NewIsJSArray(array)); | 5862 AddInstruction(HCheckInstanceType::NewIsJSArray(array, zone())); |
| 5855 instr = new(zone()) HJSArrayLength(array, mapcheck); | 5863 instr = new(zone()) HJSArrayLength(array, mapcheck); |
| 5856 | 5864 |
| 5857 } else if (expr->IsStringLength()) { | 5865 } else if (expr->IsStringLength()) { |
| 5858 HValue* string = Pop(); | 5866 HValue* string = Pop(); |
| 5859 AddInstruction(new(zone()) HCheckNonSmi(string)); | 5867 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 5860 AddInstruction(HCheckInstanceType::NewIsString(string)); | 5868 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 5861 instr = new(zone()) HStringLength(string); | 5869 instr = new(zone()) HStringLength(string); |
| 5862 } else if (expr->IsStringAccess()) { | 5870 } else if (expr->IsStringAccess()) { |
| 5863 CHECK_ALIVE(VisitForValue(expr->key())); | 5871 CHECK_ALIVE(VisitForValue(expr->key())); |
| 5864 HValue* index = Pop(); | 5872 HValue* index = Pop(); |
| 5865 HValue* string = Pop(); | 5873 HValue* string = Pop(); |
| 5866 HValue* context = environment()->LookupContext(); | 5874 HValue* context = environment()->LookupContext(); |
| 5867 HStringCharCodeAt* char_code = | 5875 HStringCharCodeAt* char_code = |
| 5868 BuildStringCharCodeAt(context, string, index); | 5876 BuildStringCharCodeAt(context, string, index); |
| 5869 AddInstruction(char_code); | 5877 AddInstruction(char_code); |
| 5870 instr = new(zone()) HStringCharFromCode(context, char_code); | 5878 instr = new(zone()) HStringCharFromCode(context, char_code); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5918 | 5926 |
| 5919 void HGraphBuilder::AddCheckConstantFunction(Call* expr, | 5927 void HGraphBuilder::AddCheckConstantFunction(Call* expr, |
| 5920 HValue* receiver, | 5928 HValue* receiver, |
| 5921 Handle<Map> receiver_map, | 5929 Handle<Map> receiver_map, |
| 5922 bool smi_and_map_check) { | 5930 bool smi_and_map_check) { |
| 5923 // Constant functions have the nice property that the map will change if they | 5931 // Constant functions have the nice property that the map will change if they |
| 5924 // are overwritten. Therefore it is enough to check the map of the holder and | 5932 // are overwritten. Therefore it is enough to check the map of the holder and |
| 5925 // its prototypes. | 5933 // its prototypes. |
| 5926 if (smi_and_map_check) { | 5934 if (smi_and_map_check) { |
| 5927 AddInstruction(new(zone()) HCheckNonSmi(receiver)); | 5935 AddInstruction(new(zone()) HCheckNonSmi(receiver)); |
| 5928 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map)); | 5936 AddInstruction(HCheckMaps::NewWithTransitions(receiver, receiver_map, |
| 5937 zone())); |
| 5929 } | 5938 } |
| 5930 if (!expr->holder().is_null()) { | 5939 if (!expr->holder().is_null()) { |
| 5931 AddInstruction(new(zone()) HCheckPrototypeMaps( | 5940 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 5932 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), | 5941 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), |
| 5933 expr->holder())); | 5942 expr->holder())); |
| 5934 } | 5943 } |
| 5935 } | 5944 } |
| 5936 | 5945 |
| 5937 | 5946 |
| 5938 class FunctionSorter { | 5947 class FunctionSorter { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6253 // generating the optimized inline code. | 6262 // generating the optimized inline code. |
| 6254 target_info.EnableDeoptimizationSupport(); | 6263 target_info.EnableDeoptimizationSupport(); |
| 6255 if (!FullCodeGenerator::MakeCode(&target_info)) { | 6264 if (!FullCodeGenerator::MakeCode(&target_info)) { |
| 6256 TraceInline(target, caller, "could not generate deoptimization info"); | 6265 TraceInline(target, caller, "could not generate deoptimization info"); |
| 6257 return false; | 6266 return false; |
| 6258 } | 6267 } |
| 6259 if (target_shared->scope_info() == ScopeInfo::Empty()) { | 6268 if (target_shared->scope_info() == ScopeInfo::Empty()) { |
| 6260 // The scope info might not have been set if a lazily compiled | 6269 // The scope info might not have been set if a lazily compiled |
| 6261 // function is inlined before being called for the first time. | 6270 // function is inlined before being called for the first time. |
| 6262 Handle<ScopeInfo> target_scope_info = | 6271 Handle<ScopeInfo> target_scope_info = |
| 6263 ScopeInfo::Create(target_info.scope()); | 6272 ScopeInfo::Create(target_info.scope(), zone()); |
| 6264 target_shared->set_scope_info(*target_scope_info); | 6273 target_shared->set_scope_info(*target_scope_info); |
| 6265 } | 6274 } |
| 6266 target_shared->EnableDeoptimizationSupport(*target_info.code()); | 6275 target_shared->EnableDeoptimizationSupport(*target_info.code()); |
| 6267 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, | 6276 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, |
| 6268 &target_info, | 6277 &target_info, |
| 6269 target_shared); | 6278 target_shared); |
| 6270 } | 6279 } |
| 6271 | 6280 |
| 6272 // ---------------------------------------------------------------- | 6281 // ---------------------------------------------------------------- |
| 6273 // After this point, we've made a decision to inline this function (so | 6282 // After this point, we've made a decision to inline this function (so |
| 6274 // TryInline should always return true). | 6283 // TryInline should always return true). |
| 6275 | 6284 |
| 6276 // Save the pending call context and type feedback oracle. Set up new ones | 6285 // Save the pending call context and type feedback oracle. Set up new ones |
| 6277 // for the inlined function. | 6286 // for the inlined function. |
| 6278 ASSERT(target_shared->has_deoptimization_support()); | 6287 ASSERT(target_shared->has_deoptimization_support()); |
| 6279 TypeFeedbackOracle target_oracle( | 6288 TypeFeedbackOracle target_oracle( |
| 6280 Handle<Code>(target_shared->code()), | 6289 Handle<Code>(target_shared->code()), |
| 6281 Handle<Context>(target->context()->global_context()), | 6290 Handle<Context>(target->context()->global_context()), |
| 6282 isolate()); | 6291 isolate(), |
| 6292 zone()); |
| 6283 // The function state is new-allocated because we need to delete it | 6293 // The function state is new-allocated because we need to delete it |
| 6284 // in two different places. | 6294 // in two different places. |
| 6285 FunctionState* target_state = new FunctionState( | 6295 FunctionState* target_state = new FunctionState( |
| 6286 this, &target_info, &target_oracle, return_handling); | 6296 this, &target_info, &target_oracle, return_handling); |
| 6287 | 6297 |
| 6288 HConstant* undefined = graph()->GetConstantUndefined(); | 6298 HConstant* undefined = graph()->GetConstantUndefined(); |
| 6289 HEnvironment* inner_env = | 6299 HEnvironment* inner_env = |
| 6290 environment()->CopyForInlining(target, | 6300 environment()->CopyForInlining(target, |
| 6291 arguments->length(), | 6301 arguments->length(), |
| 6292 function, | 6302 function, |
| 6293 undefined, | 6303 undefined, |
| 6294 call_kind, | 6304 call_kind, |
| 6295 function_state()->is_construct()); | 6305 function_state()->is_construct()); |
| 6296 #ifdef V8_TARGET_ARCH_IA32 | 6306 #ifdef V8_TARGET_ARCH_IA32 |
| 6297 // IA32 only, overwrite the caller's context in the deoptimization | 6307 // IA32 only, overwrite the caller's context in the deoptimization |
| 6298 // environment with the correct one. | 6308 // environment with the correct one. |
| 6299 // | 6309 // |
| 6300 // TODO(kmillikin): implement the same inlining on other platforms so we | 6310 // TODO(kmillikin): implement the same inlining on other platforms so we |
| 6301 // can remove the unsightly ifdefs in this function. | 6311 // can remove the unsightly ifdefs in this function. |
| 6302 HConstant* context = new HConstant(Handle<Context>(target->context()), | 6312 HConstant* context = |
| 6303 Representation::Tagged()); | 6313 new(zone()) HConstant(Handle<Context>(target->context()), |
| 6314 Representation::Tagged()); |
| 6304 AddInstruction(context); | 6315 AddInstruction(context); |
| 6305 inner_env->BindContext(context); | 6316 inner_env->BindContext(context); |
| 6306 #endif | 6317 #endif |
| 6307 | 6318 |
| 6308 AddSimulate(return_id); | 6319 AddSimulate(return_id); |
| 6309 current_block()->UpdateEnvironment(inner_env); | 6320 current_block()->UpdateEnvironment(inner_env); |
| 6310 | 6321 |
| 6311 ZoneList<HValue*>* arguments_values = NULL; | 6322 ZoneList<HValue*>* arguments_values = NULL; |
| 6312 | 6323 |
| 6313 // If the function uses arguments copy current arguments values | 6324 // If the function uses arguments copy current arguments values |
| 6314 // to use them for materialization. | 6325 // to use them for materialization. |
| 6315 if (function->scope()->arguments() != NULL) { | 6326 if (function->scope()->arguments() != NULL) { |
| 6316 HEnvironment* arguments_env = inner_env->arguments_environment(); | 6327 HEnvironment* arguments_env = inner_env->arguments_environment(); |
| 6317 int arguments_count = arguments_env->parameter_count(); | 6328 int arguments_count = arguments_env->parameter_count(); |
| 6318 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count); | 6329 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
| 6319 for (int i = 0; i < arguments_count; i++) { | 6330 for (int i = 0; i < arguments_count; i++) { |
| 6320 arguments_values->Add(arguments_env->Lookup(i)); | 6331 arguments_values->Add(arguments_env->Lookup(i), zone()); |
| 6321 } | 6332 } |
| 6322 } | 6333 } |
| 6323 | 6334 |
| 6324 HEnterInlined* enter_inlined = | 6335 HEnterInlined* enter_inlined = |
| 6325 new(zone()) HEnterInlined(target, | 6336 new(zone()) HEnterInlined(target, |
| 6326 arguments->length(), | 6337 arguments->length(), |
| 6327 function, | 6338 function, |
| 6328 call_kind, | 6339 call_kind, |
| 6329 function_state()->is_construct(), | 6340 function_state()->is_construct(), |
| 6330 function->scope()->arguments(), | 6341 function->scope()->arguments(), |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6905 Drop(argument_count); | 6916 Drop(argument_count); |
| 6906 } | 6917 } |
| 6907 | 6918 |
| 6908 } else if (expr->IsMonomorphic()) { | 6919 } else if (expr->IsMonomorphic()) { |
| 6909 // The function is on the stack in the unoptimized code during | 6920 // The function is on the stack in the unoptimized code during |
| 6910 // evaluation of the arguments. | 6921 // evaluation of the arguments. |
| 6911 CHECK_ALIVE(VisitForValue(expr->expression())); | 6922 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 6912 HValue* function = Top(); | 6923 HValue* function = Top(); |
| 6913 HValue* context = environment()->LookupContext(); | 6924 HValue* context = environment()->LookupContext(); |
| 6914 HGlobalObject* global = new(zone()) HGlobalObject(context); | 6925 HGlobalObject* global = new(zone()) HGlobalObject(context); |
| 6926 AddInstruction(global); |
| 6915 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); | 6927 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global); |
| 6916 AddInstruction(global); | |
| 6917 PushAndAdd(receiver); | 6928 PushAndAdd(receiver); |
| 6918 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 6929 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 6919 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 6930 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); |
| 6920 | 6931 |
| 6921 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. | 6932 if (TryInlineBuiltinFunctionCall(expr, true)) { // Drop the function. |
| 6922 if (FLAG_trace_inlining) { | 6933 if (FLAG_trace_inlining) { |
| 6923 PrintF("Inlining builtin "); | 6934 PrintF("Inlining builtin "); |
| 6924 expr->target()->ShortPrint(); | 6935 expr->target()->ShortPrint(); |
| 6925 PrintF("\n"); | 6936 PrintF("\n"); |
| 6926 } | 6937 } |
| 6927 return; | 6938 return; |
| 6928 } | 6939 } |
| 6929 | 6940 |
| 6930 if (TryInlineCall(expr, true)) { // Drop function from environment. | 6941 if (TryInlineCall(expr, true)) { // Drop function from environment. |
| 6931 return; | 6942 return; |
| 6932 } else { | 6943 } else { |
| 6933 call = PreProcessCall( | 6944 call = PreProcessCall( |
| 6934 new(zone()) HInvokeFunction(context, | 6945 new(zone()) HInvokeFunction(context, |
| 6935 function, | 6946 function, |
| 6936 expr->target(), | 6947 expr->target(), |
| 6937 argument_count)); | 6948 argument_count)); |
| 6938 Drop(1); // The function. | 6949 Drop(1); // The function. |
| 6939 } | 6950 } |
| 6940 | 6951 |
| 6941 } else { | 6952 } else { |
| 6942 CHECK_ALIVE(VisitForValue(expr->expression())); | 6953 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 6943 HValue* function = Top(); | 6954 HValue* function = Top(); |
| 6944 HValue* context = environment()->LookupContext(); | 6955 HValue* context = environment()->LookupContext(); |
| 6945 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 6956 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
| 6957 AddInstruction(global_object); |
| 6946 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); | 6958 HGlobalReceiver* receiver = new(zone()) HGlobalReceiver(global_object); |
| 6947 AddInstruction(global_object); | |
| 6948 AddInstruction(receiver); | 6959 AddInstruction(receiver); |
| 6949 PushAndAdd(new(zone()) HPushArgument(receiver)); | 6960 PushAndAdd(new(zone()) HPushArgument(receiver)); |
| 6950 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 6961 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
| 6951 | 6962 |
| 6952 call = new(zone()) HCallFunction(context, function, argument_count); | 6963 call = new(zone()) HCallFunction(context, function, argument_count); |
| 6953 Drop(argument_count + 1); | 6964 Drop(argument_count + 1); |
| 6954 } | 6965 } |
| 6955 } | 6966 } |
| 6956 | 6967 |
| 6957 call->set_position(expr->position()); | 6968 call->set_position(expr->position()); |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7343 break; | 7354 break; |
| 7344 } | 7355 } |
| 7345 | 7356 |
| 7346 case Variable::LOOKUP: | 7357 case Variable::LOOKUP: |
| 7347 return Bailout("lookup variable in count operation"); | 7358 return Bailout("lookup variable in count operation"); |
| 7348 } | 7359 } |
| 7349 | 7360 |
| 7350 } else { | 7361 } else { |
| 7351 // Argument of the count operation is a property. | 7362 // Argument of the count operation is a property. |
| 7352 ASSERT(prop != NULL); | 7363 ASSERT(prop != NULL); |
| 7353 prop->RecordTypeFeedback(oracle()); | 7364 prop->RecordTypeFeedback(oracle(), zone()); |
| 7354 | 7365 |
| 7355 if (prop->key()->IsPropertyName()) { | 7366 if (prop->key()->IsPropertyName()) { |
| 7356 // Named property. | 7367 // Named property. |
| 7357 if (returns_original_input) Push(graph_->GetConstantUndefined()); | 7368 if (returns_original_input) Push(graph_->GetConstantUndefined()); |
| 7358 | 7369 |
| 7359 CHECK_ALIVE(VisitForValue(prop->obj())); | 7370 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7360 HValue* obj = Top(); | 7371 HValue* obj = Top(); |
| 7361 | 7372 |
| 7362 HInstruction* load = NULL; | 7373 HInstruction* load = NULL; |
| 7363 if (prop->IsMonomorphic()) { | 7374 if (prop->IsMonomorphic()) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7397 HValue* load = HandleKeyedElementAccess( | 7408 HValue* load = HandleKeyedElementAccess( |
| 7398 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, | 7409 obj, key, NULL, prop, expr->CountId(), RelocInfo::kNoPosition, |
| 7399 false, // is_store | 7410 false, // is_store |
| 7400 &has_side_effects); | 7411 &has_side_effects); |
| 7401 Push(load); | 7412 Push(load); |
| 7402 if (has_side_effects) AddSimulate(expr->CountId()); | 7413 if (has_side_effects) AddSimulate(expr->CountId()); |
| 7403 | 7414 |
| 7404 after = BuildIncrement(returns_original_input, expr); | 7415 after = BuildIncrement(returns_original_input, expr); |
| 7405 input = Pop(); | 7416 input = Pop(); |
| 7406 | 7417 |
| 7407 expr->RecordTypeFeedback(oracle()); | 7418 expr->RecordTypeFeedback(oracle(), zone()); |
| 7408 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), | 7419 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), |
| 7409 RelocInfo::kNoPosition, | 7420 RelocInfo::kNoPosition, |
| 7410 true, // is_store | 7421 true, // is_store |
| 7411 &has_side_effects); | 7422 &has_side_effects); |
| 7412 | 7423 |
| 7413 // Drop the key from the bailout environment. Overwrite the receiver | 7424 // Drop the key from the bailout environment. Overwrite the receiver |
| 7414 // with the result of the operation, and the placeholder with the | 7425 // with the result of the operation, and the placeholder with the |
| 7415 // original value if necessary. | 7426 // original value if necessary. |
| 7416 Drop(1); | 7427 Drop(1); |
| 7417 environment()->SetExpressionStackAt(0, after); | 7428 environment()->SetExpressionStackAt(0, after); |
| 7418 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 7429 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
| 7419 ASSERT(has_side_effects); // Stores always have side effects. | 7430 ASSERT(has_side_effects); // Stores always have side effects. |
| 7420 AddSimulate(expr->AssignmentId()); | 7431 AddSimulate(expr->AssignmentId()); |
| 7421 } | 7432 } |
| 7422 } | 7433 } |
| 7423 | 7434 |
| 7424 Drop(returns_original_input ? 2 : 1); | 7435 Drop(returns_original_input ? 2 : 1); |
| 7425 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); | 7436 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); |
| 7426 } | 7437 } |
| 7427 | 7438 |
| 7428 | 7439 |
| 7429 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, | 7440 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, |
| 7430 HValue* string, | 7441 HValue* string, |
| 7431 HValue* index) { | 7442 HValue* index) { |
| 7432 AddInstruction(new(zone()) HCheckNonSmi(string)); | 7443 AddInstruction(new(zone()) HCheckNonSmi(string)); |
| 7433 AddInstruction(HCheckInstanceType::NewIsString(string)); | 7444 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
| 7434 HStringLength* length = new(zone()) HStringLength(string); | 7445 HStringLength* length = new(zone()) HStringLength(string); |
| 7435 AddInstruction(length); | 7446 AddInstruction(length); |
| 7436 HInstruction* checked_index = | 7447 HInstruction* checked_index = |
| 7437 AddInstruction(new(zone()) HBoundsCheck(index, length)); | 7448 AddInstruction(new(zone()) HBoundsCheck(index, length)); |
| 7438 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 7449 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
| 7439 } | 7450 } |
| 7440 | 7451 |
| 7441 | 7452 |
| 7442 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, | 7453 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, |
| 7443 HValue* left, | 7454 HValue* left, |
| 7444 HValue* right) { | 7455 HValue* right) { |
| 7445 HValue* context = environment()->LookupContext(); | 7456 HValue* context = environment()->LookupContext(); |
| 7446 TypeInfo info = oracle()->BinaryType(expr); | 7457 TypeInfo info = oracle()->BinaryType(expr); |
| 7447 if (info.IsUninitialized()) { | 7458 if (info.IsUninitialized()) { |
| 7448 AddInstruction(new(zone()) HSoftDeoptimize); | 7459 AddInstruction(new(zone()) HSoftDeoptimize); |
| 7449 current_block()->MarkAsDeoptimizing(); | 7460 current_block()->MarkAsDeoptimizing(); |
| 7450 info = TypeInfo::Unknown(); | 7461 info = TypeInfo::Unknown(); |
| 7451 } | 7462 } |
| 7452 HInstruction* instr = NULL; | 7463 HInstruction* instr = NULL; |
| 7453 switch (expr->op()) { | 7464 switch (expr->op()) { |
| 7454 case Token::ADD: | 7465 case Token::ADD: |
| 7455 if (info.IsString()) { | 7466 if (info.IsString()) { |
| 7456 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7467 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7457 AddInstruction(HCheckInstanceType::NewIsString(left)); | 7468 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
| 7458 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7469 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7459 AddInstruction(HCheckInstanceType::NewIsString(right)); | 7470 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
| 7460 instr = new(zone()) HStringAdd(context, left, right); | 7471 instr = new(zone()) HStringAdd(context, left, right); |
| 7461 } else { | 7472 } else { |
| 7462 instr = HAdd::NewHAdd(zone(), context, left, right); | 7473 instr = HAdd::NewHAdd(zone(), context, left, right); |
| 7463 } | 7474 } |
| 7464 break; | 7475 break; |
| 7465 case Token::SUB: | 7476 case Token::SUB: |
| 7466 instr = HSub::NewHSub(zone(), context, left, right); | 7477 instr = HSub::NewHSub(zone(), context, left, right); |
| 7467 break; | 7478 break; |
| 7468 case Token::MUL: | 7479 case Token::MUL: |
| 7469 instr = HMul::NewHMul(zone(), context, left, right); | 7480 instr = HMul::NewHMul(zone(), context, left, right); |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7849 result->set_position(expr->position()); | 7860 result->set_position(expr->position()); |
| 7850 return ast_context()->ReturnInstruction(result, expr->id()); | 7861 return ast_context()->ReturnInstruction(result, expr->id()); |
| 7851 } else if (type_info.IsNonPrimitive()) { | 7862 } else if (type_info.IsNonPrimitive()) { |
| 7852 switch (op) { | 7863 switch (op) { |
| 7853 case Token::EQ: | 7864 case Token::EQ: |
| 7854 case Token::EQ_STRICT: { | 7865 case Token::EQ_STRICT: { |
| 7855 // Can we get away with map check and not instance type check? | 7866 // Can we get away with map check and not instance type check? |
| 7856 Handle<Map> map = oracle()->GetCompareMap(expr); | 7867 Handle<Map> map = oracle()->GetCompareMap(expr); |
| 7857 if (!map.is_null()) { | 7868 if (!map.is_null()) { |
| 7858 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7869 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7859 AddInstruction(HCheckMaps::NewWithTransitions(left, map)); | 7870 AddInstruction(HCheckMaps::NewWithTransitions(left, map, zone())); |
| 7860 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7871 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7861 AddInstruction(HCheckMaps::NewWithTransitions(right, map)); | 7872 AddInstruction(HCheckMaps::NewWithTransitions(right, map, zone())); |
| 7862 HCompareObjectEqAndBranch* result = | 7873 HCompareObjectEqAndBranch* result = |
| 7863 new(zone()) HCompareObjectEqAndBranch(left, right); | 7874 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 7864 result->set_position(expr->position()); | 7875 result->set_position(expr->position()); |
| 7865 return ast_context()->ReturnControl(result, expr->id()); | 7876 return ast_context()->ReturnControl(result, expr->id()); |
| 7866 } else { | 7877 } else { |
| 7867 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7878 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7868 AddInstruction(HCheckInstanceType::NewIsSpecObject(left)); | 7879 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); |
| 7869 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7880 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7870 AddInstruction(HCheckInstanceType::NewIsSpecObject(right)); | 7881 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); |
| 7871 HCompareObjectEqAndBranch* result = | 7882 HCompareObjectEqAndBranch* result = |
| 7872 new(zone()) HCompareObjectEqAndBranch(left, right); | 7883 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 7873 result->set_position(expr->position()); | 7884 result->set_position(expr->position()); |
| 7874 return ast_context()->ReturnControl(result, expr->id()); | 7885 return ast_context()->ReturnControl(result, expr->id()); |
| 7875 } | 7886 } |
| 7876 } | 7887 } |
| 7877 default: | 7888 default: |
| 7878 return Bailout("Unsupported non-primitive compare"); | 7889 return Bailout("Unsupported non-primitive compare"); |
| 7879 } | 7890 } |
| 7880 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && | 7891 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && |
| 7881 (op == Token::EQ || op == Token::EQ_STRICT)) { | 7892 (op == Token::EQ || op == Token::EQ_STRICT)) { |
| 7882 AddInstruction(new(zone()) HCheckNonSmi(left)); | 7893 AddInstruction(new(zone()) HCheckNonSmi(left)); |
| 7883 AddInstruction(HCheckInstanceType::NewIsSymbol(left)); | 7894 AddInstruction(HCheckInstanceType::NewIsSymbol(left, zone())); |
| 7884 AddInstruction(new(zone()) HCheckNonSmi(right)); | 7895 AddInstruction(new(zone()) HCheckNonSmi(right)); |
| 7885 AddInstruction(HCheckInstanceType::NewIsSymbol(right)); | 7896 AddInstruction(HCheckInstanceType::NewIsSymbol(right, 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 Representation r = ToRepresentation(type_info); | 7902 Representation r = ToRepresentation(type_info); |
| 7892 if (r.IsTagged()) { | 7903 if (r.IsTagged()) { |
| 7893 HCompareGeneric* result = | 7904 HCompareGeneric* result = |
| 7894 new(zone()) HCompareGeneric(context, left, right, op); | 7905 new(zone()) HCompareGeneric(context, left, right, op); |
| 7895 result->set_position(expr->position()); | 7906 result->set_position(expr->position()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7947 } | 7958 } |
| 7948 | 7959 |
| 7949 | 7960 |
| 7950 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { | 7961 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) { |
| 7951 VariableProxy* proxy = declaration->proxy(); | 7962 VariableProxy* proxy = declaration->proxy(); |
| 7952 VariableMode mode = declaration->mode(); | 7963 VariableMode mode = declaration->mode(); |
| 7953 Variable* variable = proxy->var(); | 7964 Variable* variable = proxy->var(); |
| 7954 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; | 7965 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; |
| 7955 switch (variable->location()) { | 7966 switch (variable->location()) { |
| 7956 case Variable::UNALLOCATED: | 7967 case Variable::UNALLOCATED: |
| 7957 globals_.Add(variable->name()); | 7968 globals_.Add(variable->name(), zone()); |
| 7958 globals_.Add(variable->binding_needs_init() | 7969 globals_.Add(variable->binding_needs_init() |
| 7959 ? isolate()->factory()->the_hole_value() | 7970 ? isolate()->factory()->the_hole_value() |
| 7960 : isolate()->factory()->undefined_value()); | 7971 : isolate()->factory()->undefined_value(), zone()); |
| 7961 return; | 7972 return; |
| 7962 case Variable::PARAMETER: | 7973 case Variable::PARAMETER: |
| 7963 case Variable::LOCAL: | 7974 case Variable::LOCAL: |
| 7964 if (hole_init) { | 7975 if (hole_init) { |
| 7965 HValue* value = graph()->GetConstantHole(); | 7976 HValue* value = graph()->GetConstantHole(); |
| 7966 environment()->Bind(variable, value); | 7977 environment()->Bind(variable, value); |
| 7967 } | 7978 } |
| 7968 break; | 7979 break; |
| 7969 case Variable::CONTEXT: | 7980 case Variable::CONTEXT: |
| 7970 if (hole_init) { | 7981 if (hole_init) { |
| 7971 HValue* value = graph()->GetConstantHole(); | 7982 HValue* value = graph()->GetConstantHole(); |
| 7972 HValue* context = environment()->LookupContext(); | 7983 HValue* context = environment()->LookupContext(); |
| 7973 HStoreContextSlot* store = new HStoreContextSlot( | 7984 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
| 7974 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 7985 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 7975 AddInstruction(store); | 7986 AddInstruction(store); |
| 7976 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 7987 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
| 7977 } | 7988 } |
| 7978 break; | 7989 break; |
| 7979 case Variable::LOOKUP: | 7990 case Variable::LOOKUP: |
| 7980 return Bailout("unsupported lookup slot in declaration"); | 7991 return Bailout("unsupported lookup slot in declaration"); |
| 7981 } | 7992 } |
| 7982 } | 7993 } |
| 7983 | 7994 |
| 7984 | 7995 |
| 7985 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { | 7996 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { |
| 7986 VariableProxy* proxy = declaration->proxy(); | 7997 VariableProxy* proxy = declaration->proxy(); |
| 7987 Variable* variable = proxy->var(); | 7998 Variable* variable = proxy->var(); |
| 7988 switch (variable->location()) { | 7999 switch (variable->location()) { |
| 7989 case Variable::UNALLOCATED: { | 8000 case Variable::UNALLOCATED: { |
| 7990 globals_.Add(variable->name()); | 8001 globals_.Add(variable->name(), zone()); |
| 7991 Handle<SharedFunctionInfo> function = | 8002 Handle<SharedFunctionInfo> function = |
| 7992 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); | 8003 Compiler::BuildFunctionInfo(declaration->fun(), info()->script()); |
| 7993 // Check for stack-overflow exception. | 8004 // Check for stack-overflow exception. |
| 7994 if (function.is_null()) return SetStackOverflow(); | 8005 if (function.is_null()) return SetStackOverflow(); |
| 7995 globals_.Add(function); | 8006 globals_.Add(function, zone()); |
| 7996 return; | 8007 return; |
| 7997 } | 8008 } |
| 7998 case Variable::PARAMETER: | 8009 case Variable::PARAMETER: |
| 7999 case Variable::LOCAL: { | 8010 case Variable::LOCAL: { |
| 8000 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8011 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 8001 HValue* value = Pop(); | 8012 HValue* value = Pop(); |
| 8002 environment()->Bind(variable, value); | 8013 environment()->Bind(variable, value); |
| 8003 break; | 8014 break; |
| 8004 } | 8015 } |
| 8005 case Variable::CONTEXT: { | 8016 case Variable::CONTEXT: { |
| 8006 CHECK_ALIVE(VisitForValue(declaration->fun())); | 8017 CHECK_ALIVE(VisitForValue(declaration->fun())); |
| 8007 HValue* value = Pop(); | 8018 HValue* value = Pop(); |
| 8008 HValue* context = environment()->LookupContext(); | 8019 HValue* context = environment()->LookupContext(); |
| 8009 HStoreContextSlot* store = new HStoreContextSlot( | 8020 HStoreContextSlot* store = new(zone()) HStoreContextSlot( |
| 8010 context, variable->index(), HStoreContextSlot::kNoCheck, value); | 8021 context, variable->index(), HStoreContextSlot::kNoCheck, value); |
| 8011 AddInstruction(store); | 8022 AddInstruction(store); |
| 8012 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); | 8023 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); |
| 8013 break; | 8024 break; |
| 8014 } | 8025 } |
| 8015 case Variable::LOOKUP: | 8026 case Variable::LOOKUP: |
| 8016 return Bailout("unsupported lookup slot in declaration"); | 8027 return Bailout("unsupported lookup slot in declaration"); |
| 8017 } | 8028 } |
| 8018 } | 8029 } |
| 8019 | 8030 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8245 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); | 8256 HBasicBlock* if_js_value = graph()->CreateBasicBlock(); |
| 8246 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); | 8257 HBasicBlock* not_js_value = graph()->CreateBasicBlock(); |
| 8247 typecheck->SetSuccessorAt(0, if_js_value); | 8258 typecheck->SetSuccessorAt(0, if_js_value); |
| 8248 typecheck->SetSuccessorAt(1, not_js_value); | 8259 typecheck->SetSuccessorAt(1, not_js_value); |
| 8249 current_block()->Finish(typecheck); | 8260 current_block()->Finish(typecheck); |
| 8250 not_js_value->Goto(join); | 8261 not_js_value->Goto(join); |
| 8251 | 8262 |
| 8252 // Create in-object property store to kValueOffset. | 8263 // Create in-object property store to kValueOffset. |
| 8253 set_current_block(if_js_value); | 8264 set_current_block(if_js_value); |
| 8254 Handle<String> name = isolate()->factory()->undefined_symbol(); | 8265 Handle<String> name = isolate()->factory()->undefined_symbol(); |
| 8255 AddInstruction(new HStoreNamedField(object, | 8266 AddInstruction(new(zone()) HStoreNamedField(object, |
| 8256 name, | 8267 name, |
| 8257 value, | 8268 value, |
| 8258 true, // in-object store. | 8269 true, // in-object store. |
| 8259 JSValue::kValueOffset)); | 8270 JSValue::kValueOffset)); |
| 8260 if_js_value->Goto(join); | 8271 if_js_value->Goto(join); |
| 8261 join->SetJoinId(call->id()); | 8272 join->SetJoinId(call->id()); |
| 8262 set_current_block(join); | 8273 set_current_block(join); |
| 8263 return ast_context()->ReturnValue(value); | 8274 return ast_context()->ReturnValue(value); |
| 8264 } | 8275 } |
| 8265 | 8276 |
| 8266 | 8277 |
| 8267 // Fast support for charCodeAt(n). | 8278 // Fast support for charCodeAt(n). |
| 8268 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 8279 void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
| 8269 ASSERT(call->arguments()->length() == 2); | 8280 ASSERT(call->arguments()->length() == 2); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8537 return Bailout("inlined runtime function: FastAsciiArrayJoin"); | 8548 return Bailout("inlined runtime function: FastAsciiArrayJoin"); |
| 8538 } | 8549 } |
| 8539 | 8550 |
| 8540 | 8551 |
| 8541 #undef CHECK_BAILOUT | 8552 #undef CHECK_BAILOUT |
| 8542 #undef CHECK_ALIVE | 8553 #undef CHECK_ALIVE |
| 8543 | 8554 |
| 8544 | 8555 |
| 8545 HEnvironment::HEnvironment(HEnvironment* outer, | 8556 HEnvironment::HEnvironment(HEnvironment* outer, |
| 8546 Scope* scope, | 8557 Scope* scope, |
| 8547 Handle<JSFunction> closure) | 8558 Handle<JSFunction> closure, |
| 8559 Zone* zone) |
| 8548 : closure_(closure), | 8560 : closure_(closure), |
| 8549 values_(0), | 8561 values_(0, zone), |
| 8550 assigned_variables_(4), | 8562 assigned_variables_(4, zone), |
| 8551 frame_type_(JS_FUNCTION), | 8563 frame_type_(JS_FUNCTION), |
| 8552 parameter_count_(0), | 8564 parameter_count_(0), |
| 8553 specials_count_(1), | 8565 specials_count_(1), |
| 8554 local_count_(0), | 8566 local_count_(0), |
| 8555 outer_(outer), | 8567 outer_(outer), |
| 8556 pop_count_(0), | 8568 pop_count_(0), |
| 8557 push_count_(0), | 8569 push_count_(0), |
| 8558 ast_id_(AstNode::kNoNumber) { | 8570 ast_id_(AstNode::kNoNumber), |
| 8571 zone_(zone) { |
| 8559 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 8572 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
| 8560 } | 8573 } |
| 8561 | 8574 |
| 8562 | 8575 |
| 8563 HEnvironment::HEnvironment(const HEnvironment* other) | 8576 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
| 8564 : values_(0), | 8577 : values_(0, zone), |
| 8565 assigned_variables_(0), | 8578 assigned_variables_(0, zone), |
| 8566 frame_type_(JS_FUNCTION), | 8579 frame_type_(JS_FUNCTION), |
| 8567 parameter_count_(0), | 8580 parameter_count_(0), |
| 8568 specials_count_(1), | 8581 specials_count_(1), |
| 8569 local_count_(0), | 8582 local_count_(0), |
| 8570 outer_(NULL), | 8583 outer_(NULL), |
| 8571 pop_count_(0), | 8584 pop_count_(0), |
| 8572 push_count_(0), | 8585 push_count_(0), |
| 8573 ast_id_(other->ast_id()) { | 8586 ast_id_(other->ast_id()), |
| 8587 zone_(zone) { |
| 8574 Initialize(other); | 8588 Initialize(other); |
| 8575 } | 8589 } |
| 8576 | 8590 |
| 8577 | 8591 |
| 8578 HEnvironment::HEnvironment(HEnvironment* outer, | 8592 HEnvironment::HEnvironment(HEnvironment* outer, |
| 8579 Handle<JSFunction> closure, | 8593 Handle<JSFunction> closure, |
| 8580 FrameType frame_type, | 8594 FrameType frame_type, |
| 8581 int arguments) | 8595 int arguments, |
| 8596 Zone* zone) |
| 8582 : closure_(closure), | 8597 : closure_(closure), |
| 8583 values_(arguments), | 8598 values_(arguments, zone), |
| 8584 assigned_variables_(0), | 8599 assigned_variables_(0, zone), |
| 8585 frame_type_(frame_type), | 8600 frame_type_(frame_type), |
| 8586 parameter_count_(arguments), | 8601 parameter_count_(arguments), |
| 8587 local_count_(0), | 8602 local_count_(0), |
| 8588 outer_(outer), | 8603 outer_(outer), |
| 8589 pop_count_(0), | 8604 pop_count_(0), |
| 8590 push_count_(0), | 8605 push_count_(0), |
| 8591 ast_id_(AstNode::kNoNumber) { | 8606 ast_id_(AstNode::kNoNumber), |
| 8607 zone_(zone) { |
| 8592 } | 8608 } |
| 8593 | 8609 |
| 8594 | 8610 |
| 8595 void HEnvironment::Initialize(int parameter_count, | 8611 void HEnvironment::Initialize(int parameter_count, |
| 8596 int local_count, | 8612 int local_count, |
| 8597 int stack_height) { | 8613 int stack_height) { |
| 8598 parameter_count_ = parameter_count; | 8614 parameter_count_ = parameter_count; |
| 8599 local_count_ = local_count; | 8615 local_count_ = local_count; |
| 8600 | 8616 |
| 8601 // Avoid reallocating the temporaries' backing store on the first Push. | 8617 // Avoid reallocating the temporaries' backing store on the first Push. |
| 8602 int total = parameter_count + specials_count_ + local_count + stack_height; | 8618 int total = parameter_count + specials_count_ + local_count + stack_height; |
| 8603 values_.Initialize(total + 4); | 8619 values_.Initialize(total + 4, zone()); |
| 8604 for (int i = 0; i < total; ++i) values_.Add(NULL); | 8620 for (int i = 0; i < total; ++i) values_.Add(NULL, zone()); |
| 8605 } | 8621 } |
| 8606 | 8622 |
| 8607 | 8623 |
| 8608 void HEnvironment::Initialize(const HEnvironment* other) { | 8624 void HEnvironment::Initialize(const HEnvironment* other) { |
| 8609 closure_ = other->closure(); | 8625 closure_ = other->closure(); |
| 8610 values_.AddAll(other->values_); | 8626 values_.AddAll(other->values_, zone()); |
| 8611 assigned_variables_.AddAll(other->assigned_variables_); | 8627 assigned_variables_.AddAll(other->assigned_variables_, zone()); |
| 8612 frame_type_ = other->frame_type_; | 8628 frame_type_ = other->frame_type_; |
| 8613 parameter_count_ = other->parameter_count_; | 8629 parameter_count_ = other->parameter_count_; |
| 8614 local_count_ = other->local_count_; | 8630 local_count_ = other->local_count_; |
| 8615 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 8631 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
| 8616 pop_count_ = other->pop_count_; | 8632 pop_count_ = other->pop_count_; |
| 8617 push_count_ = other->push_count_; | 8633 push_count_ = other->push_count_; |
| 8618 ast_id_ = other->ast_id_; | 8634 ast_id_ = other->ast_id_; |
| 8619 } | 8635 } |
| 8620 | 8636 |
| 8621 | 8637 |
| 8622 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 8638 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
| 8623 ASSERT(!block->IsLoopHeader()); | 8639 ASSERT(!block->IsLoopHeader()); |
| 8624 ASSERT(values_.length() == other->values_.length()); | 8640 ASSERT(values_.length() == other->values_.length()); |
| 8625 | 8641 |
| 8626 int length = values_.length(); | 8642 int length = values_.length(); |
| 8627 for (int i = 0; i < length; ++i) { | 8643 for (int i = 0; i < length; ++i) { |
| 8628 HValue* value = values_[i]; | 8644 HValue* value = values_[i]; |
| 8629 if (value != NULL && value->IsPhi() && value->block() == block) { | 8645 if (value != NULL && value->IsPhi() && value->block() == block) { |
| 8630 // There is already a phi for the i'th value. | 8646 // There is already a phi for the i'th value. |
| 8631 HPhi* phi = HPhi::cast(value); | 8647 HPhi* phi = HPhi::cast(value); |
| 8632 // Assert index is correct and that we haven't missed an incoming edge. | 8648 // Assert index is correct and that we haven't missed an incoming edge. |
| 8633 ASSERT(phi->merged_index() == i); | 8649 ASSERT(phi->merged_index() == i); |
| 8634 ASSERT(phi->OperandCount() == block->predecessors()->length()); | 8650 ASSERT(phi->OperandCount() == block->predecessors()->length()); |
| 8635 phi->AddInput(other->values_[i]); | 8651 phi->AddInput(other->values_[i]); |
| 8636 } else if (values_[i] != other->values_[i]) { | 8652 } else if (values_[i] != other->values_[i]) { |
| 8637 // There is a fresh value on the incoming edge, a phi is needed. | 8653 // There is a fresh value on the incoming edge, a phi is needed. |
| 8638 ASSERT(values_[i] != NULL && other->values_[i] != NULL); | 8654 ASSERT(values_[i] != NULL && other->values_[i] != NULL); |
| 8639 HPhi* phi = new(block->zone()) HPhi(i); | 8655 HPhi* phi = new(zone()) HPhi(i, zone()); |
| 8640 HValue* old_value = values_[i]; | 8656 HValue* old_value = values_[i]; |
| 8641 for (int j = 0; j < block->predecessors()->length(); j++) { | 8657 for (int j = 0; j < block->predecessors()->length(); j++) { |
| 8642 phi->AddInput(old_value); | 8658 phi->AddInput(old_value); |
| 8643 } | 8659 } |
| 8644 phi->AddInput(other->values_[i]); | 8660 phi->AddInput(other->values_[i]); |
| 8645 this->values_[i] = phi; | 8661 this->values_[i] = phi; |
| 8646 block->AddPhi(phi); | 8662 block->AddPhi(phi); |
| 8647 } | 8663 } |
| 8648 } | 8664 } |
| 8649 } | 8665 } |
| 8650 | 8666 |
| 8651 | 8667 |
| 8652 void HEnvironment::Bind(int index, HValue* value) { | 8668 void HEnvironment::Bind(int index, HValue* value) { |
| 8653 ASSERT(value != NULL); | 8669 ASSERT(value != NULL); |
| 8654 if (!assigned_variables_.Contains(index)) { | 8670 if (!assigned_variables_.Contains(index)) { |
| 8655 assigned_variables_.Add(index); | 8671 assigned_variables_.Add(index, zone()); |
| 8656 } | 8672 } |
| 8657 values_[index] = value; | 8673 values_[index] = value; |
| 8658 } | 8674 } |
| 8659 | 8675 |
| 8660 | 8676 |
| 8661 bool HEnvironment::HasExpressionAt(int index) const { | 8677 bool HEnvironment::HasExpressionAt(int index) const { |
| 8662 return index >= parameter_count_ + specials_count_ + local_count_; | 8678 return index >= parameter_count_ + specials_count_ + local_count_; |
| 8663 } | 8679 } |
| 8664 | 8680 |
| 8665 | 8681 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8685 | 8701 |
| 8686 | 8702 |
| 8687 void HEnvironment::Drop(int count) { | 8703 void HEnvironment::Drop(int count) { |
| 8688 for (int i = 0; i < count; ++i) { | 8704 for (int i = 0; i < count; ++i) { |
| 8689 Pop(); | 8705 Pop(); |
| 8690 } | 8706 } |
| 8691 } | 8707 } |
| 8692 | 8708 |
| 8693 | 8709 |
| 8694 HEnvironment* HEnvironment::Copy() const { | 8710 HEnvironment* HEnvironment::Copy() const { |
| 8695 return new(closure()->GetIsolate()->zone()) HEnvironment(this); | 8711 return new(zone()) HEnvironment(this, zone()); |
| 8696 } | 8712 } |
| 8697 | 8713 |
| 8698 | 8714 |
| 8699 HEnvironment* HEnvironment::CopyWithoutHistory() const { | 8715 HEnvironment* HEnvironment::CopyWithoutHistory() const { |
| 8700 HEnvironment* result = Copy(); | 8716 HEnvironment* result = Copy(); |
| 8701 result->ClearHistory(); | 8717 result->ClearHistory(); |
| 8702 return result; | 8718 return result; |
| 8703 } | 8719 } |
| 8704 | 8720 |
| 8705 | 8721 |
| 8706 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { | 8722 HEnvironment* HEnvironment::CopyAsLoopHeader(HBasicBlock* loop_header) const { |
| 8707 HEnvironment* new_env = Copy(); | 8723 HEnvironment* new_env = Copy(); |
| 8708 for (int i = 0; i < values_.length(); ++i) { | 8724 for (int i = 0; i < values_.length(); ++i) { |
| 8709 HPhi* phi = new(loop_header->zone()) HPhi(i); | 8725 HPhi* phi = new(zone()) HPhi(i, zone()); |
| 8710 phi->AddInput(values_[i]); | 8726 phi->AddInput(values_[i]); |
| 8711 new_env->values_[i] = phi; | 8727 new_env->values_[i] = phi; |
| 8712 loop_header->AddPhi(phi); | 8728 loop_header->AddPhi(phi); |
| 8713 } | 8729 } |
| 8714 new_env->ClearHistory(); | 8730 new_env->ClearHistory(); |
| 8715 return new_env; | 8731 return new_env; |
| 8716 } | 8732 } |
| 8717 | 8733 |
| 8718 | 8734 |
| 8719 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, | 8735 HEnvironment* HEnvironment::CreateStubEnvironment(HEnvironment* outer, |
| 8720 Handle<JSFunction> target, | 8736 Handle<JSFunction> target, |
| 8721 FrameType frame_type, | 8737 FrameType frame_type, |
| 8722 int arguments) const { | 8738 int arguments) const { |
| 8723 HEnvironment* new_env = new(closure()->GetIsolate()->zone()) | 8739 HEnvironment* new_env = |
| 8724 HEnvironment(outer, target, frame_type, arguments + 1); | 8740 new(zone()) HEnvironment(outer, target, frame_type, |
| 8741 arguments + 1, zone()); |
| 8725 for (int i = 0; i <= arguments; ++i) { // Include receiver. | 8742 for (int i = 0; i <= arguments; ++i) { // Include receiver. |
| 8726 new_env->Push(ExpressionStackAt(arguments - i)); | 8743 new_env->Push(ExpressionStackAt(arguments - i)); |
| 8727 } | 8744 } |
| 8728 new_env->ClearHistory(); | 8745 new_env->ClearHistory(); |
| 8729 return new_env; | 8746 return new_env; |
| 8730 } | 8747 } |
| 8731 | 8748 |
| 8732 | 8749 |
| 8733 HEnvironment* HEnvironment::CopyForInlining( | 8750 HEnvironment* HEnvironment::CopyForInlining( |
| 8734 Handle<JSFunction> target, | 8751 Handle<JSFunction> target, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8754 // object instead, DoComputeConstructStubFrame() relies on that. | 8771 // object instead, DoComputeConstructStubFrame() relies on that. |
| 8755 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); | 8772 outer = CreateStubEnvironment(outer, target, JS_CONSTRUCT, arguments); |
| 8756 } | 8773 } |
| 8757 | 8774 |
| 8758 if (arity != arguments) { | 8775 if (arity != arguments) { |
| 8759 // Create artificial arguments adaptation environment. | 8776 // Create artificial arguments adaptation environment. |
| 8760 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); | 8777 outer = CreateStubEnvironment(outer, target, ARGUMENTS_ADAPTOR, arguments); |
| 8761 } | 8778 } |
| 8762 | 8779 |
| 8763 HEnvironment* inner = | 8780 HEnvironment* inner = |
| 8764 new(zone) HEnvironment(outer, function->scope(), target); | 8781 new(zone) HEnvironment(outer, function->scope(), target, zone); |
| 8765 // Get the argument values from the original environment. | 8782 // Get the argument values from the original environment. |
| 8766 for (int i = 0; i <= arity; ++i) { // Include receiver. | 8783 for (int i = 0; i <= arity; ++i) { // Include receiver. |
| 8767 HValue* push = (i <= arguments) ? | 8784 HValue* push = (i <= arguments) ? |
| 8768 ExpressionStackAt(arguments - i) : undefined; | 8785 ExpressionStackAt(arguments - i) : undefined; |
| 8769 inner->SetValueAt(i, push); | 8786 inner->SetValueAt(i, push); |
| 8770 } | 8787 } |
| 8771 // If the function we are inlining is a strict mode function or a | 8788 // If the function we are inlining is a strict mode function or a |
| 8772 // builtin function, pass undefined as the receiver for function | 8789 // builtin function, pass undefined as the receiver for function |
| 8773 // calls (instead of the global receiver). | 8790 // calls (instead of the global receiver). |
| 8774 if ((target->shared()->native() || !function->is_classic_mode()) && | 8791 if ((target->shared()->native() || !function->is_classic_mode()) && |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8944 } | 8961 } |
| 8945 } | 8962 } |
| 8946 | 8963 |
| 8947 | 8964 |
| 8948 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { | 8965 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { |
| 8949 Tag tag(this, "intervals"); | 8966 Tag tag(this, "intervals"); |
| 8950 PrintStringProperty("name", name); | 8967 PrintStringProperty("name", name); |
| 8951 | 8968 |
| 8952 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); | 8969 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); |
| 8953 for (int i = 0; i < fixed_d->length(); ++i) { | 8970 for (int i = 0; i < fixed_d->length(); ++i) { |
| 8954 TraceLiveRange(fixed_d->at(i), "fixed"); | 8971 TraceLiveRange(fixed_d->at(i), "fixed", allocator->zone()); |
| 8955 } | 8972 } |
| 8956 | 8973 |
| 8957 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); | 8974 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges(); |
| 8958 for (int i = 0; i < fixed->length(); ++i) { | 8975 for (int i = 0; i < fixed->length(); ++i) { |
| 8959 TraceLiveRange(fixed->at(i), "fixed"); | 8976 TraceLiveRange(fixed->at(i), "fixed", allocator->zone()); |
| 8960 } | 8977 } |
| 8961 | 8978 |
| 8962 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); | 8979 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); |
| 8963 for (int i = 0; i < live_ranges->length(); ++i) { | 8980 for (int i = 0; i < live_ranges->length(); ++i) { |
| 8964 TraceLiveRange(live_ranges->at(i), "object"); | 8981 TraceLiveRange(live_ranges->at(i), "object", allocator->zone()); |
| 8965 } | 8982 } |
| 8966 } | 8983 } |
| 8967 | 8984 |
| 8968 | 8985 |
| 8969 void HTracer::TraceLiveRange(LiveRange* range, const char* type) { | 8986 void HTracer::TraceLiveRange(LiveRange* range, const char* type, |
| 8987 Zone* zone) { |
| 8970 if (range != NULL && !range->IsEmpty()) { | 8988 if (range != NULL && !range->IsEmpty()) { |
| 8971 PrintIndent(); | 8989 PrintIndent(); |
| 8972 trace_.Add("%d %s", range->id(), type); | 8990 trace_.Add("%d %s", range->id(), type); |
| 8973 if (range->HasRegisterAssigned()) { | 8991 if (range->HasRegisterAssigned()) { |
| 8974 LOperand* op = range->CreateAssignedOperand(ZONE); | 8992 LOperand* op = range->CreateAssignedOperand(zone); |
| 8975 int assigned_reg = op->index(); | 8993 int assigned_reg = op->index(); |
| 8976 if (op->IsDoubleRegister()) { | 8994 if (op->IsDoubleRegister()) { |
| 8977 trace_.Add(" \"%s\"", | 8995 trace_.Add(" \"%s\"", |
| 8978 DoubleRegister::AllocationIndexToString(assigned_reg)); | 8996 DoubleRegister::AllocationIndexToString(assigned_reg)); |
| 8979 } else { | 8997 } else { |
| 8980 ASSERT(op->IsRegister()); | 8998 ASSERT(op->IsRegister()); |
| 8981 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); | 8999 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); |
| 8982 } | 9000 } |
| 8983 } else if (range->IsSpilled()) { | 9001 } else if (range->IsSpilled()) { |
| 8984 LOperand* op = range->TopLevel()->GetSpillOperand(); | 9002 LOperand* op = range->TopLevel()->GetSpillOperand(); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9126 } | 9144 } |
| 9127 } | 9145 } |
| 9128 | 9146 |
| 9129 #ifdef DEBUG | 9147 #ifdef DEBUG |
| 9130 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9148 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 9131 if (allocator_ != NULL) allocator_->Verify(); | 9149 if (allocator_ != NULL) allocator_->Verify(); |
| 9132 #endif | 9150 #endif |
| 9133 } | 9151 } |
| 9134 | 9152 |
| 9135 } } // namespace v8::internal | 9153 } } // namespace v8::internal |
| OLD | NEW |