OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
713 first_true_block_(NULL), | 713 first_true_block_(NULL), |
714 first_false_block_(NULL), | 714 first_false_block_(NULL), |
715 split_edge_merge_block_(NULL), | 715 split_edge_merge_block_(NULL), |
716 merge_block_(NULL) { | 716 merge_block_(NULL) { |
717 continuation->Continue(&first_true_block_, | 717 continuation->Continue(&first_true_block_, |
718 &first_false_block_, | 718 &first_false_block_, |
719 &position_); | 719 &position_); |
720 } | 720 } |
721 | 721 |
722 | 722 |
723 HInstruction* HGraphBuilder::IfBuilder::IfCompare( | |
724 HValue* left, | |
725 HValue* right, | |
726 Token::Value token) { | |
727 HCompareIDAndBranch* compare = | |
728 new(zone()) HCompareIDAndBranch(left, right, token); | |
729 AddCompare(compare); | |
730 return compare; | |
731 } | |
732 | |
733 | |
734 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left, | |
735 Handle<Map> map) { | |
736 HCompareMap* compare = | |
737 new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_); | |
738 AddCompare(compare); | |
739 return compare; | |
740 } | |
741 | |
742 | |
743 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { | 723 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { |
744 if (split_edge_merge_block_ != NULL) { | 724 if (split_edge_merge_block_ != NULL) { |
745 HEnvironment* env = first_false_block_->last_environment(); | 725 HEnvironment* env = first_false_block_->last_environment(); |
746 HBasicBlock* split_edge = | 726 HBasicBlock* split_edge = |
747 builder_->CreateBasicBlock(env->Copy()); | 727 builder_->CreateBasicBlock(env->Copy()); |
748 if (did_or_) { | 728 if (did_or_) { |
749 compare->SetSuccessorAt(0, split_edge); | 729 compare->SetSuccessorAt(0, split_edge); |
750 compare->SetSuccessorAt(1, first_false_block_); | 730 compare->SetSuccessorAt(1, first_false_block_); |
751 } else { | 731 } else { |
752 compare->SetSuccessorAt(0, first_true_block_); | 732 compare->SetSuccessorAt(0, first_true_block_); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
813 did_then_ = true; | 793 did_then_ = true; |
814 if (needs_compare_) { | 794 if (needs_compare_) { |
815 // Handle if's without any expressions, they jump directly to the "else" | 795 // Handle if's without any expressions, they jump directly to the "else" |
816 // branch. However, we must pretend that the "then" branch is reachable, | 796 // branch. However, we must pretend that the "then" branch is reachable, |
817 // so that the graph builder visits it and sees any live range extending | 797 // so that the graph builder visits it and sees any live range extending |
818 // constructs within it. | 798 // constructs within it. |
819 HConstant* constant_false = builder_->graph()->GetConstantFalse(); | 799 HConstant* constant_false = builder_->graph()->GetConstantFalse(); |
820 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); | 800 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); |
821 boolean_type.Add(ToBooleanStub::BOOLEAN); | 801 boolean_type.Add(ToBooleanStub::BOOLEAN); |
822 HBranch* branch = | 802 HBranch* branch = |
823 new(zone()) HBranch(constant_false, first_true_block_, | 803 new(zone()) HBranch(constant_false, boolean_type, first_true_block_, |
824 first_false_block_, boolean_type); | 804 first_false_block_); |
825 builder_->current_block()->Finish(branch); | 805 builder_->current_block()->Finish(branch); |
826 } | 806 } |
827 builder_->set_current_block(first_true_block_); | 807 builder_->set_current_block(first_true_block_); |
828 } | 808 } |
829 | 809 |
830 | 810 |
831 void HGraphBuilder::IfBuilder::Else() { | 811 void HGraphBuilder::IfBuilder::Else() { |
832 ASSERT(did_then_); | 812 ASSERT(did_then_); |
833 ASSERT(!captured_); | 813 ASSERT(!captured_); |
834 ASSERT(!finished_); | 814 ASSERT(!finished_); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
918 builder_->current_block()->GotoNoSimulate(header_block_); | 898 builder_->current_block()->GotoNoSimulate(header_block_); |
919 | 899 |
920 HEnvironment* body_env = env->Copy(); | 900 HEnvironment* body_env = env->Copy(); |
921 HEnvironment* exit_env = env->Copy(); | 901 HEnvironment* exit_env = env->Copy(); |
922 body_block_ = builder_->CreateBasicBlock(body_env); | 902 body_block_ = builder_->CreateBasicBlock(body_env); |
923 exit_block_ = builder_->CreateBasicBlock(exit_env); | 903 exit_block_ = builder_->CreateBasicBlock(exit_env); |
924 // Remove the phi from the expression stack | 904 // Remove the phi from the expression stack |
925 body_env->Pop(); | 905 body_env->Pop(); |
926 | 906 |
927 builder_->set_current_block(header_block_); | 907 builder_->set_current_block(header_block_); |
928 HCompareIDAndBranch* compare = | 908 HCompareNumericAndBranch* compare = |
929 new(zone()) HCompareIDAndBranch(phi_, terminating, token); | 909 new(zone()) HCompareNumericAndBranch(phi_, terminating, token); |
930 compare->SetSuccessorAt(0, body_block_); | 910 compare->SetSuccessorAt(0, body_block_); |
931 compare->SetSuccessorAt(1, exit_block_); | 911 compare->SetSuccessorAt(1, exit_block_); |
932 builder_->current_block()->Finish(compare); | 912 builder_->current_block()->Finish(compare); |
933 | 913 |
934 builder_->set_current_block(body_block_); | 914 builder_->set_current_block(body_block_); |
935 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { | 915 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { |
936 HValue* one = builder_->graph()->GetConstant1(); | 916 HValue* one = builder_->graph()->GetConstant1(); |
937 if (direction_ == kPreIncrement) { | 917 if (direction_ == kPreIncrement) { |
938 increment_ = HAdd::New(zone(), context_, phi_, one); | 918 increment_ = HAdd::New(zone(), context_, phi_, one); |
939 } else { | 919 } else { |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1133 | 1113 |
1134 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1114 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
1135 HValue* elements, | 1115 HValue* elements, |
1136 ElementsKind kind, | 1116 ElementsKind kind, |
1137 HValue* length, | 1117 HValue* length, |
1138 HValue* key, | 1118 HValue* key, |
1139 bool is_js_array) { | 1119 bool is_js_array) { |
1140 Zone* zone = this->zone(); | 1120 Zone* zone = this->zone(); |
1141 IfBuilder length_checker(this); | 1121 IfBuilder length_checker(this); |
1142 | 1122 |
1143 length_checker.IfCompare(length, key, Token::EQ); | 1123 length_checker.If<HCompareNumericAndBranch>(length, key, Token::EQ); |
1144 length_checker.Then(); | 1124 length_checker.Then(); |
1145 | 1125 |
1146 HValue* current_capacity = Add<HFixedArrayBaseLength>(elements); | 1126 HValue* current_capacity = Add<HFixedArrayBaseLength>(elements); |
1147 | 1127 |
1148 IfBuilder capacity_checker(this); | 1128 IfBuilder capacity_checker(this); |
1149 | 1129 |
1150 capacity_checker.IfCompare(length, current_capacity, Token::EQ); | 1130 capacity_checker.If<HCompareNumericAndBranch>(length, current_capacity, |
1131 Token::EQ); | |
1151 capacity_checker.Then(); | 1132 capacity_checker.Then(); |
1152 | 1133 |
1153 HValue* context = environment()->LookupContext(); | 1134 HValue* context = environment()->LookupContext(); |
1154 | 1135 |
1155 HValue* new_capacity = | 1136 HValue* new_capacity = |
1156 BuildNewElementsCapacity(context, current_capacity); | 1137 BuildNewElementsCapacity(context, current_capacity); |
1157 | 1138 |
1158 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1139 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1159 kind, length, | 1140 kind, length, |
1160 new_capacity); | 1141 new_capacity); |
(...skipping 27 matching lines...) Expand all Loading... | |
1188 | 1169 |
1189 | 1170 |
1190 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1171 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
1191 HValue* elements, | 1172 HValue* elements, |
1192 ElementsKind kind, | 1173 ElementsKind kind, |
1193 HValue* length) { | 1174 HValue* length) { |
1194 Heap* heap = isolate()->heap(); | 1175 Heap* heap = isolate()->heap(); |
1195 | 1176 |
1196 IfBuilder cow_checker(this); | 1177 IfBuilder cow_checker(this); |
1197 | 1178 |
1198 cow_checker.IfCompareMap(elements, | 1179 cow_checker.If<HCompareMap>(elements, |
1199 Handle<Map>(heap->fixed_cow_array_map())); | 1180 Handle<Map>(heap->fixed_cow_array_map())); |
Michael Starzinger
2013/07/01 12:30:39
nit: Use factory->fixed_cow_array_map() instead.
danno
2013/07/05 09:52:39
Done.
| |
1200 cow_checker.Then(); | 1181 cow_checker.Then(); |
1201 | 1182 |
1202 HValue* capacity = Add<HFixedArrayBaseLength>(elements); | 1183 HValue* capacity = Add<HFixedArrayBaseLength>(elements); |
1203 | 1184 |
1204 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1185 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1205 kind, length, capacity); | 1186 kind, length, capacity); |
1206 | 1187 |
1207 environment()->Push(new_elements); | 1188 environment()->Push(new_elements); |
1208 | 1189 |
1209 cow_checker.Else(); | 1190 cow_checker.Else(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1258 } else { | 1239 } else { |
1259 length = Add<HFixedArrayBaseLength>(elements); | 1240 length = Add<HFixedArrayBaseLength>(elements); |
1260 } | 1241 } |
1261 HValue* checked_key = NULL; | 1242 HValue* checked_key = NULL; |
1262 if (IsExternalArrayElementsKind(elements_kind)) { | 1243 if (IsExternalArrayElementsKind(elements_kind)) { |
1263 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1244 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1264 NoObservableSideEffectsScope no_effects(this); | 1245 NoObservableSideEffectsScope no_effects(this); |
1265 HLoadExternalArrayPointer* external_elements = | 1246 HLoadExternalArrayPointer* external_elements = |
1266 Add<HLoadExternalArrayPointer>(elements); | 1247 Add<HLoadExternalArrayPointer>(elements); |
1267 IfBuilder length_checker(this); | 1248 IfBuilder length_checker(this); |
1268 length_checker.IfCompare(key, length, Token::LT); | 1249 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
1269 length_checker.Then(); | 1250 length_checker.Then(); |
1270 IfBuilder negative_checker(this); | 1251 IfBuilder negative_checker(this); |
1271 HValue* bounds_check = negative_checker.IfCompare( | 1252 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
1272 key, graph()->GetConstant0(), Token::GTE); | 1253 key, graph()->GetConstant0(), Token::GTE); |
1273 negative_checker.Then(); | 1254 negative_checker.Then(); |
1274 HInstruction* result = BuildExternalArrayElementAccess( | 1255 HInstruction* result = BuildExternalArrayElementAccess( |
1275 external_elements, key, val, bounds_check, | 1256 external_elements, key, val, bounds_check, |
1276 elements_kind, is_store); | 1257 elements_kind, is_store); |
1277 AddInstruction(result); | 1258 AddInstruction(result); |
1278 negative_checker.ElseDeopt(); | 1259 negative_checker.ElseDeopt(); |
1279 length_checker.End(); | 1260 length_checker.End(); |
1280 return result; | 1261 return result; |
1281 } else { | 1262 } else { |
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2586 class HRangeAnalysis BASE_EMBEDDED { | 2567 class HRangeAnalysis BASE_EMBEDDED { |
2587 public: | 2568 public: |
2588 explicit HRangeAnalysis(HGraph* graph) : | 2569 explicit HRangeAnalysis(HGraph* graph) : |
2589 graph_(graph), zone_(graph->zone()), changed_ranges_(16, zone_) { } | 2570 graph_(graph), zone_(graph->zone()), changed_ranges_(16, zone_) { } |
2590 | 2571 |
2591 void Analyze(); | 2572 void Analyze(); |
2592 | 2573 |
2593 private: | 2574 private: |
2594 void TraceRange(const char* msg, ...); | 2575 void TraceRange(const char* msg, ...); |
2595 void Analyze(HBasicBlock* block); | 2576 void Analyze(HBasicBlock* block); |
2596 void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest); | 2577 void InferControlFlowRange(HCompareNumericAndBranch* test, HBasicBlock* dest); |
2597 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other); | 2578 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other); |
2598 void InferRange(HValue* value); | 2579 void InferRange(HValue* value); |
2599 void RollBackTo(int index); | 2580 void RollBackTo(int index); |
2600 void AddRange(HValue* value, Range* range); | 2581 void AddRange(HValue* value, Range* range); |
2601 | 2582 |
2602 HGraph* graph_; | 2583 HGraph* graph_; |
2603 Zone* zone_; | 2584 Zone* zone_; |
2604 ZoneList<HValue*> changed_ranges_; | 2585 ZoneList<HValue*> changed_ranges_; |
2605 }; | 2586 }; |
2606 | 2587 |
(...skipping 15 matching lines...) Expand all Loading... | |
2622 | 2603 |
2623 | 2604 |
2624 void HRangeAnalysis::Analyze(HBasicBlock* block) { | 2605 void HRangeAnalysis::Analyze(HBasicBlock* block) { |
2625 TraceRange("Analyzing block B%d\n", block->block_id()); | 2606 TraceRange("Analyzing block B%d\n", block->block_id()); |
2626 | 2607 |
2627 int last_changed_range = changed_ranges_.length() - 1; | 2608 int last_changed_range = changed_ranges_.length() - 1; |
2628 | 2609 |
2629 // Infer range based on control flow. | 2610 // Infer range based on control flow. |
2630 if (block->predecessors()->length() == 1) { | 2611 if (block->predecessors()->length() == 1) { |
2631 HBasicBlock* pred = block->predecessors()->first(); | 2612 HBasicBlock* pred = block->predecessors()->first(); |
2632 if (pred->end()->IsCompareIDAndBranch()) { | 2613 if (pred->end()->IsCompareNumericAndBranch()) { |
2633 InferControlFlowRange(HCompareIDAndBranch::cast(pred->end()), block); | 2614 InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()), block); |
2634 } | 2615 } |
2635 } | 2616 } |
2636 | 2617 |
2637 // Process phi instructions. | 2618 // Process phi instructions. |
2638 for (int i = 0; i < block->phis()->length(); ++i) { | 2619 for (int i = 0; i < block->phis()->length(); ++i) { |
2639 HPhi* phi = block->phis()->at(i); | 2620 HPhi* phi = block->phis()->at(i); |
2640 InferRange(phi); | 2621 InferRange(phi); |
2641 } | 2622 } |
2642 | 2623 |
2643 // Go through all instructions of the current block. | 2624 // Go through all instructions of the current block. |
2644 HInstruction* instr = block->first(); | 2625 HInstruction* instr = block->first(); |
2645 while (instr != block->end()) { | 2626 while (instr != block->end()) { |
2646 InferRange(instr); | 2627 InferRange(instr); |
2647 instr = instr->next(); | 2628 instr = instr->next(); |
2648 } | 2629 } |
2649 | 2630 |
2650 // Continue analysis in all dominated blocks. | 2631 // Continue analysis in all dominated blocks. |
2651 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | 2632 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { |
2652 Analyze(block->dominated_blocks()->at(i)); | 2633 Analyze(block->dominated_blocks()->at(i)); |
2653 } | 2634 } |
2654 | 2635 |
2655 RollBackTo(last_changed_range); | 2636 RollBackTo(last_changed_range); |
2656 } | 2637 } |
2657 | 2638 |
2658 | 2639 |
2659 void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test, | 2640 void HRangeAnalysis::InferControlFlowRange(HCompareNumericAndBranch* test, |
2660 HBasicBlock* dest) { | 2641 HBasicBlock* dest) { |
2661 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); | 2642 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); |
2662 if (test->representation().IsSmiOrInteger32()) { | 2643 if (test->representation().IsSmiOrInteger32()) { |
2663 Token::Value op = test->token(); | 2644 Token::Value op = test->token(); |
2664 if (test->SecondSuccessor() == dest) { | 2645 if (test->SecondSuccessor() == dest) { |
2665 op = Token::NegateCompareOp(op); | 2646 op = Token::NegateCompareOp(op); |
2666 } | 2647 } |
2667 Token::Value inverted_op = Token::ReverseCompareOp(op); | 2648 Token::Value inverted_op = Token::ReverseCompareOp(op); |
2668 UpdateControlFlowRange(op, test->left(), test->right()); | 2649 UpdateControlFlowRange(op, test->left(), test->right()); |
2669 UpdateControlFlowRange(inverted_op, test->right(), test->left()); | 2650 UpdateControlFlowRange(inverted_op, test->right(), test->left()); |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3074 HValue* input = phi->OperandAt(i); | 3055 HValue* input = phi->OperandAt(i); |
3075 if (input->IsPhi()) { | 3056 if (input->IsPhi()) { |
3076 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); | 3057 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); |
3077 } | 3058 } |
3078 } | 3059 } |
3079 } | 3060 } |
3080 | 3061 |
3081 | 3062 |
3082 void HGraph::MarkDeoptimizeOnUndefined() { | 3063 void HGraph::MarkDeoptimizeOnUndefined() { |
3083 HPhase phase("H_MarkDeoptimizeOnUndefined", this); | 3064 HPhase phase("H_MarkDeoptimizeOnUndefined", this); |
3084 // Compute DeoptimizeOnUndefined flag for phis. | 3065 // Compute DeoptimizeOnUndefined flag for phis. Any phi that can reach a use |
3085 // Any phi that can reach a use with DeoptimizeOnUndefined set must | 3066 // with DeoptimizeOnUndefined set must have DeoptimizeOnUndefined set. |
3086 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with | 3067 // Currently only HCompareNumericAndBranch, with double input representation, |
3087 // double input representation, has this flag set. | 3068 // has this flag set. The flag is used by HChange tagged->double, which must |
3088 // The flag is used by HChange tagged->double, which must deoptimize | 3069 // deoptimize if one of its uses has this flag set. |
3089 // if one of its uses has this flag set. | |
3090 for (int i = 0; i < phi_list()->length(); i++) { | 3070 for (int i = 0; i < phi_list()->length(); i++) { |
3091 HPhi* phi = phi_list()->at(i); | 3071 HPhi* phi = phi_list()->at(i); |
3092 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { | 3072 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
3093 HValue* use_value = it.value(); | 3073 HValue* use_value = it.value(); |
3094 if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) { | 3074 if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) { |
3095 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); | 3075 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); |
3096 break; | 3076 break; |
3097 } | 3077 } |
3098 } | 3078 } |
3099 } | 3079 } |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3603 builder->current_block()->Goto(if_true(), builder->function_state()); | 3583 builder->current_block()->Goto(if_true(), builder->function_state()); |
3604 } else { | 3584 } else { |
3605 builder->current_block()->Goto(if_false(), builder->function_state()); | 3585 builder->current_block()->Goto(if_false(), builder->function_state()); |
3606 } | 3586 } |
3607 builder->set_current_block(NULL); | 3587 builder->set_current_block(NULL); |
3608 return; | 3588 return; |
3609 } | 3589 } |
3610 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 3590 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
3611 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 3591 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
3612 ToBooleanStub::Types expected(condition()->to_boolean_types()); | 3592 ToBooleanStub::Types expected(condition()->to_boolean_types()); |
3613 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); | 3593 HBranch* test = new(zone()) HBranch(value, expected, empty_true, empty_false); |
3614 builder->current_block()->Finish(test); | 3594 builder->current_block()->Finish(test); |
3615 | 3595 |
3616 empty_true->Goto(if_true(), builder->function_state()); | 3596 empty_true->Goto(if_true(), builder->function_state()); |
3617 empty_false->Goto(if_false(), builder->function_state()); | 3597 empty_false->Goto(if_false(), builder->function_state()); |
3618 builder->set_current_block(NULL); | 3598 builder->set_current_block(NULL); |
3619 } | 3599 } |
3620 | 3600 |
3621 | 3601 |
3622 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. | 3602 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. |
3623 #define CHECK_BAILOUT(call) \ | 3603 #define CHECK_BAILOUT(call) \ |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4820 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 4800 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
4821 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 4801 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
4822 | 4802 |
4823 HControlInstruction* compare; | 4803 HControlInstruction* compare; |
4824 | 4804 |
4825 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { | 4805 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { |
4826 if (!clause->compare_type()->Is(Type::Smi())) { | 4806 if (!clause->compare_type()->Is(Type::Smi())) { |
4827 AddSoftDeoptimize(); | 4807 AddSoftDeoptimize(); |
4828 } | 4808 } |
4829 | 4809 |
4830 HCompareIDAndBranch* compare_ = | 4810 HCompareNumericAndBranch* compare_ = |
4831 new(zone()) HCompareIDAndBranch(tag_value, | 4811 new(zone()) HCompareNumericAndBranch(tag_value, |
4832 label_value, | 4812 label_value, |
4833 Token::EQ_STRICT); | 4813 Token::EQ_STRICT); |
4834 compare_->set_observed_input_representation( | 4814 compare_->set_observed_input_representation( |
4835 Representation::Smi(), Representation::Smi()); | 4815 Representation::Smi(), Representation::Smi()); |
4836 compare = compare_; | 4816 compare = compare_; |
4837 } else { | 4817 } else { |
4838 compare = new(zone()) HStringCompareAndBranch(context, tag_value, | 4818 compare = new(zone()) HStringCompareAndBranch(context, tag_value, |
4839 label_value, | 4819 label_value, |
4840 Token::EQ_STRICT); | 4820 Token::EQ_STRICT); |
4841 } | 4821 } |
4842 | 4822 |
4843 compare->SetSuccessorAt(0, body_block); | 4823 compare->SetSuccessorAt(0, body_block); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4928 return statement->OsrEntryId() == current_info()->osr_ast_id(); | 4908 return statement->OsrEntryId() == current_info()->osr_ast_id(); |
4929 } | 4909 } |
4930 | 4910 |
4931 | 4911 |
4932 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { | 4912 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
4933 if (!HasOsrEntryAt(statement)) return false; | 4913 if (!HasOsrEntryAt(statement)) return false; |
4934 | 4914 |
4935 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 4915 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
4936 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 4916 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
4937 HValue* true_value = graph()->GetConstantTrue(); | 4917 HValue* true_value = graph()->GetConstantTrue(); |
4938 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); | 4918 HBranch* test = new(zone()) HBranch(true_value, ToBooleanStub::Types(), |
4919 non_osr_entry, osr_entry); | |
4939 current_block()->Finish(test); | 4920 current_block()->Finish(test); |
4940 | 4921 |
4941 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 4922 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
4942 non_osr_entry->Goto(loop_predecessor); | 4923 non_osr_entry->Goto(loop_predecessor); |
4943 | 4924 |
4944 set_current_block(osr_entry); | 4925 set_current_block(osr_entry); |
4945 osr_entry->set_osr_entry(); | 4926 osr_entry->set_osr_entry(); |
4946 BailoutId osr_entry_id = statement->OsrEntryId(); | 4927 BailoutId osr_entry_id = statement->OsrEntryId(); |
4947 int first_expression_index = environment()->first_expression_index(); | 4928 int first_expression_index = environment()->first_expression_index(); |
4948 int length = environment()->length(); | 4929 int length = environment()->length(); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5177 bool osr_entry = PreProcessOsrEntry(stmt); | 5158 bool osr_entry = PreProcessOsrEntry(stmt); |
5178 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); | 5159 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); |
5179 current_block()->Goto(loop_entry); | 5160 current_block()->Goto(loop_entry); |
5180 set_current_block(loop_entry); | 5161 set_current_block(loop_entry); |
5181 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); | 5162 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); |
5182 | 5163 |
5183 HValue* index = environment()->ExpressionStackAt(0); | 5164 HValue* index = environment()->ExpressionStackAt(0); |
5184 HValue* limit = environment()->ExpressionStackAt(1); | 5165 HValue* limit = environment()->ExpressionStackAt(1); |
5185 | 5166 |
5186 // Check that we still have more keys. | 5167 // Check that we still have more keys. |
5187 HCompareIDAndBranch* compare_index = | 5168 HCompareNumericAndBranch* compare_index = |
5188 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); | 5169 new(zone()) HCompareNumericAndBranch(index, limit, Token::LT); |
5189 compare_index->set_observed_input_representation( | 5170 compare_index->set_observed_input_representation( |
5190 Representation::Smi(), Representation::Smi()); | 5171 Representation::Smi(), Representation::Smi()); |
5191 | 5172 |
5192 HBasicBlock* loop_body = graph()->CreateBasicBlock(); | 5173 HBasicBlock* loop_body = graph()->CreateBasicBlock(); |
5193 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); | 5174 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); |
5194 | 5175 |
5195 compare_index->SetSuccessorAt(0, loop_body); | 5176 compare_index->SetSuccessorAt(0, loop_body); |
5196 compare_index->SetSuccessorAt(1, loop_successor); | 5177 compare_index->SetSuccessorAt(1, loop_successor); |
5197 current_block()->Finish(compare_index); | 5178 current_block()->Finish(compare_index); |
5198 | 5179 |
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6233 LookupResult lookup(isolate()); | 6214 LookupResult lookup(isolate()); |
6234 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 6215 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
6235 if (count == 0) { | 6216 if (count == 0) { |
6236 BuildCheckHeapObject(object); | 6217 BuildCheckHeapObject(object); |
6237 join = graph()->CreateBasicBlock(); | 6218 join = graph()->CreateBasicBlock(); |
6238 } | 6219 } |
6239 ++count; | 6220 ++count; |
6240 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 6221 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
6241 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 6222 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
6242 HCompareMap* compare = | 6223 HCompareMap* compare = |
6243 new(zone()) HCompareMap(object, map, if_true, if_false); | 6224 new(zone()) HCompareMap(object, map, if_true, if_false); |
6244 current_block()->Finish(compare); | 6225 current_block()->Finish(compare); |
6245 | 6226 |
6246 set_current_block(if_true); | 6227 set_current_block(if_true); |
6247 HInstruction* instr; | 6228 HInstruction* instr; |
6248 CHECK_ALIVE( | 6229 CHECK_ALIVE( |
6249 instr = BuildStoreNamedField(object, name, value, map, &lookup)); | 6230 instr = BuildStoreNamedField(object, name, value, map, &lookup)); |
6250 instr->set_position(position); | 6231 instr->set_position(position); |
6251 // Goto will add the HSimulate for the store. | 6232 // Goto will add the HSimulate for the store. |
6252 AddInstruction(instr); | 6233 AddInstruction(instr); |
6253 if (!ast_context()->IsEffect()) Push(value); | 6234 if (!ast_context()->IsEffect()) Push(value); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6338 BailoutId ast_id) { | 6319 BailoutId ast_id) { |
6339 LookupResult lookup(isolate()); | 6320 LookupResult lookup(isolate()); |
6340 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 6321 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
6341 if (type == kUseCell) { | 6322 if (type == kUseCell) { |
6342 Handle<GlobalObject> global(current_info()->global_object()); | 6323 Handle<GlobalObject> global(current_info()->global_object()); |
6343 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 6324 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
6344 if (cell->type()->IsConstant()) { | 6325 if (cell->type()->IsConstant()) { |
6345 IfBuilder builder(this); | 6326 IfBuilder builder(this); |
6346 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); | 6327 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); |
6347 if (cell->type()->AsConstant()->IsNumber()) { | 6328 if (cell->type()->AsConstant()->IsNumber()) { |
6348 builder.IfCompare(value, constant, Token::EQ); | 6329 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ); |
6349 } else { | 6330 } else { |
6350 builder.If<HCompareObjectEqAndBranch>(value, constant); | 6331 builder.If<HCompareObjectEqAndBranch>(value, constant); |
6351 } | 6332 } |
6352 builder.Then(); | 6333 builder.Then(); |
6353 builder.Else(); | 6334 builder.Else(); |
6354 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); | 6335 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); |
6355 builder.End(); | 6336 builder.End(); |
6356 } | 6337 } |
6357 HInstruction* instr = | 6338 HInstruction* instr = |
6358 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); | 6339 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); |
(...skipping 2963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9322 CHECK_ALIVE(VisitForValue(expr->right())); | 9303 CHECK_ALIVE(VisitForValue(expr->right())); |
9323 } | 9304 } |
9324 return ast_context()->ReturnValue(Pop()); | 9305 return ast_context()->ReturnValue(Pop()); |
9325 } | 9306 } |
9326 | 9307 |
9327 // We need an extra block to maintain edge-split form. | 9308 // We need an extra block to maintain edge-split form. |
9328 HBasicBlock* empty_block = graph()->CreateBasicBlock(); | 9309 HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
9329 HBasicBlock* eval_right = graph()->CreateBasicBlock(); | 9310 HBasicBlock* eval_right = graph()->CreateBasicBlock(); |
9330 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); | 9311 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); |
9331 HBranch* test = is_logical_and | 9312 HBranch* test = is_logical_and |
9332 ? new(zone()) HBranch(left_value, eval_right, empty_block, expected) | 9313 ? new(zone()) HBranch(left_value, expected, eval_right, empty_block) |
9333 : new(zone()) HBranch(left_value, empty_block, eval_right, expected); | 9314 : new(zone()) HBranch(left_value, expected, empty_block, eval_right); |
9334 current_block()->Finish(test); | 9315 current_block()->Finish(test); |
9335 | 9316 |
9336 set_current_block(eval_right); | 9317 set_current_block(eval_right); |
9337 Drop(1); // Value of the left subexpression. | 9318 Drop(1); // Value of the left subexpression. |
9338 CHECK_BAILOUT(VisitForValue(expr->right())); | 9319 CHECK_BAILOUT(VisitForValue(expr->right())); |
9339 | 9320 |
9340 HBasicBlock* join_block = | 9321 HBasicBlock* join_block = |
9341 CreateJoin(empty_block, current_block(), expr->id()); | 9322 CreateJoin(empty_block, current_block(), expr->id()); |
9342 set_current_block(join_block); | 9323 set_current_block(join_block); |
9343 return ast_context()->ReturnValue(Pop()); | 9324 return ast_context()->ReturnValue(Pop()); |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9630 new(zone()) HCompareGeneric(context, left, right, op); | 9611 new(zone()) HCompareGeneric(context, left, right, op); |
9631 result->set_observed_input_representation(1, left_rep); | 9612 result->set_observed_input_representation(1, left_rep); |
9632 result->set_observed_input_representation(2, right_rep); | 9613 result->set_observed_input_representation(2, right_rep); |
9633 result->set_position(expr->position()); | 9614 result->set_position(expr->position()); |
9634 return ast_context()->ReturnInstruction(result, expr->id()); | 9615 return ast_context()->ReturnInstruction(result, expr->id()); |
9635 } else { | 9616 } else { |
9636 // TODO(verwaest): Remove once ToRepresentation properly returns Smi when | 9617 // TODO(verwaest): Remove once ToRepresentation properly returns Smi when |
9637 // the IC measures Smi. | 9618 // the IC measures Smi. |
9638 if (left_type->Is(Type::Smi())) left_rep = Representation::Smi(); | 9619 if (left_type->Is(Type::Smi())) left_rep = Representation::Smi(); |
9639 if (right_type->Is(Type::Smi())) right_rep = Representation::Smi(); | 9620 if (right_type->Is(Type::Smi())) right_rep = Representation::Smi(); |
9640 HCompareIDAndBranch* result = | 9621 HCompareNumericAndBranch* result = |
9641 new(zone()) HCompareIDAndBranch(left, right, op); | 9622 new(zone()) HCompareNumericAndBranch(left, right, op); |
9642 result->set_observed_input_representation(left_rep, right_rep); | 9623 result->set_observed_input_representation(left_rep, right_rep); |
9643 result->set_position(expr->position()); | 9624 result->set_position(expr->position()); |
9644 return ast_context()->ReturnControl(result, expr->id()); | 9625 return ast_context()->ReturnControl(result, expr->id()); |
9645 } | 9626 } |
9646 } | 9627 } |
9647 } | 9628 } |
9648 | 9629 |
9649 | 9630 |
9650 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 9631 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
9651 HValue* value, | 9632 HValue* value, |
(...skipping 1629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11281 if (ShouldProduceTraceOutput()) { | 11262 if (ShouldProduceTraceOutput()) { |
11282 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11263 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11283 } | 11264 } |
11284 | 11265 |
11285 #ifdef DEBUG | 11266 #ifdef DEBUG |
11286 graph_->Verify(false); // No full verify. | 11267 graph_->Verify(false); // No full verify. |
11287 #endif | 11268 #endif |
11288 } | 11269 } |
11289 | 11270 |
11290 } } // namespace v8::internal | 11271 } } // namespace v8::internal |
OLD | NEW |