| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
| 6 | 6 |
| 7 #include "src/bailout-reason.h" | 7 #include "src/bailout-reason.h" |
| 8 #include "src/crankshaft/hydrogen.h" | 8 #include "src/crankshaft/hydrogen.h" |
| 9 #include "src/crankshaft/lithium.h" | 9 #include "src/crankshaft/lithium.h" |
| 10 #include "src/field-index.h" | 10 #include "src/field-index.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 CompilationInfo* info() { return info_; } | 71 CompilationInfo* info() { return info_; } |
| 72 CodeStub* stub() { return code_stub_; } | 72 CodeStub* stub() { return code_stub_; } |
| 73 HContext* context() { return context_; } | 73 HContext* context() { return context_; } |
| 74 Isolate* isolate() { return info_->isolate(); } | 74 Isolate* isolate() { return info_->isolate(); } |
| 75 | 75 |
| 76 HLoadNamedField* BuildLoadNamedField(HValue* object, FieldIndex index); | 76 HLoadNamedField* BuildLoadNamedField(HValue* object, FieldIndex index); |
| 77 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, | 77 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, |
| 78 Representation representation, | 78 Representation representation, |
| 79 bool transition_to_field); | 79 bool transition_to_field); |
| 80 | 80 |
| 81 HValue* BuildPushElement(HValue* object, HValue* value, ElementsKind kind); | 81 HValue* BuildPushElement(HValue* object, HValue* argc, |
| 82 HValue* argument_elements, ElementsKind kind); |
| 82 | 83 |
| 83 enum ArgumentClass { | 84 enum ArgumentClass { |
| 84 NONE, | 85 NONE, |
| 85 SINGLE, | 86 SINGLE, |
| 86 MULTIPLE | 87 MULTIPLE |
| 87 }; | 88 }; |
| 88 | 89 |
| 89 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value); | 90 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value); |
| 90 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key, | 91 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key, |
| 91 HValue* value); | 92 HValue* value); |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 HObjectAccess::ForContextSlot(slot_index), | 776 HObjectAccess::ForContextSlot(slot_index), |
| 776 GetParameter(2), STORE_TO_INITIALIZED_ENTRY); | 777 GetParameter(2), STORE_TO_INITIALIZED_ENTRY); |
| 777 return GetParameter(2); | 778 return GetParameter(2); |
| 778 } | 779 } |
| 779 | 780 |
| 780 | 781 |
| 781 Handle<Code> StoreScriptContextFieldStub::GenerateCode() { | 782 Handle<Code> StoreScriptContextFieldStub::GenerateCode() { |
| 782 return DoGenerateCode(this); | 783 return DoGenerateCode(this); |
| 783 } | 784 } |
| 784 | 785 |
| 785 HValue* CodeStubGraphBuilderBase::BuildPushElement(HValue* object, | 786 HValue* CodeStubGraphBuilderBase::BuildPushElement(HValue* object, HValue* argc, |
| 786 HValue* value, | 787 HValue* argument_elements, |
| 787 ElementsKind kind) { | 788 ElementsKind kind) { |
| 789 // Precheck whether all elements fit into the array. |
| 790 if (!IsFastObjectElementsKind(kind)) { |
| 791 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
| 792 HValue* start = graph()->GetConstant0(); |
| 793 HValue* key = builder.BeginBody(start, argc, Token::LT); |
| 794 { |
| 795 HInstruction* argument = |
| 796 Add<HAccessArgumentsAt>(argument_elements, argc, key); |
| 797 Representation r = IsFastSmiElementsKind(kind) ? Representation::Smi() |
| 798 : Representation::Double(); |
| 799 AddUncasted<HForceRepresentation>(argument, r); |
| 800 } |
| 801 builder.EndBody(); |
| 802 } |
| 803 |
| 788 HValue* length = Add<HLoadNamedField>(object, nullptr, | 804 HValue* length = Add<HLoadNamedField>(object, nullptr, |
| 789 HObjectAccess::ForArrayLength(kind)); | 805 HObjectAccess::ForArrayLength(kind)); |
| 790 HValue* key = length; | 806 HValue* new_length = AddUncasted<HAdd>(length, argc); |
| 807 HValue* max_key = AddUncasted<HSub>(new_length, graph()->GetConstant1()); |
| 808 |
| 791 HValue* elements = Add<HLoadNamedField>(object, nullptr, | 809 HValue* elements = Add<HLoadNamedField>(object, nullptr, |
| 792 HObjectAccess::ForElementsPointer()); | 810 HObjectAccess::ForElementsPointer()); |
| 793 elements = BuildCheckForCapacityGrow(object, elements, kind, length, key, | 811 elements = BuildCheckForCapacityGrow(object, elements, kind, length, max_key, |
| 794 true, STORE); | 812 true, STORE); |
| 795 AddElementAccess(elements, key, value, object, nullptr, kind, STORE); | 813 |
| 796 return key; | 814 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
| 815 HValue* start = graph()->GetConstant0(); |
| 816 HValue* key = builder.BeginBody(start, argc, Token::LT); |
| 817 { |
| 818 HValue* argument = Add<HAccessArgumentsAt>(argument_elements, argc, key); |
| 819 HValue* index = AddUncasted<HAdd>(key, length); |
| 820 AddElementAccess(elements, index, argument, object, nullptr, kind, STORE); |
| 821 } |
| 822 builder.EndBody(); |
| 823 return new_length; |
| 797 } | 824 } |
| 798 | 825 |
| 799 template <> | 826 template <> |
| 800 HValue* CodeStubGraphBuilder<FastArrayPushStub>::BuildCodeStub() { | 827 HValue* CodeStubGraphBuilder<FastArrayPushStub>::BuildCodeStub() { |
| 801 // TODO(verwaest): Fix deoptimizer messages. | 828 // TODO(verwaest): Fix deoptimizer messages. |
| 802 HValue* argc = GetArgumentsLength(); | 829 HValue* argc = GetArgumentsLength(); |
| 803 IfBuilder arg_check(this); | |
| 804 arg_check.If<HCompareNumericAndBranch>(argc, graph()->GetConstant1(), | |
| 805 Token::NE); | |
| 806 arg_check.ThenDeopt(Deoptimizer::kFastArrayPushFailed); | |
| 807 arg_check.End(); | |
| 808 | |
| 809 HInstruction* argument_elements = Add<HArgumentsElements>(false, false); | 830 HInstruction* argument_elements = Add<HArgumentsElements>(false, false); |
| 810 HInstruction* object = Add<HAccessArgumentsAt>(argument_elements, argc, | 831 HInstruction* object = Add<HAccessArgumentsAt>(argument_elements, argc, |
| 811 graph()->GetConstantMinus1()); | 832 graph()->GetConstantMinus1()); |
| 812 HInstruction* value = | |
| 813 Add<HAccessArgumentsAt>(argument_elements, argc, graph()->GetConstant0()); | |
| 814 | |
| 815 BuildCheckHeapObject(object); | 833 BuildCheckHeapObject(object); |
| 816 HValue* map = Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMap()); | 834 HValue* map = Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMap()); |
| 817 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_JS_ARRAY); | 835 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_JS_ARRAY); |
| 818 | 836 |
| 819 // Disallow pushing onto prototypes. It might be the JSArray prototype. | 837 // Disallow pushing onto prototypes. It might be the JSArray prototype. |
| 820 // Disallow pushing onto non-extensible objects. | 838 // Disallow pushing onto non-extensible objects. |
| 821 { | 839 { |
| 822 HValue* bit_field2 = | 840 HValue* bit_field2 = |
| 823 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2()); | 841 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2()); |
| 824 HValue* mask = | 842 HValue* mask = |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 STATIC_ASSERT(FAST_SMI_ELEMENTS < FAST_HOLEY_SMI_ELEMENTS); | 941 STATIC_ASSERT(FAST_SMI_ELEMENTS < FAST_HOLEY_SMI_ELEMENTS); |
| 924 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS < FAST_HOLEY_ELEMENTS); | 942 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS < FAST_HOLEY_ELEMENTS); |
| 925 STATIC_ASSERT(FAST_ELEMENTS < FAST_HOLEY_ELEMENTS); | 943 STATIC_ASSERT(FAST_ELEMENTS < FAST_HOLEY_ELEMENTS); |
| 926 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FAST_HOLEY_DOUBLE_ELEMENTS); | 944 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FAST_HOLEY_DOUBLE_ELEMENTS); |
| 927 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FAST_HOLEY_DOUBLE_ELEMENTS); | 945 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FAST_HOLEY_DOUBLE_ELEMENTS); |
| 928 IfBuilder has_smi_elements(this); | 946 IfBuilder has_smi_elements(this); |
| 929 has_smi_elements.If<HCompareNumericAndBranch>( | 947 has_smi_elements.If<HCompareNumericAndBranch>( |
| 930 kind, Add<HConstant>(FAST_HOLEY_SMI_ELEMENTS), Token::LTE); | 948 kind, Add<HConstant>(FAST_HOLEY_SMI_ELEMENTS), Token::LTE); |
| 931 has_smi_elements.Then(); | 949 has_smi_elements.Then(); |
| 932 { | 950 { |
| 933 HValue* smi_value = | 951 HValue* new_length = BuildPushElement(object, argc, argument_elements, |
| 934 AddUncasted<HForceRepresentation>(value, Representation::Smi()); | 952 FAST_HOLEY_SMI_ELEMENTS); |
| 935 HValue* key = BuildPushElement(object, smi_value, FAST_HOLEY_SMI_ELEMENTS); | 953 environment()->Push(new_length); |
| 936 environment()->Push(key); | |
| 937 } | 954 } |
| 938 has_smi_elements.Else(); | 955 has_smi_elements.Else(); |
| 939 { | 956 { |
| 940 IfBuilder has_object_elements(this); | 957 IfBuilder has_object_elements(this); |
| 941 has_object_elements.If<HCompareNumericAndBranch>( | 958 has_object_elements.If<HCompareNumericAndBranch>( |
| 942 kind, Add<HConstant>(FAST_HOLEY_ELEMENTS), Token::LTE); | 959 kind, Add<HConstant>(FAST_HOLEY_ELEMENTS), Token::LTE); |
| 943 has_object_elements.Then(); | 960 has_object_elements.Then(); |
| 944 { | 961 { |
| 945 HValue* key = BuildPushElement(object, value, FAST_HOLEY_ELEMENTS); | 962 HValue* new_length = BuildPushElement(object, argc, argument_elements, |
| 946 environment()->Push(key); | 963 FAST_HOLEY_ELEMENTS); |
| 964 environment()->Push(new_length); |
| 947 } | 965 } |
| 948 has_object_elements.Else(); | 966 has_object_elements.Else(); |
| 949 { | 967 { |
| 950 IfBuilder has_double_elements(this); | 968 IfBuilder has_double_elements(this); |
| 951 has_double_elements.If<HCompareNumericAndBranch>( | 969 has_double_elements.If<HCompareNumericAndBranch>( |
| 952 kind, Add<HConstant>(FAST_HOLEY_DOUBLE_ELEMENTS), Token::LTE); | 970 kind, Add<HConstant>(FAST_HOLEY_DOUBLE_ELEMENTS), Token::LTE); |
| 953 has_double_elements.Then(); | 971 has_double_elements.Then(); |
| 954 { | 972 { |
| 955 HValue* double_value = | 973 HValue* new_length = BuildPushElement(object, argc, argument_elements, |
| 956 AddUncasted<HForceRepresentation>(value, Representation::Double()); | 974 FAST_HOLEY_DOUBLE_ELEMENTS); |
| 957 HValue* key = | 975 environment()->Push(new_length); |
| 958 BuildPushElement(object, double_value, FAST_HOLEY_DOUBLE_ELEMENTS); | |
| 959 environment()->Push(key); | |
| 960 } | 976 } |
| 961 has_double_elements.ElseDeopt(Deoptimizer::kFastArrayPushFailed); | 977 has_double_elements.ElseDeopt(Deoptimizer::kFastArrayPushFailed); |
| 962 has_double_elements.End(); | 978 has_double_elements.End(); |
| 963 } | 979 } |
| 964 has_object_elements.End(); | 980 has_object_elements.End(); |
| 965 } | 981 } |
| 966 has_smi_elements.End(); | 982 has_smi_elements.End(); |
| 967 | 983 |
| 968 HValue* key = environment()->Pop(); | 984 return environment()->Pop(); |
| 969 return AddUncasted<HAdd>(key, graph()->GetConstant1()); | |
| 970 } | 985 } |
| 971 | 986 |
| 972 Handle<Code> FastArrayPushStub::GenerateCode() { return DoGenerateCode(this); } | 987 Handle<Code> FastArrayPushStub::GenerateCode() { return DoGenerateCode(this); } |
| 973 | 988 |
| 974 template <> | 989 template <> |
| 975 HValue* CodeStubGraphBuilder<GrowArrayElementsStub>::BuildCodeStub() { | 990 HValue* CodeStubGraphBuilder<GrowArrayElementsStub>::BuildCodeStub() { |
| 976 ElementsKind kind = casted_stub()->elements_kind(); | 991 ElementsKind kind = casted_stub()->elements_kind(); |
| 977 if (IsFastDoubleElementsKind(kind)) { | 992 if (IsFastDoubleElementsKind(kind)) { |
| 978 info()->MarkAsSavesCallerDoubles(); | 993 info()->MarkAsSavesCallerDoubles(); |
| 979 } | 994 } |
| (...skipping 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2553 return Pop(); | 2568 return Pop(); |
| 2554 } | 2569 } |
| 2555 | 2570 |
| 2556 | 2571 |
| 2557 Handle<Code> KeyedLoadGenericStub::GenerateCode() { | 2572 Handle<Code> KeyedLoadGenericStub::GenerateCode() { |
| 2558 return DoGenerateCode(this); | 2573 return DoGenerateCode(this); |
| 2559 } | 2574 } |
| 2560 | 2575 |
| 2561 } // namespace internal | 2576 } // namespace internal |
| 2562 } // namespace v8 | 2577 } // namespace v8 |
| OLD | NEW |