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 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 } | 593 } |
594 | 594 |
595 | 595 |
596 // nop(CODE_AGE_MARKER_NOP) | 596 // nop(CODE_AGE_MARKER_NOP) |
597 static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180; | 597 static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180; |
598 | 598 |
599 static byte* GetNoCodeAgeSequence(uint32_t* length) { | 599 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
600 // The sequence of instructions that is patched out for aging code is the | 600 // The sequence of instructions that is patched out for aging code is the |
601 // following boilerplate stack-building prologue that is found in FUNCTIONS | 601 // following boilerplate stack-building prologue that is found in FUNCTIONS |
602 static bool initialized = false; | 602 static bool initialized = false; |
603 static uint32_t sequence[kNoCodeAgeSequenceLength]; | 603 static uint32_t sequence[kCodeAgeSequenceLength]; |
604 byte* byte_sequence = reinterpret_cast<byte*>(sequence); | 604 byte* byte_sequence = reinterpret_cast<byte*>(sequence); |
605 *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize; | 605 *length = kCodeAgeSequenceLength * Assembler::kInstrSize; |
606 if (!initialized) { | 606 if (!initialized) { |
607 CodePatcher patcher(byte_sequence, kNoCodeAgeSequenceLength); | 607 CodePatcher patcher(byte_sequence, kCodeAgeSequenceLength); |
608 patcher.masm()->Push(ra, fp, cp, a1); | 608 patcher.masm()->Push(ra, fp, cp, a1); |
609 patcher.masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP); | 609 patcher.masm()->nop(Assembler::CODE_AGE_YOUNG_SEQUENCE_NOP); |
610 patcher.masm()->Addu(fp, sp, Operand(2 * kPointerSize)); | 610 patcher.masm()->Addu(fp, sp, Operand(2 * kPointerSize)); |
611 initialized = true; | 611 initialized = true; |
612 } | 612 } |
| 613 return byte_sequence; |
| 614 } |
| 615 |
| 616 |
| 617 static byte* GetPreAgedCodeAgeSequence(uint32_t* length) { |
| 618 // If code is "pre-aged" then this sequence of instructions is found in the |
| 619 // boilerplate stack-building prologue that is found in FUNCTIONS, and is |
| 620 // patched out for code aging. |
| 621 static bool initialized = false; |
| 622 static uint32_t sequence[kCodeAgeSequenceLength]; |
| 623 byte* byte_sequence = reinterpret_cast<byte*>(sequence); |
| 624 *length = kCodeAgeSequenceLength * Assembler::kInstrSize; |
| 625 if (!initialized) { |
| 626 CodePatcher patcher(byte_sequence, kCodeAgeSequenceLength); |
| 627 patcher.masm()->Push(ra, fp, cp, a1); |
| 628 patcher.masm()->nop(Assembler::CODE_AGE_PRE_AGED_SEQUENCE_NOP); |
| 629 patcher.masm()->Addu(fp, sp, Operand(2 * kPointerSize)); |
| 630 initialized = true; |
| 631 } |
613 return byte_sequence; | 632 return byte_sequence; |
614 } | 633 } |
615 | 634 |
616 | 635 |
617 bool Code::IsYoungSequence(byte* sequence) { | 636 bool Code::IsYoungSequence(byte* sequence) { |
618 uint32_t young_length; | 637 uint32_t young_length; |
619 byte* young_sequence = GetNoCodeAgeSequence(&young_length); | 638 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
620 bool result = !memcmp(sequence, young_sequence, young_length); | 639 bool result = !memcmp(sequence, young_sequence, young_length); |
621 ASSERT(result || | 640 ASSERT(result || |
622 Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction); | 641 Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction || |
| 642 IsPreAgedSequence(sequence)); |
623 return result; | 643 return result; |
624 } | 644 } |
625 | 645 |
| 646 |
| 647 bool Code::IsPreAgedSequence(byte* sequence) { |
| 648 uint32_t pre_aged_length; |
| 649 byte* pre_aged_sequence = GetPreAgedCodeAgeSequence(&pre_aged_length); |
| 650 bool result = !memcmp(sequence, pre_aged_sequence, pre_aged_length); |
| 651 ASSERT(result || |
| 652 Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction || |
| 653 IsYoungSequence(sequence)); |
| 654 return result; |
| 655 } |
| 656 |
626 | 657 |
627 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, | 658 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, |
628 MarkingParity* parity) { | 659 MarkingParity* parity) { |
629 if (IsYoungSequence(sequence)) { | 660 if (IsYoungSequence(sequence)) { |
630 *age = kNoAge; | 661 *age = kNoAge; |
631 *parity = NO_MARKING_PARITY; | 662 *parity = NO_MARKING_PARITY; |
| 663 } else if (IsPreAgedSequence(sequence)) { |
| 664 *age = kPreAgedCodeAge; |
| 665 *parity = NO_MARKING_PARITY; |
632 } else { | 666 } else { |
633 Address target_address = Memory::Address_at( | 667 Address target_address = Memory::Address_at( |
634 sequence + Assembler::kInstrSize * (kNoCodeAgeSequenceLength - 1)); | 668 sequence + Assembler::kInstrSize * (kCodeAgeSequenceLength - 1)); |
635 Code* stub = GetCodeFromTargetAddress(target_address); | 669 Code* stub = GetCodeFromTargetAddress(target_address); |
636 GetCodeAgeAndParity(stub, age, parity); | 670 GetCodeAgeAndParity(stub, age, parity); |
637 } | 671 } |
638 } | 672 } |
639 | 673 |
640 | 674 |
641 void Code::PatchPlatformCodeAge(byte* sequence, | 675 void Code::PatchPlatformCodeAge(byte* sequence, |
642 Code::Age age, | 676 Code::Age age, |
643 MarkingParity parity) { | 677 MarkingParity parity) { |
644 uint32_t young_length; | 678 uint32_t young_length; |
(...skipping 17 matching lines...) Expand all Loading... |
662 patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start())); | 696 patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start())); |
663 } | 697 } |
664 } | 698 } |
665 | 699 |
666 | 700 |
667 #undef __ | 701 #undef __ |
668 | 702 |
669 } } // namespace v8::internal | 703 } } // namespace v8::internal |
670 | 704 |
671 #endif // V8_TARGET_ARCH_MIPS | 705 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |