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(); |
} |