| 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 |