| Index: src/x64/codegen-x64.cc
|
| diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
|
| index ce69d15814139045e9f42e84f7259c48f347f843..a6f1659cd9e2c041dc3dbd34200ae1b46d27a334 100644
|
| --- a/src/x64/codegen-x64.cc
|
| +++ b/src/x64/codegen-x64.cc
|
| @@ -686,19 +686,20 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
|
| #undef __
|
|
|
|
|
| -static const int kNoCodeAgeSequenceLength = 6;
|
| +static const int kCodeAgeSequenceLength = 7;
|
|
|
| static byte* GetNoCodeAgeSequence(uint32_t* length) {
|
| static bool initialized = false;
|
| - static byte sequence[kNoCodeAgeSequenceLength];
|
| - *length = kNoCodeAgeSequenceLength;
|
| + static byte sequence[kCodeAgeSequenceLength];
|
| + *length = kCodeAgeSequenceLength;
|
| if (!initialized) {
|
| // The sequence of instructions that is patched out for aging code is the
|
| // following boilerplate stack-building prologue that is found both in
|
| // FUNCTION and OPTIMIZED_FUNCTION code:
|
| - CodePatcher patcher(sequence, kNoCodeAgeSequenceLength);
|
| + CodePatcher patcher(sequence, kCodeAgeSequenceLength);
|
| patcher.masm()->push(rbp);
|
| patcher.masm()->movq(rbp, rsp);
|
| + patcher.masm()->nop();
|
| patcher.masm()->push(rsi);
|
| patcher.masm()->push(rdi);
|
| initialized = true;
|
| @@ -707,11 +708,40 @@ static byte* GetNoCodeAgeSequence(uint32_t* length) {
|
| }
|
|
|
|
|
| +static byte* GetPreAgedCodeAgeSequence(uint32_t* length) {
|
| + static bool initialized = false;
|
| + static byte sequence[kCodeAgeSequenceLength];
|
| + *length = kCodeAgeSequenceLength;
|
| + if (!initialized) {
|
| + // If code is "pre-aged" then this sequence of instructions is found in the
|
| + // boilerplate stack-building prologue that is found in FUNCTIONS and
|
| + // OPTIMIZED_FUNCTION code, and is patched out for code aging.
|
| + CodePatcher patcher(sequence, kCodeAgeSequenceLength);
|
| + patcher.masm()->push(rbp);
|
| + patcher.masm()->movq(rbp, rsp);
|
| + patcher.masm()->push(rsi);
|
| + patcher.masm()->nop();
|
| + patcher.masm()->push(rdi);
|
| + initialized = true;
|
| + }
|
| + return sequence;
|
| +}
|
| +
|
| +
|
| bool Code::IsYoungSequence(byte* sequence) {
|
| uint32_t young_length;
|
| byte* young_sequence = GetNoCodeAgeSequence(&young_length);
|
| bool result = (!memcmp(sequence, young_sequence, young_length));
|
| - ASSERT(result || *sequence == kCallOpcode);
|
| + ASSERT(result || *sequence == kCallOpcode || IsPreAgedSequence(sequence));
|
| + return result;
|
| +}
|
| +
|
| +
|
| +bool Code::IsPreAgedSequence(byte* sequence) {
|
| + uint32_t pre_aged_length;
|
| + byte* pre_aged_sequence = GetPreAgedCodeAgeSequence(&pre_aged_length);
|
| + bool result = (!memcmp(sequence, pre_aged_sequence, pre_aged_length));
|
| + ASSERT(result || *sequence == kCallOpcode || IsYoungSequence(sequence));
|
| return result;
|
| }
|
|
|
| @@ -721,6 +751,9 @@ void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
|
| if (IsYoungSequence(sequence)) {
|
| *age = kNoAge;
|
| *parity = NO_MARKING_PARITY;
|
| + } else if (IsPreAgedSequence(sequence)) {
|
| + *age = kPreAgedCodeAge;
|
| + *parity = NO_MARKING_PARITY;
|
| } else {
|
| sequence++; // Skip the kCallOpcode byte
|
| Address target_address = sequence + *reinterpret_cast<int*>(sequence) +
|
| @@ -744,7 +777,7 @@ void Code::PatchPlatformCodeAge(byte* sequence,
|
| CodePatcher patcher(sequence, young_length);
|
| patcher.masm()->call(stub->instruction_start());
|
| for (int i = 0;
|
| - i < kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength;
|
| + i < kCodeAgeSequenceLength - Assembler::kShortCallInstructionLength;
|
| i++) {
|
| patcher.masm()->nop();
|
| }
|
|
|