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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 descriptor->stack_parameter_count_ = &rax; | 130 descriptor->stack_parameter_count_ = &rax; |
131 } | 131 } |
132 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 132 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
133 descriptor->register_params_ = registers; | 133 descriptor->register_params_ = registers; |
134 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 134 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
135 descriptor->deoptimization_handler_ = | 135 descriptor->deoptimization_handler_ = |
136 FUNCTION_ADDR(ArrayConstructor_StubFailure); | 136 FUNCTION_ADDR(ArrayConstructor_StubFailure); |
137 } | 137 } |
138 | 138 |
139 | 139 |
| 140 static void InitializeInternalArrayConstructorDescriptor( |
| 141 Isolate* isolate, |
| 142 CodeStubInterfaceDescriptor* descriptor, |
| 143 int constant_stack_parameter_count) { |
| 144 // register state |
| 145 // rax -- number of arguments |
| 146 // rdi -- constructor function |
| 147 static Register registers[] = { rdi }; |
| 148 descriptor->register_param_count_ = 1; |
| 149 |
| 150 if (constant_stack_parameter_count != 0) { |
| 151 // stack param count needs (constructor pointer, and single argument) |
| 152 descriptor->stack_parameter_count_ = &rax; |
| 153 } |
| 154 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
| 155 descriptor->register_params_ = registers; |
| 156 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
| 157 descriptor->deoptimization_handler_ = |
| 158 FUNCTION_ADDR(InternalArrayConstructor_StubFailure); |
| 159 } |
| 160 |
| 161 |
140 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 162 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
141 Isolate* isolate, | 163 Isolate* isolate, |
142 CodeStubInterfaceDescriptor* descriptor) { | 164 CodeStubInterfaceDescriptor* descriptor) { |
143 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); | 165 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); |
144 } | 166 } |
145 | 167 |
146 | 168 |
147 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 169 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
148 Isolate* isolate, | 170 Isolate* isolate, |
149 CodeStubInterfaceDescriptor* descriptor) { | 171 CodeStubInterfaceDescriptor* descriptor) { |
150 InitializeArrayConstructorDescriptor(isolate, descriptor, 1); | 172 InitializeArrayConstructorDescriptor(isolate, descriptor, 1); |
151 } | 173 } |
152 | 174 |
153 | 175 |
154 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 176 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
155 Isolate* isolate, | 177 Isolate* isolate, |
156 CodeStubInterfaceDescriptor* descriptor) { | 178 CodeStubInterfaceDescriptor* descriptor) { |
157 InitializeArrayConstructorDescriptor(isolate, descriptor, -1); | 179 InitializeArrayConstructorDescriptor(isolate, descriptor, -1); |
158 } | 180 } |
159 | 181 |
160 | 182 |
| 183 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
| 184 Isolate* isolate, |
| 185 CodeStubInterfaceDescriptor* descriptor) { |
| 186 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0); |
| 187 } |
| 188 |
| 189 |
| 190 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
| 191 Isolate* isolate, |
| 192 CodeStubInterfaceDescriptor* descriptor) { |
| 193 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1); |
| 194 } |
| 195 |
| 196 |
| 197 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
| 198 Isolate* isolate, |
| 199 CodeStubInterfaceDescriptor* descriptor) { |
| 200 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1); |
| 201 } |
| 202 |
| 203 |
161 void CompareNilICStub::InitializeInterfaceDescriptor( | 204 void CompareNilICStub::InitializeInterfaceDescriptor( |
162 Isolate* isolate, | 205 Isolate* isolate, |
163 CodeStubInterfaceDescriptor* descriptor) { | 206 CodeStubInterfaceDescriptor* descriptor) { |
164 static Register registers[] = { rax }; | 207 static Register registers[] = { rax }; |
165 descriptor->register_param_count_ = 1; | 208 descriptor->register_param_count_ = 1; |
166 descriptor->register_params_ = registers; | 209 descriptor->register_params_ = registers; |
167 descriptor->deoptimization_handler_ = | 210 descriptor->deoptimization_handler_ = |
168 FUNCTION_ADDR(CompareNilIC_Miss); | 211 FUNCTION_ADDR(CompareNilIC_Miss); |
169 descriptor->SetMissHandler( | 212 descriptor->SetMissHandler( |
170 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate)); | 213 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate)); |
(...skipping 3631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3802 __ bind(&call); | 3845 __ bind(&call); |
3803 } | 3846 } |
3804 | 3847 |
3805 // Check that the function really is a JavaScript function. | 3848 // Check that the function really is a JavaScript function. |
3806 __ JumpIfSmi(rdi, &non_function); | 3849 __ JumpIfSmi(rdi, &non_function); |
3807 // Goto slow case if we do not have a function. | 3850 // Goto slow case if we do not have a function. |
3808 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); | 3851 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); |
3809 __ j(not_equal, &slow); | 3852 __ j(not_equal, &slow); |
3810 | 3853 |
3811 if (RecordCallTarget()) { | 3854 if (RecordCallTarget()) { |
3812 GenerateRecordCallTargetNoArray(masm); | 3855 if (FLAG_optimize_constructed_arrays) { |
| 3856 GenerateRecordCallTarget(masm); |
| 3857 } else { |
| 3858 GenerateRecordCallTargetNoArray(masm); |
| 3859 } |
3813 } | 3860 } |
3814 | 3861 |
3815 // Fast-case: Just invoke the function. | 3862 // Fast-case: Just invoke the function. |
3816 ParameterCount actual(argc_); | 3863 ParameterCount actual(argc_); |
3817 | 3864 |
3818 if (ReceiverMightBeImplicit()) { | 3865 if (ReceiverMightBeImplicit()) { |
3819 Label call_as_function; | 3866 Label call_as_function; |
3820 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 3867 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
3821 __ j(equal, &call_as_function); | 3868 __ j(equal, &call_as_function); |
3822 __ InvokeFunction(rdi, | 3869 __ InvokeFunction(rdi, |
(...skipping 3005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6828 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 6875 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
6829 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 6876 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
6830 isolate); | 6877 isolate); |
6831 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( | 6878 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( |
6832 isolate); | 6879 isolate); |
6833 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( | 6880 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( |
6834 isolate); | 6881 isolate); |
6835 } | 6882 } |
6836 | 6883 |
6837 | 6884 |
| 6885 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime( |
| 6886 Isolate* isolate) { |
| 6887 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS }; |
| 6888 for (int i = 0; i < 2; i++) { |
| 6889 // For internal arrays we only need a few things |
| 6890 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); |
| 6891 stubh1.GetCode(isolate)->set_is_pregenerated(true); |
| 6892 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); |
| 6893 stubh2.GetCode(isolate)->set_is_pregenerated(true); |
| 6894 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); |
| 6895 stubh3.GetCode(isolate)->set_is_pregenerated(true); |
| 6896 } |
| 6897 } |
| 6898 |
6838 | 6899 |
6839 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 6900 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
6840 // ----------- S t a t e ------------- | 6901 // ----------- S t a t e ------------- |
6841 // -- rax : argc | 6902 // -- rax : argc |
6842 // -- rbx : type info cell | 6903 // -- rbx : type info cell |
6843 // -- rdi : constructor | 6904 // -- rdi : constructor |
6844 // -- rsp[0] : return address | 6905 // -- rsp[0] : return address |
6845 // -- rsp[4] : last argument | 6906 // -- rsp[4] : last argument |
6846 // ----------------------------------- | 6907 // ----------------------------------- |
6847 Handle<Object> undefined_sentinel( | 6908 Handle<Object> undefined_sentinel( |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6915 // Jump to the generic construct code in case the specialized code cannot | 6976 // Jump to the generic construct code in case the specialized code cannot |
6916 // handle the construction. | 6977 // handle the construction. |
6917 __ bind(&generic_constructor); | 6978 __ bind(&generic_constructor); |
6918 Handle<Code> generic_construct_stub = | 6979 Handle<Code> generic_construct_stub = |
6919 masm->isolate()->builtins()->JSConstructStubGeneric(); | 6980 masm->isolate()->builtins()->JSConstructStubGeneric(); |
6920 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 6981 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
6921 } | 6982 } |
6922 } | 6983 } |
6923 | 6984 |
6924 | 6985 |
| 6986 void InternalArrayConstructorStub::GenerateCase( |
| 6987 MacroAssembler* masm, ElementsKind kind) { |
| 6988 Label not_zero_case, not_one_case; |
| 6989 Label normal_sequence; |
| 6990 |
| 6991 __ testq(rax, rax); |
| 6992 __ j(not_zero, ¬_zero_case); |
| 6993 InternalArrayNoArgumentConstructorStub stub0(kind); |
| 6994 __ TailCallStub(&stub0); |
| 6995 |
| 6996 __ bind(¬_zero_case); |
| 6997 __ cmpl(rax, Immediate(1)); |
| 6998 __ j(greater, ¬_one_case); |
| 6999 |
| 7000 if (IsFastPackedElementsKind(kind)) { |
| 7001 // We might need to create a holey array |
| 7002 // look at the first argument |
| 7003 __ movq(rcx, Operand(rsp, kPointerSize)); |
| 7004 __ testq(rcx, rcx); |
| 7005 __ j(zero, &normal_sequence); |
| 7006 |
| 7007 InternalArraySingleArgumentConstructorStub |
| 7008 stub1_holey(GetHoleyElementsKind(kind)); |
| 7009 __ TailCallStub(&stub1_holey); |
| 7010 } |
| 7011 |
| 7012 __ bind(&normal_sequence); |
| 7013 InternalArraySingleArgumentConstructorStub stub1(kind); |
| 7014 __ TailCallStub(&stub1); |
| 7015 |
| 7016 __ bind(¬_one_case); |
| 7017 InternalArrayNArgumentsConstructorStub stubN(kind); |
| 7018 __ TailCallStub(&stubN); |
| 7019 } |
| 7020 |
| 7021 |
| 7022 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 7023 // ----------- S t a t e ------------- |
| 7024 // -- eax : argc |
| 7025 // -- ebx : type info cell |
| 7026 // -- edi : constructor |
| 7027 // -- esp[0] : return address |
| 7028 // -- esp[4] : last argument |
| 7029 // ----------------------------------- |
| 7030 |
| 7031 if (FLAG_debug_code) { |
| 7032 // The array construct code is only set for the global and natives |
| 7033 // builtin Array functions which always have maps. |
| 7034 |
| 7035 // Initial map for the builtin Array function should be a map. |
| 7036 __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 7037 // Will both indicate a NULL and a Smi. |
| 7038 STATIC_ASSERT(kSmiTag == 0); |
| 7039 Condition not_smi = NegateCondition(masm->CheckSmi(rcx)); |
| 7040 __ Check(not_smi, "Unexpected initial map for Array function"); |
| 7041 __ CmpObjectType(rcx, MAP_TYPE, rcx); |
| 7042 __ Check(equal, "Unexpected initial map for Array function"); |
| 7043 } |
| 7044 |
| 7045 if (FLAG_optimize_constructed_arrays) { |
| 7046 // Figure out the right elements kind |
| 7047 __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 7048 |
| 7049 // Load the map's "bit field 2" into |result|. We only need the first byte, |
| 7050 // but the following masking takes care of that anyway. |
| 7051 __ movzxbq(rcx, FieldOperand(rcx, Map::kBitField2Offset)); |
| 7052 // Retrieve elements_kind from bit field 2. |
| 7053 __ and_(rcx, Immediate(Map::kElementsKindMask)); |
| 7054 __ shr(rcx, Immediate(Map::kElementsKindShift)); |
| 7055 |
| 7056 if (FLAG_debug_code) { |
| 7057 Label done; |
| 7058 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); |
| 7059 __ j(equal, &done); |
| 7060 __ cmpl(rcx, Immediate(FAST_HOLEY_ELEMENTS)); |
| 7061 __ Assert(equal, |
| 7062 "Invalid ElementsKind for InternalArray or InternalPackedArray"); |
| 7063 __ bind(&done); |
| 7064 } |
| 7065 |
| 7066 Label fast_elements_case; |
| 7067 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); |
| 7068 __ j(equal, &fast_elements_case); |
| 7069 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
| 7070 |
| 7071 __ bind(&fast_elements_case); |
| 7072 GenerateCase(masm, FAST_ELEMENTS); |
| 7073 } else { |
| 7074 Label generic_constructor; |
| 7075 // Run the native code for the Array function called as constructor. |
| 7076 ArrayNativeCode(masm, &generic_constructor); |
| 7077 |
| 7078 // Jump to the generic construct code in case the specialized code cannot |
| 7079 // handle the construction. |
| 7080 __ bind(&generic_constructor); |
| 7081 Handle<Code> generic_construct_stub = |
| 7082 masm->isolate()->builtins()->JSConstructStubGeneric(); |
| 7083 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 7084 } |
| 7085 } |
| 7086 |
| 7087 |
6925 #undef __ | 7088 #undef __ |
6926 | 7089 |
6927 } } // namespace v8::internal | 7090 } } // namespace v8::internal |
6928 | 7091 |
6929 #endif // V8_TARGET_ARCH_X64 | 7092 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |