Index: src/ia32/codegen-ia32.cc |
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc |
index eb6868729ba320f9ac8424c8ae51be4813163318..f07f7b129aa0d98154d4cf107a54e738fe511121 100644 |
--- a/src/ia32/codegen-ia32.cc |
+++ b/src/ia32/codegen-ia32.cc |
@@ -757,6 +757,73 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm, |
#undef __ |
+ |
+static byte* GetNoCodeAgeSequence(uint32_t* length) { |
+ // 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: |
+ // |
+ // __ push(ebp); |
+ // __ mov(ebp, esp); |
+ // __ push(esi); |
+ // __ push(edi); |
+ static byte sequence[] = { 0x55, 0x89, 0xe5, 0x56, 0x57 }; |
+ *length = sizeof(sequence); |
+ return sequence; |
+} |
+ |
+ |
+byte* Code::FindPlatformCodeAgeSequence() { |
+ byte* start = instruction_start(); |
+ uint32_t young_length; |
+ byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
+ if (!memcmp(start, young_sequence, young_length) || |
+ *start == kCallOpcode) { |
+ return start; |
+ } else { |
+ byte* start_after_strict = start + kSizeOfStrictModePrologue; |
+ ASSERT(!memcmp(start_after_strict, young_sequence, young_length) || |
+ start[kSizeOfStrictModePrologue] == kCallOpcode); |
+ return start_after_strict; |
+ } |
+} |
+ |
+ |
+void Code::GetCodeAgeAndParity(byte* sequence, Age* age, |
+ MarkingParity* parity) { |
+ uint32_t young_length; |
+ byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
+ if (!memcmp(sequence, young_sequence, young_length)) { |
+ *age = kNoAge; |
+ *parity = NO_MARKING_PARITY; |
+ } else { |
+ Address target_address = |
+ sequence + *reinterpret_cast<int*>(sequence + 1) + young_length; |
+ Code* stub = GetCodeFromTargetAddress(target_address); |
+ GetCodeAgeAndParity(stub, age, parity); |
+ } |
+} |
+ |
+ |
+void Code::PatchPlatformCodeAge(byte* sequence, |
+ Code::Age age, |
+ MarkingParity parity) { |
+ uint32_t young_length; |
+ byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
+ if (age == kNoAge) { |
+ memcpy(sequence, young_sequence, young_length); |
+ } else { |
+ Code* stub = GetCodeAgeStub(age, parity); |
+ Address instruction_start = stub->instruction_start(); |
+ int32_t stub_offset = |
+ instruction_start - sequence - young_length; |
+ *sequence = kCallOpcode; |
+ *reinterpret_cast<int32_t*>(sequence + 1) = stub_offset; |
+ } |
+ CPU::FlushICache(sequence, young_length); |
+} |
+ |
+ |
} } // namespace v8::internal |
#endif // V8_TARGET_ARCH_IA32 |