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