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

Side by Side Diff: src/mips64/macro-assembler-mips64.cc

Issue 1468073004: Reshuffle registers in JSConstructStub to avoid trashing costructor and new.target on fast path (so… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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/mips64/code-stubs-mips64.cc ('k') | src/x64/builtins-x64.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 #include <limits.h> // For LONG_MIN, LONG_MAX. 5 #include <limits.h> // For LONG_MIN, LONG_MAX.
6 6
7 #if V8_TARGET_ARCH_MIPS64 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/base/division-by-constant.h" 9 #include "src/base/division-by-constant.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 3486 matching lines...) Expand 10 before | Expand all | Expand 10 after
3497 if (emit_debug_code()) { 3497 if (emit_debug_code()) {
3498 // Trash the registers to simulate an allocation failure. 3498 // Trash the registers to simulate an allocation failure.
3499 li(result, 0x7091); 3499 li(result, 0x7091);
3500 li(scratch1, 0x7191); 3500 li(scratch1, 0x7191);
3501 li(scratch2, 0x7291); 3501 li(scratch2, 0x7291);
3502 } 3502 }
3503 jmp(gc_required); 3503 jmp(gc_required);
3504 return; 3504 return;
3505 } 3505 }
3506 3506
3507 DCHECK(!result.is(scratch1)); 3507 DCHECK(!AreAliased(result, scratch1, scratch2, t9));
3508 DCHECK(!result.is(scratch2));
3509 DCHECK(!scratch1.is(scratch2));
3510 DCHECK(!scratch1.is(t9));
3511 DCHECK(!scratch2.is(t9));
3512 DCHECK(!result.is(t9));
3513 3508
3514 // Make object size into bytes. 3509 // Make object size into bytes.
3515 if ((flags & SIZE_IN_WORDS) != 0) { 3510 if ((flags & SIZE_IN_WORDS) != 0) {
3516 object_size *= kPointerSize; 3511 object_size *= kPointerSize;
3517 } 3512 }
3518 DCHECK(0 == (object_size & kObjectAlignmentMask)); 3513 DCHECK(0 == (object_size & kObjectAlignmentMask));
3519 3514
3520 // Check relative positions of allocation top and limit addresses. 3515 // Check relative positions of allocation top and limit addresses.
3521 // ARM adds additional checks to make sure the ldm instruction can be 3516 // ARM adds additional checks to make sure the ldm instruction can be
3522 // used. On MIPS we don't have ldm so we don't need additional checks either. 3517 // used. On MIPS we don't have ldm so we don't need additional checks either.
3523 ExternalReference allocation_top = 3518 ExternalReference allocation_top =
3524 AllocationUtils::GetAllocationTopReference(isolate(), flags); 3519 AllocationUtils::GetAllocationTopReference(isolate(), flags);
3525 ExternalReference allocation_limit = 3520 ExternalReference allocation_limit =
3526 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 3521 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3527 3522
3528 intptr_t top = 3523 intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
3529 reinterpret_cast<intptr_t>(allocation_top.address()); 3524 intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
3530 intptr_t limit =
3531 reinterpret_cast<intptr_t>(allocation_limit.address());
3532 DCHECK((limit - top) == kPointerSize); 3525 DCHECK((limit - top) == kPointerSize);
3533 3526
3534 // Set up allocation top address and object size registers. 3527 // Set up allocation top address and allocation limit registers.
3535 Register topaddr = scratch1; 3528 Register top_address = scratch1;
3536 li(topaddr, Operand(allocation_top)); 3529 // This code stores a temporary value in t9.
3530 Register alloc_limit = t9;
3531 Register result_end = scratch2;
3532 li(top_address, Operand(allocation_top));
3537 3533
3538 // This code stores a temporary value in t9.
3539 if ((flags & RESULT_CONTAINS_TOP) == 0) { 3534 if ((flags & RESULT_CONTAINS_TOP) == 0) {
3540 // Load allocation top into result and allocation limit into t9. 3535 // Load allocation top into result and allocation limit into alloc_limit.
3541 ld(result, MemOperand(topaddr)); 3536 ld(result, MemOperand(top_address));
3542 ld(t9, MemOperand(topaddr, kPointerSize)); 3537 ld(alloc_limit, MemOperand(top_address, kPointerSize));
3543 } else { 3538 } else {
3544 if (emit_debug_code()) { 3539 if (emit_debug_code()) {
3545 // Assert that result actually contains top on entry. t9 is used 3540 // Assert that result actually contains top on entry.
3546 // immediately below so this use of t9 does not cause difference with 3541 ld(alloc_limit, MemOperand(top_address));
3547 // respect to register content between debug and release mode. 3542 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit));
3548 ld(t9, MemOperand(topaddr));
3549 Check(eq, kUnexpectedAllocationTop, result, Operand(t9));
3550 } 3543 }
3551 // Load allocation limit into t9. Result already contains allocation top. 3544 // Load allocation limit. Result already contains allocation top.
3552 ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top))); 3545 ld(alloc_limit, MemOperand(top_address, static_cast<int32_t>(limit - top)));
3553 } 3546 }
3554 3547
3555 DCHECK(kPointerSize == kDoubleSize); 3548 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have
3549 // the same alignment on ARM64.
3550 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
3551
3556 if (emit_debug_code()) { 3552 if (emit_debug_code()) {
3557 And(at, result, Operand(kDoubleAlignmentMask)); 3553 And(at, result, Operand(kDoubleAlignmentMask));
3558 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); 3554 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg));
3559 } 3555 }
3560 3556
3561 // Calculate new top and bail out if new space is exhausted. Use result 3557 // Calculate new top and bail out if new space is exhausted. Use result
3562 // to calculate the new top. 3558 // to calculate the new top.
3563 Daddu(scratch2, result, Operand(object_size)); 3559 Daddu(result_end, result, Operand(object_size));
3564 Branch(gc_required, Ugreater, scratch2, Operand(t9)); 3560 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit));
3565 sd(scratch2, MemOperand(topaddr)); 3561 sd(result_end, MemOperand(top_address));
3566 3562
3567 // Tag object if requested. 3563 // Tag object if requested.
3568 if ((flags & TAG_OBJECT) != 0) { 3564 if ((flags & TAG_OBJECT) != 0) {
3569 Daddu(result, result, Operand(kHeapObjectTag)); 3565 Daddu(result, result, Operand(kHeapObjectTag));
3570 } 3566 }
3571 } 3567 }
3572 3568
3573 3569
3574 void MacroAssembler::Allocate(Register object_size, Register result, 3570 void MacroAssembler::Allocate(Register object_size, Register result,
3575 Register result_end, Register scratch, 3571 Register result_end, Register scratch,
3576 Label* gc_required, AllocationFlags flags) { 3572 Label* gc_required, AllocationFlags flags) {
3577 if (!FLAG_inline_new) { 3573 if (!FLAG_inline_new) {
3578 if (emit_debug_code()) { 3574 if (emit_debug_code()) {
3579 // Trash the registers to simulate an allocation failure. 3575 // Trash the registers to simulate an allocation failure.
3580 li(result, 0x7091); 3576 li(result, 0x7091);
3581 li(scratch, 0x7191); 3577 li(scratch, 0x7191);
3582 li(result_end, 0x7291); 3578 li(result_end, 0x7291);
3583 } 3579 }
3584 jmp(gc_required); 3580 jmp(gc_required);
3585 return; 3581 return;
3586 } 3582 }
3587 3583
3588 DCHECK(!result.is(scratch)); 3584 // |object_size| and |result_end| may overlap, other registers must not.
3589 DCHECK(!result.is(result_end)); 3585 DCHECK(!AreAliased(object_size, result, scratch, t9));
3590 DCHECK(!scratch.is(result_end)); 3586 DCHECK(!AreAliased(result_end, result, scratch, t9));
3591 DCHECK(!object_size.is(t9));
3592 DCHECK(!scratch.is(t9) && !result_end.is(t9) && !result.is(t9));
3593 3587
3594 // Check relative positions of allocation top and limit addresses. 3588 // Check relative positions of allocation top and limit addresses.
3595 // ARM adds additional checks to make sure the ldm instruction can be 3589 // ARM adds additional checks to make sure the ldm instruction can be
3596 // used. On MIPS we don't have ldm so we don't need additional checks either. 3590 // used. On MIPS we don't have ldm so we don't need additional checks either.
3597 ExternalReference allocation_top = 3591 ExternalReference allocation_top =
3598 AllocationUtils::GetAllocationTopReference(isolate(), flags); 3592 AllocationUtils::GetAllocationTopReference(isolate(), flags);
3599 ExternalReference allocation_limit = 3593 ExternalReference allocation_limit =
3600 AllocationUtils::GetAllocationLimitReference(isolate(), flags); 3594 AllocationUtils::GetAllocationLimitReference(isolate(), flags);
3601 intptr_t top = 3595 intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
3602 reinterpret_cast<intptr_t>(allocation_top.address()); 3596 intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
3603 intptr_t limit =
3604 reinterpret_cast<intptr_t>(allocation_limit.address());
3605 DCHECK((limit - top) == kPointerSize); 3597 DCHECK((limit - top) == kPointerSize);
3606 3598
3607 // Set up allocation top address and object size registers. 3599 // Set up allocation top address and object size registers.
3608 Register topaddr = scratch; 3600 Register top_address = scratch;
3609 li(topaddr, Operand(allocation_top)); 3601 // This code stores a temporary value in t9.
3602 Register alloc_limit = t9;
3603 li(top_address, Operand(allocation_top));
3610 3604
3611 // This code stores a temporary value in t9.
3612 if ((flags & RESULT_CONTAINS_TOP) == 0) { 3605 if ((flags & RESULT_CONTAINS_TOP) == 0) {
3613 // Load allocation top into result and allocation limit into t9. 3606 // Load allocation top into result and allocation limit into alloc_limit.
3614 ld(result, MemOperand(topaddr)); 3607 ld(result, MemOperand(top_address));
3615 ld(t9, MemOperand(topaddr, kPointerSize)); 3608 ld(alloc_limit, MemOperand(top_address, kPointerSize));
3616 } else { 3609 } else {
3617 if (emit_debug_code()) { 3610 if (emit_debug_code()) {
3618 // Assert that result actually contains top on entry. t9 is used 3611 // Assert that result actually contains top on entry.
3619 // immediately below so this use of t9 does not cause difference with 3612 ld(alloc_limit, MemOperand(top_address));
3620 // respect to register content between debug and release mode. 3613 Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit));
3621 ld(t9, MemOperand(topaddr));
3622 Check(eq, kUnexpectedAllocationTop, result, Operand(t9));
3623 } 3614 }
3624 // Load allocation limit into t9. Result already contains allocation top. 3615 // Load allocation limit. Result already contains allocation top.
3625 ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top))); 3616 ld(alloc_limit, MemOperand(top_address, static_cast<int32_t>(limit - top)));
3626 } 3617 }
3627 3618
3628 DCHECK(kPointerSize == kDoubleSize); 3619 // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have
3620 // the same alignment on ARM64.
3621 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
3622
3629 if (emit_debug_code()) { 3623 if (emit_debug_code()) {
3630 And(at, result, Operand(kDoubleAlignmentMask)); 3624 And(at, result, Operand(kDoubleAlignmentMask));
3631 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); 3625 Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg));
3632 } 3626 }
3633 3627
3634 // Calculate new top and bail out if new space is exhausted. Use result 3628 // Calculate new top and bail out if new space is exhausted. Use result
3635 // to calculate the new top. Object size may be in words so a shift is 3629 // to calculate the new top. Object size may be in words so a shift is
3636 // required to get the number of bytes. 3630 // required to get the number of bytes.
3637 if ((flags & SIZE_IN_WORDS) != 0) { 3631 if ((flags & SIZE_IN_WORDS) != 0) {
3638 dsll(result_end, object_size, kPointerSizeLog2); 3632 dsll(result_end, object_size, kPointerSizeLog2);
3639 Daddu(result_end, result, result_end); 3633 Daddu(result_end, result, result_end);
3640 } else { 3634 } else {
3641 Daddu(result_end, result, Operand(object_size)); 3635 Daddu(result_end, result, Operand(object_size));
3642 } 3636 }
3643 Branch(gc_required, Ugreater, result_end, Operand(t9)); 3637 Branch(gc_required, Ugreater, result_end, Operand(alloc_limit));
3644 3638
3645 // Update allocation top. result temporarily holds the new top. 3639 // Update allocation top. result temporarily holds the new top.
3646 if (emit_debug_code()) { 3640 if (emit_debug_code()) {
3647 And(t9, result_end, Operand(kObjectAlignmentMask)); 3641 And(at, result_end, Operand(kObjectAlignmentMask));
3648 Check(eq, kUnalignedAllocationInNewSpace, t9, Operand(zero_reg)); 3642 Check(eq, kUnalignedAllocationInNewSpace, at, Operand(zero_reg));
3649 } 3643 }
3650 sd(result_end, MemOperand(topaddr)); 3644 sd(result_end, MemOperand(top_address));
3651 3645
3652 // Tag object if requested. 3646 // Tag object if requested.
3653 if ((flags & TAG_OBJECT) != 0) { 3647 if ((flags & TAG_OBJECT) != 0) {
3654 Daddu(result, result, Operand(kHeapObjectTag)); 3648 Daddu(result, result, Operand(kHeapObjectTag));
3655 } 3649 }
3656 } 3650 }
3657 3651
3658 3652
3659 void MacroAssembler::AllocateTwoByteString(Register result, 3653 void MacroAssembler::AllocateTwoByteString(Register result,
3660 Register length, 3654 Register length,
(...skipping 2601 matching lines...) Expand 10 before | Expand all | Expand 10 after
6262 if (mag.shift > 0) sra(result, result, mag.shift); 6256 if (mag.shift > 0) sra(result, result, mag.shift);
6263 srl(at, dividend, 31); 6257 srl(at, dividend, 31);
6264 Addu(result, result, Operand(at)); 6258 Addu(result, result, Operand(at));
6265 } 6259 }
6266 6260
6267 6261
6268 } // namespace internal 6262 } // namespace internal
6269 } // namespace v8 6263 } // namespace v8
6270 6264
6271 #endif // V8_TARGET_ARCH_MIPS64 6265 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/code-stubs-mips64.cc ('k') | src/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698