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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 descriptor->stack_parameter_count_ = &eax; | 140 descriptor->stack_parameter_count_ = &eax; |
141 } | 141 } |
142 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; | 142 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
143 descriptor->register_params_ = registers; | 143 descriptor->register_params_ = registers; |
144 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; | 144 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
145 descriptor->deoptimization_handler_ = | 145 descriptor->deoptimization_handler_ = |
146 FUNCTION_ADDR(ArrayConstructor_StubFailure); | 146 FUNCTION_ADDR(ArrayConstructor_StubFailure); |
147 } | 147 } |
148 | 148 |
149 | 149 |
| 150 static void InitializeInternalArrayConstructorDescriptor( |
| 151 Isolate* isolate, |
| 152 CodeStubInterfaceDescriptor* descriptor, |
| 153 int constant_stack_parameter_count) { |
| 154 // register state |
| 155 // eax -- number of arguments |
| 156 // edi -- constructor function |
| 157 static Register registers[] = { edi }; |
| 158 descriptor->register_param_count_ = 1; |
| 159 |
| 160 if (constant_stack_parameter_count != 0) { |
| 161 // stack param count needs (constructor pointer, and single argument) |
| 162 descriptor->stack_parameter_count_ = &eax; |
| 163 } |
| 164 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; |
| 165 descriptor->register_params_ = registers; |
| 166 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; |
| 167 descriptor->deoptimization_handler_ = |
| 168 FUNCTION_ADDR(InternalArrayConstructor_StubFailure); |
| 169 } |
| 170 |
| 171 |
150 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 172 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
151 Isolate* isolate, | 173 Isolate* isolate, |
152 CodeStubInterfaceDescriptor* descriptor) { | 174 CodeStubInterfaceDescriptor* descriptor) { |
153 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); | 175 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); |
154 } | 176 } |
155 | 177 |
156 | 178 |
157 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 179 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
158 Isolate* isolate, | 180 Isolate* isolate, |
159 CodeStubInterfaceDescriptor* descriptor) { | 181 CodeStubInterfaceDescriptor* descriptor) { |
160 InitializeArrayConstructorDescriptor(isolate, descriptor, 1); | 182 InitializeArrayConstructorDescriptor(isolate, descriptor, 1); |
161 } | 183 } |
162 | 184 |
163 | 185 |
164 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 186 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
165 Isolate* isolate, | 187 Isolate* isolate, |
166 CodeStubInterfaceDescriptor* descriptor) { | 188 CodeStubInterfaceDescriptor* descriptor) { |
167 InitializeArrayConstructorDescriptor(isolate, descriptor, -1); | 189 InitializeArrayConstructorDescriptor(isolate, descriptor, -1); |
168 } | 190 } |
169 | 191 |
170 | 192 |
| 193 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
| 194 Isolate* isolate, |
| 195 CodeStubInterfaceDescriptor* descriptor) { |
| 196 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0); |
| 197 } |
| 198 |
| 199 |
| 200 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
| 201 Isolate* isolate, |
| 202 CodeStubInterfaceDescriptor* descriptor) { |
| 203 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1); |
| 204 } |
| 205 |
| 206 |
| 207 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
| 208 Isolate* isolate, |
| 209 CodeStubInterfaceDescriptor* descriptor) { |
| 210 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1); |
| 211 } |
| 212 |
| 213 |
171 void CompareNilICStub::InitializeInterfaceDescriptor( | 214 void CompareNilICStub::InitializeInterfaceDescriptor( |
172 Isolate* isolate, | 215 Isolate* isolate, |
173 CodeStubInterfaceDescriptor* descriptor) { | 216 CodeStubInterfaceDescriptor* descriptor) { |
174 static Register registers[] = { eax }; | 217 static Register registers[] = { eax }; |
175 descriptor->register_param_count_ = 1; | 218 descriptor->register_param_count_ = 1; |
176 descriptor->register_params_ = registers; | 219 descriptor->register_params_ = registers; |
177 descriptor->deoptimization_handler_ = | 220 descriptor->deoptimization_handler_ = |
178 FUNCTION_ADDR(CompareNilIC_Miss); | 221 FUNCTION_ADDR(CompareNilIC_Miss); |
179 descriptor->miss_handler_ = | 222 descriptor->miss_handler_ = |
180 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate); | 223 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate); |
(...skipping 7793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7974 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 8017 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
7975 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 8018 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
7976 isolate); | 8019 isolate); |
7977 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( | 8020 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( |
7978 isolate); | 8021 isolate); |
7979 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( | 8022 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( |
7980 isolate); | 8023 isolate); |
7981 } | 8024 } |
7982 | 8025 |
7983 | 8026 |
| 8027 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime( |
| 8028 Isolate* isolate) { |
| 8029 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS }; |
| 8030 for (int i = 0; i < 2; i++) { |
| 8031 // For internal arrays we only need a few things |
| 8032 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]); |
| 8033 stubh1.GetCode(isolate)->set_is_pregenerated(true); |
| 8034 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]); |
| 8035 stubh2.GetCode(isolate)->set_is_pregenerated(true); |
| 8036 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]); |
| 8037 stubh3.GetCode(isolate)->set_is_pregenerated(true); |
| 8038 } |
| 8039 } |
| 8040 |
| 8041 |
7984 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 8042 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
7985 // ----------- S t a t e ------------- | 8043 // ----------- S t a t e ------------- |
7986 // -- eax : argc (only if argument_count_ == ANY) | 8044 // -- eax : argc (only if argument_count_ == ANY) |
7987 // -- ebx : type info cell | 8045 // -- ebx : type info cell |
7988 // -- edi : constructor | 8046 // -- edi : constructor |
7989 // -- esp[0] : return address | 8047 // -- esp[0] : return address |
7990 // -- esp[4] : last argument | 8048 // -- esp[4] : last argument |
7991 // ----------------------------------- | 8049 // ----------------------------------- |
7992 Handle<Object> undefined_sentinel( | 8050 Handle<Object> undefined_sentinel( |
7993 masm->isolate()->heap()->undefined_value(), | 8051 masm->isolate()->heap()->undefined_value(), |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8059 // Jump to the generic construct code in case the specialized code cannot | 8117 // Jump to the generic construct code in case the specialized code cannot |
8060 // handle the construction. | 8118 // handle the construction. |
8061 __ bind(&generic_constructor); | 8119 __ bind(&generic_constructor); |
8062 Handle<Code> generic_construct_stub = | 8120 Handle<Code> generic_construct_stub = |
8063 masm->isolate()->builtins()->JSConstructStubGeneric(); | 8121 masm->isolate()->builtins()->JSConstructStubGeneric(); |
8064 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 8122 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
8065 } | 8123 } |
8066 } | 8124 } |
8067 | 8125 |
8068 | 8126 |
| 8127 void InternalArrayConstructorStub::GenerateCase( |
| 8128 MacroAssembler* masm, ElementsKind kind) { |
| 8129 Label not_zero_case, not_one_case; |
| 8130 Label normal_sequence; |
| 8131 |
| 8132 __ test(eax, eax); |
| 8133 __ j(not_zero, ¬_zero_case); |
| 8134 InternalArrayNoArgumentConstructorStub stub0(kind); |
| 8135 __ TailCallStub(&stub0); |
| 8136 |
| 8137 __ bind(¬_zero_case); |
| 8138 __ cmp(eax, 1); |
| 8139 __ j(greater, ¬_one_case); |
| 8140 |
| 8141 if (IsFastPackedElementsKind(kind)) { |
| 8142 // We might need to create a holey array |
| 8143 // look at the first argument |
| 8144 __ mov(ecx, Operand(esp, kPointerSize)); |
| 8145 __ test(ecx, ecx); |
| 8146 __ j(zero, &normal_sequence); |
| 8147 |
| 8148 InternalArraySingleArgumentConstructorStub |
| 8149 stub1_holey(GetHoleyElementsKind(kind)); |
| 8150 __ TailCallStub(&stub1_holey); |
| 8151 } |
| 8152 |
| 8153 __ bind(&normal_sequence); |
| 8154 InternalArraySingleArgumentConstructorStub stub1(kind); |
| 8155 __ TailCallStub(&stub1); |
| 8156 |
| 8157 __ bind(¬_one_case); |
| 8158 InternalArrayNArgumentsConstructorStub stubN(kind); |
| 8159 __ TailCallStub(&stubN); |
| 8160 } |
| 8161 |
| 8162 |
| 8163 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) { |
| 8164 // ----------- S t a t e ------------- |
| 8165 // -- eax : argc |
| 8166 // -- ebx : type info cell |
| 8167 // -- edi : constructor |
| 8168 // -- esp[0] : return address |
| 8169 // -- esp[4] : last argument |
| 8170 // ----------------------------------- |
| 8171 |
| 8172 if (FLAG_debug_code) { |
| 8173 // The array construct code is only set for the global and natives |
| 8174 // builtin Array functions which always have maps. |
| 8175 |
| 8176 // Initial map for the builtin Array function should be a map. |
| 8177 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 8178 // Will both indicate a NULL and a Smi. |
| 8179 __ test(ecx, Immediate(kSmiTagMask)); |
| 8180 __ Assert(not_zero, "Unexpected initial map for Array function"); |
| 8181 __ CmpObjectType(ecx, MAP_TYPE, ecx); |
| 8182 __ Assert(equal, "Unexpected initial map for Array function"); |
| 8183 } |
| 8184 |
| 8185 if (FLAG_optimize_constructed_arrays) { |
| 8186 // Figure out the right elements kind |
| 8187 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 8188 |
| 8189 // Load the map's "bit field 2" into |result|. We only need the first byte, |
| 8190 // but the following masking takes care of that anyway. |
| 8191 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); |
| 8192 // Retrieve elements_kind from bit field 2. |
| 8193 __ and_(ecx, Map::kElementsKindMask); |
| 8194 __ shr(ecx, Map::kElementsKindShift); |
| 8195 |
| 8196 if (FLAG_debug_code) { |
| 8197 Label done; |
| 8198 __ cmp(ecx, Immediate(FAST_ELEMENTS)); |
| 8199 __ j(equal, &done); |
| 8200 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS)); |
| 8201 __ Assert(equal, |
| 8202 "Invalid ElementsKind for InternalArray or InternalPackedArray"); |
| 8203 __ bind(&done); |
| 8204 } |
| 8205 |
| 8206 Label fast_elements_case; |
| 8207 __ cmp(ecx, Immediate(FAST_ELEMENTS)); |
| 8208 __ j(equal, &fast_elements_case); |
| 8209 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
| 8210 |
| 8211 __ bind(&fast_elements_case); |
| 8212 GenerateCase(masm, FAST_ELEMENTS); |
| 8213 } else { |
| 8214 Label generic_constructor; |
| 8215 // Run the native code for the Array function called as constructor. |
| 8216 ArrayNativeCode(masm, true, &generic_constructor); |
| 8217 |
| 8218 // Jump to the generic construct code in case the specialized code cannot |
| 8219 // handle the construction. |
| 8220 __ bind(&generic_constructor); |
| 8221 Handle<Code> generic_construct_stub = |
| 8222 masm->isolate()->builtins()->JSConstructStubGeneric(); |
| 8223 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 8224 } |
| 8225 } |
| 8226 |
| 8227 |
8069 #undef __ | 8228 #undef __ |
8070 | 8229 |
8071 } } // namespace v8::internal | 8230 } } // namespace v8::internal |
8072 | 8231 |
8073 #endif // V8_TARGET_ARCH_IA32 | 8232 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |