| OLD | NEW |
| 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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 __ subsd(result, double_scratch); | 679 __ subsd(result, double_scratch); |
| 680 __ addsd(result, Operand(kScratchRegister, 8 * kDoubleSize)); | 680 __ addsd(result, Operand(kScratchRegister, 8 * kDoubleSize)); |
| 681 __ mulsd(result, input); | 681 __ mulsd(result, input); |
| 682 | 682 |
| 683 __ bind(&done); | 683 __ bind(&done); |
| 684 } | 684 } |
| 685 | 685 |
| 686 #undef __ | 686 #undef __ |
| 687 | 687 |
| 688 | 688 |
| 689 static const int kNoCodeAgeSequenceLength = 6; | 689 static const int kCodeAgeSequenceLength = 7; |
| 690 | 690 |
| 691 static byte* GetNoCodeAgeSequence(uint32_t* length) { | 691 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
| 692 static bool initialized = false; | 692 static bool initialized = false; |
| 693 static byte sequence[kNoCodeAgeSequenceLength]; | 693 static byte sequence[kCodeAgeSequenceLength]; |
| 694 *length = kNoCodeAgeSequenceLength; | 694 *length = kCodeAgeSequenceLength; |
| 695 if (!initialized) { | 695 if (!initialized) { |
| 696 // The sequence of instructions that is patched out for aging code is the | 696 // The sequence of instructions that is patched out for aging code is the |
| 697 // following boilerplate stack-building prologue that is found both in | 697 // following boilerplate stack-building prologue that is found both in |
| 698 // FUNCTION and OPTIMIZED_FUNCTION code: | 698 // FUNCTION and OPTIMIZED_FUNCTION code: |
| 699 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength); | 699 CodePatcher patcher(sequence, kCodeAgeSequenceLength); |
| 700 patcher.masm()->push(rbp); | 700 patcher.masm()->push(rbp); |
| 701 patcher.masm()->movq(rbp, rsp); | 701 patcher.masm()->movq(rbp, rsp); |
| 702 patcher.masm()->nop(); |
| 702 patcher.masm()->push(rsi); | 703 patcher.masm()->push(rsi); |
| 703 patcher.masm()->push(rdi); | 704 patcher.masm()->push(rdi); |
| 704 initialized = true; | 705 initialized = true; |
| 705 } | 706 } |
| 706 return sequence; | 707 return sequence; |
| 707 } | 708 } |
| 708 | 709 |
| 709 | 710 |
| 711 static byte* GetPreAgedCodeAgeSequence(uint32_t* length) { |
| 712 static bool initialized = false; |
| 713 static byte sequence[kCodeAgeSequenceLength]; |
| 714 *length = kCodeAgeSequenceLength; |
| 715 if (!initialized) { |
| 716 // If code is "pre-aged" then this sequence of instructions is found in the |
| 717 // boilerplate stack-building prologue that is found in FUNCTIONS and |
| 718 // OPTIMIZED_FUNCTION code, and is patched out for code aging. |
| 719 CodePatcher patcher(sequence, kCodeAgeSequenceLength); |
| 720 patcher.masm()->push(rbp); |
| 721 patcher.masm()->movq(rbp, rsp); |
| 722 patcher.masm()->push(rsi); |
| 723 patcher.masm()->nop(); |
| 724 patcher.masm()->push(rdi); |
| 725 initialized = true; |
| 726 } |
| 727 return sequence; |
| 728 } |
| 729 |
| 730 |
| 710 bool Code::IsYoungSequence(byte* sequence) { | 731 bool Code::IsYoungSequence(byte* sequence) { |
| 711 uint32_t young_length; | 732 uint32_t young_length; |
| 712 byte* young_sequence = GetNoCodeAgeSequence(&young_length); | 733 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 713 bool result = (!memcmp(sequence, young_sequence, young_length)); | 734 bool result = (!memcmp(sequence, young_sequence, young_length)); |
| 714 ASSERT(result || *sequence == kCallOpcode); | 735 ASSERT(result || *sequence == kCallOpcode || IsPreAgedSequence(sequence)); |
| 715 return result; | 736 return result; |
| 716 } | 737 } |
| 717 | 738 |
| 739 |
| 740 bool Code::IsPreAgedSequence(byte* sequence) { |
| 741 uint32_t pre_aged_length; |
| 742 byte* pre_aged_sequence = GetPreAgedCodeAgeSequence(&pre_aged_length); |
| 743 bool result = (!memcmp(sequence, pre_aged_sequence, pre_aged_length)); |
| 744 ASSERT(result || *sequence == kCallOpcode || IsYoungSequence(sequence)); |
| 745 return result; |
| 746 } |
| 747 |
| 718 | 748 |
| 719 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, | 749 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, |
| 720 MarkingParity* parity) { | 750 MarkingParity* parity) { |
| 721 if (IsYoungSequence(sequence)) { | 751 if (IsYoungSequence(sequence)) { |
| 722 *age = kNoAge; | 752 *age = kNoAge; |
| 723 *parity = NO_MARKING_PARITY; | 753 *parity = NO_MARKING_PARITY; |
| 754 } else if (IsPreAgedSequence(sequence)) { |
| 755 *age = kPreAgedCodeAge; |
| 756 *parity = NO_MARKING_PARITY; |
| 724 } else { | 757 } else { |
| 725 sequence++; // Skip the kCallOpcode byte | 758 sequence++; // Skip the kCallOpcode byte |
| 726 Address target_address = sequence + *reinterpret_cast<int*>(sequence) + | 759 Address target_address = sequence + *reinterpret_cast<int*>(sequence) + |
| 727 Assembler::kCallTargetAddressOffset; | 760 Assembler::kCallTargetAddressOffset; |
| 728 Code* stub = GetCodeFromTargetAddress(target_address); | 761 Code* stub = GetCodeFromTargetAddress(target_address); |
| 729 GetCodeAgeAndParity(stub, age, parity); | 762 GetCodeAgeAndParity(stub, age, parity); |
| 730 } | 763 } |
| 731 } | 764 } |
| 732 | 765 |
| 733 | 766 |
| 734 void Code::PatchPlatformCodeAge(byte* sequence, | 767 void Code::PatchPlatformCodeAge(byte* sequence, |
| 735 Code::Age age, | 768 Code::Age age, |
| 736 MarkingParity parity) { | 769 MarkingParity parity) { |
| 737 uint32_t young_length; | 770 uint32_t young_length; |
| 738 byte* young_sequence = GetNoCodeAgeSequence(&young_length); | 771 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 739 if (age == kNoAge) { | 772 if (age == kNoAge) { |
| 740 CopyBytes(sequence, young_sequence, young_length); | 773 CopyBytes(sequence, young_sequence, young_length); |
| 741 CPU::FlushICache(sequence, young_length); | 774 CPU::FlushICache(sequence, young_length); |
| 742 } else { | 775 } else { |
| 743 Code* stub = GetCodeAgeStub(age, parity); | 776 Code* stub = GetCodeAgeStub(age, parity); |
| 744 CodePatcher patcher(sequence, young_length); | 777 CodePatcher patcher(sequence, young_length); |
| 745 patcher.masm()->call(stub->instruction_start()); | 778 patcher.masm()->call(stub->instruction_start()); |
| 746 for (int i = 0; | 779 for (int i = 0; |
| 747 i < kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength; | 780 i < kCodeAgeSequenceLength - Assembler::kShortCallInstructionLength; |
| 748 i++) { | 781 i++) { |
| 749 patcher.masm()->nop(); | 782 patcher.masm()->nop(); |
| 750 } | 783 } |
| 751 } | 784 } |
| 752 } | 785 } |
| 753 | 786 |
| 754 | 787 |
| 755 Operand StackArgumentsAccessor::GetArgumentOperand(int index) { | 788 Operand StackArgumentsAccessor::GetArgumentOperand(int index) { |
| 756 ASSERT(index >= 0); | 789 ASSERT(index >= 0); |
| 757 ASSERT(base_reg_.is(rsp) || base_reg_.is(rbp)); | 790 ASSERT(base_reg_.is(rsp) || base_reg_.is(rbp)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 770 // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize. | 803 // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize. |
| 771 return Operand(base_reg_, argument_count_reg_, times_pointer_size, | 804 return Operand(base_reg_, argument_count_reg_, times_pointer_size, |
| 772 displacement_to_last_argument + (receiver - 1 - index) * kPointerSize); | 805 displacement_to_last_argument + (receiver - 1 - index) * kPointerSize); |
| 773 } | 806 } |
| 774 } | 807 } |
| 775 | 808 |
| 776 | 809 |
| 777 } } // namespace v8::internal | 810 } } // namespace v8::internal |
| 778 | 811 |
| 779 #endif // V8_TARGET_ARCH_X64 | 812 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |