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 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 first_true_block_(NULL), | 718 first_true_block_(NULL), |
719 first_false_block_(NULL), | 719 first_false_block_(NULL), |
720 split_edge_merge_block_(NULL), | 720 split_edge_merge_block_(NULL), |
721 merge_block_(NULL) { | 721 merge_block_(NULL) { |
722 continuation->Continue(&first_true_block_, | 722 continuation->Continue(&first_true_block_, |
723 &first_false_block_, | 723 &first_false_block_, |
724 &position_); | 724 &position_); |
725 } | 725 } |
726 | 726 |
727 | 727 |
728 HInstruction* HGraphBuilder::IfBuilder::IfCompare( | |
729 HValue* left, | |
730 HValue* right, | |
731 Token::Value token) { | |
732 HCompareIDAndBranch* compare = | |
733 new(zone()) HCompareIDAndBranch(left, right, token); | |
734 AddCompare(compare); | |
735 return compare; | |
736 } | |
737 | |
738 | |
739 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left, | |
740 Handle<Map> map) { | |
741 HCompareMap* compare = | |
742 new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_); | |
743 AddCompare(compare); | |
744 return compare; | |
745 } | |
746 | |
747 | |
748 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { | 728 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { |
749 if (split_edge_merge_block_ != NULL) { | 729 if (split_edge_merge_block_ != NULL) { |
750 HEnvironment* env = first_false_block_->last_environment(); | 730 HEnvironment* env = first_false_block_->last_environment(); |
751 HBasicBlock* split_edge = | 731 HBasicBlock* split_edge = |
752 builder_->CreateBasicBlock(env->Copy()); | 732 builder_->CreateBasicBlock(env->Copy()); |
753 if (did_or_) { | 733 if (did_or_) { |
754 compare->SetSuccessorAt(0, split_edge); | 734 compare->SetSuccessorAt(0, split_edge); |
755 compare->SetSuccessorAt(1, first_false_block_); | 735 compare->SetSuccessorAt(1, first_false_block_); |
756 } else { | 736 } else { |
757 compare->SetSuccessorAt(0, first_true_block_); | 737 compare->SetSuccessorAt(0, first_true_block_); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 did_then_ = true; | 798 did_then_ = true; |
819 if (needs_compare_) { | 799 if (needs_compare_) { |
820 // Handle if's without any expressions, they jump directly to the "else" | 800 // Handle if's without any expressions, they jump directly to the "else" |
821 // branch. However, we must pretend that the "then" branch is reachable, | 801 // branch. However, we must pretend that the "then" branch is reachable, |
822 // so that the graph builder visits it and sees any live range extending | 802 // so that the graph builder visits it and sees any live range extending |
823 // constructs within it. | 803 // constructs within it. |
824 HConstant* constant_false = builder_->graph()->GetConstantFalse(); | 804 HConstant* constant_false = builder_->graph()->GetConstantFalse(); |
825 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); | 805 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); |
826 boolean_type.Add(ToBooleanStub::BOOLEAN); | 806 boolean_type.Add(ToBooleanStub::BOOLEAN); |
827 HBranch* branch = | 807 HBranch* branch = |
828 new(zone()) HBranch(constant_false, first_true_block_, | 808 new(zone()) HBranch(constant_false, boolean_type, first_true_block_, |
829 first_false_block_, boolean_type); | 809 first_false_block_); |
830 builder_->current_block()->Finish(branch); | 810 builder_->current_block()->Finish(branch); |
831 } | 811 } |
832 builder_->set_current_block(first_true_block_); | 812 builder_->set_current_block(first_true_block_); |
833 } | 813 } |
834 | 814 |
835 | 815 |
836 void HGraphBuilder::IfBuilder::Else() { | 816 void HGraphBuilder::IfBuilder::Else() { |
837 ASSERT(did_then_); | 817 ASSERT(did_then_); |
838 ASSERT(!captured_); | 818 ASSERT(!captured_); |
839 ASSERT(!finished_); | 819 ASSERT(!finished_); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 builder_->current_block()->GotoNoSimulate(header_block_); | 903 builder_->current_block()->GotoNoSimulate(header_block_); |
924 | 904 |
925 HEnvironment* body_env = env->Copy(); | 905 HEnvironment* body_env = env->Copy(); |
926 HEnvironment* exit_env = env->Copy(); | 906 HEnvironment* exit_env = env->Copy(); |
927 body_block_ = builder_->CreateBasicBlock(body_env); | 907 body_block_ = builder_->CreateBasicBlock(body_env); |
928 exit_block_ = builder_->CreateBasicBlock(exit_env); | 908 exit_block_ = builder_->CreateBasicBlock(exit_env); |
929 // Remove the phi from the expression stack | 909 // Remove the phi from the expression stack |
930 body_env->Pop(); | 910 body_env->Pop(); |
931 | 911 |
932 builder_->set_current_block(header_block_); | 912 builder_->set_current_block(header_block_); |
933 HCompareIDAndBranch* compare = | 913 HCompareNumericAndBranch* compare = |
934 new(zone()) HCompareIDAndBranch(phi_, terminating, token); | 914 new(zone()) HCompareNumericAndBranch(phi_, terminating, token); |
935 compare->SetSuccessorAt(0, body_block_); | 915 compare->SetSuccessorAt(0, body_block_); |
936 compare->SetSuccessorAt(1, exit_block_); | 916 compare->SetSuccessorAt(1, exit_block_); |
937 builder_->current_block()->Finish(compare); | 917 builder_->current_block()->Finish(compare); |
938 | 918 |
939 builder_->set_current_block(body_block_); | 919 builder_->set_current_block(body_block_); |
940 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { | 920 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { |
941 HValue* one = builder_->graph()->GetConstant1(); | 921 HValue* one = builder_->graph()->GetConstant1(); |
942 if (direction_ == kPreIncrement) { | 922 if (direction_ == kPreIncrement) { |
943 increment_ = HAdd::New(zone(), context_, phi_, one); | 923 increment_ = HAdd::New(zone(), context_, phi_, one); |
944 } else { | 924 } else { |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 | 1129 |
1150 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1130 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
1151 HValue* elements, | 1131 HValue* elements, |
1152 ElementsKind kind, | 1132 ElementsKind kind, |
1153 HValue* length, | 1133 HValue* length, |
1154 HValue* key, | 1134 HValue* key, |
1155 bool is_js_array) { | 1135 bool is_js_array) { |
1156 Zone* zone = this->zone(); | 1136 Zone* zone = this->zone(); |
1157 IfBuilder length_checker(this); | 1137 IfBuilder length_checker(this); |
1158 | 1138 |
1159 length_checker.IfCompare(length, key, Token::EQ); | 1139 length_checker.If<HCompareNumericAndBranch>(length, key, Token::EQ); |
1160 length_checker.Then(); | 1140 length_checker.Then(); |
1161 | 1141 |
1162 HValue* current_capacity = AddLoadFixedArrayLength(elements); | 1142 HValue* current_capacity = AddLoadFixedArrayLength(elements); |
1163 | 1143 |
1164 IfBuilder capacity_checker(this); | 1144 IfBuilder capacity_checker(this); |
1165 | 1145 |
1166 capacity_checker.IfCompare(length, current_capacity, Token::EQ); | 1146 capacity_checker.If<HCompareNumericAndBranch>(length, current_capacity, |
| 1147 Token::EQ); |
1167 capacity_checker.Then(); | 1148 capacity_checker.Then(); |
1168 | 1149 |
1169 HValue* context = environment()->LookupContext(); | 1150 HValue* context = environment()->LookupContext(); |
1170 | 1151 |
1171 HValue* new_capacity = | 1152 HValue* new_capacity = |
1172 BuildNewElementsCapacity(context, current_capacity); | 1153 BuildNewElementsCapacity(context, current_capacity); |
1173 | 1154 |
1174 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1155 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1175 kind, length, | 1156 kind, length, |
1176 new_capacity); | 1157 new_capacity); |
(...skipping 23 matching lines...) Expand all Loading... |
1200 length_checker.End(); | 1181 length_checker.End(); |
1201 | 1182 |
1202 return environment()->Pop(); | 1183 return environment()->Pop(); |
1203 } | 1184 } |
1204 | 1185 |
1205 | 1186 |
1206 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1187 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
1207 HValue* elements, | 1188 HValue* elements, |
1208 ElementsKind kind, | 1189 ElementsKind kind, |
1209 HValue* length) { | 1190 HValue* length) { |
1210 Heap* heap = isolate()->heap(); | 1191 Factory* factory = isolate()->factory(); |
1211 | 1192 |
1212 IfBuilder cow_checker(this); | 1193 IfBuilder cow_checker(this); |
1213 | 1194 |
1214 cow_checker.IfCompareMap(elements, | 1195 cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map()); |
1215 Handle<Map>(heap->fixed_cow_array_map())); | |
1216 cow_checker.Then(); | 1196 cow_checker.Then(); |
1217 | 1197 |
1218 HValue* capacity = AddLoadFixedArrayLength(elements); | 1198 HValue* capacity = AddLoadFixedArrayLength(elements); |
1219 | 1199 |
1220 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1200 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1221 kind, length, capacity); | 1201 kind, length, capacity); |
1222 | 1202 |
1223 environment()->Push(new_elements); | 1203 environment()->Push(new_elements); |
1224 | 1204 |
1225 cow_checker.Else(); | 1205 cow_checker.Else(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 length = AddLoadFixedArrayLength(elements); | 1254 length = AddLoadFixedArrayLength(elements); |
1275 } | 1255 } |
1276 length->set_type(HType::Smi()); | 1256 length->set_type(HType::Smi()); |
1277 HValue* checked_key = NULL; | 1257 HValue* checked_key = NULL; |
1278 if (IsExternalArrayElementsKind(elements_kind)) { | 1258 if (IsExternalArrayElementsKind(elements_kind)) { |
1279 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1259 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1280 NoObservableSideEffectsScope no_effects(this); | 1260 NoObservableSideEffectsScope no_effects(this); |
1281 HLoadExternalArrayPointer* external_elements = | 1261 HLoadExternalArrayPointer* external_elements = |
1282 Add<HLoadExternalArrayPointer>(elements); | 1262 Add<HLoadExternalArrayPointer>(elements); |
1283 IfBuilder length_checker(this); | 1263 IfBuilder length_checker(this); |
1284 length_checker.IfCompare(key, length, Token::LT); | 1264 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
1285 length_checker.Then(); | 1265 length_checker.Then(); |
1286 IfBuilder negative_checker(this); | 1266 IfBuilder negative_checker(this); |
1287 HValue* bounds_check = negative_checker.IfCompare( | 1267 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
1288 key, graph()->GetConstant0(), Token::GTE); | 1268 key, graph()->GetConstant0(), Token::GTE); |
1289 negative_checker.Then(); | 1269 negative_checker.Then(); |
1290 HInstruction* result = BuildExternalArrayElementAccess( | 1270 HInstruction* result = BuildExternalArrayElementAccess( |
1291 external_elements, key, val, bounds_check, | 1271 external_elements, key, val, bounds_check, |
1292 elements_kind, is_store); | 1272 elements_kind, is_store); |
1293 AddInstruction(result); | 1273 AddInstruction(result); |
1294 negative_checker.ElseDeopt(); | 1274 negative_checker.ElseDeopt(); |
1295 length_checker.End(); | 1275 length_checker.End(); |
1296 return result; | 1276 return result; |
1297 } else { | 1277 } else { |
(...skipping 1675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2973 HValue* input = phi->OperandAt(i); | 2953 HValue* input = phi->OperandAt(i); |
2974 if (input->IsPhi()) { | 2954 if (input->IsPhi()) { |
2975 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); | 2955 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); |
2976 } | 2956 } |
2977 } | 2957 } |
2978 } | 2958 } |
2979 | 2959 |
2980 | 2960 |
2981 void HGraph::MarkDeoptimizeOnUndefined() { | 2961 void HGraph::MarkDeoptimizeOnUndefined() { |
2982 HPhase phase("H_MarkDeoptimizeOnUndefined", this); | 2962 HPhase phase("H_MarkDeoptimizeOnUndefined", this); |
2983 // Compute DeoptimizeOnUndefined flag for phis. | 2963 // Compute DeoptimizeOnUndefined flag for phis. Any phi that can reach a use |
2984 // Any phi that can reach a use with DeoptimizeOnUndefined set must | 2964 // with DeoptimizeOnUndefined set must have DeoptimizeOnUndefined set. |
2985 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with | 2965 // Currently only HCompareNumericAndBranch, with double input representation, |
2986 // double input representation, has this flag set. | 2966 // has this flag set. The flag is used by HChange tagged->double, which must |
2987 // The flag is used by HChange tagged->double, which must deoptimize | 2967 // deoptimize if one of its uses has this flag set. |
2988 // if one of its uses has this flag set. | |
2989 for (int i = 0; i < phi_list()->length(); i++) { | 2968 for (int i = 0; i < phi_list()->length(); i++) { |
2990 HPhi* phi = phi_list()->at(i); | 2969 HPhi* phi = phi_list()->at(i); |
2991 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { | 2970 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
2992 HValue* use_value = it.value(); | 2971 HValue* use_value = it.value(); |
2993 if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) { | 2972 if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) { |
2994 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); | 2973 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); |
2995 break; | 2974 break; |
2996 } | 2975 } |
2997 } | 2976 } |
2998 } | 2977 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3279 builder->current_block()->Goto(if_true(), builder->function_state()); | 3258 builder->current_block()->Goto(if_true(), builder->function_state()); |
3280 } else { | 3259 } else { |
3281 builder->current_block()->Goto(if_false(), builder->function_state()); | 3260 builder->current_block()->Goto(if_false(), builder->function_state()); |
3282 } | 3261 } |
3283 builder->set_current_block(NULL); | 3262 builder->set_current_block(NULL); |
3284 return; | 3263 return; |
3285 } | 3264 } |
3286 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 3265 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
3287 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 3266 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
3288 ToBooleanStub::Types expected(condition()->to_boolean_types()); | 3267 ToBooleanStub::Types expected(condition()->to_boolean_types()); |
3289 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); | 3268 HBranch* test = new(zone()) HBranch(value, expected, empty_true, empty_false); |
3290 builder->current_block()->Finish(test); | 3269 builder->current_block()->Finish(test); |
3291 | 3270 |
3292 empty_true->Goto(if_true(), builder->function_state()); | 3271 empty_true->Goto(if_true(), builder->function_state()); |
3293 empty_false->Goto(if_false(), builder->function_state()); | 3272 empty_false->Goto(if_false(), builder->function_state()); |
3294 builder->set_current_block(NULL); | 3273 builder->set_current_block(NULL); |
3295 } | 3274 } |
3296 | 3275 |
3297 | 3276 |
3298 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. | 3277 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. |
3299 #define CHECK_BAILOUT(call) \ | 3278 #define CHECK_BAILOUT(call) \ |
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4481 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 4460 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
4482 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 4461 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
4483 | 4462 |
4484 HControlInstruction* compare; | 4463 HControlInstruction* compare; |
4485 | 4464 |
4486 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { | 4465 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { |
4487 if (!clause->compare_type()->Is(Type::Smi())) { | 4466 if (!clause->compare_type()->Is(Type::Smi())) { |
4488 AddSoftDeoptimize(); | 4467 AddSoftDeoptimize(); |
4489 } | 4468 } |
4490 | 4469 |
4491 HCompareIDAndBranch* compare_ = | 4470 HCompareNumericAndBranch* compare_ = |
4492 new(zone()) HCompareIDAndBranch(tag_value, | 4471 new(zone()) HCompareNumericAndBranch(tag_value, |
4493 label_value, | 4472 label_value, |
4494 Token::EQ_STRICT); | 4473 Token::EQ_STRICT); |
4495 compare_->set_observed_input_representation( | 4474 compare_->set_observed_input_representation( |
4496 Representation::Smi(), Representation::Smi()); | 4475 Representation::Smi(), Representation::Smi()); |
4497 compare = compare_; | 4476 compare = compare_; |
4498 } else { | 4477 } else { |
4499 compare = new(zone()) HStringCompareAndBranch(context, tag_value, | 4478 compare = new(zone()) HStringCompareAndBranch(context, tag_value, |
4500 label_value, | 4479 label_value, |
4501 Token::EQ_STRICT); | 4480 Token::EQ_STRICT); |
4502 } | 4481 } |
4503 | 4482 |
4504 compare->SetSuccessorAt(0, body_block); | 4483 compare->SetSuccessorAt(0, body_block); |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4768 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); | 4747 enumerable, map, DescriptorArray::kEnumCacheBridgeIndicesCacheIndex); |
4769 HForInCacheArray::cast(array)->set_index_cache( | 4748 HForInCacheArray::cast(array)->set_index_cache( |
4770 HForInCacheArray::cast(index_cache)); | 4749 HForInCacheArray::cast(index_cache)); |
4771 | 4750 |
4772 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); | 4751 HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt); |
4773 | 4752 |
4774 HValue* index = environment()->ExpressionStackAt(0); | 4753 HValue* index = environment()->ExpressionStackAt(0); |
4775 HValue* limit = environment()->ExpressionStackAt(1); | 4754 HValue* limit = environment()->ExpressionStackAt(1); |
4776 | 4755 |
4777 // Check that we still have more keys. | 4756 // Check that we still have more keys. |
4778 HCompareIDAndBranch* compare_index = | 4757 HCompareNumericAndBranch* compare_index = |
4779 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); | 4758 new(zone()) HCompareNumericAndBranch(index, limit, Token::LT); |
4780 compare_index->set_observed_input_representation( | 4759 compare_index->set_observed_input_representation( |
4781 Representation::Smi(), Representation::Smi()); | 4760 Representation::Smi(), Representation::Smi()); |
4782 | 4761 |
4783 HBasicBlock* loop_body = graph()->CreateBasicBlock(); | 4762 HBasicBlock* loop_body = graph()->CreateBasicBlock(); |
4784 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); | 4763 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); |
4785 | 4764 |
4786 compare_index->SetSuccessorAt(0, loop_body); | 4765 compare_index->SetSuccessorAt(0, loop_body); |
4787 compare_index->SetSuccessorAt(1, loop_successor); | 4766 compare_index->SetSuccessorAt(1, loop_successor); |
4788 current_block()->Finish(compare_index); | 4767 current_block()->Finish(compare_index); |
4789 | 4768 |
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5828 LookupResult lookup(isolate()); | 5807 LookupResult lookup(isolate()); |
5829 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 5808 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
5830 if (count == 0) { | 5809 if (count == 0) { |
5831 BuildCheckHeapObject(object); | 5810 BuildCheckHeapObject(object); |
5832 join = graph()->CreateBasicBlock(); | 5811 join = graph()->CreateBasicBlock(); |
5833 } | 5812 } |
5834 ++count; | 5813 ++count; |
5835 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 5814 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
5836 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 5815 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
5837 HCompareMap* compare = | 5816 HCompareMap* compare = |
5838 new(zone()) HCompareMap(object, map, if_true, if_false); | 5817 new(zone()) HCompareMap(object, map, if_true, if_false); |
5839 current_block()->Finish(compare); | 5818 current_block()->Finish(compare); |
5840 | 5819 |
5841 set_current_block(if_true); | 5820 set_current_block(if_true); |
5842 HInstruction* instr; | 5821 HInstruction* instr; |
5843 CHECK_ALIVE( | 5822 CHECK_ALIVE( |
5844 instr = BuildStoreNamedField(object, name, value, map, &lookup)); | 5823 instr = BuildStoreNamedField(object, name, value, map, &lookup)); |
5845 instr->set_position(position); | 5824 instr->set_position(position); |
5846 // Goto will add the HSimulate for the store. | 5825 // Goto will add the HSimulate for the store. |
5847 AddInstruction(instr); | 5826 AddInstruction(instr); |
5848 if (!ast_context()->IsEffect()) Push(value); | 5827 if (!ast_context()->IsEffect()) Push(value); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5933 BailoutId ast_id) { | 5912 BailoutId ast_id) { |
5934 LookupResult lookup(isolate()); | 5913 LookupResult lookup(isolate()); |
5935 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 5914 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
5936 if (type == kUseCell) { | 5915 if (type == kUseCell) { |
5937 Handle<GlobalObject> global(current_info()->global_object()); | 5916 Handle<GlobalObject> global(current_info()->global_object()); |
5938 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); | 5917 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
5939 if (cell->type()->IsConstant()) { | 5918 if (cell->type()->IsConstant()) { |
5940 IfBuilder builder(this); | 5919 IfBuilder builder(this); |
5941 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); | 5920 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); |
5942 if (cell->type()->AsConstant()->IsNumber()) { | 5921 if (cell->type()->AsConstant()->IsNumber()) { |
5943 builder.IfCompare(value, constant, Token::EQ); | 5922 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ); |
5944 } else { | 5923 } else { |
5945 builder.If<HCompareObjectEqAndBranch>(value, constant); | 5924 builder.If<HCompareObjectEqAndBranch>(value, constant); |
5946 } | 5925 } |
5947 builder.Then(); | 5926 builder.Then(); |
5948 builder.Else(); | 5927 builder.Else(); |
5949 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); | 5928 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); |
5950 builder.End(); | 5929 builder.End(); |
5951 } | 5930 } |
5952 HInstruction* instr = | 5931 HInstruction* instr = |
5953 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); | 5932 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); |
(...skipping 2952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8906 CHECK_ALIVE(VisitForValue(expr->right())); | 8885 CHECK_ALIVE(VisitForValue(expr->right())); |
8907 } | 8886 } |
8908 return ast_context()->ReturnValue(Pop()); | 8887 return ast_context()->ReturnValue(Pop()); |
8909 } | 8888 } |
8910 | 8889 |
8911 // We need an extra block to maintain edge-split form. | 8890 // We need an extra block to maintain edge-split form. |
8912 HBasicBlock* empty_block = graph()->CreateBasicBlock(); | 8891 HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
8913 HBasicBlock* eval_right = graph()->CreateBasicBlock(); | 8892 HBasicBlock* eval_right = graph()->CreateBasicBlock(); |
8914 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); | 8893 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); |
8915 HBranch* test = is_logical_and | 8894 HBranch* test = is_logical_and |
8916 ? new(zone()) HBranch(left_value, eval_right, empty_block, expected) | 8895 ? new(zone()) HBranch(left_value, expected, eval_right, empty_block) |
8917 : new(zone()) HBranch(left_value, empty_block, eval_right, expected); | 8896 : new(zone()) HBranch(left_value, expected, empty_block, eval_right); |
8918 current_block()->Finish(test); | 8897 current_block()->Finish(test); |
8919 | 8898 |
8920 set_current_block(eval_right); | 8899 set_current_block(eval_right); |
8921 Drop(1); // Value of the left subexpression. | 8900 Drop(1); // Value of the left subexpression. |
8922 CHECK_BAILOUT(VisitForValue(expr->right())); | 8901 CHECK_BAILOUT(VisitForValue(expr->right())); |
8923 | 8902 |
8924 HBasicBlock* join_block = | 8903 HBasicBlock* join_block = |
8925 CreateJoin(empty_block, current_block(), expr->id()); | 8904 CreateJoin(empty_block, current_block(), expr->id()); |
8926 set_current_block(join_block); | 8905 set_current_block(join_block); |
8927 return ast_context()->ReturnValue(Pop()); | 8906 return ast_context()->ReturnValue(Pop()); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9200 new(zone()) HCompareGeneric(context, left, right, op); | 9179 new(zone()) HCompareGeneric(context, left, right, op); |
9201 result->set_observed_input_representation(1, left_rep); | 9180 result->set_observed_input_representation(1, left_rep); |
9202 result->set_observed_input_representation(2, right_rep); | 9181 result->set_observed_input_representation(2, right_rep); |
9203 result->set_position(expr->position()); | 9182 result->set_position(expr->position()); |
9204 return ast_context()->ReturnInstruction(result, expr->id()); | 9183 return ast_context()->ReturnInstruction(result, expr->id()); |
9205 } else { | 9184 } else { |
9206 // TODO(verwaest): Remove once Representation::FromType properly | 9185 // TODO(verwaest): Remove once Representation::FromType properly |
9207 // returns Smi when the IC measures Smi. | 9186 // returns Smi when the IC measures Smi. |
9208 if (left_type->Is(Type::Smi())) left_rep = Representation::Smi(); | 9187 if (left_type->Is(Type::Smi())) left_rep = Representation::Smi(); |
9209 if (right_type->Is(Type::Smi())) right_rep = Representation::Smi(); | 9188 if (right_type->Is(Type::Smi())) right_rep = Representation::Smi(); |
9210 HCompareIDAndBranch* result = | 9189 HCompareNumericAndBranch* result = |
9211 new(zone()) HCompareIDAndBranch(left, right, op); | 9190 new(zone()) HCompareNumericAndBranch(left, right, op); |
9212 result->set_observed_input_representation(left_rep, right_rep); | 9191 result->set_observed_input_representation(left_rep, right_rep); |
9213 result->set_position(expr->position()); | 9192 result->set_position(expr->position()); |
9214 return ast_context()->ReturnControl(result, expr->id()); | 9193 return ast_context()->ReturnControl(result, expr->id()); |
9215 } | 9194 } |
9216 } | 9195 } |
9217 } | 9196 } |
9218 | 9197 |
9219 | 9198 |
9220 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 9199 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
9221 HValue* value, | 9200 HValue* value, |
(...skipping 1636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10858 if (ShouldProduceTraceOutput()) { | 10837 if (ShouldProduceTraceOutput()) { |
10859 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10838 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10860 } | 10839 } |
10861 | 10840 |
10862 #ifdef DEBUG | 10841 #ifdef DEBUG |
10863 graph_->Verify(false); // No full verify. | 10842 graph_->Verify(false); // No full verify. |
10864 #endif | 10843 #endif |
10865 } | 10844 } |
10866 | 10845 |
10867 } } // namespace v8::internal | 10846 } } // namespace v8::internal |
OLD | NEW |