Chromium Code Reviews| Index: src/ia32/codegen-ia32.cc |
| diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc |
| index 0e4fe8c41ba40ba2c06ebee281763cbd12296579..ff304fa5cf6ed4ba8d4d38f7fa21c0000e30b2dd 100644 |
| --- a/src/ia32/codegen-ia32.cc |
| +++ b/src/ia32/codegen-ia32.cc |
| @@ -1128,21 +1128,42 @@ void MathExpGenerator::EmitMathExp(MacroAssembler* masm, |
| #undef __ |
| -static const int kNoCodeAgeSequenceLength = 5; |
| +static const int kCodeAgeSequenceLength = 6; |
| 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(ebp); |
| patcher.masm()->mov(ebp, esp); |
| patcher.masm()->push(esi); |
| patcher.masm()->push(edi); |
| + patcher.masm()->nop(); |
|
rmcilroy
2013/09/11 15:28:28
If you have any ideas for how to distingish betwee
|
| + initialized = true; |
| + } |
| + return sequence; |
| +} |
| + |
| + |
| +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(ebp); |
| + patcher.masm()->mov(ebp, esp); |
| + patcher.masm()->push(esi); |
| + patcher.masm()->nop(); |
| + patcher.masm()->push(edi); |
| initialized = true; |
| } |
| return sequence; |
| @@ -1153,7 +1174,16 @@ 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; |
| } |
| @@ -1163,6 +1193,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) + |
| @@ -1185,6 +1218,7 @@ void Code::PatchPlatformCodeAge(byte* sequence, |
| Code* stub = GetCodeAgeStub(age, parity); |
| CodePatcher patcher(sequence, young_length); |
| patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); |
| + patcher.masm()->nop(); |
| } |
| } |