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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
214 | 214 |
215 void HBasicBlock::SetJoinId(BailoutId ast_id) { | 215 void HBasicBlock::SetJoinId(BailoutId ast_id) { |
216 int length = predecessors_.length(); | 216 int length = predecessors_.length(); |
217 ASSERT(length > 0); | 217 ASSERT(length > 0); |
218 for (int i = 0; i < length; i++) { | 218 for (int i = 0; i < length; i++) { |
219 HBasicBlock* predecessor = predecessors_[i]; | 219 HBasicBlock* predecessor = predecessors_[i]; |
220 ASSERT(predecessor->end()->IsGoto()); | 220 ASSERT(predecessor->end()->IsGoto()); |
221 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); | 221 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); |
222 // We only need to verify the ID once. | 222 // We only need to verify the ID once. |
223 ASSERT(i != 0 || | 223 ASSERT(i != 0 || |
224 predecessor->last_environment()->closure()->shared() | 224 (predecessor->last_environment()->closure().is_null() || |
225 ->VerifyBailoutId(ast_id)); | 225 predecessor->last_environment()->closure()->shared() |
226 ->VerifyBailoutId(ast_id))); | |
226 simulate->set_ast_id(ast_id); | 227 simulate->set_ast_id(ast_id); |
227 } | 228 } |
228 } | 229 } |
229 | 230 |
230 | 231 |
231 bool HBasicBlock::Dominates(HBasicBlock* other) const { | 232 bool HBasicBlock::Dominates(HBasicBlock* other) const { |
232 HBasicBlock* current = other->dominator(); | 233 HBasicBlock* current = other->dominator(); |
233 while (current != NULL) { | 234 while (current != NULL) { |
234 if (current == this) return true; | 235 if (current == this) return true; |
235 current = current->dominator(); | 236 current = current->dominator(); |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 HConstant* HGraph::GetConstantFalse() { | 621 HConstant* HGraph::GetConstantFalse() { |
621 return GetConstant(&constant_false_, isolate()->factory()->false_value()); | 622 return GetConstant(&constant_false_, isolate()->factory()->false_value()); |
622 } | 623 } |
623 | 624 |
624 | 625 |
625 HConstant* HGraph::GetConstantHole() { | 626 HConstant* HGraph::GetConstantHole() { |
626 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); | 627 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); |
627 } | 628 } |
628 | 629 |
629 | 630 |
631 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id) | |
632 : builder_(builder), | |
633 finished_(false), | |
634 id_(id) { | |
635 HEnvironment* env = builder->environment(); | |
636 true_env_ = env->Copy(); | |
637 false_env_ = env->Copy(); | |
638 merge_env_ = env->Copy(); | |
639 true_block_ = builder->CreateBasicBlock(true_env_); | |
640 false_block_ = builder->CreateBasicBlock(false_env_); | |
641 merge_block_ = builder->CreateBasicBlock(merge_env_); | |
642 } | |
643 | |
644 | |
645 void HGraphBuilder::IfBuilder::BeginTrue(HValue* left, | |
646 HValue* right, | |
647 Token::Value token) { | |
648 HCompareIDAndBranch* compare = | |
649 new(zone()) HCompareIDAndBranch(left, right, token); | |
650 compare->ChangeRepresentation(Representation::Integer32()); | |
651 compare->SetSuccessorAt(0, true_block_); | |
652 compare->SetSuccessorAt(1, false_block_); | |
653 builder_->current_block()->Finish(compare); | |
654 builder_->set_current_block(true_block_); | |
655 } | |
656 | |
657 | |
658 void HGraphBuilder::IfBuilder::BeginFalse() { | |
659 builder_->current_block()->Goto(merge_block_); | |
660 builder_->set_current_block(false_block_); | |
661 } | |
662 | |
663 | |
664 void HGraphBuilder::IfBuilder::End() { | |
665 ASSERT(!finished_); | |
666 builder_->current_block()->Goto(merge_block_); | |
667 builder_->set_current_block(merge_block_); | |
668 merge_block_->SetJoinId(id_); | |
669 finished_ = true; | |
670 } | |
671 | |
672 | |
673 HValue* HGraphBuilder::IntegerConstant(int value) { | |
674 Handle<Object> smi(Smi::FromInt(value)); | |
675 return AddInstruction( | |
676 new(zone()) HConstant(smi, Representation::Integer32())); | |
677 } | |
678 | |
679 | |
680 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, | |
681 HValue* context, | |
682 LoopBuilder::Direction direction, | |
683 BailoutId id) | |
684 : builder_(builder), | |
685 context_(context), | |
686 direction_(direction), | |
687 id_(id), | |
688 finished_(false) { | |
689 HEnvironment* env = builder_->environment(); | |
690 body_env_ = env->Copy(); | |
691 exit_env_ = env->Copy(); | |
692 header_block_ = builder->CreateLoopHeaderBlock(); | |
693 body_block_ = builder->CreateBasicBlock(body_env_); | |
694 exit_block_ = builder->CreateBasicBlock(exit_env_); | |
695 } | |
696 | |
697 | |
698 HValue* HGraphBuilder::LoopBuilder::BeginBody(HValue* initial, | |
699 HValue* terminating, | |
700 Token::Value token) { | |
701 phi_ = new(zone()) HPhi(0, zone()); | |
702 header_block_->AddPhi(phi_); | |
703 phi_->AddInput(initial); | |
704 phi_->ChangeRepresentation(Representation::Integer32()); | |
705 HEnvironment* env = builder_->environment(); | |
706 env->Push(initial); | |
707 builder_->current_block()->Goto(header_block_); | |
708 builder_->set_current_block(header_block_); | |
709 | |
710 builder_->set_current_block(header_block_); | |
711 HCompareIDAndBranch* compare = | |
712 new(zone()) HCompareIDAndBranch(phi_, terminating, token); | |
713 compare->ChangeRepresentation(Representation::Integer32()); | |
714 compare->SetSuccessorAt(0, body_block_); | |
715 compare->SetSuccessorAt(1, exit_block_); | |
716 builder_->current_block()->Finish(compare); | |
717 | |
718 builder_->set_current_block(body_block_); | |
719 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { | |
720 if (direction_ == kPreIncrement) { | |
721 increment_ = new(zone()) HAdd(context_, phi_, builder_->One()); | |
722 } else { | |
723 increment_ = new(zone()) HSub(context_, phi_, builder_->One()); | |
724 } | |
725 increment_->ClearFlag(HValue::kCanOverflow); | |
726 increment_->ChangeRepresentation(Representation::Integer32()); | |
727 builder_->AddInstruction(increment_); | |
728 return increment_; | |
729 } else { | |
730 return phi_; | |
731 } | |
732 } | |
733 | |
734 | |
735 void HGraphBuilder::LoopBuilder::EndBody() { | |
736 ASSERT(!finished_); | |
737 | |
738 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { | |
739 if (direction_ == kPostIncrement) { | |
740 increment_ = new(zone()) HAdd(context_, phi_, builder_->One()); | |
741 } else { | |
742 increment_ = new(zone()) HSub(context_, phi_, builder_->One()); | |
743 } | |
744 increment_->ClearFlag(HValue::kCanOverflow); | |
745 increment_->ChangeRepresentation(Representation::Integer32()); | |
746 builder_->AddInstruction(increment_); | |
747 } | |
748 | |
749 body_env_->Push(increment_); | |
750 builder_->current_block()->Goto(header_block_); | |
751 header_block_->loop_information()->RegisterBackEdge(body_block_); | |
752 header_block_->SetJoinId(BailoutId::StubEntry()); | |
753 builder_->set_current_block(exit_block_); | |
754 finished_ = true; | |
755 } | |
756 | |
757 | |
630 HGraph* HGraphBuilder::CreateGraph() { | 758 HGraph* HGraphBuilder::CreateGraph() { |
631 graph_ = new(zone()) HGraph(info_); | 759 graph_ = new(zone()) HGraph(info_); |
632 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_); | 760 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_); |
633 HPhase phase("H_Block building"); | 761 HPhase phase("H_Block building"); |
634 set_current_block(graph()->entry_block()); | 762 set_current_block(graph()->entry_block()); |
635 if (!BuildGraph()) return NULL; | 763 if (!BuildGraph()) return NULL; |
636 return graph_; | 764 return graph_; |
637 } | 765 } |
638 | 766 |
639 | 767 |
640 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 768 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
641 ASSERT(current_block() != NULL); | 769 ASSERT(current_block() != NULL); |
642 current_block()->AddInstruction(instr); | 770 current_block()->AddInstruction(instr); |
643 return instr; | 771 return instr; |
644 } | 772 } |
645 | 773 |
646 | 774 |
647 void HGraphBuilder::AddSimulate(BailoutId id, | 775 void HGraphBuilder::AddSimulate(BailoutId id, |
648 RemovableSimulate removable) { | 776 RemovableSimulate removable) { |
649 ASSERT(current_block() != NULL); | 777 ASSERT(current_block() != NULL); |
650 current_block()->AddSimulate(id, removable); | 778 current_block()->AddSimulate(id, removable); |
651 } | 779 } |
652 | 780 |
653 | 781 |
782 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | |
783 HBasicBlock* b = graph()->CreateBasicBlock(); | |
784 b->SetInitialEnvironment(env); | |
785 return b; | |
786 } | |
787 | |
788 | |
789 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | |
790 HBasicBlock* header = graph()->CreateBasicBlock(); | |
791 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | |
792 header->SetInitialEnvironment(entry_env); | |
793 header->AttachLoopInformation(); | |
794 return header; | |
795 } | |
796 | |
797 | |
654 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 798 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
655 HValue* external_elements, | 799 HValue* external_elements, |
656 HValue* checked_key, | 800 HValue* checked_key, |
657 HValue* val, | 801 HValue* val, |
658 HValue* dependency, | 802 HValue* dependency, |
659 ElementsKind elements_kind, | 803 ElementsKind elements_kind, |
660 bool is_store) { | 804 bool is_store) { |
661 Zone* zone = this->zone(); | 805 Zone* zone = this->zone(); |
662 if (is_store) { | 806 if (is_store) { |
663 ASSERT(val != NULL); | 807 ASSERT(val != NULL); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 } else { | 936 } else { |
793 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 937 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
794 } | 938 } |
795 checked_key = AddInstruction(new(zone) HBoundsCheck( | 939 checked_key = AddInstruction(new(zone) HBoundsCheck( |
796 key, length, ALLOW_SMI_KEY, checked_index_representation)); | 940 key, length, ALLOW_SMI_KEY, checked_index_representation)); |
797 return BuildFastElementAccess(elements, checked_key, val, mapcheck, | 941 return BuildFastElementAccess(elements, checked_key, val, mapcheck, |
798 elements_kind, is_store); | 942 elements_kind, is_store); |
799 } | 943 } |
800 | 944 |
801 | 945 |
946 HValue* HGraphBuilder::BuildAllocateElements(HContext* context, | |
947 ElementsKind kind, | |
948 HValue* capacity) { | |
949 Zone* zone = this->zone(); | |
950 | |
951 int elements_size = IsFastDoubleElementsKind(kind) | |
952 ? kDoubleSize : kPointerSize; | |
953 HValue* mul = AddInstruction( | |
954 new(zone) HMul(context, capacity, IntegerConstant(elements_size))); | |
955 mul->ChangeRepresentation(Representation::Integer32()); | |
956 mul->ClearFlag(HValue::kCanOverflow); | |
957 | |
958 HValue* header_size = IntegerConstant(FixedArrayBase::kHeaderSize); | |
959 HValue* total_size = AddInstruction( | |
960 new(zone) HAdd(context, mul, header_size)); | |
961 total_size->ChangeRepresentation(Representation::Integer32()); | |
962 total_size->ClearFlag(HValue::kCanOverflow); | |
963 | |
964 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | |
965 if (IsFastDoubleElementsKind(kind)) { | |
966 flags = static_cast<HAllocate::Flags>( | |
967 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
968 } | |
969 | |
970 HValue* elements = | |
971 AddInstruction(new(zone) HAllocate(context, total_size, | |
972 HType::JSArray(), flags)); | |
973 Isolate* isolate = graph()->isolate(); | |
974 | |
975 Factory* factory = isolate->factory(); | |
976 Handle<String> map_field_name = factory->map_field_symbol(); | |
977 Handle<Map> map = IsFastDoubleElementsKind(kind) | |
978 ? factory->fixed_double_array_map() | |
979 : factory->fixed_array_map(); | |
980 HValue* map_constant = | |
981 AddInstruction(new(zone) HConstant(map, Representation::Tagged())); | |
982 HInstruction* store_map = | |
983 new(zone) HStoreNamedField(elements, map_field_name, map_constant, | |
984 true, JSObject::kMapOffset); | |
985 store_map->SetSideEffectDominator(kChangesNewSpacePromotion, elements); | |
Michael Starzinger
2013/01/31 13:15:10
Since we are doing GVN we shouldn't need to set th
danno
2013/01/31 15:53:25
Done.
| |
986 AddInstruction(store_map); | |
987 AddSimulate(BailoutId::StubEntry(), FIXED_SIMULATE); | |
988 | |
989 Handle<String> fixed_array_length_field_name = | |
990 isolate->factory()->fixed_array_length_field_symbol(); | |
991 HInstruction* store_length = | |
992 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, | |
993 capacity, true, FixedArray::kLengthOffset); | |
994 store_length->SetSideEffectDominator(kChangesNewSpacePromotion, elements); | |
Michael Starzinger
2013/01/31 13:15:10
Likewise.
danno
2013/01/31 15:53:25
Done.
| |
995 AddInstruction(store_length); | |
996 AddSimulate(BailoutId::StubEntry(), FIXED_SIMULATE); | |
997 | |
998 return elements; | |
999 } | |
1000 | |
1001 | |
1002 void HGraphBuilder::BuildCopyElements(HContext* context, | |
1003 HValue* from_elements, | |
1004 ElementsKind from_elements_kind, | |
1005 HValue* to_elements, | |
1006 ElementsKind to_elements_kind, | |
1007 HValue* length) { | |
1008 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | |
1009 | |
1010 HValue* key = builder.BeginBody(Zero(), length, Token::LT); | |
1011 | |
1012 HValue* element = | |
1013 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, | |
1014 from_elements_kind, | |
1015 ALLOW_RETURN_HOLE)); | |
1016 | |
1017 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, | |
1018 to_elements_kind)); | |
1019 AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE); | |
1020 | |
1021 builder.EndBody(); | |
1022 } | |
1023 | |
1024 | |
802 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1025 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
803 TypeFeedbackOracle* oracle) | 1026 TypeFeedbackOracle* oracle) |
804 : HGraphBuilder(info), | 1027 : HGraphBuilder(info), |
805 function_state_(NULL), | 1028 function_state_(NULL), |
806 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1029 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
807 ast_context_(NULL), | 1030 ast_context_(NULL), |
808 break_scope_(NULL), | 1031 break_scope_(NULL), |
809 inlined_count_(0), | 1032 inlined_count_(0), |
810 globals_(10, info->zone()), | 1033 globals_(10, info->zone()), |
811 inline_bailout_(false) { | 1034 inline_bailout_(false) { |
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2251 TRACE_GVN_1("Updated first-time accumulated %s\n", | 2474 TRACE_GVN_1("Updated first-time accumulated %s\n", |
2252 *GetGVNFlagsString(*first_time_changes)); | 2475 *GetGVNFlagsString(*first_time_changes)); |
2253 } | 2476 } |
2254 } | 2477 } |
2255 instr = next; | 2478 instr = next; |
2256 } | 2479 } |
2257 } | 2480 } |
2258 | 2481 |
2259 | 2482 |
2260 bool HGlobalValueNumberer::AllowCodeMotion() { | 2483 bool HGlobalValueNumberer::AllowCodeMotion() { |
2261 return info()->opt_count() + 1 < FLAG_max_opt_count; | 2484 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count; |
2262 } | 2485 } |
2263 | 2486 |
2264 | 2487 |
2265 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, | 2488 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, |
2266 HBasicBlock* loop_header) { | 2489 HBasicBlock* loop_header) { |
2267 // If we've disabled code motion or we're in a block that unconditionally | 2490 // If we've disabled code motion or we're in a block that unconditionally |
2268 // deoptimizes, don't move any instructions. | 2491 // deoptimizes, don't move any instructions. |
2269 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); | 2492 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); |
2270 } | 2493 } |
2271 | 2494 |
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3503 int checksum = type_info->own_type_change_checksum(); | 3726 int checksum = type_info->own_type_change_checksum(); |
3504 int composite_checksum = graph()->update_type_change_checksum(checksum); | 3727 int composite_checksum = graph()->update_type_change_checksum(checksum); |
3505 graph()->set_use_optimistic_licm( | 3728 graph()->set_use_optimistic_licm( |
3506 !type_info->matches_inlined_type_change_checksum(composite_checksum)); | 3729 !type_info->matches_inlined_type_change_checksum(composite_checksum)); |
3507 type_info->set_inlined_type_change_checksum(composite_checksum); | 3730 type_info->set_inlined_type_change_checksum(composite_checksum); |
3508 | 3731 |
3509 return true; | 3732 return true; |
3510 } | 3733 } |
3511 | 3734 |
3512 | 3735 |
3736 void HGraph::GlobalValueNumbering() { | |
3737 // Perform common subexpression elimination and loop-invariant code motion. | |
3738 if (FLAG_use_gvn) { | |
3739 HPhase phase("H_Global value numbering", this); | |
3740 HGlobalValueNumberer gvn(this, info()); | |
3741 bool removed_side_effects = gvn.Analyze(); | |
3742 // Trigger a second analysis pass to further eliminate duplicate values that | |
3743 // could only be discovered by removing side-effect-generating instructions | |
3744 // during the first pass. | |
3745 if (FLAG_smi_only_arrays && removed_side_effects) { | |
3746 removed_side_effects = gvn.Analyze(); | |
3747 ASSERT(!removed_side_effects); | |
3748 } | |
3749 } | |
3750 } | |
3751 | |
3752 | |
3513 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { | 3753 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
3514 *bailout_reason = SmartArrayPointer<char>(); | 3754 *bailout_reason = SmartArrayPointer<char>(); |
3515 OrderBlocks(); | 3755 OrderBlocks(); |
3516 AssignDominators(); | 3756 AssignDominators(); |
3517 | 3757 |
3518 #ifdef DEBUG | 3758 #ifdef DEBUG |
3519 // Do a full verify after building the graph and computing dominators. | 3759 // Do a full verify after building the graph and computing dominators. |
3520 Verify(true); | 3760 Verify(true); |
3521 #endif | 3761 #endif |
3522 | 3762 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3556 | 3796 |
3557 InitializeInferredTypes(); | 3797 InitializeInferredTypes(); |
3558 | 3798 |
3559 // Must be performed before canonicalization to ensure that Canonicalize | 3799 // Must be performed before canonicalization to ensure that Canonicalize |
3560 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with | 3800 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with |
3561 // zero. | 3801 // zero. |
3562 ComputeSafeUint32Operations(); | 3802 ComputeSafeUint32Operations(); |
3563 | 3803 |
3564 Canonicalize(); | 3804 Canonicalize(); |
3565 | 3805 |
3566 // Perform common subexpression elimination and loop-invariant code motion. | 3806 GlobalValueNumbering(); |
3567 if (FLAG_use_gvn) { | |
3568 HPhase phase("H_Global value numbering", this); | |
3569 HGlobalValueNumberer gvn(this, info()); | |
3570 bool removed_side_effects = gvn.Analyze(); | |
3571 // Trigger a second analysis pass to further eliminate duplicate values that | |
3572 // could only be discovered by removing side-effect-generating instructions | |
3573 // during the first pass. | |
3574 if (FLAG_smi_only_arrays && removed_side_effects) { | |
3575 removed_side_effects = gvn.Analyze(); | |
3576 ASSERT(!removed_side_effects); | |
3577 } | |
3578 } | |
3579 | 3807 |
3580 if (FLAG_use_range) { | 3808 if (FLAG_use_range) { |
3581 HRangeAnalysis rangeAnalysis(this); | 3809 HRangeAnalysis rangeAnalysis(this); |
3582 rangeAnalysis.Analyze(); | 3810 rangeAnalysis.Analyze(); |
3583 } | 3811 } |
3584 ComputeMinusZeroChecks(); | 3812 ComputeMinusZeroChecks(); |
3585 | 3813 |
3586 // Eliminate redundant stack checks on backwards branches. | 3814 // Eliminate redundant stack checks on backwards branches. |
3587 HStackCheckEliminator sce(this); | 3815 HStackCheckEliminator sce(this); |
3588 sce.Process(); | 3816 sce.Process(); |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4158 } | 4386 } |
4159 | 4387 |
4160 | 4388 |
4161 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { | 4389 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { |
4162 for (int i = 0; i < statements->length(); i++) { | 4390 for (int i = 0; i < statements->length(); i++) { |
4163 CHECK_ALIVE(Visit(statements->at(i))); | 4391 CHECK_ALIVE(Visit(statements->at(i))); |
4164 } | 4392 } |
4165 } | 4393 } |
4166 | 4394 |
4167 | 4395 |
4168 HBasicBlock* HOptimizedGraphBuilder::CreateBasicBlock(HEnvironment* env) { | |
4169 HBasicBlock* b = graph()->CreateBasicBlock(); | |
4170 b->SetInitialEnvironment(env); | |
4171 return b; | |
4172 } | |
4173 | |
4174 | |
4175 HBasicBlock* HOptimizedGraphBuilder::CreateLoopHeaderBlock() { | |
4176 HBasicBlock* header = graph()->CreateBasicBlock(); | |
4177 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | |
4178 header->SetInitialEnvironment(entry_env); | |
4179 header->AttachLoopInformation(); | |
4180 return header; | |
4181 } | |
4182 | |
4183 | |
4184 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { | 4396 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { |
4185 ASSERT(!HasStackOverflow()); | 4397 ASSERT(!HasStackOverflow()); |
4186 ASSERT(current_block() != NULL); | 4398 ASSERT(current_block() != NULL); |
4187 ASSERT(current_block()->HasPredecessor()); | 4399 ASSERT(current_block()->HasPredecessor()); |
4188 if (stmt->scope() != NULL) { | 4400 if (stmt->scope() != NULL) { |
4189 return Bailout("ScopedBlock"); | 4401 return Bailout("ScopedBlock"); |
4190 } | 4402 } |
4191 BreakAndContinueInfo break_info(stmt); | 4403 BreakAndContinueInfo break_info(stmt); |
4192 { BreakAndContinueScope push(&break_info, this); | 4404 { BreakAndContinueScope push(&break_info, this); |
4193 CHECK_BAILOUT(VisitStatements(stmt->statements())); | 4405 CHECK_BAILOUT(VisitStatements(stmt->statements())); |
(...skipping 2301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6495 int num_untransitionable_maps = 0; | 6707 int num_untransitionable_maps = 0; |
6496 Handle<Map> untransitionable_map; | 6708 Handle<Map> untransitionable_map; |
6497 HTransitionElementsKind* transition = NULL; | 6709 HTransitionElementsKind* transition = NULL; |
6498 for (int i = 0; i < maps->length(); ++i) { | 6710 for (int i = 0; i < maps->length(); ++i) { |
6499 Handle<Map> map = maps->at(i); | 6711 Handle<Map> map = maps->at(i); |
6500 ASSERT(map->IsMap()); | 6712 ASSERT(map->IsMap()); |
6501 if (!transition_target.at(i).is_null()) { | 6713 if (!transition_target.at(i).is_null()) { |
6502 ASSERT(Map::IsValidElementsTransition( | 6714 ASSERT(Map::IsValidElementsTransition( |
6503 map->elements_kind(), | 6715 map->elements_kind(), |
6504 transition_target.at(i)->elements_kind())); | 6716 transition_target.at(i)->elements_kind())); |
6717 HValue* context = environment()->LookupContext(); | |
6505 transition = new(zone()) HTransitionElementsKind( | 6718 transition = new(zone()) HTransitionElementsKind( |
6506 object, map, transition_target.at(i)); | 6719 context, object, map, transition_target.at(i)); |
6507 AddInstruction(transition); | 6720 AddInstruction(transition); |
6508 } else { | 6721 } else { |
6509 type_todo[map->elements_kind()] = true; | 6722 type_todo[map->elements_kind()] = true; |
6510 if (IsExternalArrayElementsKind(map->elements_kind())) { | 6723 if (IsExternalArrayElementsKind(map->elements_kind())) { |
6511 todo_external_array = true; | 6724 todo_external_array = true; |
6512 } | 6725 } |
6513 num_untransitionable_maps++; | 6726 num_untransitionable_maps++; |
6514 untransitionable_map = map; | 6727 untransitionable_map = map; |
6515 } | 6728 } |
6516 } | 6729 } |
(...skipping 3231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9748 ast_id_(BailoutId::None()), | 9961 ast_id_(BailoutId::None()), |
9749 zone_(zone) { | 9962 zone_(zone) { |
9750 Initialize(0, 0, 0); | 9963 Initialize(0, 0, 0); |
9751 } | 9964 } |
9752 | 9965 |
9753 | 9966 |
9754 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) | 9967 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
9755 : values_(0, zone), | 9968 : values_(0, zone), |
9756 frame_type_(JS_FUNCTION), | 9969 frame_type_(JS_FUNCTION), |
9757 parameter_count_(0), | 9970 parameter_count_(0), |
9758 specials_count_(1), | 9971 specials_count_(0), |
9759 local_count_(0), | 9972 local_count_(0), |
9760 outer_(NULL), | 9973 outer_(NULL), |
9761 entry_(NULL), | 9974 entry_(NULL), |
9762 pop_count_(0), | 9975 pop_count_(0), |
9763 push_count_(0), | 9976 push_count_(0), |
9764 ast_id_(other->ast_id()), | 9977 ast_id_(other->ast_id()), |
9765 zone_(zone) { | 9978 zone_(zone) { |
9766 Initialize(other); | 9979 Initialize(other); |
9767 } | 9980 } |
9768 | 9981 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9803 closure_ = other->closure(); | 10016 closure_ = other->closure(); |
9804 values_.AddAll(other->values_, zone()); | 10017 values_.AddAll(other->values_, zone()); |
9805 assigned_variables_.Union(other->assigned_variables_, zone()); | 10018 assigned_variables_.Union(other->assigned_variables_, zone()); |
9806 frame_type_ = other->frame_type_; | 10019 frame_type_ = other->frame_type_; |
9807 parameter_count_ = other->parameter_count_; | 10020 parameter_count_ = other->parameter_count_; |
9808 local_count_ = other->local_count_; | 10021 local_count_ = other->local_count_; |
9809 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 10022 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
9810 entry_ = other->entry_; | 10023 entry_ = other->entry_; |
9811 pop_count_ = other->pop_count_; | 10024 pop_count_ = other->pop_count_; |
9812 push_count_ = other->push_count_; | 10025 push_count_ = other->push_count_; |
10026 specials_count_ = other->specials_count_; | |
9813 ast_id_ = other->ast_id_; | 10027 ast_id_ = other->ast_id_; |
9814 } | 10028 } |
9815 | 10029 |
9816 | 10030 |
9817 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 10031 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
9818 ASSERT(!block->IsLoopHeader()); | 10032 ASSERT(!block->IsLoopHeader()); |
9819 ASSERT(values_.length() == other->values_.length()); | 10033 ASSERT(values_.length() == other->values_.length()); |
9820 | 10034 |
9821 int length = values_.length(); | 10035 int length = values_.length(); |
9822 for (int i = 0; i < length; ++i) { | 10036 for (int i = 0; i < length; ++i) { |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10348 } | 10562 } |
10349 } | 10563 } |
10350 | 10564 |
10351 #ifdef DEBUG | 10565 #ifdef DEBUG |
10352 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10566 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10353 if (allocator_ != NULL) allocator_->Verify(); | 10567 if (allocator_ != NULL) allocator_->Verify(); |
10354 #endif | 10568 #endif |
10355 } | 10569 } |
10356 | 10570 |
10357 } } // namespace v8::internal | 10571 } } // namespace v8::internal |
OLD | NEW |