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

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

Powered by Google App Engine
This is Rietveld 408576698