| 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 |