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 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 2175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 // ----------- S t a t e ------------- | 2186 // ----------- S t a t e ------------- |
2187 // -- eax : argumentsList | 2187 // -- eax : argumentsList |
2188 // -- edi : target | 2188 // -- edi : target |
2189 // -- edx : new.target (checked to be constructor or undefined) | 2189 // -- edx : new.target (checked to be constructor or undefined) |
2190 // -- esp[0] : return address. | 2190 // -- esp[0] : return address. |
2191 // -- esp[4] : thisArgument | 2191 // -- esp[4] : thisArgument |
2192 // ----------------------------------- | 2192 // ----------------------------------- |
2193 | 2193 |
2194 // Create the list of arguments from the array-like argumentsList. | 2194 // Create the list of arguments from the array-like argumentsList. |
2195 { | 2195 { |
2196 Label create_arguments, create_array, create_runtime, done_create; | 2196 Label create_arguments, create_array, create_holey_array, create_runtime, |
| 2197 done_create; |
2197 __ JumpIfSmi(eax, &create_runtime); | 2198 __ JumpIfSmi(eax, &create_runtime); |
2198 | 2199 |
2199 // Load the map of argumentsList into ecx. | 2200 // Load the map of argumentsList into ecx. |
2200 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 2201 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
2201 | 2202 |
2202 // Load native context into ebx. | 2203 // Load native context into ebx. |
2203 __ mov(ebx, NativeContextOperand()); | 2204 __ mov(ebx, NativeContextOperand()); |
2204 | 2205 |
2205 // Check if argumentsList is an (unmodified) arguments object. | 2206 // Check if argumentsList is an (unmodified) arguments object. |
2206 __ cmp(ecx, ContextOperand(ebx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | 2207 __ cmp(ecx, ContextOperand(ebx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
(...skipping 23 matching lines...) Expand all Loading... |
2230 // Try to create the list from an arguments object. | 2231 // Try to create the list from an arguments object. |
2231 __ bind(&create_arguments); | 2232 __ bind(&create_arguments); |
2232 __ mov(ebx, FieldOperand(eax, JSArgumentsObject::kLengthOffset)); | 2233 __ mov(ebx, FieldOperand(eax, JSArgumentsObject::kLengthOffset)); |
2233 __ mov(ecx, FieldOperand(eax, JSObject::kElementsOffset)); | 2234 __ mov(ecx, FieldOperand(eax, JSObject::kElementsOffset)); |
2234 __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset)); | 2235 __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset)); |
2235 __ j(not_equal, &create_runtime); | 2236 __ j(not_equal, &create_runtime); |
2236 __ SmiUntag(ebx); | 2237 __ SmiUntag(ebx); |
2237 __ mov(eax, ecx); | 2238 __ mov(eax, ecx); |
2238 __ jmp(&done_create); | 2239 __ jmp(&done_create); |
2239 | 2240 |
| 2241 // For holey JSArrays we need to check that the array prototype chain |
| 2242 // protector is intact and our prototype is the Array.prototype actually. |
| 2243 __ bind(&create_holey_array); |
| 2244 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 2245 __ mov(ecx, FieldOperand(ecx, Map::kPrototypeOffset)); |
| 2246 __ cmp(ecx, ContextOperand(ebx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); |
| 2247 __ j(not_equal, &create_runtime); |
| 2248 __ LoadRoot(ecx, Heap::kArrayProtectorRootIndex); |
| 2249 __ cmp(FieldOperand(ecx, PropertyCell::kValueOffset), |
| 2250 Immediate(Smi::FromInt(Isolate::kProtectorValid))); |
| 2251 __ j(not_equal, &create_runtime); |
| 2252 __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset)); |
| 2253 __ SmiUntag(ebx); |
| 2254 __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset)); |
| 2255 __ jmp(&done_create); |
| 2256 |
2240 // Try to create the list from a JSArray object. | 2257 // Try to create the list from a JSArray object. |
2241 __ bind(&create_array); | 2258 __ bind(&create_array); |
2242 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); | 2259 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); |
2243 __ DecodeField<Map::ElementsKindBits>(ecx); | 2260 __ DecodeField<Map::ElementsKindBits>(ecx); |
2244 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 2261 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
2245 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 2262 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
2246 STATIC_ASSERT(FAST_ELEMENTS == 2); | 2263 STATIC_ASSERT(FAST_ELEMENTS == 2); |
2247 __ cmp(ecx, Immediate(FAST_ELEMENTS)); | 2264 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 2265 __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); |
| 2266 __ j(equal, &create_holey_array, Label::kNear); |
| 2267 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS)); |
| 2268 __ j(equal, &create_holey_array, Label::kNear); |
2248 __ j(above, &create_runtime); | 2269 __ j(above, &create_runtime); |
2249 __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); | |
2250 __ j(equal, &create_runtime); | |
2251 __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset)); | 2270 __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset)); |
2252 __ SmiUntag(ebx); | 2271 __ SmiUntag(ebx); |
2253 __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset)); | 2272 __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset)); |
2254 | 2273 |
2255 __ bind(&done_create); | 2274 __ bind(&done_create); |
2256 } | 2275 } |
2257 | 2276 |
2258 // Check for stack overflow. | 2277 // Check for stack overflow. |
2259 { | 2278 { |
2260 // Check the stack for overflow. We are not trying to catch interruptions | 2279 // Check the stack for overflow. We are not trying to catch interruptions |
(...skipping 19 matching lines...) Expand all Loading... |
2280 // -- eax : args (a FixedArray built from argumentsList) | 2299 // -- eax : args (a FixedArray built from argumentsList) |
2281 // -- ebx : len (number of elements to push from args) | 2300 // -- ebx : len (number of elements to push from args) |
2282 // -- edx : new.target (checked to be constructor or undefined) | 2301 // -- edx : new.target (checked to be constructor or undefined) |
2283 // -- esp[0] : return address. | 2302 // -- esp[0] : return address. |
2284 // -- esp[4] : thisArgument | 2303 // -- esp[4] : thisArgument |
2285 // ----------------------------------- | 2304 // ----------------------------------- |
2286 | 2305 |
2287 // Push arguments onto the stack (thisArgument is already on the stack). | 2306 // Push arguments onto the stack (thisArgument is already on the stack). |
2288 { | 2307 { |
2289 __ movd(xmm0, edx); | 2308 __ movd(xmm0, edx); |
| 2309 __ movd(xmm1, edi); |
2290 __ PopReturnAddressTo(edx); | 2310 __ PopReturnAddressTo(edx); |
2291 __ Move(ecx, Immediate(0)); | 2311 __ Move(ecx, Immediate(0)); |
2292 Label done, loop; | 2312 Label done, push, loop; |
2293 __ bind(&loop); | 2313 __ bind(&loop); |
2294 __ cmp(ecx, ebx); | 2314 __ cmp(ecx, ebx); |
2295 __ j(equal, &done, Label::kNear); | 2315 __ j(equal, &done, Label::kNear); |
2296 __ Push( | 2316 // Turn the hole into undefined as we go. |
2297 FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize)); | 2317 __ mov(edi, |
| 2318 FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize)); |
| 2319 __ CompareRoot(edi, Heap::kTheHoleValueRootIndex); |
| 2320 __ j(not_equal, &push, Label::kNear); |
| 2321 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex); |
| 2322 __ bind(&push); |
| 2323 __ Push(edi); |
2298 __ inc(ecx); | 2324 __ inc(ecx); |
2299 __ jmp(&loop); | 2325 __ jmp(&loop); |
2300 __ bind(&done); | 2326 __ bind(&done); |
2301 __ PushReturnAddressFrom(edx); | 2327 __ PushReturnAddressFrom(edx); |
| 2328 __ movd(edi, xmm1); |
2302 __ movd(edx, xmm0); | 2329 __ movd(edx, xmm0); |
2303 __ Move(eax, ebx); | 2330 __ Move(eax, ebx); |
2304 } | 2331 } |
2305 | 2332 |
2306 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2333 // Dispatch to Call or Construct depending on whether new.target is undefined. |
2307 { | 2334 { |
2308 __ CompareRoot(edx, Heap::kUndefinedValueRootIndex); | 2335 __ CompareRoot(edx, Heap::kUndefinedValueRootIndex); |
2309 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2336 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2310 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2337 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2311 } | 2338 } |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3130 | 3157 |
3131 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { | 3158 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
3132 Generate_OnStackReplacementHelper(masm, true); | 3159 Generate_OnStackReplacementHelper(masm, true); |
3133 } | 3160 } |
3134 | 3161 |
3135 #undef __ | 3162 #undef __ |
3136 } // namespace internal | 3163 } // namespace internal |
3137 } // namespace v8 | 3164 } // namespace v8 |
3138 | 3165 |
3139 #endif // V8_TARGET_ARCH_IA32 | 3166 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |