Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 2645743002: [builtins] Port parameter and argument-related code stubs to CSA (Closed)
Patch Set: Remove stray change Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 3205 matching lines...) Expand 10 before | Expand all | Expand 10 after
3216 3216
3217 Label fast_elements_case; 3217 Label fast_elements_case;
3218 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); 3218 __ cmpl(rcx, Immediate(FAST_ELEMENTS));
3219 __ j(equal, &fast_elements_case); 3219 __ j(equal, &fast_elements_case);
3220 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 3220 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
3221 3221
3222 __ bind(&fast_elements_case); 3222 __ bind(&fast_elements_case);
3223 GenerateCase(masm, FAST_ELEMENTS); 3223 GenerateCase(masm, FAST_ELEMENTS);
3224 } 3224 }
3225 3225
3226 void FastNewRestParameterStub::Generate(MacroAssembler* masm) {
3227 // ----------- S t a t e -------------
3228 // -- rdi : function
3229 // -- rsi : context
3230 // -- rbp : frame pointer
3231 // -- rsp[0] : return address
3232 // -----------------------------------
3233 __ AssertFunction(rdi);
3234
3235 // Make rdx point to the JavaScript frame.
3236 __ movp(rdx, rbp);
3237 if (skip_stub_frame()) {
3238 // For Ignition we need to skip the handler/stub frame to reach the
3239 // JavaScript frame for the function.
3240 __ movp(rdx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3241 }
3242 if (FLAG_debug_code) {
3243 Label ok;
3244 __ cmpp(rdi, Operand(rdx, StandardFrameConstants::kFunctionOffset));
3245 __ j(equal, &ok);
3246 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3247 __ bind(&ok);
3248 }
3249
3250 // Check if we have rest parameters (only possible if we have an
3251 // arguments adaptor frame below the function frame).
3252 Label no_rest_parameters;
3253 __ movp(rbx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3254 __ Cmp(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset),
3255 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3256 __ j(not_equal, &no_rest_parameters, Label::kNear);
3257
3258 // Check if the arguments adaptor frame contains more arguments than
3259 // specified by the function's internal formal parameter count.
3260 Label rest_parameters;
3261 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
3262 __ LoadSharedFunctionInfoSpecialField(
3263 rcx, rcx, SharedFunctionInfo::kFormalParameterCountOffset);
3264 __ SmiToInteger32(
3265 rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
3266 __ subl(rax, rcx);
3267 __ j(greater, &rest_parameters);
3268
3269 // Return an empty rest parameter array.
3270 __ bind(&no_rest_parameters);
3271 {
3272 // ----------- S t a t e -------------
3273 // -- rsi : context
3274 // -- rsp[0] : return address
3275 // -----------------------------------
3276
3277 // Allocate an empty rest parameter array.
3278 Label allocate, done_allocate;
3279 __ Allocate(JSArray::kSize, rax, rdx, rcx, &allocate, NO_ALLOCATION_FLAGS);
3280 __ bind(&done_allocate);
3281
3282 // Setup the rest parameter array in rax.
3283 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, rcx);
3284 __ movp(FieldOperand(rax, JSArray::kMapOffset), rcx);
3285 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
3286 __ movp(FieldOperand(rax, JSArray::kPropertiesOffset), rcx);
3287 __ movp(FieldOperand(rax, JSArray::kElementsOffset), rcx);
3288 __ movp(FieldOperand(rax, JSArray::kLengthOffset), Immediate(0));
3289 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3290 __ Ret();
3291
3292 // Fall back to %AllocateInNewSpace.
3293 __ bind(&allocate);
3294 {
3295 FrameScope scope(masm, StackFrame::INTERNAL);
3296 __ Push(Smi::FromInt(JSArray::kSize));
3297 __ CallRuntime(Runtime::kAllocateInNewSpace);
3298 }
3299 __ jmp(&done_allocate);
3300 }
3301
3302 __ bind(&rest_parameters);
3303 {
3304 // Compute the pointer to the first rest parameter (skippping the receiver).
3305 __ leap(rbx, Operand(rbx, rax, times_pointer_size,
3306 StandardFrameConstants::kCallerSPOffset -
3307 1 * kPointerSize));
3308
3309 // ----------- S t a t e -------------
3310 // -- rdi : function
3311 // -- rsi : context
3312 // -- rax : number of rest parameters
3313 // -- rbx : pointer to first rest parameters
3314 // -- rsp[0] : return address
3315 // -----------------------------------
3316
3317 // Allocate space for the rest parameter array plus the backing store.
3318 Label allocate, done_allocate;
3319 __ leal(rcx, Operand(rax, times_pointer_size,
3320 JSArray::kSize + FixedArray::kHeaderSize));
3321 __ Allocate(rcx, rdx, r8, no_reg, &allocate, NO_ALLOCATION_FLAGS);
3322 __ bind(&done_allocate);
3323
3324 // Compute the arguments.length in rdi.
3325 __ Integer32ToSmi(rdi, rax);
3326
3327 // Setup the elements array in rdx.
3328 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex);
3329 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx);
3330 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi);
3331 {
3332 Label loop, done_loop;
3333 __ Set(rcx, 0);
3334 __ bind(&loop);
3335 __ cmpl(rcx, rax);
3336 __ j(equal, &done_loop, Label::kNear);
3337 __ movp(kScratchRegister, Operand(rbx, 0 * kPointerSize));
3338 __ movp(
3339 FieldOperand(rdx, rcx, times_pointer_size, FixedArray::kHeaderSize),
3340 kScratchRegister);
3341 __ subp(rbx, Immediate(1 * kPointerSize));
3342 __ addl(rcx, Immediate(1));
3343 __ jmp(&loop);
3344 __ bind(&done_loop);
3345 }
3346
3347 // Setup the rest parameter array in rax.
3348 __ leap(rax,
3349 Operand(rdx, rax, times_pointer_size, FixedArray::kHeaderSize));
3350 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, rcx);
3351 __ movp(FieldOperand(rax, JSArray::kMapOffset), rcx);
3352 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
3353 __ movp(FieldOperand(rax, JSArray::kPropertiesOffset), rcx);
3354 __ movp(FieldOperand(rax, JSArray::kElementsOffset), rdx);
3355 __ movp(FieldOperand(rax, JSArray::kLengthOffset), rdi);
3356 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3357 __ Ret();
3358
3359 // Fall back to %AllocateInNewSpace (if not too big).
3360 Label too_big_for_new_space;
3361 __ bind(&allocate);
3362 __ cmpl(rcx, Immediate(kMaxRegularHeapObjectSize));
3363 __ j(greater, &too_big_for_new_space);
3364 {
3365 FrameScope scope(masm, StackFrame::INTERNAL);
3366 __ Integer32ToSmi(rax, rax);
3367 __ Integer32ToSmi(rcx, rcx);
3368 __ Push(rax);
3369 __ Push(rbx);
3370 __ Push(rcx);
3371 __ CallRuntime(Runtime::kAllocateInNewSpace);
3372 __ movp(rdx, rax);
3373 __ Pop(rbx);
3374 __ Pop(rax);
3375 __ SmiToInteger32(rax, rax);
3376 }
3377 __ jmp(&done_allocate);
3378
3379 // Fall back to %NewRestParameter.
3380 __ bind(&too_big_for_new_space);
3381 __ PopReturnAddressTo(kScratchRegister);
3382 __ Push(rdi);
3383 __ PushReturnAddressFrom(kScratchRegister);
3384 __ TailCallRuntime(Runtime::kNewRestParameter);
3385 }
3386 }
3387
3388
3389 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) {
3390 // ----------- S t a t e -------------
3391 // -- rdi : function
3392 // -- rsi : context
3393 // -- rbp : frame pointer
3394 // -- rsp[0] : return address
3395 // -----------------------------------
3396 __ AssertFunction(rdi);
3397
3398 // Make r9 point to the JavaScript frame.
3399 __ movp(r9, rbp);
3400 if (skip_stub_frame()) {
3401 // For Ignition we need to skip the handler/stub frame to reach the
3402 // JavaScript frame for the function.
3403 __ movp(r9, Operand(r9, StandardFrameConstants::kCallerFPOffset));
3404 }
3405 if (FLAG_debug_code) {
3406 Label ok;
3407 __ cmpp(rdi, Operand(r9, StandardFrameConstants::kFunctionOffset));
3408 __ j(equal, &ok);
3409 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3410 __ bind(&ok);
3411 }
3412
3413 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub.
3414 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
3415 __ LoadSharedFunctionInfoSpecialField(
3416 rcx, rcx, SharedFunctionInfo::kFormalParameterCountOffset);
3417 __ leap(rdx, Operand(r9, rcx, times_pointer_size,
3418 StandardFrameConstants::kCallerSPOffset));
3419 __ Integer32ToSmi(rcx, rcx);
3420
3421 // rcx : number of parameters (tagged)
3422 // rdx : parameters pointer
3423 // rdi : function
3424 // rsp[0] : return address
3425 // r9 : JavaScript frame pointer.
3426 // Registers used over the whole function:
3427 // rbx: the mapped parameter count (untagged)
3428 // rax: the allocated object (tagged).
3429 Factory* factory = isolate()->factory();
3430
3431 __ SmiToInteger64(rbx, rcx);
3432 // rbx = parameter count (untagged)
3433
3434 // Check if the calling frame is an arguments adaptor frame.
3435 Label adaptor_frame, try_allocate, runtime;
3436 __ movp(rax, Operand(r9, StandardFrameConstants::kCallerFPOffset));
3437 __ movp(r8, Operand(rax, CommonFrameConstants::kContextOrFrameTypeOffset));
3438 __ Cmp(r8, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3439 __ j(equal, &adaptor_frame);
3440
3441 // No adaptor, parameter count = argument count.
3442 __ movp(r11, rbx);
3443 __ jmp(&try_allocate, Label::kNear);
3444
3445 // We have an adaptor frame. Patch the parameters pointer.
3446 __ bind(&adaptor_frame);
3447 __ SmiToInteger64(
3448 r11, Operand(rax, ArgumentsAdaptorFrameConstants::kLengthOffset));
3449 __ leap(rdx, Operand(rax, r11, times_pointer_size,
3450 StandardFrameConstants::kCallerSPOffset));
3451
3452 // rbx = parameter count (untagged)
3453 // r11 = argument count (untagged)
3454 // Compute the mapped parameter count = min(rbx, r11) in rbx.
3455 __ cmpp(rbx, r11);
3456 __ j(less_equal, &try_allocate, Label::kNear);
3457 __ movp(rbx, r11);
3458
3459 __ bind(&try_allocate);
3460
3461 // Compute the sizes of backing store, parameter map, and arguments object.
3462 // 1. Parameter map, has 2 extra words containing context and backing store.
3463 const int kParameterMapHeaderSize =
3464 FixedArray::kHeaderSize + 2 * kPointerSize;
3465 Label no_parameter_map;
3466 __ xorp(r8, r8);
3467 __ testp(rbx, rbx);
3468 __ j(zero, &no_parameter_map, Label::kNear);
3469 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize));
3470 __ bind(&no_parameter_map);
3471
3472 // 2. Backing store.
3473 __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize));
3474
3475 // 3. Arguments object.
3476 __ addp(r8, Immediate(JSSloppyArgumentsObject::kSize));
3477
3478 // Do the allocation of all three objects in one go.
3479 __ Allocate(r8, rax, r9, no_reg, &runtime, NO_ALLOCATION_FLAGS);
3480
3481 // rax = address of new object(s) (tagged)
3482 // r11 = argument count (untagged)
3483 // Get the arguments map from the current native context into r9.
3484 Label has_mapped_parameters, instantiate;
3485 __ movp(r9, NativeContextOperand());
3486 __ testp(rbx, rbx);
3487 __ j(not_zero, &has_mapped_parameters, Label::kNear);
3488
3489 const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX;
3490 __ movp(r9, Operand(r9, Context::SlotOffset(kIndex)));
3491 __ jmp(&instantiate, Label::kNear);
3492
3493 const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX;
3494 __ bind(&has_mapped_parameters);
3495 __ movp(r9, Operand(r9, Context::SlotOffset(kAliasedIndex)));
3496 __ bind(&instantiate);
3497
3498 // rax = address of new object (tagged)
3499 // rbx = mapped parameter count (untagged)
3500 // r11 = argument count (untagged)
3501 // r9 = address of arguments map (tagged)
3502 __ movp(FieldOperand(rax, JSObject::kMapOffset), r9);
3503 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
3504 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
3505 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
3506
3507 // Set up the callee in-object property.
3508 __ AssertNotSmi(rdi);
3509 __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kCalleeOffset), rdi);
3510
3511 // Use the length (smi tagged) and set that as an in-object property too.
3512 // Note: r11 is tagged from here on.
3513 __ Integer32ToSmi(r11, r11);
3514 __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kLengthOffset), r11);
3515
3516 // Set up the elements pointer in the allocated arguments object.
3517 // If we allocated a parameter map, rdi will point there, otherwise to the
3518 // backing store.
3519 __ leap(rdi, Operand(rax, JSSloppyArgumentsObject::kSize));
3520 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
3521
3522 // rax = address of new object (tagged)
3523 // rbx = mapped parameter count (untagged)
3524 // r11 = argument count (tagged)
3525 // rdi = address of parameter map or backing store (tagged)
3526
3527 // Initialize parameter map. If there are no mapped arguments, we're done.
3528 Label skip_parameter_map;
3529 __ testp(rbx, rbx);
3530 __ j(zero, &skip_parameter_map);
3531
3532 __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex);
3533 // rbx contains the untagged argument count. Add 2 and tag to write.
3534 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
3535 __ Integer64PlusConstantToSmi(r9, rbx, 2);
3536 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9);
3537 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi);
3538 __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
3539 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9);
3540
3541 // Copy the parameter slots and the holes in the arguments.
3542 // We need to fill in mapped_parameter_count slots. They index the context,
3543 // where parameters are stored in reverse order, at
3544 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
3545 // The mapped parameter thus need to get indices
3546 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
3547 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
3548 // We loop from right to left.
3549 Label parameters_loop, parameters_test;
3550
3551 // Load tagged parameter count into r9.
3552 __ Integer32ToSmi(r9, rbx);
3553 __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
3554 __ addp(r8, rcx);
3555 __ subp(r8, r9);
3556 __ movp(rcx, rdi);
3557 __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
3558 __ SmiToInteger64(r9, r9);
3559 // r9 = loop variable (untagged)
3560 // r8 = mapping index (tagged)
3561 // rcx = address of parameter map (tagged)
3562 // rdi = address of backing store (tagged)
3563 __ jmp(&parameters_test, Label::kNear);
3564
3565 __ bind(&parameters_loop);
3566 __ subp(r9, Immediate(1));
3567 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
3568 __ movp(FieldOperand(rcx, r9, times_pointer_size, kParameterMapHeaderSize),
3569 r8);
3570 __ movp(FieldOperand(rdi, r9, times_pointer_size, FixedArray::kHeaderSize),
3571 kScratchRegister);
3572 __ SmiAddConstant(r8, r8, Smi::FromInt(1));
3573 __ bind(&parameters_test);
3574 __ testp(r9, r9);
3575 __ j(not_zero, &parameters_loop, Label::kNear);
3576
3577 __ bind(&skip_parameter_map);
3578
3579 // r11 = argument count (tagged)
3580 // rdi = address of backing store (tagged)
3581 // Copy arguments header and remaining slots (if there are any).
3582 __ Move(FieldOperand(rdi, FixedArray::kMapOffset),
3583 factory->fixed_array_map());
3584 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r11);
3585
3586 Label arguments_loop, arguments_test;
3587 __ movp(r8, rbx);
3588 // Untag r11 for the loop below.
3589 __ SmiToInteger64(r11, r11);
3590 __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0));
3591 __ subp(rdx, kScratchRegister);
3592 __ jmp(&arguments_test, Label::kNear);
3593
3594 __ bind(&arguments_loop);
3595 __ subp(rdx, Immediate(kPointerSize));
3596 __ movp(r9, Operand(rdx, 0));
3597 __ movp(FieldOperand(rdi, r8,
3598 times_pointer_size,
3599 FixedArray::kHeaderSize),
3600 r9);
3601 __ addp(r8, Immediate(1));
3602
3603 __ bind(&arguments_test);
3604 __ cmpp(r8, r11);
3605 __ j(less, &arguments_loop, Label::kNear);
3606
3607 // Return.
3608 __ ret(0);
3609
3610 // Do the runtime call to allocate the arguments object.
3611 // r11 = argument count (untagged)
3612 __ bind(&runtime);
3613 __ Integer32ToSmi(r11, r11);
3614 __ PopReturnAddressTo(rax);
3615 __ Push(rdi); // Push function.
3616 __ Push(rdx); // Push parameters pointer.
3617 __ Push(r11); // Push parameter count.
3618 __ PushReturnAddressFrom(rax);
3619 __ TailCallRuntime(Runtime::kNewSloppyArguments);
3620 }
3621
3622
3623 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
3624 // ----------- S t a t e -------------
3625 // -- rdi : function
3626 // -- rsi : context
3627 // -- rbp : frame pointer
3628 // -- rsp[0] : return address
3629 // -----------------------------------
3630 __ AssertFunction(rdi);
3631
3632 // Make rdx point to the JavaScript frame.
3633 __ movp(rdx, rbp);
3634 if (skip_stub_frame()) {
3635 // For Ignition we need to skip the handler/stub frame to reach the
3636 // JavaScript frame for the function.
3637 __ movp(rdx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3638 }
3639 if (FLAG_debug_code) {
3640 Label ok;
3641 __ cmpp(rdi, Operand(rdx, StandardFrameConstants::kFunctionOffset));
3642 __ j(equal, &ok);
3643 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3644 __ bind(&ok);
3645 }
3646
3647 // Check if we have an arguments adaptor frame below the function frame.
3648 Label arguments_adaptor, arguments_done;
3649 __ movp(rbx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3650 __ Cmp(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset),
3651 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3652 __ j(equal, &arguments_adaptor, Label::kNear);
3653 {
3654 __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
3655 __ LoadSharedFunctionInfoSpecialField(
3656 rax, rax, SharedFunctionInfo::kFormalParameterCountOffset);
3657 __ leap(rbx, Operand(rdx, rax, times_pointer_size,
3658 StandardFrameConstants::kCallerSPOffset -
3659 1 * kPointerSize));
3660 }
3661 __ jmp(&arguments_done, Label::kNear);
3662 __ bind(&arguments_adaptor);
3663 {
3664 __ SmiToInteger32(
3665 rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
3666 __ leap(rbx, Operand(rbx, rax, times_pointer_size,
3667 StandardFrameConstants::kCallerSPOffset -
3668 1 * kPointerSize));
3669 }
3670 __ bind(&arguments_done);
3671
3672 // ----------- S t a t e -------------
3673 // -- rax : number of arguments
3674 // -- rbx : pointer to the first argument
3675 // -- rdi : function
3676 // -- rsi : context
3677 // -- rsp[0] : return address
3678 // -----------------------------------
3679
3680 // Allocate space for the strict arguments object plus the backing store.
3681 Label allocate, done_allocate;
3682 __ leal(rcx, Operand(rax, times_pointer_size, JSStrictArgumentsObject::kSize +
3683 FixedArray::kHeaderSize));
3684 __ Allocate(rcx, rdx, r8, no_reg, &allocate, NO_ALLOCATION_FLAGS);
3685 __ bind(&done_allocate);
3686
3687 // Compute the arguments.length in rdi.
3688 __ Integer32ToSmi(rdi, rax);
3689
3690 // Setup the elements array in rdx.
3691 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex);
3692 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx);
3693 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi);
3694 {
3695 Label loop, done_loop;
3696 __ Set(rcx, 0);
3697 __ bind(&loop);
3698 __ cmpl(rcx, rax);
3699 __ j(equal, &done_loop, Label::kNear);
3700 __ movp(kScratchRegister, Operand(rbx, 0 * kPointerSize));
3701 __ movp(
3702 FieldOperand(rdx, rcx, times_pointer_size, FixedArray::kHeaderSize),
3703 kScratchRegister);
3704 __ subp(rbx, Immediate(1 * kPointerSize));
3705 __ addl(rcx, Immediate(1));
3706 __ jmp(&loop);
3707 __ bind(&done_loop);
3708 }
3709
3710 // Setup the strict arguments object in rax.
3711 __ leap(rax,
3712 Operand(rdx, rax, times_pointer_size, FixedArray::kHeaderSize));
3713 __ LoadNativeContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX, rcx);
3714 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kMapOffset), rcx);
3715 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
3716 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kPropertiesOffset), rcx);
3717 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kElementsOffset), rdx);
3718 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kLengthOffset), rdi);
3719 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
3720 __ Ret();
3721
3722 // Fall back to %AllocateInNewSpace (if not too big).
3723 Label too_big_for_new_space;
3724 __ bind(&allocate);
3725 __ cmpl(rcx, Immediate(kMaxRegularHeapObjectSize));
3726 __ j(greater, &too_big_for_new_space);
3727 {
3728 FrameScope scope(masm, StackFrame::INTERNAL);
3729 __ Integer32ToSmi(rax, rax);
3730 __ Integer32ToSmi(rcx, rcx);
3731 __ Push(rax);
3732 __ Push(rbx);
3733 __ Push(rcx);
3734 __ CallRuntime(Runtime::kAllocateInNewSpace);
3735 __ movp(rdx, rax);
3736 __ Pop(rbx);
3737 __ Pop(rax);
3738 __ SmiToInteger32(rax, rax);
3739 }
3740 __ jmp(&done_allocate);
3741
3742 // Fall back to %NewStrictArguments.
3743 __ bind(&too_big_for_new_space);
3744 __ PopReturnAddressTo(kScratchRegister);
3745 __ Push(rdi);
3746 __ PushReturnAddressFrom(kScratchRegister);
3747 __ TailCallRuntime(Runtime::kNewStrictArguments);
3748 }
3749
3750
3751 static int Offset(ExternalReference ref0, ExternalReference ref1) { 3226 static int Offset(ExternalReference ref0, ExternalReference ref1) {
3752 int64_t offset = (ref0.address() - ref1.address()); 3227 int64_t offset = (ref0.address() - ref1.address());
3753 // Check that fits into int. 3228 // Check that fits into int.
3754 DCHECK(static_cast<int>(offset) == offset); 3229 DCHECK(static_cast<int>(offset) == offset);
3755 return static_cast<int>(offset); 3230 return static_cast<int>(offset);
3756 } 3231 }
3757 3232
3758
3759 // Prepares stack to put arguments (aligns and so on). WIN64 calling 3233 // Prepares stack to put arguments (aligns and so on). WIN64 calling
3760 // convention requires to put the pointer to the return value slot into 3234 // convention requires to put the pointer to the return value slot into
3761 // rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves 3235 // rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves
3762 // context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize 3236 // context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize
3763 // inside the exit frame (not GCed) accessible via StackSpaceOperand. 3237 // inside the exit frame (not GCed) accessible via StackSpaceOperand.
3764 static void PrepareCallApiFunction(MacroAssembler* masm, int arg_stack_space) { 3238 static void PrepareCallApiFunction(MacroAssembler* masm, int arg_stack_space) {
3765 __ EnterApiExitFrame(arg_stack_space); 3239 __ EnterApiExitFrame(arg_stack_space);
3766 } 3240 }
3767 3241
3768 3242
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
4132 kStackUnwindSpace, nullptr, return_value_operand, 3606 kStackUnwindSpace, nullptr, return_value_operand,
4133 NULL); 3607 NULL);
4134 } 3608 }
4135 3609
4136 #undef __ 3610 #undef __
4137 3611
4138 } // namespace internal 3612 } // namespace internal
4139 } // namespace v8 3613 } // namespace v8
4140 3614
4141 #endif // V8_TARGET_ARCH_X64 3615 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698