Index: src/ia32/code-stubs-ia32.h |
diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h |
index cc6bd1675c3ed7d11a01f241c9611d5726d77f49..0358f99a014ab02c052a3ca758fd366daaf9ebbd 100644 |
--- a/src/ia32/code-stubs-ia32.h |
+++ b/src/ia32/code-stubs-ia32.h |
@@ -544,22 +544,56 @@ class RecordWriteStub: public CodeStub { |
value) { // One scratch reg. |
} |
- static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8. |
- static const byte kSkipNonIncrementalPartInstruction = 0xeb; // Jmp #imm8. |
- |
- static byte GetInstruction(bool enable) { |
- // Can't use ternary operator here, because gcc makes an undefined |
- // reference to a static const int. |
- if (enable) { |
- return kSkipNonIncrementalPartInstruction; |
- } else { |
- return kTwoByteNopInstruction; |
+ enum Mode { |
+ STORE_BUFFER_ONLY, |
+ INCREMENTAL, |
+ INCREMENTAL_COMPACTION |
+ }; |
+ |
+ static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8. |
+ static const byte kTwoByteJumpInstruction = 0xeb; // Jmp #imm8. |
+ |
+ static const byte kFiveByteNopInstruction = 0x3d; // Cmpl eax, #imm32. |
+ static const byte kFiveByteJumpInstruction = 0xe9; // Jmp #imm32. |
+ |
+ static Mode GetMode(Code* stub) { |
+ byte first_instruction = stub->instruction_start()[0]; |
+ byte second_instruction = stub->instruction_start()[2]; |
+ |
+ if (first_instruction == kTwoByteJumpInstruction) { |
+ return INCREMENTAL; |
+ } |
+ |
+ ASSERT(first_instruction == kTwoByteNopInstruction); |
+ |
+ if (second_instruction == kFiveByteJumpInstruction) { |
+ return INCREMENTAL_COMPACTION; |
} |
+ |
+ ASSERT(second_instruction == kFiveByteNopInstruction); |
+ |
+ return STORE_BUFFER_ONLY; |
} |
- static void Patch(Code* stub, bool enable) { |
- ASSERT(*stub->instruction_start() == GetInstruction(!enable)); |
- *stub->instruction_start() = GetInstruction(enable); |
+ static void Patch(Code* stub, Mode mode) { |
+ switch (mode) { |
+ case STORE_BUFFER_ONLY: |
+ ASSERT(GetMode(stub) == INCREMENTAL || |
+ GetMode(stub) == INCREMENTAL_COMPACTION); |
+ stub->instruction_start()[0] = kTwoByteNopInstruction; |
+ stub->instruction_start()[2] = kFiveByteNopInstruction; |
+ break; |
+ case INCREMENTAL: |
+ ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); |
+ stub->instruction_start()[0] = kTwoByteJumpInstruction; |
+ break; |
+ case INCREMENTAL_COMPACTION: |
+ ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); |
+ stub->instruction_start()[0] = kTwoByteNopInstruction; |
+ stub->instruction_start()[2] = kFiveByteJumpInstruction; |
+ break; |
+ } |
+ ASSERT(GetMode(stub) == mode); |
} |
private: |
@@ -708,14 +742,15 @@ class RecordWriteStub: public CodeStub { |
enum OnNoNeedToInformIncrementalMarker { |
kReturnOnNoNeedToInformIncrementalMarker, |
kUpdateRememberedSetOnNoNeedToInformIncrementalMarker |
- }; |
- |
+ } |
+; |
void Generate(MacroAssembler* masm); |
- void GenerateIncremental(MacroAssembler* masm); |
+ void GenerateIncremental(MacroAssembler* masm, Mode mode); |
void CheckNeedsToInformIncrementalMarker( |
MacroAssembler* masm, |
- OnNoNeedToInformIncrementalMarker on_no_need); |
- void InformIncrementalMarker(MacroAssembler* masm); |
+ OnNoNeedToInformIncrementalMarker on_no_need, |
+ Mode mode); |
+ void InformIncrementalMarker(MacroAssembler* masm, Mode mode); |
Major MajorKey() { return RecordWrite; } |