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

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

Issue 2645743002: [builtins] Port parameter and argument-related code stubs to CSA (Closed)
Patch Set: Review feedback 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
« no previous file with comments | « src/mips/interface-descriptors-mips.cc ('k') | src/mips64/interface-descriptors-mips64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
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 3291 matching lines...) Expand 10 before | Expand all | Expand 10 after
3302 } 3302 }
3303 3303
3304 Label fast_elements_case; 3304 Label fast_elements_case;
3305 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); 3305 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS));
3306 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 3306 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
3307 3307
3308 __ bind(&fast_elements_case); 3308 __ bind(&fast_elements_case);
3309 GenerateCase(masm, FAST_ELEMENTS); 3309 GenerateCase(masm, FAST_ELEMENTS);
3310 } 3310 }
3311 3311
3312 void FastNewRestParameterStub::Generate(MacroAssembler* masm) {
3313 // ----------- S t a t e -------------
3314 // -- a1 : function
3315 // -- cp : context
3316 // -- fp : frame pointer
3317 // -- ra : return address
3318 // -----------------------------------
3319 __ AssertFunction(a1);
3320
3321 // Make a2 point to the JavaScript frame.
3322 __ mov(a2, fp);
3323 if (skip_stub_frame()) {
3324 // For Ignition we need to skip the handler/stub frame to reach the
3325 // JavaScript frame for the function.
3326 __ ld(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
3327 }
3328 if (FLAG_debug_code) {
3329 Label ok;
3330 __ ld(a3, MemOperand(a2, StandardFrameConstants::kFunctionOffset));
3331 __ Branch(&ok, eq, a1, Operand(a3));
3332 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3333 __ bind(&ok);
3334 }
3335
3336 // Check if we have rest parameters (only possible if we have an
3337 // arguments adaptor frame below the function frame).
3338 Label no_rest_parameters;
3339 __ ld(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
3340 __ ld(a3, MemOperand(a2, CommonFrameConstants::kContextOrFrameTypeOffset));
3341 __ Branch(&no_rest_parameters, ne, a3,
3342 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3343
3344 // Check if the arguments adaptor frame contains more arguments than
3345 // specified by the function's internal formal parameter count.
3346 Label rest_parameters;
3347 __ SmiLoadUntag(
3348 a0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset));
3349 __ ld(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
3350 __ lw(a3,
3351 FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset));
3352 __ Dsubu(a0, a0, Operand(a3));
3353 __ Branch(&rest_parameters, gt, a0, Operand(zero_reg));
3354
3355 // Return an empty rest parameter array.
3356 __ bind(&no_rest_parameters);
3357 {
3358 // ----------- S t a t e -------------
3359 // -- cp : context
3360 // -- ra : return address
3361 // -----------------------------------
3362
3363 // Allocate an empty rest parameter array.
3364 Label allocate, done_allocate;
3365 __ Allocate(JSArray::kSize, v0, a0, a1, &allocate, NO_ALLOCATION_FLAGS);
3366 __ bind(&done_allocate);
3367
3368 // Setup the rest parameter array in v0.
3369 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, a1);
3370 __ sd(a1, FieldMemOperand(v0, JSArray::kMapOffset));
3371 __ LoadRoot(a1, Heap::kEmptyFixedArrayRootIndex);
3372 __ sd(a1, FieldMemOperand(v0, JSArray::kPropertiesOffset));
3373 __ sd(a1, FieldMemOperand(v0, JSArray::kElementsOffset));
3374 __ Move(a1, Smi::kZero);
3375 __ Ret(USE_DELAY_SLOT);
3376 __ sd(a1, FieldMemOperand(v0, JSArray::kLengthOffset)); // In delay slot
3377 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3378
3379 // Fall back to %AllocateInNewSpace.
3380 __ bind(&allocate);
3381 {
3382 FrameScope scope(masm, StackFrame::INTERNAL);
3383 __ Push(Smi::FromInt(JSArray::kSize));
3384 __ CallRuntime(Runtime::kAllocateInNewSpace);
3385 }
3386 __ jmp(&done_allocate);
3387 }
3388
3389 __ bind(&rest_parameters);
3390 {
3391 // Compute the pointer to the first rest parameter (skippping the receiver).
3392 __ Dlsa(a2, a2, a0, kPointerSizeLog2);
3393 __ Daddu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset -
3394 1 * kPointerSize));
3395
3396 // ----------- S t a t e -------------
3397 // -- cp : context
3398 // -- a0 : number of rest parameters
3399 // -- a1 : function
3400 // -- a2 : pointer to first rest parameters
3401 // -- ra : return address
3402 // -----------------------------------
3403
3404 // Allocate space for the rest parameter array plus the backing store.
3405 Label allocate, done_allocate;
3406 __ li(a5, Operand(JSArray::kSize + FixedArray::kHeaderSize));
3407 __ Dlsa(a5, a5, a0, kPointerSizeLog2);
3408 __ Allocate(a5, v0, a3, a4, &allocate, NO_ALLOCATION_FLAGS);
3409 __ bind(&done_allocate);
3410
3411 // Compute arguments.length in a4.
3412 __ SmiTag(a4, a0);
3413
3414 // Setup the elements array in v0.
3415 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex);
3416 __ sd(at, FieldMemOperand(v0, FixedArray::kMapOffset));
3417 __ sd(a4, FieldMemOperand(v0, FixedArray::kLengthOffset));
3418 __ Daddu(a3, v0, Operand(FixedArray::kHeaderSize));
3419 {
3420 Label loop, done_loop;
3421 __ Dlsa(a1, a3, a0, kPointerSizeLog2);
3422 __ bind(&loop);
3423 __ Branch(&done_loop, eq, a1, Operand(a3));
3424 __ ld(at, MemOperand(a2, 0 * kPointerSize));
3425 __ sd(at, FieldMemOperand(a3, 0 * kPointerSize));
3426 __ Dsubu(a2, a2, Operand(1 * kPointerSize));
3427 __ Daddu(a3, a3, Operand(1 * kPointerSize));
3428 __ Branch(&loop);
3429 __ bind(&done_loop);
3430 }
3431
3432 // Setup the rest parameter array in a3.
3433 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, at);
3434 __ sd(at, FieldMemOperand(a3, JSArray::kMapOffset));
3435 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
3436 __ sd(at, FieldMemOperand(a3, JSArray::kPropertiesOffset));
3437 __ sd(v0, FieldMemOperand(a3, JSArray::kElementsOffset));
3438 __ sd(a4, FieldMemOperand(a3, JSArray::kLengthOffset));
3439 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3440 __ Ret(USE_DELAY_SLOT);
3441 __ mov(v0, a3); // In delay slot
3442
3443 // Fall back to %AllocateInNewSpace (if not too big).
3444 Label too_big_for_new_space;
3445 __ bind(&allocate);
3446 __ Branch(&too_big_for_new_space, gt, a5,
3447 Operand(kMaxRegularHeapObjectSize));
3448 {
3449 FrameScope scope(masm, StackFrame::INTERNAL);
3450 __ SmiTag(a0);
3451 __ SmiTag(a5);
3452 __ Push(a0, a2, a5);
3453 __ CallRuntime(Runtime::kAllocateInNewSpace);
3454 __ Pop(a0, a2);
3455 __ SmiUntag(a0);
3456 }
3457 __ jmp(&done_allocate);
3458
3459 // Fall back to %NewStrictArguments.
3460 __ bind(&too_big_for_new_space);
3461 __ Push(a1);
3462 __ TailCallRuntime(Runtime::kNewStrictArguments);
3463 }
3464 }
3465
3466
3467 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) {
3468 // ----------- S t a t e -------------
3469 // -- a1 : function
3470 // -- cp : context
3471 // -- fp : frame pointer
3472 // -- ra : return address
3473 // -----------------------------------
3474 __ AssertFunction(a1);
3475
3476 // Make t0 point to the JavaScript frame.
3477 __ mov(t0, fp);
3478 if (skip_stub_frame()) {
3479 // For Ignition we need to skip the handler/stub frame to reach the
3480 // JavaScript frame for the function.
3481 __ ld(t0, MemOperand(t0, StandardFrameConstants::kCallerFPOffset));
3482 }
3483 if (FLAG_debug_code) {
3484 Label ok;
3485 __ ld(a3, MemOperand(t0, StandardFrameConstants::kFunctionOffset));
3486 __ Branch(&ok, eq, a1, Operand(a3));
3487 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3488 __ bind(&ok);
3489 }
3490
3491 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub.
3492 __ ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
3493 __ lw(a2,
3494 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
3495 __ Lsa(a3, t0, a2, kPointerSizeLog2);
3496 __ Addu(a3, a3, Operand(StandardFrameConstants::kCallerSPOffset));
3497 __ SmiTag(a2);
3498
3499 // a1 : function
3500 // a2 : number of parameters (tagged)
3501 // a3 : parameters pointer
3502 // t0 : Javascript frame pointer
3503 // Registers used over whole function:
3504 // a5 : arguments count (tagged)
3505 // a6 : mapped parameter count (tagged)
3506
3507 // Check if the calling frame is an arguments adaptor frame.
3508 Label adaptor_frame, try_allocate, runtime;
3509 __ ld(a4, MemOperand(t0, StandardFrameConstants::kCallerFPOffset));
3510 __ ld(a0, MemOperand(a4, CommonFrameConstants::kContextOrFrameTypeOffset));
3511 __ Branch(&adaptor_frame, eq, a0,
3512 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3513
3514 // No adaptor, parameter count = argument count.
3515 __ mov(a5, a2);
3516 __ Branch(USE_DELAY_SLOT, &try_allocate);
3517 __ mov(a6, a2); // In delay slot.
3518
3519 // We have an adaptor frame. Patch the parameters pointer.
3520 __ bind(&adaptor_frame);
3521 __ ld(a5, MemOperand(a4, ArgumentsAdaptorFrameConstants::kLengthOffset));
3522 __ SmiScale(t2, a5, kPointerSizeLog2);
3523 __ Daddu(a4, a4, Operand(t2));
3524 __ Daddu(a3, a4, Operand(StandardFrameConstants::kCallerSPOffset));
3525
3526 // a5 = argument count (tagged)
3527 // a6 = parameter count (tagged)
3528 // Compute the mapped parameter count = min(a6, a5) in a6.
3529 __ mov(a6, a2);
3530 __ Branch(&try_allocate, le, a6, Operand(a5));
3531 __ mov(a6, a5);
3532
3533 __ bind(&try_allocate);
3534
3535 // Compute the sizes of backing store, parameter map, and arguments object.
3536 // 1. Parameter map, has 2 extra words containing context and backing store.
3537 const int kParameterMapHeaderSize =
3538 FixedArray::kHeaderSize + 2 * kPointerSize;
3539 // If there are no mapped parameters, we do not need the parameter_map.
3540 Label param_map_size;
3541 DCHECK_EQ(static_cast<Smi*>(0), Smi::kZero);
3542 __ Branch(USE_DELAY_SLOT, &param_map_size, eq, a6, Operand(zero_reg));
3543 __ mov(t1, zero_reg); // In delay slot: param map size = 0 when a6 == 0.
3544 __ SmiScale(t1, a6, kPointerSizeLog2);
3545 __ daddiu(t1, t1, kParameterMapHeaderSize);
3546 __ bind(&param_map_size);
3547
3548 // 2. Backing store.
3549 __ SmiScale(t2, a5, kPointerSizeLog2);
3550 __ Daddu(t1, t1, Operand(t2));
3551 __ Daddu(t1, t1, Operand(FixedArray::kHeaderSize));
3552
3553 // 3. Arguments object.
3554 __ Daddu(t1, t1, Operand(JSSloppyArgumentsObject::kSize));
3555
3556 // Do the allocation of all three objects in one go.
3557 __ Allocate(t1, v0, t1, a4, &runtime, NO_ALLOCATION_FLAGS);
3558
3559 // v0 = address of new object(s) (tagged)
3560 // a2 = argument count (smi-tagged)
3561 // Get the arguments boilerplate from the current native context into a4.
3562 const int kNormalOffset =
3563 Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
3564 const int kAliasedOffset =
3565 Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
3566
3567 __ ld(a4, NativeContextMemOperand());
3568 Label skip2_ne, skip2_eq;
3569 __ Branch(&skip2_ne, ne, a6, Operand(zero_reg));
3570 __ ld(a4, MemOperand(a4, kNormalOffset));
3571 __ bind(&skip2_ne);
3572
3573 __ Branch(&skip2_eq, eq, a6, Operand(zero_reg));
3574 __ ld(a4, MemOperand(a4, kAliasedOffset));
3575 __ bind(&skip2_eq);
3576
3577 // v0 = address of new object (tagged)
3578 // a2 = argument count (smi-tagged)
3579 // a4 = address of arguments map (tagged)
3580 // a6 = mapped parameter count (tagged)
3581 __ sd(a4, FieldMemOperand(v0, JSObject::kMapOffset));
3582 __ LoadRoot(t1, Heap::kEmptyFixedArrayRootIndex);
3583 __ sd(t1, FieldMemOperand(v0, JSObject::kPropertiesOffset));
3584 __ sd(t1, FieldMemOperand(v0, JSObject::kElementsOffset));
3585
3586 // Set up the callee in-object property.
3587 __ AssertNotSmi(a1);
3588 __ sd(a1, FieldMemOperand(v0, JSSloppyArgumentsObject::kCalleeOffset));
3589
3590 // Use the length (smi tagged) and set that as an in-object property too.
3591 __ AssertSmi(a5);
3592 __ sd(a5, FieldMemOperand(v0, JSSloppyArgumentsObject::kLengthOffset));
3593
3594 // Set up the elements pointer in the allocated arguments object.
3595 // If we allocated a parameter map, a4 will point there, otherwise
3596 // it will point to the backing store.
3597 __ Daddu(a4, v0, Operand(JSSloppyArgumentsObject::kSize));
3598 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset));
3599
3600 // v0 = address of new object (tagged)
3601 // a2 = argument count (tagged)
3602 // a4 = address of parameter map or backing store (tagged)
3603 // a6 = mapped parameter count (tagged)
3604 // Initialize parameter map. If there are no mapped arguments, we're done.
3605 Label skip_parameter_map;
3606 Label skip3;
3607 __ Branch(&skip3, ne, a6, Operand(Smi::kZero));
3608 // Move backing store address to a1, because it is
3609 // expected there when filling in the unmapped arguments.
3610 __ mov(a1, a4);
3611 __ bind(&skip3);
3612
3613 __ Branch(&skip_parameter_map, eq, a6, Operand(Smi::kZero));
3614
3615 __ LoadRoot(a5, Heap::kSloppyArgumentsElementsMapRootIndex);
3616 __ sd(a5, FieldMemOperand(a4, FixedArray::kMapOffset));
3617 __ Daddu(a5, a6, Operand(Smi::FromInt(2)));
3618 __ sd(a5, FieldMemOperand(a4, FixedArray::kLengthOffset));
3619 __ sd(cp, FieldMemOperand(a4, FixedArray::kHeaderSize + 0 * kPointerSize));
3620 __ SmiScale(t2, a6, kPointerSizeLog2);
3621 __ Daddu(a5, a4, Operand(t2));
3622 __ Daddu(a5, a5, Operand(kParameterMapHeaderSize));
3623 __ sd(a5, FieldMemOperand(a4, FixedArray::kHeaderSize + 1 * kPointerSize));
3624
3625 // Copy the parameter slots and the holes in the arguments.
3626 // We need to fill in mapped_parameter_count slots. They index the context,
3627 // where parameters are stored in reverse order, at
3628 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
3629 // The mapped parameter thus need to get indices
3630 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
3631 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
3632 // We loop from right to left.
3633 Label parameters_loop, parameters_test;
3634 __ mov(a5, a6);
3635 __ Daddu(t1, a2, Operand(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
3636 __ Dsubu(t1, t1, Operand(a6));
3637 __ LoadRoot(a7, Heap::kTheHoleValueRootIndex);
3638 __ SmiScale(t2, a5, kPointerSizeLog2);
3639 __ Daddu(a1, a4, Operand(t2));
3640 __ Daddu(a1, a1, Operand(kParameterMapHeaderSize));
3641
3642 // a1 = address of backing store (tagged)
3643 // a4 = address of parameter map (tagged)
3644 // a0 = temporary scratch (a.o., for address calculation)
3645 // t1 = loop variable (tagged)
3646 // a7 = the hole value
3647 __ jmp(&parameters_test);
3648
3649 __ bind(&parameters_loop);
3650 __ Dsubu(a5, a5, Operand(Smi::FromInt(1)));
3651 __ SmiScale(a0, a5, kPointerSizeLog2);
3652 __ Daddu(a0, a0, Operand(kParameterMapHeaderSize - kHeapObjectTag));
3653 __ Daddu(t2, a4, a0);
3654 __ sd(t1, MemOperand(t2));
3655 __ Dsubu(a0, a0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
3656 __ Daddu(t2, a1, a0);
3657 __ sd(a7, MemOperand(t2));
3658 __ Daddu(t1, t1, Operand(Smi::FromInt(1)));
3659 __ bind(&parameters_test);
3660 __ Branch(&parameters_loop, ne, a5, Operand(Smi::kZero));
3661
3662 // Restore t1 = argument count (tagged).
3663 __ ld(a5, FieldMemOperand(v0, JSSloppyArgumentsObject::kLengthOffset));
3664
3665 __ bind(&skip_parameter_map);
3666 // v0 = address of new object (tagged)
3667 // a1 = address of backing store (tagged)
3668 // a5 = argument count (tagged)
3669 // a6 = mapped parameter count (tagged)
3670 // t1 = scratch
3671 // Copy arguments header and remaining slots (if there are any).
3672 __ LoadRoot(t1, Heap::kFixedArrayMapRootIndex);
3673 __ sd(t1, FieldMemOperand(a1, FixedArray::kMapOffset));
3674 __ sd(a5, FieldMemOperand(a1, FixedArray::kLengthOffset));
3675
3676 Label arguments_loop, arguments_test;
3677 __ SmiScale(t2, a6, kPointerSizeLog2);
3678 __ Dsubu(a3, a3, Operand(t2));
3679 __ jmp(&arguments_test);
3680
3681 __ bind(&arguments_loop);
3682 __ Dsubu(a3, a3, Operand(kPointerSize));
3683 __ ld(a4, MemOperand(a3, 0));
3684 __ SmiScale(t2, a6, kPointerSizeLog2);
3685 __ Daddu(t1, a1, Operand(t2));
3686 __ sd(a4, FieldMemOperand(t1, FixedArray::kHeaderSize));
3687 __ Daddu(a6, a6, Operand(Smi::FromInt(1)));
3688
3689 __ bind(&arguments_test);
3690 __ Branch(&arguments_loop, lt, a6, Operand(a5));
3691
3692 // Return.
3693 __ Ret();
3694
3695 // Do the runtime call to allocate the arguments object.
3696 // a5 = argument count (tagged)
3697 __ bind(&runtime);
3698 __ Push(a1, a3, a5);
3699 __ TailCallRuntime(Runtime::kNewSloppyArguments);
3700 }
3701
3702
3703 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
3704 // ----------- S t a t e -------------
3705 // -- a1 : function
3706 // -- cp : context
3707 // -- fp : frame pointer
3708 // -- ra : return address
3709 // -----------------------------------
3710 __ AssertFunction(a1);
3711
3712 // Make a2 point to the JavaScript frame.
3713 __ mov(a2, fp);
3714 if (skip_stub_frame()) {
3715 // For Ignition we need to skip the handler/stub frame to reach the
3716 // JavaScript frame for the function.
3717 __ ld(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
3718 }
3719 if (FLAG_debug_code) {
3720 Label ok;
3721 __ ld(a3, MemOperand(a2, StandardFrameConstants::kFunctionOffset));
3722 __ Branch(&ok, eq, a1, Operand(a3));
3723 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3724 __ bind(&ok);
3725 }
3726
3727 // Check if we have an arguments adaptor frame below the function frame.
3728 Label arguments_adaptor, arguments_done;
3729 __ ld(a3, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
3730 __ ld(a0, MemOperand(a3, CommonFrameConstants::kContextOrFrameTypeOffset));
3731 __ Branch(&arguments_adaptor, eq, a0,
3732 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3733 {
3734 __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
3735 __ lw(a0,
3736 FieldMemOperand(a4, SharedFunctionInfo::kFormalParameterCountOffset));
3737 __ Dlsa(a2, a2, a0, kPointerSizeLog2);
3738 __ Daddu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset -
3739 1 * kPointerSize));
3740 }
3741 __ Branch(&arguments_done);
3742 __ bind(&arguments_adaptor);
3743 {
3744 __ SmiLoadUntag(
3745 a0, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset));
3746 __ Dlsa(a2, a3, a0, kPointerSizeLog2);
3747 __ Daddu(a2, a2, Operand(StandardFrameConstants::kCallerSPOffset -
3748 1 * kPointerSize));
3749 }
3750 __ bind(&arguments_done);
3751
3752 // ----------- S t a t e -------------
3753 // -- cp : context
3754 // -- a0 : number of rest parameters
3755 // -- a1 : function
3756 // -- a2 : pointer to first rest parameters
3757 // -- ra : return address
3758 // -----------------------------------
3759
3760 // Allocate space for the rest parameter array plus the backing store.
3761 Label allocate, done_allocate;
3762 __ li(a5, Operand(JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize));
3763 __ Dlsa(a5, a5, a0, kPointerSizeLog2);
3764 __ Allocate(a5, v0, a3, a4, &allocate, NO_ALLOCATION_FLAGS);
3765 __ bind(&done_allocate);
3766
3767 // Compute arguments.length in a4.
3768 __ SmiTag(a4, a0);
3769
3770 // Setup the elements array in v0.
3771 __ LoadRoot(at, Heap::kFixedArrayMapRootIndex);
3772 __ sd(at, FieldMemOperand(v0, FixedArray::kMapOffset));
3773 __ sd(a4, FieldMemOperand(v0, FixedArray::kLengthOffset));
3774 __ Daddu(a3, v0, Operand(FixedArray::kHeaderSize));
3775 {
3776 Label loop, done_loop;
3777 __ Dlsa(a1, a3, a0, kPointerSizeLog2);
3778 __ bind(&loop);
3779 __ Branch(&done_loop, eq, a1, Operand(a3));
3780 __ ld(at, MemOperand(a2, 0 * kPointerSize));
3781 __ sd(at, FieldMemOperand(a3, 0 * kPointerSize));
3782 __ Dsubu(a2, a2, Operand(1 * kPointerSize));
3783 __ Daddu(a3, a3, Operand(1 * kPointerSize));
3784 __ Branch(&loop);
3785 __ bind(&done_loop);
3786 }
3787
3788 // Setup the strict arguments object in a3.
3789 __ LoadNativeContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX, at);
3790 __ sd(at, FieldMemOperand(a3, JSStrictArgumentsObject::kMapOffset));
3791 __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
3792 __ sd(at, FieldMemOperand(a3, JSStrictArgumentsObject::kPropertiesOffset));
3793 __ sd(v0, FieldMemOperand(a3, JSStrictArgumentsObject::kElementsOffset));
3794 __ sd(a4, FieldMemOperand(a3, JSStrictArgumentsObject::kLengthOffset));
3795 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
3796 __ Ret(USE_DELAY_SLOT);
3797 __ mov(v0, a3); // In delay slot
3798
3799 // Fall back to %AllocateInNewSpace (if not too big).
3800 Label too_big_for_new_space;
3801 __ bind(&allocate);
3802 __ Branch(&too_big_for_new_space, gt, a5, Operand(kMaxRegularHeapObjectSize));
3803 {
3804 FrameScope scope(masm, StackFrame::INTERNAL);
3805 __ SmiTag(a0);
3806 __ SmiTag(a5);
3807 __ Push(a0, a2, a5);
3808 __ CallRuntime(Runtime::kAllocateInNewSpace);
3809 __ Pop(a0, a2);
3810 __ SmiUntag(a0);
3811 }
3812 __ jmp(&done_allocate);
3813
3814 // Fall back to %NewStrictArguments.
3815 __ bind(&too_big_for_new_space);
3816 __ Push(a1);
3817 __ TailCallRuntime(Runtime::kNewStrictArguments);
3818 }
3819
3820
3821 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { 3312 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
3822 int64_t offset = (ref0.address() - ref1.address()); 3313 int64_t offset = (ref0.address() - ref1.address());
3823 DCHECK(static_cast<int>(offset) == offset); 3314 DCHECK(static_cast<int>(offset) == offset);
3824 return static_cast<int>(offset); 3315 return static_cast<int>(offset);
3825 } 3316 }
3826 3317
3827 3318
3828 // Calls an API function. Allocates HandleScope, extracts returned value 3319 // Calls an API function. Allocates HandleScope, extracts returned value
3829 // from handle and propagates exceptions. Restores context. stack_space 3320 // from handle and propagates exceptions. Restores context. stack_space
3830 // - space to be unwound on exit (includes the call JS arguments space and 3321 // - space to be unwound on exit (includes the call JS arguments space and
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
4128 kStackUnwindSpace, kInvalidStackOffset, 3619 kStackUnwindSpace, kInvalidStackOffset,
4129 return_value_operand, NULL); 3620 return_value_operand, NULL);
4130 } 3621 }
4131 3622
4132 #undef __ 3623 #undef __
4133 3624
4134 } // namespace internal 3625 } // namespace internal
4135 } // namespace v8 3626 } // namespace v8
4136 3627
4137 #endif // V8_TARGET_ARCH_MIPS64 3628 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips/interface-descriptors-mips.cc ('k') | src/mips64/interface-descriptors-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698