Commit ac2801f1 authored by jing.bao's avatar jing.bao Committed by Commit Bot

[x64] Eliminate redundant code in RecordWriteStub

Do conditional jump based on the second instruction rather than
generate similar assembly code twice.

Bug: 
Change-Id: I8c10f3415f213f88d8222a92671e7104c65befdc
Reviewed-on: https://chromium-review.googlesource.com/634631
Commit-Queue: Jing Bao <jing.bao@intel.com>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47844}
parent 9865b356
...@@ -975,16 +975,17 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( ...@@ -975,16 +975,17 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
// we keep the GC informed. The word in the object where the value has been // we keep the GC informed. The word in the object where the value has been
// written is in the address register. // written is in the address register.
void RecordWriteStub::Generate(MacroAssembler* masm) { void RecordWriteStub::Generate(MacroAssembler* masm) {
Label skip_to_incremental_noncompacting; Label skip_to_incremental;
Label skip_to_incremental_compacting; Label second_instr;
// The first two instructions are generated with labels so as to get the // The first two instructions are generated with labels so as to get the
// offset fixed up correctly by the bind(Label*) call. We patch it back and // offset fixed up correctly by the bind(Label*) call. We patch it back and
// forth between a compare instructions (a nop in this position) and the // forth between a compare instructions (a nop in this position) and the
// real branch when we start and stop incremental heap marking. // real branch when we start and stop incremental heap marking.
// See RecordWriteStub::Patch for details. // See RecordWriteStub::Patch for details.
__ jmp(&skip_to_incremental_noncompacting, Label::kNear); __ jmp(&skip_to_incremental, Label::kNear);
__ jmp(&skip_to_incremental_compacting, Label::kFar); __ bind(&second_instr);
__ jmp(&skip_to_incremental, Label::kNear);
if (remembered_set_action() == EMIT_REMEMBERED_SET) { if (remembered_set_action() == EMIT_REMEMBERED_SET) {
__ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(), __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(),
...@@ -993,20 +994,18 @@ void RecordWriteStub::Generate(MacroAssembler* masm) { ...@@ -993,20 +994,18 @@ void RecordWriteStub::Generate(MacroAssembler* masm) {
__ ret(0); __ ret(0);
} }
__ bind(&skip_to_incremental_noncompacting); __ bind(&skip_to_incremental);
GenerateIncremental(masm, INCREMENTAL);
__ bind(&skip_to_incremental_compacting); GenerateIncremental(masm, &second_instr);
GenerateIncremental(masm, INCREMENTAL_COMPACTION);
// Initial mode of the stub is expected to be STORE_BUFFER_ONLY. // Initial mode of the stub is expected to be STORE_BUFFER_ONLY.
// Will be checked in IncrementalMarking::ActivateGeneratedStub. // Will be checked in IncrementalMarking::ActivateGeneratedStub.
masm->set_byte_at(0, kTwoByteNopInstruction); masm->set_byte_at(0, kTwoByteNopInstruction);
masm->set_byte_at(2, kFiveByteNopInstruction); masm->set_byte_at(2, kTwoByteNopInstruction);
} }
void RecordWriteStub::GenerateIncremental(MacroAssembler* masm,
void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) { Label* second_instr) {
regs_.Save(masm); regs_.Save(masm);
if (remembered_set_action() == EMIT_REMEMBERED_SET) { if (remembered_set_action() == EMIT_REMEMBERED_SET) {
...@@ -1023,7 +1022,8 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) { ...@@ -1023,7 +1022,8 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) {
// First notify the incremental marker if necessary, then update the // First notify the incremental marker if necessary, then update the
// remembered set. // remembered set.
CheckNeedsToInformIncrementalMarker( CheckNeedsToInformIncrementalMarker(
masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker, mode); masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker,
second_instr);
InformIncrementalMarker(masm); InformIncrementalMarker(masm);
regs_.Restore(masm); regs_.Restore(masm);
__ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(), __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(),
...@@ -1033,7 +1033,7 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) { ...@@ -1033,7 +1033,7 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) {
} }
CheckNeedsToInformIncrementalMarker( CheckNeedsToInformIncrementalMarker(
masm, kReturnOnNoNeedToInformIncrementalMarker, mode); masm, kReturnOnNoNeedToInformIncrementalMarker, second_instr);
InformIncrementalMarker(masm); InformIncrementalMarker(masm);
regs_.Restore(masm); regs_.Restore(masm);
__ ret(0); __ ret(0);
...@@ -1067,9 +1067,8 @@ void RecordWriteStub::Activate(Code* code) { ...@@ -1067,9 +1067,8 @@ void RecordWriteStub::Activate(Code* code) {
} }
void RecordWriteStub::CheckNeedsToInformIncrementalMarker( void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
MacroAssembler* masm, MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
OnNoNeedToInformIncrementalMarker on_no_need, Label* second_instr) {
Mode mode) {
Label need_incremental; Label need_incremental;
Label need_incremental_pop_object; Label need_incremental_pop_object;
...@@ -1097,24 +1096,22 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( ...@@ -1097,24 +1096,22 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
// Get the value from the slot. // Get the value from the slot.
__ movp(regs_.scratch0(), Operand(regs_.address(), 0)); __ movp(regs_.scratch0(), Operand(regs_.address(), 0));
if (mode == INCREMENTAL_COMPACTION) {
Label ensure_not_white; Label ensure_not_white;
// If second instruction is TwoByteNopInstruction, we're in noncompacting
// mode.
__ cmpb(Operand(second_instr), Immediate(kTwoByteNopInstruction));
__ j(equal, &ensure_not_white, Label::kNear);
__ CheckPageFlag(regs_.scratch0(), // Contains value. __ CheckPageFlag(regs_.scratch0(), // Contains value.
regs_.scratch1(), // Scratch. regs_.scratch1(), // Scratch.
MemoryChunk::kEvacuationCandidateMask, MemoryChunk::kEvacuationCandidateMask, zero,
zero, &ensure_not_white, Label::kNear);
&ensure_not_white,
Label::kNear);
__ CheckPageFlag(regs_.object(), __ CheckPageFlag(regs_.object(),
regs_.scratch1(), // Scratch. regs_.scratch1(), // Scratch.
MemoryChunk::kSkipEvacuationSlotsRecordingMask, MemoryChunk::kSkipEvacuationSlotsRecordingMask, zero,
zero,
&need_incremental); &need_incremental);
__ bind(&ensure_not_white); __ bind(&ensure_not_white);
}
// We need an extra register for this, so we push the object register // We need an extra register for this, so we push the object register
// temporarily. // temporarily.
......
...@@ -119,9 +119,6 @@ class RecordWriteStub: public PlatformCodeStub { ...@@ -119,9 +119,6 @@ class RecordWriteStub: public PlatformCodeStub {
static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8. static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8.
static const byte kTwoByteJumpInstruction = 0xeb; // Jmp #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) { static Mode GetMode(Code* stub) {
byte first_instruction = stub->instruction_start()[0]; byte first_instruction = stub->instruction_start()[0];
byte second_instruction = stub->instruction_start()[2]; byte second_instruction = stub->instruction_start()[2];
...@@ -132,11 +129,11 @@ class RecordWriteStub: public PlatformCodeStub { ...@@ -132,11 +129,11 @@ class RecordWriteStub: public PlatformCodeStub {
DCHECK(first_instruction == kTwoByteNopInstruction); DCHECK(first_instruction == kTwoByteNopInstruction);
if (second_instruction == kFiveByteJumpInstruction) { if (second_instruction == kTwoByteJumpInstruction) {
return INCREMENTAL_COMPACTION; return INCREMENTAL_COMPACTION;
} }
DCHECK(second_instruction == kFiveByteNopInstruction); DCHECK(second_instruction == kTwoByteNopInstruction);
return STORE_BUFFER_ONLY; return STORE_BUFFER_ONLY;
} }
...@@ -147,7 +144,7 @@ class RecordWriteStub: public PlatformCodeStub { ...@@ -147,7 +144,7 @@ class RecordWriteStub: public PlatformCodeStub {
DCHECK(GetMode(stub) == INCREMENTAL || DCHECK(GetMode(stub) == INCREMENTAL ||
GetMode(stub) == INCREMENTAL_COMPACTION); GetMode(stub) == INCREMENTAL_COMPACTION);
stub->instruction_start()[0] = kTwoByteNopInstruction; stub->instruction_start()[0] = kTwoByteNopInstruction;
stub->instruction_start()[2] = kFiveByteNopInstruction; stub->instruction_start()[2] = kTwoByteNopInstruction;
break; break;
case INCREMENTAL: case INCREMENTAL:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
...@@ -156,7 +153,7 @@ class RecordWriteStub: public PlatformCodeStub { ...@@ -156,7 +153,7 @@ class RecordWriteStub: public PlatformCodeStub {
case INCREMENTAL_COMPACTION: case INCREMENTAL_COMPACTION:
DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
stub->instruction_start()[0] = kTwoByteNopInstruction; stub->instruction_start()[0] = kTwoByteNopInstruction;
stub->instruction_start()[2] = kFiveByteJumpInstruction; stub->instruction_start()[2] = kTwoByteJumpInstruction;
break; break;
} }
DCHECK(GetMode(stub) == mode); DCHECK(GetMode(stub) == mode);
...@@ -297,11 +294,10 @@ class RecordWriteStub: public PlatformCodeStub { ...@@ -297,11 +294,10 @@ class RecordWriteStub: public PlatformCodeStub {
Major MajorKey() const final { return RecordWrite; } Major MajorKey() const final { return RecordWrite; }
void Generate(MacroAssembler* masm) override; void Generate(MacroAssembler* masm) override;
void GenerateIncremental(MacroAssembler* masm, Mode mode); void GenerateIncremental(MacroAssembler* masm, Label* second_instr);
void CheckNeedsToInformIncrementalMarker( void CheckNeedsToInformIncrementalMarker(
MacroAssembler* masm, MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
OnNoNeedToInformIncrementalMarker on_no_need, Label* second_instr);
Mode mode);
void InformIncrementalMarker(MacroAssembler* masm); void InformIncrementalMarker(MacroAssembler* masm);
void Activate(Code* code) override; void Activate(Code* code) override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment