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

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

Issue 194793002: [v8-dev] ARM: safepoints frame optimization (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 ldm(ia_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | 617 ldm(ia_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) |
618 cp.bit() | 618 cp.bit() |
619 (FLAG_enable_ool_constant_pool ? pp.bit() : 0) | 619 (FLAG_enable_ool_constant_pool ? pp.bit() : 0) |
620 fp.bit() | 620 fp.bit() |
621 lr.bit()); 621 lr.bit());
622 } 622 }
623 623
624 624
625 // Push and pop all registers that can hold pointers. 625 // Push and pop all registers that can hold pointers.
626 void MacroAssembler::PushSafepointRegisters() { 626 void MacroAssembler::PushSafepointRegisters() {
627 // Safepoints expect a block of contiguous register values starting with r0: 627 // This function must be called from LCodeGen::GenerateCode where
628 ASSERT(((1 << kNumSafepointSavedRegisters) - 1) == kSafepointSavedRegisters); 628 // registers_mask and double_registers_mask are set.
629 // Safepoints expect a block of kNumSafepointRegisters values on the 629 ASSERT(registers_mask() != kRegListEmpty);
630 // stack, so adjust the stack for unsaved registers. 630 stm(db_w, sp, registers_mask());
631 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
632 ASSERT(num_unsaved >= 0);
633 sub(sp, sp, Operand(num_unsaved * kPointerSize));
634 stm(db_w, sp, kSafepointSavedRegisters);
635 } 631 }
636 632
637 633
638 void MacroAssembler::PopSafepointRegisters() { 634 void MacroAssembler::PopSafepointRegisters() {
639 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; 635 // This function must be called from LCodeGen::GenerateCode where
640 ldm(ia_w, sp, kSafepointSavedRegisters); 636 // registers_mask and double_registers_mask are set.
641 add(sp, sp, Operand(num_unsaved * kPointerSize)); 637 ASSERT(registers_mask() != kRegListEmpty);
638 ldm(ia_w, sp, registers_mask());
642 } 639 }
643 640
644 641
645 void MacroAssembler::PushSafepointRegistersAndDoubles() { 642 void MacroAssembler::PushSafepointRegistersAndDoubles() {
646 // Number of d-regs not known at snapshot time.
647 ASSERT(!Serializer::enabled());
648 PushSafepointRegisters(); 643 PushSafepointRegisters();
649 // Only save allocatable registers. 644 // The vstm instruction can only save up to 16 doubles. So we save all the
650 ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14)); 645 // doubles registers with up to 2 instructions.
651 ASSERT(DwVfpRegister::NumReservedRegisters() == 2); 646 RegList high_mask = double_registers_mask() & 0xffff0000;
652 if (CpuFeatures::IsSupported(VFP32DREGS)) { 647 if (high_mask != 0) {
653 vstm(db_w, sp, d16, d31); 648 for (int i = LowDwVfpRegister::kMaxNumLowRegisters;
649 i < DoubleRegister::NumRegisters();
650 i++) {
651 if ((high_mask & (1 << i)) != 0) {
652 int last = i + CompilerIntrinsics::CountSetBits(high_mask) - 1;
653 // When double_registers_mask has been initialized, we ensured that
654 // there is no holes between the first and the last high registers.
655 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) ==
656 high_mask);
657 vstm(db_w, sp, DwVfpRegister::from_code(i),
658 DwVfpRegister::from_code(last));
659 break;
660 }
661 }
654 } 662 }
655 vstm(db_w, sp, d0, d13); 663 RegList low_mask = double_registers_mask() & 0xffff;
664 if (low_mask != 0) {
665 for (int i = 0; i < LowDwVfpRegister::kMaxNumLowRegisters; i++) {
666 if ((low_mask & (1 << i)) != 0) {
667 int last = i + CompilerIntrinsics::CountSetBits(low_mask) - 1;
668 // When double_registers_mask has been initialized, we ensured that
669 // there is no holes between the first and the last low registers.
670 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) ==
671 low_mask);
672 vstm(db_w, sp, LowDwVfpRegister::from_code(i),
673 LowDwVfpRegister::from_code(last));
674 break;
675 }
676 }
677 }
656 } 678 }
657 679
658 680
659 void MacroAssembler::PopSafepointRegistersAndDoubles() { 681 void MacroAssembler::PopSafepointRegistersAndDoubles() {
660 // Number of d-regs not known at snapshot time. 682 // The vldm instruction can only restore up to 16 doubles. So we save all the
661 ASSERT(!Serializer::enabled()); 683 // doubles registers with up to 2 instructions.
662 // Only save allocatable registers. 684 RegList low_mask = double_registers_mask() & 0xffff;
663 ASSERT(kScratchDoubleReg.is(d15) && kDoubleRegZero.is(d14)); 685 if (low_mask != 0) {
664 ASSERT(DwVfpRegister::NumReservedRegisters() == 2); 686 for (int i = 0; i < LowDwVfpRegister::kMaxNumLowRegisters; i++) {
665 vldm(ia_w, sp, d0, d13); 687 if ((low_mask & (1 << i)) != 0) {
666 if (CpuFeatures::IsSupported(VFP32DREGS)) { 688 int last = i + CompilerIntrinsics::CountSetBits(low_mask) - 1;
667 vldm(ia_w, sp, d16, d31); 689 // When double_registers_mask has been initialized, we ensured that
690 // there is no holes between the first and the last low registers.
691 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) ==
692 low_mask);
693 vldm(ia_w, sp, LowDwVfpRegister::from_code(i),
694 LowDwVfpRegister::from_code(last));
695 break;
696 }
697 }
698 }
699 RegList high_mask = double_registers_mask() & 0xffff0000;
700 if (high_mask != 0) {
701 for (int i = LowDwVfpRegister::kMaxNumLowRegisters;
702 i < DoubleRegister::NumRegisters();
703 i++) {
704 if ((high_mask & (1 << i)) != 0) {
705 int last = i + CompilerIntrinsics::CountSetBits(high_mask) - 1;
706 // When double_registers_mask has been initialized, we ensured that
707 // there is no holes between the first and the last high registers.
708 ASSERT(((((1 << last) - 1) | (1 << last)) & ~((1 << i) - 1)) ==
709 high_mask);
710 vldm(ia_w, sp, DwVfpRegister::from_code(i),
711 DwVfpRegister::from_code(last));
712 break;
713 }
714 }
668 } 715 }
669 PopSafepointRegisters(); 716 PopSafepointRegisters();
670 } 717 }
671 718
672 void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src, 719 void MacroAssembler::StoreToSafepointRegistersAndDoublesSlot(Register src,
673 Register dst) { 720 Register dst) {
721 // This function must be called from LCodeGen::GenerateCode where
722 // registers_mask and double_registers_mask are set.
723 ASSERT((registers_mask() & dst.bit()) != kRegListEmpty);
674 str(src, SafepointRegistersAndDoublesSlot(dst)); 724 str(src, SafepointRegistersAndDoublesSlot(dst));
675 } 725 }
676 726
677 727
678 void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) { 728 void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) {
729 // This function must be called from LCodeGen::GenerateCode where
730 // registers_mask and double_registers_mask are set.
731 ASSERT((registers_mask() & dst.bit()) != kRegListEmpty);
679 str(src, SafepointRegisterSlot(dst)); 732 str(src, SafepointRegisterSlot(dst));
680 } 733 }
681 734
682 735
683 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 736 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
737 // This function must be called from LCodeGen::GenerateCode where
738 // registers_mask and double_registers_mask are set.
739 ASSERT((registers_mask() & dst.bit()) != kRegListEmpty);
684 ldr(dst, SafepointRegisterSlot(src)); 740 ldr(dst, SafepointRegisterSlot(src));
685 } 741 }
686 742
687 743
688 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) { 744 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) {
745 // This function must be called from LCodeGen::GenerateCode where
746 // registers_mask and double_registers_mask are set.
747 ASSERT((registers_mask() & (1 << reg_code)) != kRegListEmpty);
689 // The registers are pushed starting with the highest encoding, 748 // The registers are pushed starting with the highest encoding,
690 // which means that lowest encodings are closest to the stack pointer. 749 // which means that lowest encodings are closest to the stack pointer.
691 ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters); 750 ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters);
692 return reg_code; 751 ASSERT((registers_mask() & (1 << reg_code)) != 0);
752 // Only count registers below reg_code.
753 return
754 CompilerIntrinsics::CountSetBits(registers_mask() & ((1 << reg_code) - 1));
693 } 755 }
694 756
695 757
696 MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 758 MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
697 return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 759 return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
698 } 760 }
699 761
700 762
701 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { 763 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
702 // Number of d-regs not known at snapshot time.
703 ASSERT(!Serializer::enabled());
704 // General purpose registers are pushed last on the stack. 764 // General purpose registers are pushed last on the stack.
705 int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize; 765 int doubles_size =
766 CompilerIntrinsics::CountSetBits(double_registers_mask()) * kDoubleSize;
706 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; 767 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
707 return MemOperand(sp, doubles_size + register_offset); 768 return MemOperand(sp, doubles_size + register_offset);
708 } 769 }
709 770
710 771
711 void MacroAssembler::Ldrd(Register dst1, Register dst2, 772 void MacroAssembler::Ldrd(Register dst1, Register dst2,
712 const MemOperand& src, Condition cond) { 773 const MemOperand& src, Condition cond) {
713 ASSERT(src.rm().is(no_reg)); 774 ASSERT(src.rm().is(no_reg));
714 ASSERT(!dst1.is(lr)); // r14. 775 ASSERT(!dst1.is(lr)); // r14.
715 776
(...skipping 3331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4047 if (divisor < 0 && ms.multiplier() > 0) { 4108 if (divisor < 0 && ms.multiplier() > 0) {
4048 sub(result, result, Operand(dividend)); 4109 sub(result, result, Operand(dividend));
4049 } 4110 }
4050 if (ms.shift() > 0) mov(result, Operand(result, ASR, ms.shift())); 4111 if (ms.shift() > 0) mov(result, Operand(result, ASR, ms.shift()));
4051 } 4112 }
4052 4113
4053 4114
4054 } } // namespace v8::internal 4115 } } // namespace v8::internal
4055 4116
4056 #endif // V8_TARGET_ARCH_ARM 4117 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« src/arm/assembler-arm.h ('K') | « src/arm/macro-assembler-arm.h ('k') | src/frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698