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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 phi->Kill(); | 106 phi->Kill(); |
107 phis_.RemoveElement(phi); | 107 phis_.RemoveElement(phi); |
108 phi->SetBlock(NULL); | 108 phi->SetBlock(NULL); |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 void HBasicBlock::AddInstruction(HInstruction* instr) { | 112 void HBasicBlock::AddInstruction(HInstruction* instr) { |
113 ASSERT(!IsStartBlock() || !IsFinished()); | 113 ASSERT(!IsStartBlock() || !IsFinished()); |
114 ASSERT(!instr->IsLinked()); | 114 ASSERT(!instr->IsLinked()); |
115 ASSERT(!IsFinished()); | 115 ASSERT(!IsFinished()); |
| 116 // Make sure that we never add instructions without knowing |
| 117 // what the previous ast id is. |
| 118 ASSERT(instr->IsSimulate() || instr->IsGoto() || |
| 119 !last_environment()->previous_ast_id().IsNone()); |
116 if (first_ == NULL) { | 120 if (first_ == NULL) { |
117 ASSERT(last_environment() != NULL); | |
118 ASSERT(!last_environment()->ast_id().IsNone()); | |
119 HBlockEntry* entry = new(zone()) HBlockEntry(); | 121 HBlockEntry* entry = new(zone()) HBlockEntry(); |
120 entry->InitializeAsFirst(this); | 122 entry->InitializeAsFirst(this); |
121 first_ = last_ = entry; | 123 first_ = last_ = entry; |
122 } | 124 } |
123 instr->InsertAfter(last_); | 125 instr->InsertAfter(last_); |
124 } | 126 } |
125 | 127 |
126 | 128 |
127 HDeoptimize* HBasicBlock::CreateDeoptimize( | 129 HDeoptimize* HBasicBlock::CreateDeoptimize( |
128 HDeoptimize::UseEnvironment has_uses) { | 130 HDeoptimize::UseEnvironment has_uses) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 ASSERT(return_value != NULL); | 208 ASSERT(return_value != NULL); |
207 AddInstruction(new(zone()) HLeaveInlined()); | 209 AddInstruction(new(zone()) HLeaveInlined()); |
208 last_environment_ = last_environment()->DiscardInlined(drop_extra); | 210 last_environment_ = last_environment()->DiscardInlined(drop_extra); |
209 last_environment()->Push(return_value); | 211 last_environment()->Push(return_value); |
210 AddSimulate(BailoutId::None()); | 212 AddSimulate(BailoutId::None()); |
211 HGoto* instr = new(zone()) HGoto(target); | 213 HGoto* instr = new(zone()) HGoto(target); |
212 Finish(instr); | 214 Finish(instr); |
213 } | 215 } |
214 | 216 |
215 | 217 |
216 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { | 218 void HBasicBlock::SetInitialEnvironment(HEnvironment* env, |
| 219 BailoutId previous_ast_id) { |
217 ASSERT(!HasEnvironment()); | 220 ASSERT(!HasEnvironment()); |
218 ASSERT(first() == NULL); | 221 ASSERT(first() == NULL); |
219 UpdateEnvironment(env); | 222 UpdateEnvironment(env); |
| 223 env->set_previous_ast_id(previous_ast_id); |
220 } | 224 } |
221 | 225 |
222 | 226 |
223 void HBasicBlock::SetJoinId(BailoutId ast_id) { | 227 void HBasicBlock::SetJoinId(BailoutId ast_id) { |
224 int length = predecessors_.length(); | 228 int length = predecessors_.length(); |
225 ASSERT(length > 0); | 229 ASSERT(length > 0); |
226 for (int i = 0; i < length; i++) { | 230 for (int i = 0; i < length; i++) { |
227 HBasicBlock* predecessor = predecessors_[i]; | 231 HBasicBlock* predecessor = predecessors_[i]; |
228 ASSERT(predecessor->end()->IsGoto()); | 232 ASSERT(predecessor->end()->IsGoto()); |
229 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); | 233 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); |
230 // We only need to verify the ID once. | |
231 ASSERT(i != 0 || | 234 ASSERT(i != 0 || |
232 (predecessor->last_environment()->closure().is_null() || | 235 (predecessor->last_environment()->closure().is_null() || |
233 predecessor->last_environment()->closure()->shared() | 236 predecessor->last_environment()->closure()->shared() |
234 ->VerifyBailoutId(ast_id))); | 237 ->VerifyBailoutId(ast_id))); |
235 simulate->set_ast_id(ast_id); | 238 simulate->set_ast_id(ast_id); |
236 predecessor->last_environment()->set_ast_id(ast_id); | 239 } |
| 240 HEnvironment* last_environment = this->last_environment(); |
| 241 ASSERT(last_environment || IsFinished()); |
| 242 if (last_environment != NULL) { |
| 243 last_environment->set_previous_ast_id(ast_id); |
237 } | 244 } |
238 } | 245 } |
239 | 246 |
240 | 247 |
241 bool HBasicBlock::Dominates(HBasicBlock* other) const { | 248 bool HBasicBlock::Dominates(HBasicBlock* other) const { |
242 HBasicBlock* current = other->dominator(); | 249 HBasicBlock* current = other->dominator(); |
243 while (current != NULL) { | 250 while (current != NULL) { |
244 if (current == this) return true; | 251 if (current == this) return true; |
245 current = current->dominator(); | 252 current = current->dominator(); |
246 } | 253 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 if (IsLoopHeader()) { | 294 if (IsLoopHeader()) { |
288 ASSERT(phis()->length() == incoming_env->length()); | 295 ASSERT(phis()->length() == incoming_env->length()); |
289 for (int i = 0; i < phis_.length(); ++i) { | 296 for (int i = 0; i < phis_.length(); ++i) { |
290 phis_[i]->AddInput(incoming_env->values()->at(i)); | 297 phis_[i]->AddInput(incoming_env->values()->at(i)); |
291 } | 298 } |
292 } else { | 299 } else { |
293 last_environment()->AddIncomingEdge(this, pred->last_environment()); | 300 last_environment()->AddIncomingEdge(this, pred->last_environment()); |
294 } | 301 } |
295 } else if (!HasEnvironment() && !IsFinished()) { | 302 } else if (!HasEnvironment() && !IsFinished()) { |
296 ASSERT(!IsLoopHeader()); | 303 ASSERT(!IsLoopHeader()); |
297 SetInitialEnvironment(pred->last_environment()->Copy()); | 304 HEnvironment* new_env = pred->last_environment()->Copy(); |
| 305 SetInitialEnvironment(new_env, |
| 306 pred->last_environment()->previous_ast_id()); |
298 } | 307 } |
299 | 308 |
300 predecessors_.Add(pred, zone()); | 309 predecessors_.Add(pred, zone()); |
301 } | 310 } |
302 | 311 |
303 | 312 |
304 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { | 313 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { |
305 ASSERT(!dominated_blocks_.Contains(block)); | 314 ASSERT(!dominated_blocks_.Contains(block)); |
306 // Keep the list of dominated blocks sorted such that if there is two | 315 // Keep the list of dominated blocks sorted such that if there is two |
307 // succeeding block in this list, the predecessor is before the successor. | 316 // succeeding block in this list, the predecessor is before the successor. |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 if (second != NULL) { | 547 if (second != NULL) { |
539 ASSERT(second->predecessors()->Contains(block)); | 548 ASSERT(second->predecessors()->Contains(block)); |
540 } | 549 } |
541 } | 550 } |
542 | 551 |
543 // Check that phis have correct arguments. | 552 // Check that phis have correct arguments. |
544 for (int j = 0; j < block->phis()->length(); j++) { | 553 for (int j = 0; j < block->phis()->length(); j++) { |
545 HPhi* phi = block->phis()->at(j); | 554 HPhi* phi = block->phis()->at(j); |
546 phi->Verify(); | 555 phi->Verify(); |
547 } | 556 } |
548 | |
549 // Check that all join blocks have predecessors that end with an | |
550 // unconditional goto and agree on their environment node id. | |
551 if (block->predecessors()->length() >= 2) { | |
552 BailoutId id = | |
553 block->predecessors()->first()->last_environment()->ast_id(); | |
554 for (int k = 0; k < block->predecessors()->length(); k++) { | |
555 HBasicBlock* predecessor = block->predecessors()->at(k); | |
556 ASSERT(predecessor->end()->IsGoto()); | |
557 ASSERT(predecessor->last_environment()->ast_id() == id); | |
558 } | |
559 } | |
560 } | 557 } |
561 | 558 |
562 // Check special property of first block to have no predecessors. | 559 // Check special property of first block to have no predecessors. |
563 ASSERT(blocks_.at(0)->predecessors()->is_empty()); | 560 ASSERT(blocks_.at(0)->predecessors()->is_empty()); |
564 | 561 |
565 if (do_full_verify) { | 562 if (do_full_verify) { |
566 // Check that the graph is fully connected. | 563 // Check that the graph is fully connected. |
567 ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); | 564 ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); |
568 ASSERT(analyzer.visited_count() == blocks_.length()); | 565 ASSERT(analyzer.visited_count() == blocks_.length()); |
569 | 566 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 } | 630 } |
634 | 631 |
635 | 632 |
636 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) | 633 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) |
637 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) | 634 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) |
638 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) | 635 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) |
639 | 636 |
640 #undef DEFINE_GET_CONSTANT | 637 #undef DEFINE_GET_CONSTANT |
641 | 638 |
642 | 639 |
643 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder, BailoutId id) | 640 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder) |
644 : builder_(builder), | 641 : builder_(builder), |
645 finished_(false), | 642 finished_(false), |
646 id_(id) { | 643 id_(builder->current_block()->last_environment()->previous_ast_id()) { |
647 HEnvironment* env = builder->environment(); | 644 HEnvironment* env = builder->environment(); |
648 failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); | 645 failure_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
649 merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory()); | 646 merge_block_ = builder->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
650 } | 647 } |
651 | 648 |
652 | 649 |
653 HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { | 650 HValue* HGraphBuilder::CheckBuilder::CheckNotUndefined(HValue* value) { |
654 HEnvironment* env = builder_->environment(); | 651 HEnvironment* env = builder_->environment(); |
655 HIsNilAndBranch* compare = | 652 HIsNilAndBranch* compare = |
656 new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue); | 653 new(zone()) HIsNilAndBranch(value, kStrictEquality, kUndefinedValue); |
657 HBasicBlock* success_block = | 654 HBasicBlock* success_block = |
658 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 655 builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
659 HBasicBlock* failure_block = | 656 HBasicBlock* failure_block = |
660 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 657 builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
661 compare->SetSuccessorAt(0, failure_block); | 658 compare->SetSuccessorAt(0, failure_block); |
662 compare->SetSuccessorAt(1, success_block); | 659 compare->SetSuccessorAt(1, success_block); |
663 failure_block->Goto(failure_block_); | 660 failure_block->Goto(failure_block_); |
664 builder_->current_block()->Finish(compare); | 661 builder_->current_block()->Finish(compare); |
665 builder_->set_current_block(success_block); | 662 builder_->set_current_block(success_block); |
666 return compare; | 663 return compare; |
667 } | 664 } |
668 | 665 |
669 | 666 |
670 HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, | 667 HValue* HGraphBuilder::CheckBuilder::CheckIntegerCompare(HValue* left, |
671 HValue* right, | 668 HValue* right, |
672 Token::Value op) { | 669 Token::Value op) { |
673 HEnvironment* env = builder_->environment(); | 670 HEnvironment* env = builder_->environment(); |
674 HCompareIDAndBranch* compare = | 671 HCompareIDAndBranch* compare = |
675 new(zone()) HCompareIDAndBranch(left, right, op); | 672 new(zone()) HCompareIDAndBranch(left, right, op); |
676 compare->AssumeRepresentation(Representation::Integer32()); | 673 compare->AssumeRepresentation(Representation::Integer32()); |
677 HBasicBlock* success_block = | 674 HBasicBlock* success_block = |
678 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 675 builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
679 HBasicBlock* failure_block = | 676 HBasicBlock* failure_block = |
680 builder_->CreateBasicBlock(env->CopyWithoutHistory()); | 677 builder_->CreateBasicBlock(env->CopyWithoutHistory(), id_); |
681 compare->SetSuccessorAt(0, success_block); | 678 compare->SetSuccessorAt(0, success_block); |
682 compare->SetSuccessorAt(1, failure_block); | 679 compare->SetSuccessorAt(1, failure_block); |
683 failure_block->Goto(failure_block_); | 680 failure_block->Goto(failure_block_); |
684 builder_->current_block()->Finish(compare); | 681 builder_->current_block()->Finish(compare); |
685 builder_->set_current_block(success_block); | 682 builder_->set_current_block(success_block); |
686 return compare; | 683 return compare; |
687 } | 684 } |
688 | 685 |
689 | 686 |
690 HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, | 687 HValue* HGraphBuilder::CheckBuilder::CheckIntegerEq(HValue* left, |
691 HValue* right) { | 688 HValue* right) { |
692 return CheckIntegerCompare(left, right, Token::EQ); | 689 return CheckIntegerCompare(left, right, Token::EQ); |
693 } | 690 } |
694 | 691 |
695 | 692 |
696 void HGraphBuilder::CheckBuilder::End() { | 693 void HGraphBuilder::CheckBuilder::End() { |
697 ASSERT(!finished_); | 694 ASSERT(!finished_); |
698 builder_->current_block()->Goto(merge_block_); | 695 builder_->current_block()->Goto(merge_block_); |
| 696 failure_block_->SetJoinId(id_); |
699 failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); | 697 failure_block_->FinishExitWithDeoptimization(HDeoptimize::kUseAll); |
700 failure_block_->SetJoinId(id_); | |
701 builder_->set_current_block(merge_block_); | 698 builder_->set_current_block(merge_block_); |
702 merge_block_->SetJoinId(id_); | 699 merge_block_->SetJoinId(id_); |
703 finished_ = true; | 700 finished_ = true; |
704 } | 701 } |
705 | 702 |
706 | 703 |
707 HConstant* HGraph::GetInvalidContext() { | 704 HConstant* HGraph::GetInvalidContext() { |
708 return GetConstantInt32(&constant_invalid_context_, 0xFFFFC0C7); | 705 return GetConstantInt32(&constant_invalid_context_, 0xFFFFC0C7); |
709 } | 706 } |
710 | 707 |
711 | 708 |
712 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id) | 709 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) |
713 : builder_(builder), | 710 : builder_(builder), |
714 finished_(false), | 711 finished_(false), |
715 did_else_(false), | 712 did_else_(false), |
716 id_(id) { | 713 id_(builder->current_block()->last_environment()->previous_ast_id()) { |
717 HEnvironment* env = builder->environment(); | 714 HEnvironment* env = builder->environment(); |
718 first_true_block_ = builder->CreateBasicBlock(env->Copy()); | 715 first_true_block_ = builder->CreateBasicBlock(env->Copy(), id_); |
719 last_true_block_ = NULL; | 716 last_true_block_ = NULL; |
720 first_false_block_ = builder->CreateBasicBlock(env->Copy()); | 717 first_false_block_ = builder->CreateBasicBlock(env->Copy(), id_); |
721 } | 718 } |
722 | 719 |
723 | 720 |
724 HInstruction* HGraphBuilder::IfBuilder::BeginIf( | 721 HInstruction* HGraphBuilder::IfBuilder::BeginIf( |
725 HValue* left, | 722 HValue* left, |
726 HValue* right, | 723 HValue* right, |
727 Token::Value token, | 724 Token::Value token, |
728 Representation input_representation) { | 725 Representation input_representation) { |
729 HCompareIDAndBranch* compare = | 726 HCompareIDAndBranch* compare = |
730 new(zone()) HCompareIDAndBranch(left, right, token); | 727 new(zone()) HCompareIDAndBranch(left, right, token); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 | 768 |
772 | 769 |
773 void HGraphBuilder::IfBuilder::End() { | 770 void HGraphBuilder::IfBuilder::End() { |
774 ASSERT(!finished_); | 771 ASSERT(!finished_); |
775 if (!did_else_) BeginElse(); | 772 if (!did_else_) BeginElse(); |
776 ASSERT(!last_true_block_->IsFinished()); | 773 ASSERT(!last_true_block_->IsFinished()); |
777 HBasicBlock* last_false_block = builder_->current_block(); | 774 HBasicBlock* last_false_block = builder_->current_block(); |
778 ASSERT(!last_false_block->IsFinished()); | 775 ASSERT(!last_false_block->IsFinished()); |
779 HEnvironment* merge_env = | 776 HEnvironment* merge_env = |
780 last_true_block_->last_environment()->CopyWithoutHistory(); | 777 last_true_block_->last_environment()->CopyWithoutHistory(); |
781 merge_block_ = builder_->CreateBasicBlock(merge_env); | 778 merge_block_ = builder_->CreateBasicBlock(merge_env, id_); |
782 last_true_block_->Goto(merge_block_); | 779 last_true_block_->Goto(merge_block_); |
783 last_false_block->Goto(merge_block_); | 780 last_false_block->Goto(merge_block_); |
784 merge_block_->SetJoinId(id_); | 781 merge_block_->SetJoinId(id_); |
785 builder_->set_current_block(merge_block_); | 782 builder_->set_current_block(merge_block_); |
786 finished_ = true; | 783 finished_ = true; |
787 } | 784 } |
788 | 785 |
789 | 786 |
790 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, | 787 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
791 HValue* context, | 788 HValue* context, |
792 LoopBuilder::Direction direction, | 789 LoopBuilder::Direction direction) |
793 BailoutId id) | |
794 : builder_(builder), | 790 : builder_(builder), |
795 context_(context), | 791 context_(context), |
796 direction_(direction), | 792 direction_(direction), |
797 id_(id), | 793 id_(builder->current_block()->last_environment()->previous_ast_id()), |
798 finished_(false) { | 794 finished_(false) { |
799 header_block_ = builder->CreateLoopHeaderBlock(); | 795 header_block_ = builder->CreateLoopHeaderBlock(id_); |
800 body_block_ = NULL; | 796 body_block_ = NULL; |
801 exit_block_ = NULL; | 797 exit_block_ = NULL; |
802 } | 798 } |
803 | 799 |
804 | 800 |
805 HValue* HGraphBuilder::LoopBuilder::BeginBody( | 801 HValue* HGraphBuilder::LoopBuilder::BeginBody( |
806 HValue* initial, | 802 HValue* initial, |
807 HValue* terminating, | 803 HValue* terminating, |
808 Token::Value token, | 804 Token::Value token, |
809 Representation input_representation) { | 805 Representation input_representation) { |
810 HEnvironment* env = builder_->environment(); | 806 HEnvironment* env = builder_->environment(); |
811 phi_ = new(zone()) HPhi(env->values()->length(), zone()); | 807 phi_ = new(zone()) HPhi(env->values()->length(), zone()); |
812 header_block_->AddPhi(phi_); | 808 header_block_->AddPhi(phi_); |
813 phi_->AddInput(initial); | 809 phi_->AddInput(initial); |
814 phi_->ChangeRepresentation(Representation::Integer32()); | 810 phi_->ChangeRepresentation(Representation::Integer32()); |
815 env->Push(initial); | 811 env->Push(initial); |
816 builder_->current_block()->Goto(header_block_); | 812 builder_->current_block()->Goto(header_block_); |
817 | 813 |
818 HEnvironment* body_env = env->Copy(); | 814 HEnvironment* body_env = env->Copy(); |
819 HEnvironment* exit_env = env->Copy(); | 815 HEnvironment* exit_env = env->Copy(); |
820 body_block_ = builder_->CreateBasicBlock(body_env); | 816 body_block_ = builder_->CreateBasicBlock(body_env, id_); |
821 exit_block_ = builder_->CreateBasicBlock(exit_env); | 817 exit_block_ = builder_->CreateBasicBlock(exit_env, id_); |
822 // Remove the phi from the expression stack | 818 // Remove the phi from the expression stack |
823 body_env->Pop(); | 819 body_env->Pop(); |
824 | 820 |
825 builder_->set_current_block(header_block_); | 821 builder_->set_current_block(header_block_); |
826 HCompareIDAndBranch* compare = | 822 HCompareIDAndBranch* compare = |
827 new(zone()) HCompareIDAndBranch(phi_, terminating, token); | 823 new(zone()) HCompareIDAndBranch(phi_, terminating, token); |
828 compare->set_observed_input_representation(input_representation, | 824 compare->set_observed_input_representation(input_representation, |
829 input_representation); | 825 input_representation); |
830 compare->ChangeRepresentation(input_representation); | 826 compare->ChangeRepresentation(input_representation); |
831 compare->SetSuccessorAt(0, body_block_); | 827 compare->SetSuccessorAt(0, body_block_); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 ASSERT(current_block() != NULL); | 888 ASSERT(current_block() != NULL); |
893 current_block()->AddInstruction(instr); | 889 current_block()->AddInstruction(instr); |
894 return instr; | 890 return instr; |
895 } | 891 } |
896 | 892 |
897 | 893 |
898 void HGraphBuilder::AddSimulate(BailoutId id, | 894 void HGraphBuilder::AddSimulate(BailoutId id, |
899 RemovableSimulate removable) { | 895 RemovableSimulate removable) { |
900 ASSERT(current_block() != NULL); | 896 ASSERT(current_block() != NULL); |
901 current_block()->AddSimulate(id, removable); | 897 current_block()->AddSimulate(id, removable); |
902 environment()->set_ast_id(id); | 898 environment()->set_previous_ast_id(id); |
903 } | 899 } |
904 | 900 |
905 | 901 |
906 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, | 902 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, |
907 HValue* length, | 903 HValue* length, |
908 BoundsCheckKeyMode key_mode, | 904 BoundsCheckKeyMode key_mode, |
909 Representation r) { | 905 Representation r) { |
910 if (!index->type().IsSmi()) { | 906 if (!index->type().IsSmi()) { |
911 index = new(graph()->zone()) HCheckSmiOrInt32(index); | 907 index = new(graph()->zone()) HCheckSmiOrInt32(index); |
912 AddInstruction(HCheckSmiOrInt32::cast(index)); | 908 AddInstruction(HCheckSmiOrInt32::cast(index)); |
(...skipping 14 matching lines...) Expand all Loading... |
927 int num_parameters = graph()->info()->num_parameters(); | 923 int num_parameters = graph()->info()->num_parameters(); |
928 HValue* params = AddInstruction(new(graph()->zone()) | 924 HValue* params = AddInstruction(new(graph()->zone()) |
929 HConstant(num_parameters, Representation::Integer32())); | 925 HConstant(num_parameters, Representation::Integer32())); |
930 HReturn* return_instruction = new(graph()->zone()) | 926 HReturn* return_instruction = new(graph()->zone()) |
931 HReturn(value, context, params); | 927 HReturn(value, context, params); |
932 current_block()->FinishExit(return_instruction); | 928 current_block()->FinishExit(return_instruction); |
933 return return_instruction; | 929 return return_instruction; |
934 } | 930 } |
935 | 931 |
936 | 932 |
937 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 933 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env, |
| 934 BailoutId previous_ast_id) { |
938 HBasicBlock* b = graph()->CreateBasicBlock(); | 935 HBasicBlock* b = graph()->CreateBasicBlock(); |
939 b->SetInitialEnvironment(env); | 936 b->SetInitialEnvironment(env, previous_ast_id); |
940 return b; | 937 return b; |
941 } | 938 } |
942 | 939 |
943 | 940 |
944 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 941 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock(BailoutId previous_ast_id) { |
945 HBasicBlock* header = graph()->CreateBasicBlock(); | 942 HBasicBlock* header = graph()->CreateBasicBlock(); |
946 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 943 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
947 header->SetInitialEnvironment(entry_env); | 944 header->SetInitialEnvironment(entry_env, previous_ast_id); |
948 header->AttachLoopInformation(); | 945 header->AttachLoopInformation(); |
949 return header; | 946 return header; |
950 } | 947 } |
951 | 948 |
952 | 949 |
953 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 950 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
954 HValue* external_elements, | 951 HValue* external_elements, |
955 HValue* checked_key, | 952 HValue* checked_key, |
956 HValue* val, | 953 HValue* val, |
957 HValue* dependency, | 954 HValue* dependency, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 elements_kind); | 1034 elements_kind); |
1038 } | 1035 } |
1039 | 1036 |
1040 | 1037 |
1041 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1038 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
1042 HValue* elements, | 1039 HValue* elements, |
1043 ElementsKind kind, | 1040 ElementsKind kind, |
1044 HValue* length, | 1041 HValue* length, |
1045 HValue* key, | 1042 HValue* key, |
1046 bool is_js_array) { | 1043 bool is_js_array) { |
1047 BailoutId ast_id = environment()->ast_id(); | 1044 BailoutId ast_id = current_block()->last_environment()->previous_ast_id(); |
1048 Zone* zone = this->zone(); | 1045 Zone* zone = this->zone(); |
1049 IfBuilder length_checker(this, ast_id); | 1046 IfBuilder length_checker(this); |
1050 | 1047 |
1051 length_checker.BeginIf(length, key, Token::EQ); | 1048 length_checker.BeginIf(length, key, Token::EQ); |
1052 | 1049 |
1053 HValue* current_capacity = | 1050 HValue* current_capacity = |
1054 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1051 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1055 | 1052 |
1056 IfBuilder capacity_checker(this, ast_id); | 1053 IfBuilder capacity_checker(this); |
1057 | 1054 |
1058 capacity_checker.BeginIf(length, current_capacity, Token::EQ); | 1055 capacity_checker.BeginIf(length, current_capacity, Token::EQ); |
1059 | 1056 |
1060 HValue* context = environment()->LookupContext(); | 1057 HValue* context = environment()->LookupContext(); |
1061 | 1058 |
1062 HValue* new_capacity = | 1059 HValue* new_capacity = |
1063 BuildNewElementsCapacity(context, current_capacity); | 1060 BuildNewElementsCapacity(context, current_capacity); |
1064 | 1061 |
1065 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1062 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1066 kind, length, | 1063 kind, length, |
1067 new_capacity, ast_id); | 1064 new_capacity); |
1068 | 1065 |
1069 environment()->Push(new_elements); | 1066 environment()->Push(new_elements); |
1070 capacity_checker.BeginElse(); | 1067 capacity_checker.BeginElse(); |
1071 | 1068 |
1072 environment()->Push(elements); | 1069 environment()->Push(elements); |
1073 capacity_checker.End(); | 1070 capacity_checker.End(); |
1074 | 1071 |
1075 if (is_js_array) { | 1072 if (is_js_array) { |
1076 HValue* new_length = AddInstruction( | 1073 HValue* new_length = AddInstruction( |
1077 HAdd::New(zone, context, length, graph_->GetConstant1())); | 1074 HAdd::New(zone, context, length, graph_->GetConstant1())); |
(...skipping 19 matching lines...) Expand all Loading... |
1097 length_checker.End(); | 1094 length_checker.End(); |
1098 | 1095 |
1099 return environment()->Pop(); | 1096 return environment()->Pop(); |
1100 } | 1097 } |
1101 | 1098 |
1102 | 1099 |
1103 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1100 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
1104 HValue* elements, | 1101 HValue* elements, |
1105 ElementsKind kind, | 1102 ElementsKind kind, |
1106 HValue* length) { | 1103 HValue* length) { |
1107 BailoutId ast_id = environment()->ast_id(); | |
1108 Zone* zone = this->zone(); | 1104 Zone* zone = this->zone(); |
1109 Heap* heap = isolate()->heap(); | 1105 Heap* heap = isolate()->heap(); |
1110 | 1106 |
1111 IfBuilder cow_checker(this, ast_id); | 1107 IfBuilder cow_checker(this); |
1112 | 1108 |
1113 cow_checker.BeginIfMapEquals(elements, | 1109 cow_checker.BeginIfMapEquals(elements, |
1114 Handle<Map>(heap->fixed_cow_array_map())); | 1110 Handle<Map>(heap->fixed_cow_array_map())); |
1115 | 1111 |
1116 HValue* capacity = | 1112 HValue* capacity = |
1117 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1113 AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1118 | 1114 |
1119 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1115 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1120 kind, length, | 1116 kind, length, |
1121 capacity, ast_id); | 1117 capacity); |
1122 | 1118 |
1123 environment()->Push(new_elements); | 1119 environment()->Push(new_elements); |
1124 | 1120 |
1125 cow_checker.BeginElse(); | 1121 cow_checker.BeginElse(); |
1126 | 1122 |
1127 environment()->Push(elements); | 1123 environment()->Push(elements); |
1128 | 1124 |
1129 cow_checker.End(); | 1125 cow_checker.End(); |
1130 | 1126 |
1131 return environment()->Pop(); | 1127 return environment()->Pop(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 HType::Smi())); | 1169 HType::Smi())); |
1174 } else { | 1170 } else { |
1175 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 1171 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
1176 } | 1172 } |
1177 HValue* checked_key = NULL; | 1173 HValue* checked_key = NULL; |
1178 if (IsExternalArrayElementsKind(elements_kind)) { | 1174 if (IsExternalArrayElementsKind(elements_kind)) { |
1179 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1175 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1180 HLoadExternalArrayPointer* external_elements = | 1176 HLoadExternalArrayPointer* external_elements = |
1181 new(zone) HLoadExternalArrayPointer(elements); | 1177 new(zone) HLoadExternalArrayPointer(elements); |
1182 AddInstruction(external_elements); | 1178 AddInstruction(external_elements); |
1183 BailoutId previous_id = environment()->ast_id(); | 1179 IfBuilder length_checker(this); |
1184 ASSERT(!previous_id.IsNone()); | |
1185 IfBuilder length_checker(this, previous_id); | |
1186 length_checker.BeginIf(key, length, Token::LT); | 1180 length_checker.BeginIf(key, length, Token::LT); |
1187 CheckBuilder negative_checker(this, previous_id); | 1181 CheckBuilder negative_checker(this); |
1188 HValue* bounds_check = negative_checker.CheckIntegerCompare( | 1182 HValue* bounds_check = negative_checker.CheckIntegerCompare( |
1189 key, graph()->GetConstant0(), Token::GTE); | 1183 key, graph()->GetConstant0(), Token::GTE); |
1190 negative_checker.End(); | 1184 negative_checker.End(); |
1191 HInstruction* result = BuildExternalArrayElementAccess( | 1185 HInstruction* result = BuildExternalArrayElementAccess( |
1192 external_elements, key, val, bounds_check, | 1186 external_elements, key, val, bounds_check, |
1193 elements_kind, is_store); | 1187 elements_kind, is_store); |
1194 AddInstruction(result); | 1188 AddInstruction(result); |
1195 length_checker.End(); | 1189 length_checker.End(); |
1196 return result; | 1190 return result; |
1197 } else { | 1191 } else { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 } | 1230 } |
1237 } | 1231 } |
1238 return AddInstruction( | 1232 return AddInstruction( |
1239 BuildFastElementAccess(elements, checked_key, val, mapcheck, | 1233 BuildFastElementAccess(elements, checked_key, val, mapcheck, |
1240 elements_kind, is_store, store_mode)); | 1234 elements_kind, is_store, store_mode)); |
1241 } | 1235 } |
1242 | 1236 |
1243 | 1237 |
1244 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, | 1238 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, |
1245 ElementsKind kind, | 1239 ElementsKind kind, |
1246 HValue* capacity, | 1240 HValue* capacity) { |
1247 BailoutId ast_id) { | 1241 BailoutId ast_id = current_block()->last_environment()->previous_ast_id(); |
1248 Zone* zone = this->zone(); | 1242 Zone* zone = this->zone(); |
1249 | 1243 |
1250 int elements_size = IsFastDoubleElementsKind(kind) | 1244 int elements_size = IsFastDoubleElementsKind(kind) |
1251 ? kDoubleSize : kPointerSize; | 1245 ? kDoubleSize : kPointerSize; |
1252 HConstant* elements_size_value = | 1246 HConstant* elements_size_value = |
1253 new(zone) HConstant(elements_size, Representation::Integer32()); | 1247 new(zone) HConstant(elements_size, Representation::Integer32()); |
1254 AddInstruction(elements_size_value); | 1248 AddInstruction(elements_size_value); |
1255 HValue* mul = AddInstruction( | 1249 HValue* mul = AddInstruction( |
1256 HMul::New(zone, context, capacity, elements_size_value)); | 1250 HMul::New(zone, context, capacity, elements_size_value)); |
1257 mul->ChangeRepresentation(Representation::Integer32()); | 1251 mul->ChangeRepresentation(Representation::Integer32()); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 AddInstruction(new(zone) | 1358 AddInstruction(new(zone) |
1365 HBoundsCheck(length, max_size_constant, | 1359 HBoundsCheck(length, max_size_constant, |
1366 DONT_ALLOW_SMI_KEY, Representation::Integer32())); | 1360 DONT_ALLOW_SMI_KEY, Representation::Integer32())); |
1367 } | 1361 } |
1368 | 1362 |
1369 | 1363 |
1370 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1364 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
1371 HValue* elements, | 1365 HValue* elements, |
1372 ElementsKind kind, | 1366 ElementsKind kind, |
1373 HValue* length, | 1367 HValue* length, |
1374 HValue* new_capacity, | 1368 HValue* new_capacity) { |
1375 BailoutId ast_id) { | |
1376 Zone* zone = this->zone(); | 1369 Zone* zone = this->zone(); |
1377 HValue* context = environment()->LookupContext(); | 1370 HValue* context = environment()->LookupContext(); |
1378 | 1371 |
1379 BuildNewSpaceArrayCheck(new_capacity, kind); | 1372 BuildNewSpaceArrayCheck(new_capacity, kind); |
1380 | 1373 |
1381 HValue* new_elements = | 1374 HValue* new_elements = |
1382 BuildAllocateElements(context, kind, new_capacity, ast_id); | 1375 BuildAllocateElements(context, kind, new_capacity); |
1383 | 1376 |
1384 BuildCopyElements(context, elements, kind, | 1377 BuildCopyElements(context, elements, kind, |
1385 new_elements, kind, | 1378 new_elements, kind, |
1386 length, new_capacity, ast_id); | 1379 length, new_capacity); |
1387 | 1380 |
1388 Factory* factory = isolate()->factory(); | 1381 Factory* factory = isolate()->factory(); |
1389 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 1382 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( |
1390 object, | 1383 object, |
1391 factory->elements_field_string(), | 1384 factory->elements_field_string(), |
1392 new_elements, true, | 1385 new_elements, true, |
1393 JSArray::kElementsOffset)); | 1386 JSArray::kElementsOffset)); |
1394 elements_store->SetGVNFlag(kChangesElementsPointer); | 1387 elements_store->SetGVNFlag(kChangesElementsPointer); |
1395 | 1388 |
1396 return new_elements; | 1389 return new_elements; |
1397 } | 1390 } |
1398 | 1391 |
1399 | 1392 |
1400 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1393 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
1401 HValue* elements, | 1394 HValue* elements, |
1402 ElementsKind elements_kind, | 1395 ElementsKind elements_kind, |
1403 HValue* from, | 1396 HValue* from, |
1404 HValue* to, | 1397 HValue* to) { |
1405 BailoutId ast_id) { | 1398 BailoutId ast_id = current_block()->last_environment()->previous_ast_id(); |
1406 // Fast elements kinds need to be initialized in case statements below cause | 1399 // Fast elements kinds need to be initialized in case statements below cause |
1407 // a garbage collection. | 1400 // a garbage collection. |
1408 Factory* factory = isolate()->factory(); | 1401 Factory* factory = isolate()->factory(); |
1409 | 1402 |
1410 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1403 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
1411 Zone* zone = this->zone(); | 1404 Zone* zone = this->zone(); |
1412 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1405 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
1413 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), | 1406 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
1414 Representation::Tagged())) | 1407 Representation::Tagged())) |
1415 : AddInstruction(new(zone) HConstant(nan_double, | 1408 : AddInstruction(new(zone) HConstant(nan_double, |
1416 Representation::Double())); | 1409 Representation::Double())); |
1417 | 1410 |
1418 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); | 1411 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1419 | 1412 |
1420 HValue* key = builder.BeginBody(from, to, Token::LT); | 1413 HValue* key = builder.BeginBody(from, to, Token::LT); |
1421 | 1414 |
1422 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1415 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
1423 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 1416 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
1424 | 1417 |
1425 builder.EndBody(); | 1418 builder.EndBody(); |
1426 } | 1419 } |
1427 | 1420 |
1428 | 1421 |
1429 void HGraphBuilder::BuildCopyElements(HValue* context, | 1422 void HGraphBuilder::BuildCopyElements(HValue* context, |
1430 HValue* from_elements, | 1423 HValue* from_elements, |
1431 ElementsKind from_elements_kind, | 1424 ElementsKind from_elements_kind, |
1432 HValue* to_elements, | 1425 HValue* to_elements, |
1433 ElementsKind to_elements_kind, | 1426 ElementsKind to_elements_kind, |
1434 HValue* length, | 1427 HValue* length, |
1435 HValue* capacity, | 1428 HValue* capacity) { |
1436 BailoutId ast_id) { | 1429 BailoutId ast_id = current_block()->last_environment()->previous_ast_id(); |
1437 bool pre_fill_with_holes = | 1430 bool pre_fill_with_holes = |
1438 IsFastDoubleElementsKind(from_elements_kind) && | 1431 IsFastDoubleElementsKind(from_elements_kind) && |
1439 IsFastObjectElementsKind(to_elements_kind); | 1432 IsFastObjectElementsKind(to_elements_kind); |
1440 | 1433 |
1441 if (pre_fill_with_holes) { | 1434 if (pre_fill_with_holes) { |
1442 // If the copy might trigger a GC, make sure that the FixedArray is | 1435 // If the copy might trigger a GC, make sure that the FixedArray is |
1443 // pre-initialized with holes to make sure that it's always in a consistent | 1436 // pre-initialized with holes to make sure that it's always in a consistent |
1444 // state. | 1437 // state. |
1445 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1438 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1446 graph()->GetConstant0(), capacity, ast_id); | 1439 graph()->GetConstant0(), capacity); |
1447 } | 1440 } |
1448 | 1441 |
1449 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement, ast_id); | 1442 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1450 | 1443 |
1451 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); | 1444 HValue* key = builder.BeginBody(graph()->GetConstant0(), length, Token::LT); |
1452 | 1445 |
1453 HValue* element = | 1446 HValue* element = |
1454 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | 1447 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, |
1455 from_elements_kind, | 1448 from_elements_kind, |
1456 ALLOW_RETURN_HOLE)); | 1449 ALLOW_RETURN_HOLE)); |
1457 | 1450 |
1458 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, | 1451 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, |
1459 to_elements_kind)); | 1452 to_elements_kind)); |
1460 AddSimulate(ast_id, REMOVABLE_SIMULATE); | 1453 AddSimulate(ast_id, REMOVABLE_SIMULATE); |
1461 | 1454 |
1462 builder.EndBody(); | 1455 builder.EndBody(); |
1463 | 1456 |
1464 if (!pre_fill_with_holes && length != capacity) { | 1457 if (!pre_fill_with_holes && length != capacity) { |
1465 // Fill unused capacity with the hole. | 1458 // Fill unused capacity with the hole. |
1466 BuildFillElementsWithHole(context, to_elements, to_elements_kind, | 1459 BuildFillElementsWithHole(context, to_elements, to_elements_kind, |
1467 key, capacity, ast_id); | 1460 key, capacity); |
1468 } | 1461 } |
1469 } | 1462 } |
1470 | 1463 |
1471 | 1464 |
1472 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1465 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
1473 TypeFeedbackOracle* oracle) | 1466 TypeFeedbackOracle* oracle) |
1474 : HGraphBuilder(info), | 1467 : HGraphBuilder(info), |
1475 function_state_(NULL), | 1468 function_state_(NULL), |
1476 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1469 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
1477 ast_context_(NULL), | 1470 ast_context_(NULL), |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 if (info->IsStub()) { | 1548 if (info->IsStub()) { |
1556 HydrogenCodeStub* stub = info->code_stub(); | 1549 HydrogenCodeStub* stub = info->code_stub(); |
1557 CodeStubInterfaceDescriptor* descriptor = | 1550 CodeStubInterfaceDescriptor* descriptor = |
1558 stub->GetInterfaceDescriptor(isolate_); | 1551 stub->GetInterfaceDescriptor(isolate_); |
1559 start_environment_ = | 1552 start_environment_ = |
1560 new(zone_) HEnvironment(zone_, descriptor->environment_length()); | 1553 new(zone_) HEnvironment(zone_, descriptor->environment_length()); |
1561 } else { | 1554 } else { |
1562 start_environment_ = | 1555 start_environment_ = |
1563 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 1556 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
1564 } | 1557 } |
1565 start_environment_->set_ast_id(BailoutId::FunctionEntry()); | |
1566 entry_block_ = CreateBasicBlock(); | 1558 entry_block_ = CreateBasicBlock(); |
1567 entry_block_->SetInitialEnvironment(start_environment_); | 1559 entry_block_->SetInitialEnvironment(start_environment_, |
| 1560 BailoutId::FunctionEntry()); |
1568 } | 1561 } |
1569 | 1562 |
1570 | 1563 |
1571 HBasicBlock* HGraph::CreateBasicBlock() { | 1564 HBasicBlock* HGraph::CreateBasicBlock() { |
1572 HBasicBlock* result = new(zone()) HBasicBlock(this); | 1565 HBasicBlock* result = new(zone()) HBasicBlock(this); |
1573 blocks_.Add(result, zone()); | 1566 blocks_.Add(result, zone()); |
1574 return result; | 1567 return result; |
1575 } | 1568 } |
1576 | 1569 |
1577 | 1570 |
(...skipping 2564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4142 // translation, so they cannot have an environment effect. The edge to | 4135 // translation, so they cannot have an environment effect. The edge to |
4143 // the body's entry block (along with some special logic for the start | 4136 // the body's entry block (along with some special logic for the start |
4144 // block in HInstruction::InsertAfter) seals the start block from | 4137 // block in HInstruction::InsertAfter) seals the start block from |
4145 // getting unwanted instructions inserted. | 4138 // getting unwanted instructions inserted. |
4146 // | 4139 // |
4147 // TODO(kmillikin): Fix this. Stop mutating the initial environment. | 4140 // TODO(kmillikin): Fix this. Stop mutating the initial environment. |
4148 // Make the Hydrogen instructions in the initial block into Hydrogen | 4141 // Make the Hydrogen instructions in the initial block into Hydrogen |
4149 // values (but not instructions), present in the initial environment and | 4142 // values (but not instructions), present in the initial environment and |
4150 // not replayed by the Lithium translation. | 4143 // not replayed by the Lithium translation. |
4151 HEnvironment* initial_env = environment()->CopyWithoutHistory(); | 4144 HEnvironment* initial_env = environment()->CopyWithoutHistory(); |
4152 HBasicBlock* body_entry = CreateBasicBlock(initial_env); | 4145 HBasicBlock* body_entry = CreateBasicBlock(initial_env, |
| 4146 BailoutId::FunctionEntry()); |
4153 current_block()->Goto(body_entry); | 4147 current_block()->Goto(body_entry); |
4154 body_entry->SetJoinId(BailoutId::FunctionEntry()); | 4148 body_entry->SetJoinId(BailoutId::FunctionEntry()); |
4155 set_current_block(body_entry); | 4149 set_current_block(body_entry); |
4156 | 4150 |
4157 // Handle implicit declaration of the function name in named function | 4151 // Handle implicit declaration of the function name in named function |
4158 // expressions before other declarations. | 4152 // expressions before other declarations. |
4159 if (scope->is_function_scope() && scope->function() != NULL) { | 4153 if (scope->is_function_scope() && scope->function() != NULL) { |
4160 VisitVariableDeclaration(scope->function()); | 4154 VisitVariableDeclaration(scope->function()); |
4161 } | 4155 } |
4162 VisitDeclarations(scope->declarations()); | 4156 VisitDeclarations(scope->declarations()); |
(...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5400 CHECK_BAILOUT(Visit(stmt->body())); | 5394 CHECK_BAILOUT(Visit(stmt->body())); |
5401 } | 5395 } |
5402 | 5396 |
5403 | 5397 |
5404 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 5398 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
5405 ASSERT(!HasStackOverflow()); | 5399 ASSERT(!HasStackOverflow()); |
5406 ASSERT(current_block() != NULL); | 5400 ASSERT(current_block() != NULL); |
5407 ASSERT(current_block()->HasPredecessor()); | 5401 ASSERT(current_block()->HasPredecessor()); |
5408 ASSERT(current_block() != NULL); | 5402 ASSERT(current_block() != NULL); |
5409 bool osr_entry = PreProcessOsrEntry(stmt); | 5403 bool osr_entry = PreProcessOsrEntry(stmt); |
5410 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5404 HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
5411 current_block()->Goto(loop_entry); | 5405 current_block()->Goto(loop_entry); |
5412 set_current_block(loop_entry); | 5406 set_current_block(loop_entry); |
5413 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5407 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
5414 | 5408 |
5415 BreakAndContinueInfo break_info(stmt); | 5409 BreakAndContinueInfo break_info(stmt); |
5416 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); | 5410 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); |
5417 HBasicBlock* body_exit = | 5411 HBasicBlock* body_exit = |
5418 JoinContinue(stmt, current_block(), break_info.continue_block()); | 5412 JoinContinue(stmt, current_block(), break_info.continue_block()); |
5419 HBasicBlock* loop_successor = NULL; | 5413 HBasicBlock* loop_successor = NULL; |
5420 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { | 5414 if (body_exit != NULL && !stmt->cond()->ToBooleanIsTrue()) { |
(...skipping 22 matching lines...) Expand all Loading... |
5443 set_current_block(loop_exit); | 5437 set_current_block(loop_exit); |
5444 } | 5438 } |
5445 | 5439 |
5446 | 5440 |
5447 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 5441 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
5448 ASSERT(!HasStackOverflow()); | 5442 ASSERT(!HasStackOverflow()); |
5449 ASSERT(current_block() != NULL); | 5443 ASSERT(current_block() != NULL); |
5450 ASSERT(current_block()->HasPredecessor()); | 5444 ASSERT(current_block()->HasPredecessor()); |
5451 ASSERT(current_block() != NULL); | 5445 ASSERT(current_block() != NULL); |
5452 bool osr_entry = PreProcessOsrEntry(stmt); | 5446 bool osr_entry = PreProcessOsrEntry(stmt); |
5453 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5447 HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
5454 current_block()->Goto(loop_entry); | 5448 current_block()->Goto(loop_entry); |
5455 set_current_block(loop_entry); | 5449 set_current_block(loop_entry); |
5456 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5450 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
5457 | 5451 |
5458 | 5452 |
5459 // If the condition is constant true, do not generate a branch. | 5453 // If the condition is constant true, do not generate a branch. |
5460 HBasicBlock* loop_successor = NULL; | 5454 HBasicBlock* loop_successor = NULL; |
5461 if (!stmt->cond()->ToBooleanIsTrue()) { | 5455 if (!stmt->cond()->ToBooleanIsTrue()) { |
5462 HBasicBlock* body_entry = graph()->CreateBasicBlock(); | 5456 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
5463 loop_successor = graph()->CreateBasicBlock(); | 5457 loop_successor = graph()->CreateBasicBlock(); |
(...skipping 26 matching lines...) Expand all Loading... |
5490 | 5484 |
5491 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { | 5485 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { |
5492 ASSERT(!HasStackOverflow()); | 5486 ASSERT(!HasStackOverflow()); |
5493 ASSERT(current_block() != NULL); | 5487 ASSERT(current_block() != NULL); |
5494 ASSERT(current_block()->HasPredecessor()); | 5488 ASSERT(current_block()->HasPredecessor()); |
5495 if (stmt->init() != NULL) { | 5489 if (stmt->init() != NULL) { |
5496 CHECK_ALIVE(Visit(stmt->init())); | 5490 CHECK_ALIVE(Visit(stmt->init())); |
5497 } | 5491 } |
5498 ASSERT(current_block() != NULL); | 5492 ASSERT(current_block() != NULL); |
5499 bool osr_entry = PreProcessOsrEntry(stmt); | 5493 bool osr_entry = PreProcessOsrEntry(stmt); |
5500 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5494 HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
5501 current_block()->Goto(loop_entry); | 5495 current_block()->Goto(loop_entry); |
5502 set_current_block(loop_entry); | 5496 set_current_block(loop_entry); |
5503 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5497 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
5504 | 5498 |
5505 HBasicBlock* loop_successor = NULL; | 5499 HBasicBlock* loop_successor = NULL; |
5506 if (stmt->cond() != NULL) { | 5500 if (stmt->cond() != NULL) { |
5507 HBasicBlock* body_entry = graph()->CreateBasicBlock(); | 5501 HBasicBlock* body_entry = graph()->CreateBasicBlock(); |
5508 loop_successor = graph()->CreateBasicBlock(); | 5502 loop_successor = graph()->CreateBasicBlock(); |
5509 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); | 5503 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); |
5510 if (body_entry->HasPredecessor()) { | 5504 if (body_entry->HasPredecessor()) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5585 | 5579 |
5586 HInstruction* index_cache = AddInstruction( | 5580 HInstruction* index_cache = AddInstruction( |
5587 new(zone()) HForInCacheArray( | 5581 new(zone()) HForInCacheArray( |
5588 enumerable, | 5582 enumerable, |
5589 map, | 5583 map, |
5590 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); | 5584 DescriptorArray::kEnumCacheBridgeIndicesCacheIndex)); |
5591 HForInCacheArray::cast(array)->set_index_cache( | 5585 HForInCacheArray::cast(array)->set_index_cache( |
5592 HForInCacheArray::cast(index_cache)); | 5586 HForInCacheArray::cast(index_cache)); |
5593 | 5587 |
5594 bool osr_entry = PreProcessOsrEntry(stmt); | 5588 bool osr_entry = PreProcessOsrEntry(stmt); |
5595 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5589 HBasicBlock* loop_entry = CreateLoopHeaderBlock(stmt->EntryId()); |
5596 current_block()->Goto(loop_entry); | 5590 current_block()->Goto(loop_entry); |
5597 set_current_block(loop_entry); | 5591 set_current_block(loop_entry); |
5598 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5592 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
5599 | 5593 |
5600 HValue* index = environment()->ExpressionStackAt(0); | 5594 HValue* index = environment()->ExpressionStackAt(0); |
5601 HValue* limit = environment()->ExpressionStackAt(1); | 5595 HValue* limit = environment()->ExpressionStackAt(1); |
5602 | 5596 |
5603 // Check that we still have more keys. | 5597 // Check that we still have more keys. |
5604 HCompareIDAndBranch* compare_index = | 5598 HCompareIDAndBranch* compare_index = |
5605 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); | 5599 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); |
(...skipping 2473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8079 // can remove the unsightly ifdefs in this function. | 8073 // can remove the unsightly ifdefs in this function. |
8080 HConstant* context = | 8074 HConstant* context = |
8081 new(zone()) HConstant(Handle<Context>(target->context()), | 8075 new(zone()) HConstant(Handle<Context>(target->context()), |
8082 Representation::Tagged()); | 8076 Representation::Tagged()); |
8083 AddInstruction(context); | 8077 AddInstruction(context); |
8084 inner_env->BindContext(context); | 8078 inner_env->BindContext(context); |
8085 #endif | 8079 #endif |
8086 | 8080 |
8087 AddSimulate(return_id); | 8081 AddSimulate(return_id); |
8088 current_block()->UpdateEnvironment(inner_env); | 8082 current_block()->UpdateEnvironment(inner_env); |
8089 | 8083 inner_env->set_previous_ast_id(BailoutId::FunctionEntry()); |
8090 ZoneList<HValue*>* arguments_values = NULL; | 8084 ZoneList<HValue*>* arguments_values = NULL; |
8091 | 8085 |
8092 // If the function uses arguments copy current arguments values | 8086 // If the function uses arguments copy current arguments values |
8093 // to use them for materialization. | 8087 // to use them for materialization. |
8094 if (function->scope()->arguments() != NULL) { | 8088 if (function->scope()->arguments() != NULL) { |
8095 HEnvironment* arguments_env = inner_env->arguments_environment(); | 8089 HEnvironment* arguments_env = inner_env->arguments_environment(); |
8096 int arguments_count = arguments_env->parameter_count(); | 8090 int arguments_count = arguments_env->parameter_count(); |
8097 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); | 8091 arguments_values = new(zone()) ZoneList<HValue*>(arguments_count, zone()); |
8098 for (int i = 0; i < arguments_count; i++) { | 8092 for (int i = 0; i < arguments_count; i++) { |
8099 arguments_values->Add(arguments_env->Lookup(i), zone()); | 8093 arguments_values->Add(arguments_env->Lookup(i), zone()); |
(...skipping 2502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10602 values_(0, zone), | 10596 values_(0, zone), |
10603 frame_type_(JS_FUNCTION), | 10597 frame_type_(JS_FUNCTION), |
10604 parameter_count_(0), | 10598 parameter_count_(0), |
10605 specials_count_(1), | 10599 specials_count_(1), |
10606 local_count_(0), | 10600 local_count_(0), |
10607 outer_(outer), | 10601 outer_(outer), |
10608 entry_(NULL), | 10602 entry_(NULL), |
10609 pop_count_(0), | 10603 pop_count_(0), |
10610 push_count_(0), | 10604 push_count_(0), |
10611 ast_id_(BailoutId::None()), | 10605 ast_id_(BailoutId::None()), |
| 10606 previous_ast_id_(BailoutId::None()), |
10612 zone_(zone) { | 10607 zone_(zone) { |
10613 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 10608 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
10614 } | 10609 } |
10615 | 10610 |
10616 | 10611 |
10617 HEnvironment::HEnvironment(Zone* zone, int parameter_count) | 10612 HEnvironment::HEnvironment(Zone* zone, int parameter_count) |
10618 : values_(0, zone), | 10613 : values_(0, zone), |
10619 frame_type_(STUB), | 10614 frame_type_(STUB), |
10620 parameter_count_(parameter_count), | 10615 parameter_count_(parameter_count), |
10621 specials_count_(1), | 10616 specials_count_(1), |
10622 local_count_(0), | 10617 local_count_(0), |
10623 outer_(NULL), | 10618 outer_(NULL), |
10624 entry_(NULL), | 10619 entry_(NULL), |
10625 pop_count_(0), | 10620 pop_count_(0), |
10626 push_count_(0), | 10621 push_count_(0), |
10627 ast_id_(BailoutId::None()), | 10622 ast_id_(BailoutId::None()), |
| 10623 previous_ast_id_(BailoutId::None()), |
10628 zone_(zone) { | 10624 zone_(zone) { |
10629 Initialize(parameter_count, 0, 0); | 10625 Initialize(parameter_count, 0, 0); |
10630 } | 10626 } |
10631 | 10627 |
10632 | 10628 |
10633 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) | 10629 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
10634 : values_(0, zone), | 10630 : values_(0, zone), |
10635 frame_type_(JS_FUNCTION), | 10631 frame_type_(JS_FUNCTION), |
10636 parameter_count_(0), | 10632 parameter_count_(0), |
10637 specials_count_(0), | 10633 specials_count_(0), |
10638 local_count_(0), | 10634 local_count_(0), |
10639 outer_(NULL), | 10635 outer_(NULL), |
10640 entry_(NULL), | 10636 entry_(NULL), |
10641 pop_count_(0), | 10637 pop_count_(0), |
10642 push_count_(0), | 10638 push_count_(0), |
10643 ast_id_(other->ast_id()), | 10639 ast_id_(other->ast_id()), |
| 10640 previous_ast_id_(BailoutId::None()), |
10644 zone_(zone) { | 10641 zone_(zone) { |
10645 Initialize(other); | 10642 Initialize(other); |
10646 } | 10643 } |
10647 | 10644 |
10648 | 10645 |
10649 HEnvironment::HEnvironment(HEnvironment* outer, | 10646 HEnvironment::HEnvironment(HEnvironment* outer, |
10650 Handle<JSFunction> closure, | 10647 Handle<JSFunction> closure, |
10651 FrameType frame_type, | 10648 FrameType frame_type, |
10652 int arguments, | 10649 int arguments, |
10653 Zone* zone) | 10650 Zone* zone) |
10654 : closure_(closure), | 10651 : closure_(closure), |
10655 values_(arguments, zone), | 10652 values_(arguments, zone), |
10656 frame_type_(frame_type), | 10653 frame_type_(frame_type), |
10657 parameter_count_(arguments), | 10654 parameter_count_(arguments), |
10658 local_count_(0), | 10655 local_count_(0), |
10659 outer_(outer), | 10656 outer_(outer), |
10660 entry_(NULL), | 10657 entry_(NULL), |
10661 pop_count_(0), | 10658 pop_count_(0), |
10662 push_count_(0), | 10659 push_count_(0), |
10663 ast_id_(BailoutId::None()), | 10660 ast_id_(BailoutId::None()), |
| 10661 previous_ast_id_(BailoutId::None()), |
10664 zone_(zone) { | 10662 zone_(zone) { |
10665 } | 10663 } |
10666 | 10664 |
10667 | 10665 |
10668 void HEnvironment::Initialize(int parameter_count, | 10666 void HEnvironment::Initialize(int parameter_count, |
10669 int local_count, | 10667 int local_count, |
10670 int stack_height) { | 10668 int stack_height) { |
10671 parameter_count_ = parameter_count; | 10669 parameter_count_ = parameter_count; |
10672 local_count_ = local_count; | 10670 local_count_ = local_count; |
10673 | 10671 |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11263 } | 11261 } |
11264 } | 11262 } |
11265 | 11263 |
11266 #ifdef DEBUG | 11264 #ifdef DEBUG |
11267 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11265 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11268 if (allocator_ != NULL) allocator_->Verify(); | 11266 if (allocator_ != NULL) allocator_->Verify(); |
11269 #endif | 11267 #endif |
11270 } | 11268 } |
11271 | 11269 |
11272 } } // namespace v8::internal | 11270 } } // namespace v8::internal |
OLD | NEW |