| 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_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 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 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2285 // ----------- S t a t e ------------- | 2285 // ----------- S t a t e ------------- |
| 2286 // -- rax : argumentsList | 2286 // -- rax : argumentsList |
| 2287 // -- rdi : target | 2287 // -- rdi : target |
| 2288 // -- rdx : new.target (checked to be constructor or undefined) | 2288 // -- rdx : new.target (checked to be constructor or undefined) |
| 2289 // -- rsp[0] : return address. | 2289 // -- rsp[0] : return address. |
| 2290 // -- rsp[8] : thisArgument | 2290 // -- rsp[8] : thisArgument |
| 2291 // ----------------------------------- | 2291 // ----------------------------------- |
| 2292 | 2292 |
| 2293 // Create the list of arguments from the array-like argumentsList. | 2293 // Create the list of arguments from the array-like argumentsList. |
| 2294 { | 2294 { |
| 2295 Label create_arguments, create_array, create_runtime, done_create; | 2295 Label create_arguments, create_array, create_holey_array, create_runtime, |
| 2296 done_create; |
| 2296 __ JumpIfSmi(rax, &create_runtime); | 2297 __ JumpIfSmi(rax, &create_runtime); |
| 2297 | 2298 |
| 2298 // Load the map of argumentsList into rcx. | 2299 // Load the map of argumentsList into rcx. |
| 2299 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); | 2300 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 2300 | 2301 |
| 2301 // Load native context into rbx. | 2302 // Load native context into rbx. |
| 2302 __ movp(rbx, NativeContextOperand()); | 2303 __ movp(rbx, NativeContextOperand()); |
| 2303 | 2304 |
| 2304 // Check if argumentsList is an (unmodified) arguments object. | 2305 // Check if argumentsList is an (unmodified) arguments object. |
| 2305 __ cmpp(rcx, ContextOperand(rbx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); | 2306 __ cmpp(rcx, ContextOperand(rbx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2328 // Try to create the list from an arguments object. | 2329 // Try to create the list from an arguments object. |
| 2329 __ bind(&create_arguments); | 2330 __ bind(&create_arguments); |
| 2330 __ movp(rbx, FieldOperand(rax, JSArgumentsObject::kLengthOffset)); | 2331 __ movp(rbx, FieldOperand(rax, JSArgumentsObject::kLengthOffset)); |
| 2331 __ movp(rcx, FieldOperand(rax, JSObject::kElementsOffset)); | 2332 __ movp(rcx, FieldOperand(rax, JSObject::kElementsOffset)); |
| 2332 __ cmpp(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); | 2333 __ cmpp(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); |
| 2333 __ j(not_equal, &create_runtime); | 2334 __ j(not_equal, &create_runtime); |
| 2334 __ SmiToInteger32(rbx, rbx); | 2335 __ SmiToInteger32(rbx, rbx); |
| 2335 __ movp(rax, rcx); | 2336 __ movp(rax, rcx); |
| 2336 __ jmp(&done_create); | 2337 __ jmp(&done_create); |
| 2337 | 2338 |
| 2339 __ bind(&create_holey_array); |
| 2340 // For holey JSArrays we need to check that the array prototype chain |
| 2341 // protector is intact and our prototype is the Array.prototype actually. |
| 2342 __ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 2343 __ movp(rcx, FieldOperand(rcx, Map::kPrototypeOffset)); |
| 2344 __ cmpp(rcx, ContextOperand(rbx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); |
| 2345 __ j(not_equal, &create_runtime); |
| 2346 __ LoadRoot(rcx, Heap::kArrayProtectorRootIndex); |
| 2347 __ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset), |
| 2348 Smi::FromInt(Isolate::kProtectorValid)); |
| 2349 __ j(not_equal, &create_runtime); |
| 2350 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); |
| 2351 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); |
| 2352 __ jmp(&done_create); |
| 2353 |
| 2338 // Try to create the list from a JSArray object. | 2354 // Try to create the list from a JSArray object. |
| 2339 __ bind(&create_array); | 2355 __ bind(&create_array); |
| 2340 __ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset)); | 2356 __ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset)); |
| 2341 __ DecodeField<Map::ElementsKindBits>(rcx); | 2357 __ DecodeField<Map::ElementsKindBits>(rcx); |
| 2342 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 2358 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
| 2343 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 2359 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 2344 STATIC_ASSERT(FAST_ELEMENTS == 2); | 2360 STATIC_ASSERT(FAST_ELEMENTS == 2); |
| 2345 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); | 2361 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 2362 __ cmpl(rcx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); |
| 2363 __ j(equal, &create_holey_array); |
| 2364 __ cmpl(rcx, Immediate(FAST_HOLEY_ELEMENTS)); |
| 2365 __ j(equal, &create_holey_array); |
| 2346 __ j(above, &create_runtime); | 2366 __ j(above, &create_runtime); |
| 2347 __ cmpl(rcx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); | |
| 2348 __ j(equal, &create_runtime); | |
| 2349 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); | 2367 __ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset)); |
| 2350 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); | 2368 __ movp(rax, FieldOperand(rax, JSArray::kElementsOffset)); |
| 2351 | 2369 |
| 2352 __ bind(&done_create); | 2370 __ bind(&done_create); |
| 2353 } | 2371 } |
| 2354 | 2372 |
| 2355 // Check for stack overflow. | 2373 // Check for stack overflow. |
| 2356 { | 2374 { |
| 2357 // Check the stack for overflow. We are not trying to catch interruptions | 2375 // Check the stack for overflow. We are not trying to catch interruptions |
| 2358 // (i.e. debug break and preemption) here, so check the "real stack limit". | 2376 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2376 // -- rbx : len (number of elements to push from args) | 2394 // -- rbx : len (number of elements to push from args) |
| 2377 // -- rdx : new.target (checked to be constructor or undefined) | 2395 // -- rdx : new.target (checked to be constructor or undefined) |
| 2378 // -- rsp[0] : return address. | 2396 // -- rsp[0] : return address. |
| 2379 // -- rsp[8] : thisArgument | 2397 // -- rsp[8] : thisArgument |
| 2380 // ----------------------------------- | 2398 // ----------------------------------- |
| 2381 | 2399 |
| 2382 // Push arguments onto the stack (thisArgument is already on the stack). | 2400 // Push arguments onto the stack (thisArgument is already on the stack). |
| 2383 { | 2401 { |
| 2384 __ PopReturnAddressTo(r8); | 2402 __ PopReturnAddressTo(r8); |
| 2385 __ Set(rcx, 0); | 2403 __ Set(rcx, 0); |
| 2386 Label done, loop; | 2404 Label done, push, loop; |
| 2387 __ bind(&loop); | 2405 __ bind(&loop); |
| 2388 __ cmpl(rcx, rbx); | 2406 __ cmpl(rcx, rbx); |
| 2389 __ j(equal, &done, Label::kNear); | 2407 __ j(equal, &done, Label::kNear); |
| 2390 __ Push( | 2408 // Turn the hole into undefined as we go. |
| 2391 FieldOperand(rax, rcx, times_pointer_size, FixedArray::kHeaderSize)); | 2409 __ movp(r9, FieldOperand(rax, rcx, times_pointer_size, |
| 2410 FixedArray::kHeaderSize)); |
| 2411 __ CompareRoot(r9, Heap::kTheHoleValueRootIndex); |
| 2412 __ j(not_equal, &push, Label::kNear); |
| 2413 __ LoadRoot(r9, Heap::kUndefinedValueRootIndex); |
| 2414 __ bind(&push); |
| 2415 __ Push(r9); |
| 2392 __ incl(rcx); | 2416 __ incl(rcx); |
| 2393 __ jmp(&loop); | 2417 __ jmp(&loop); |
| 2394 __ bind(&done); | 2418 __ bind(&done); |
| 2395 __ PushReturnAddressFrom(r8); | 2419 __ PushReturnAddressFrom(r8); |
| 2396 __ Move(rax, rcx); | 2420 __ Move(rax, rcx); |
| 2397 } | 2421 } |
| 2398 | 2422 |
| 2399 // Dispatch to Call or Construct depending on whether new.target is undefined. | 2423 // Dispatch to Call or Construct depending on whether new.target is undefined. |
| 2400 { | 2424 { |
| 2401 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); | 2425 __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex); |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3077 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { | 3101 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
| 3078 Generate_OnStackReplacementHelper(masm, true); | 3102 Generate_OnStackReplacementHelper(masm, true); |
| 3079 } | 3103 } |
| 3080 | 3104 |
| 3081 #undef __ | 3105 #undef __ |
| 3082 | 3106 |
| 3083 } // namespace internal | 3107 } // namespace internal |
| 3084 } // namespace v8 | 3108 } // namespace v8 |
| 3085 | 3109 |
| 3086 #endif // V8_TARGET_ARCH_X64 | 3110 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |