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 4351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4362 current_block()->Finish(compare_index); | 4362 current_block()->Finish(compare_index); |
4363 | 4363 |
4364 set_current_block(loop_successor); | 4364 set_current_block(loop_successor); |
4365 Drop(5); | 4365 Drop(5); |
4366 | 4366 |
4367 set_current_block(loop_body); | 4367 set_current_block(loop_body); |
4368 | 4368 |
4369 HValue* key = AddInstruction( | 4369 HValue* key = AddInstruction( |
4370 new(zone()) HLoadKeyedFastElement( | 4370 new(zone()) HLoadKeyedFastElement( |
4371 environment()->ExpressionStackAt(2), // Enum cache. | 4371 environment()->ExpressionStackAt(2), // Enum cache. |
4372 environment()->ExpressionStackAt(0))); // Iteration index. | 4372 environment()->ExpressionStackAt(0), // Iteration index. |
| 4373 environment()->ExpressionStackAt(0))); |
4373 | 4374 |
4374 // Check if the expected map still matches that of the enumerable. | 4375 // Check if the expected map still matches that of the enumerable. |
4375 // If not just deoptimize. | 4376 // If not just deoptimize. |
4376 AddInstruction(new(zone()) HCheckMapValue( | 4377 AddInstruction(new(zone()) HCheckMapValue( |
4377 environment()->ExpressionStackAt(4), | 4378 environment()->ExpressionStackAt(4), |
4378 environment()->ExpressionStackAt(3))); | 4379 environment()->ExpressionStackAt(3))); |
4379 | 4380 |
4380 Bind(each_var, key); | 4381 Bind(each_var, key); |
4381 | 4382 |
4382 BreakAndContinueInfo break_info(stmt, 5); | 4383 BreakAndContinueInfo break_info(stmt, 5); |
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5702 HValue* key) { | 5703 HValue* key) { |
5703 HValue* context = environment()->LookupContext(); | 5704 HValue* context = environment()->LookupContext(); |
5704 return new(zone()) HLoadKeyedGeneric(context, object, key); | 5705 return new(zone()) HLoadKeyedGeneric(context, object, key); |
5705 } | 5706 } |
5706 | 5707 |
5707 | 5708 |
5708 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 5709 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
5709 HValue* external_elements, | 5710 HValue* external_elements, |
5710 HValue* checked_key, | 5711 HValue* checked_key, |
5711 HValue* val, | 5712 HValue* val, |
| 5713 HValue* dependency, |
5712 ElementsKind elements_kind, | 5714 ElementsKind elements_kind, |
5713 bool is_store) { | 5715 bool is_store) { |
5714 if (is_store) { | 5716 if (is_store) { |
5715 ASSERT(val != NULL); | 5717 ASSERT(val != NULL); |
5716 switch (elements_kind) { | 5718 switch (elements_kind) { |
5717 case EXTERNAL_PIXEL_ELEMENTS: { | 5719 case EXTERNAL_PIXEL_ELEMENTS: { |
5718 val = AddInstruction(new(zone()) HClampToUint8(val)); | 5720 val = AddInstruction(new(zone()) HClampToUint8(val)); |
5719 break; | 5721 break; |
5720 } | 5722 } |
5721 case EXTERNAL_BYTE_ELEMENTS: | 5723 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 23 matching lines...) Expand all Loading... |
5745 case DICTIONARY_ELEMENTS: | 5747 case DICTIONARY_ELEMENTS: |
5746 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5748 case NON_STRICT_ARGUMENTS_ELEMENTS: |
5747 UNREACHABLE(); | 5749 UNREACHABLE(); |
5748 break; | 5750 break; |
5749 } | 5751 } |
5750 return new(zone()) HStoreKeyedSpecializedArrayElement( | 5752 return new(zone()) HStoreKeyedSpecializedArrayElement( |
5751 external_elements, checked_key, val, elements_kind); | 5753 external_elements, checked_key, val, elements_kind); |
5752 } else { | 5754 } else { |
5753 ASSERT(val == NULL); | 5755 ASSERT(val == NULL); |
5754 return new(zone()) HLoadKeyedSpecializedArrayElement( | 5756 return new(zone()) HLoadKeyedSpecializedArrayElement( |
5755 external_elements, checked_key, elements_kind); | 5757 external_elements, checked_key, dependency, elements_kind); |
5756 } | 5758 } |
5757 } | 5759 } |
5758 | 5760 |
5759 | 5761 |
5760 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, | 5762 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, |
5761 HValue* checked_key, | 5763 HValue* checked_key, |
5762 HValue* val, | 5764 HValue* val, |
| 5765 HValue* load_dependency, |
5763 ElementsKind elements_kind, | 5766 ElementsKind elements_kind, |
5764 bool is_store) { | 5767 bool is_store) { |
5765 if (is_store) { | 5768 if (is_store) { |
5766 ASSERT(val != NULL); | 5769 ASSERT(val != NULL); |
5767 switch (elements_kind) { | 5770 switch (elements_kind) { |
5768 case FAST_DOUBLE_ELEMENTS: | 5771 case FAST_DOUBLE_ELEMENTS: |
5769 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5772 case FAST_HOLEY_DOUBLE_ELEMENTS: |
5770 return new(zone()) HStoreKeyedFastDoubleElement( | 5773 return new(zone()) HStoreKeyedFastDoubleElement( |
5771 elements, checked_key, val); | 5774 elements, checked_key, val); |
5772 case FAST_SMI_ELEMENTS: | 5775 case FAST_SMI_ELEMENTS: |
5773 case FAST_HOLEY_SMI_ELEMENTS: | 5776 case FAST_HOLEY_SMI_ELEMENTS: |
5774 // Smi-only arrays need a smi check. | 5777 // Smi-only arrays need a smi check. |
5775 AddInstruction(new(zone()) HCheckSmi(val)); | 5778 AddInstruction(new(zone()) HCheckSmi(val)); |
5776 // Fall through. | 5779 // Fall through. |
5777 case FAST_ELEMENTS: | 5780 case FAST_ELEMENTS: |
5778 case FAST_HOLEY_ELEMENTS: | 5781 case FAST_HOLEY_ELEMENTS: |
5779 return new(zone()) HStoreKeyedFastElement( | 5782 return new(zone()) HStoreKeyedFastElement( |
5780 elements, checked_key, val, elements_kind); | 5783 elements, checked_key, val, elements_kind); |
5781 default: | 5784 default: |
5782 UNREACHABLE(); | 5785 UNREACHABLE(); |
5783 return NULL; | 5786 return NULL; |
5784 } | 5787 } |
5785 } | 5788 } |
5786 // It's an element load (!is_store). | 5789 // It's an element load (!is_store). |
5787 HoleCheckMode mode = IsFastPackedElementsKind(elements_kind) ? | 5790 HoleCheckMode mode = IsFastPackedElementsKind(elements_kind) ? |
5788 OMIT_HOLE_CHECK : | 5791 OMIT_HOLE_CHECK : |
5789 PERFORM_HOLE_CHECK; | 5792 PERFORM_HOLE_CHECK; |
5790 if (IsFastDoubleElementsKind(elements_kind)) { | 5793 if (IsFastDoubleElementsKind(elements_kind)) { |
5791 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key, mode); | 5794 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key, |
| 5795 load_dependency, mode); |
5792 } else { // Smi or Object elements. | 5796 } else { // Smi or Object elements. |
5793 return new(zone()) HLoadKeyedFastElement(elements, checked_key, | 5797 return new(zone()) HLoadKeyedFastElement(elements, checked_key, |
5794 elements_kind); | 5798 load_dependency, elements_kind); |
5795 } | 5799 } |
5796 } | 5800 } |
5797 | 5801 |
5798 | 5802 |
5799 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 5803 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
5800 HValue* key, | 5804 HValue* key, |
5801 HValue* val, | 5805 HValue* val, |
5802 HValue* dependency, | 5806 HValue* dependency, |
5803 Handle<Map> map, | 5807 Handle<Map> map, |
5804 bool is_store) { | 5808 bool is_store) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5840 AddInstruction(check_cow_map); | 5844 AddInstruction(check_cow_map); |
5841 } | 5845 } |
5842 HInstruction* length = NULL; | 5846 HInstruction* length = NULL; |
5843 HInstruction* checked_key = NULL; | 5847 HInstruction* checked_key = NULL; |
5844 if (map->has_external_array_elements()) { | 5848 if (map->has_external_array_elements()) { |
5845 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 5849 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
5846 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 5850 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
5847 HLoadExternalArrayPointer* external_elements = | 5851 HLoadExternalArrayPointer* external_elements = |
5848 new(zone()) HLoadExternalArrayPointer(elements); | 5852 new(zone()) HLoadExternalArrayPointer(elements); |
5849 AddInstruction(external_elements); | 5853 AddInstruction(external_elements); |
5850 return BuildExternalArrayElementAccess(external_elements, checked_key, | 5854 return BuildExternalArrayElementAccess( |
5851 val, map->elements_kind(), is_store); | 5855 external_elements, checked_key, val, mapcheck, |
| 5856 map->elements_kind(), is_store); |
5852 } | 5857 } |
5853 ASSERT(fast_smi_only_elements || | 5858 ASSERT(fast_smi_only_elements || |
5854 fast_elements || | 5859 fast_elements || |
5855 map->has_fast_double_elements()); | 5860 map->has_fast_double_elements()); |
5856 if (map->instance_type() == JS_ARRAY_TYPE) { | 5861 if (map->instance_type() == JS_ARRAY_TYPE) { |
5857 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck, | 5862 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck, |
5858 HType::Smi())); | 5863 HType::Smi())); |
5859 } else { | 5864 } else { |
5860 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 5865 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
5861 } | 5866 } |
5862 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 5867 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
5863 return BuildFastElementAccess(elements, checked_key, val, | 5868 return BuildFastElementAccess(elements, checked_key, val, mapcheck, |
5864 map->elements_kind(), is_store); | 5869 map->elements_kind(), is_store); |
5865 } | 5870 } |
5866 | 5871 |
5867 | 5872 |
5868 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad( | 5873 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad( |
5869 HValue* object, | 5874 HValue* object, |
5870 HValue* key, | 5875 HValue* key, |
5871 HValue* val, | 5876 HValue* val, |
5872 SmallMapList* maps) { | 5877 SmallMapList* maps) { |
5873 // For polymorphic loads of similar elements kinds (i.e. all tagged or all | 5878 // For polymorphic loads of similar elements kinds (i.e. all tagged or all |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6073 typecheck->SetSuccessorAt(0, if_jsarray); | 6078 typecheck->SetSuccessorAt(0, if_jsarray); |
6074 typecheck->SetSuccessorAt(1, if_fastobject); | 6079 typecheck->SetSuccessorAt(1, if_fastobject); |
6075 current_block()->Finish(typecheck); | 6080 current_block()->Finish(typecheck); |
6076 | 6081 |
6077 set_current_block(if_jsarray); | 6082 set_current_block(if_jsarray); |
6078 HInstruction* length; | 6083 HInstruction* length; |
6079 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck, | 6084 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck, |
6080 HType::Smi())); | 6085 HType::Smi())); |
6081 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 6086 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
6082 access = AddInstruction(BuildFastElementAccess( | 6087 access = AddInstruction(BuildFastElementAccess( |
6083 elements, checked_key, val, elements_kind, is_store)); | 6088 elements, checked_key, val, elements_kind_branch, |
| 6089 elements_kind, is_store)); |
6084 if (!is_store) { | 6090 if (!is_store) { |
6085 Push(access); | 6091 Push(access); |
6086 } | 6092 } |
6087 | 6093 |
6088 *has_side_effects |= access->HasObservableSideEffects(); | 6094 *has_side_effects |= access->HasObservableSideEffects(); |
6089 if (position != -1) { | 6095 if (position != -1) { |
6090 access->set_position(position); | 6096 access->set_position(position); |
6091 } | 6097 } |
6092 if_jsarray->Goto(join); | 6098 if_jsarray->Goto(join); |
6093 | 6099 |
6094 set_current_block(if_fastobject); | 6100 set_current_block(if_fastobject); |
6095 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 6101 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
6096 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 6102 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
6097 access = AddInstruction(BuildFastElementAccess( | 6103 access = AddInstruction(BuildFastElementAccess( |
6098 elements, checked_key, val, elements_kind, is_store)); | 6104 elements, checked_key, val, elements_kind_branch, |
| 6105 elements_kind, is_store)); |
6099 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 6106 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
6100 if (is_store) { | 6107 if (is_store) { |
6101 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 6108 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
6102 } else { | 6109 } else { |
6103 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 6110 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
6104 } | 6111 } |
6105 } else { // External array elements. | 6112 } else { // External array elements. |
6106 access = AddInstruction(BuildExternalArrayElementAccess( | 6113 access = AddInstruction(BuildExternalArrayElementAccess( |
6107 external_elements, checked_key, val, elements_kind, is_store)); | 6114 external_elements, checked_key, val, elements_kind_branch, |
| 6115 elements_kind, is_store)); |
6108 } | 6116 } |
6109 *has_side_effects |= access->HasObservableSideEffects(); | 6117 *has_side_effects |= access->HasObservableSideEffects(); |
6110 if (position != RelocInfo::kNoPosition) access->set_position(position); | 6118 if (position != RelocInfo::kNoPosition) access->set_position(position); |
6111 if (!is_store) { | 6119 if (!is_store) { |
6112 Push(access); | 6120 Push(access); |
6113 } | 6121 } |
6114 current_block()->Goto(join); | 6122 current_block()->Goto(join); |
6115 set_current_block(if_false); | 6123 set_current_block(if_false); |
6116 } | 6124 } |
6117 } | 6125 } |
(...skipping 3455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9573 } | 9581 } |
9574 } | 9582 } |
9575 | 9583 |
9576 #ifdef DEBUG | 9584 #ifdef DEBUG |
9577 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9585 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9578 if (allocator_ != NULL) allocator_->Verify(); | 9586 if (allocator_ != NULL) allocator_->Verify(); |
9579 #endif | 9587 #endif |
9580 } | 9588 } |
9581 | 9589 |
9582 } } // namespace v8::internal | 9590 } } // namespace v8::internal |
OLD | NEW |