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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 __ bind(&ascii); | 750 __ bind(&ascii); |
751 __ movzx_b(result, FieldOperand(string, | 751 __ movzx_b(result, FieldOperand(string, |
752 index, | 752 index, |
753 times_1, | 753 times_1, |
754 SeqAsciiString::kHeaderSize)); | 754 SeqAsciiString::kHeaderSize)); |
755 __ bind(&done); | 755 __ bind(&done); |
756 } | 756 } |
757 | 757 |
758 #undef __ | 758 #undef __ |
759 | 759 |
| 760 static const int kNoCodeAgeSequenceLength = 5; |
| 761 |
| 762 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
| 763 static bool initialized = false; |
| 764 static byte sequence[kNoCodeAgeSequenceLength]; |
| 765 *length = kNoCodeAgeSequenceLength; |
| 766 if (!initialized) { |
| 767 // The sequence of instructions that is patched out for aging code is the |
| 768 // following boilerplate stack-building prologue that is found both in |
| 769 // FUNCTION and OPTIMIZED_FUNCTION code: |
| 770 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength); |
| 771 patcher.masm()->push(ebp); |
| 772 patcher.masm()->mov(ebp, esp); |
| 773 patcher.masm()->push(esi); |
| 774 patcher.masm()->push(edi); |
| 775 initialized = true; |
| 776 } |
| 777 return sequence; |
| 778 } |
| 779 |
| 780 |
| 781 byte* Code::FindPlatformCodeAgeSequence() { |
| 782 byte* start = instruction_start(); |
| 783 uint32_t young_length; |
| 784 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 785 if (!memcmp(start, young_sequence, young_length) || |
| 786 *start == kCallOpcode) { |
| 787 return start; |
| 788 } else { |
| 789 if (kind() == FUNCTION) { |
| 790 byte* start_after_strict = |
| 791 start + kSizeOfFullCodegenStrictModePrologue; |
| 792 ASSERT(!memcmp(start_after_strict, young_sequence, young_length) || |
| 793 start[kSizeOfFullCodegenStrictModePrologue] == kCallOpcode); |
| 794 return start_after_strict; |
| 795 } else { |
| 796 ASSERT(kind() == OPTIMIZED_FUNCTION); |
| 797 start = instruction_start() + kSizeOfOptimizedStrictModePrologue; |
| 798 if (!memcmp(start, young_sequence, young_length) || |
| 799 *start == kCallOpcode) { |
| 800 return start; |
| 801 } |
| 802 start = instruction_start() + kSizeOfOptimizedAlignStackPrologue; |
| 803 if (!memcmp(start, young_sequence, young_length) || |
| 804 *start == kCallOpcode) { |
| 805 return start; |
| 806 } |
| 807 start = instruction_start() + kSizeOfOptimizedAlignStackPrologue + |
| 808 kSizeOfOptimizedStrictModePrologue; |
| 809 ASSERT(!memcmp(start, young_sequence, young_length) || |
| 810 *start == kCallOpcode); |
| 811 return start; |
| 812 } |
| 813 } |
| 814 } |
| 815 |
| 816 |
| 817 bool Code::IsYoungSequence(byte* sequence) { |
| 818 uint32_t young_length; |
| 819 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 820 bool result = (!memcmp(sequence, young_sequence, young_length)); |
| 821 ASSERT(result || *sequence == kCallOpcode); |
| 822 return result; |
| 823 } |
| 824 |
| 825 |
| 826 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, |
| 827 MarkingParity* parity) { |
| 828 if (IsYoungSequence(sequence)) { |
| 829 *age = kNoAge; |
| 830 *parity = NO_MARKING_PARITY; |
| 831 } else { |
| 832 sequence++; // Skip the kCallOpcode byte |
| 833 Address target_address = sequence + *reinterpret_cast<int*>(sequence) + |
| 834 Assembler::kCallTargetAddressOffset; |
| 835 Code* stub = GetCodeFromTargetAddress(target_address); |
| 836 GetCodeAgeAndParity(stub, age, parity); |
| 837 } |
| 838 } |
| 839 |
| 840 |
| 841 void Code::PatchPlatformCodeAge(byte* sequence, |
| 842 Code::Age age, |
| 843 MarkingParity parity) { |
| 844 uint32_t young_length; |
| 845 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
| 846 if (age == kNoAge) { |
| 847 memcpy(sequence, young_sequence, young_length); |
| 848 CPU::FlushICache(sequence, young_length); |
| 849 } else { |
| 850 Code* stub = GetCodeAgeStub(age, parity); |
| 851 CodePatcher patcher(sequence, young_length); |
| 852 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE); |
| 853 } |
| 854 } |
| 855 |
| 856 |
760 } } // namespace v8::internal | 857 } } // namespace v8::internal |
761 | 858 |
762 #endif // V8_TARGET_ARCH_IA32 | 859 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |