Chromium Code Reviews| Index: src/x64/code-stubs-x64.cc |
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
| index 061413c87967defd8d0a2da21c07beb4aaf30e0c..c1c6ff1d9e1d320c7ed42be9388492fbdc35a4a9 100644 |
| --- a/src/x64/code-stubs-x64.cc |
| +++ b/src/x64/code-stubs-x64.cc |
| @@ -5158,18 +5158,15 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { |
| // we keep the GC informed. The word in the object where the value has been |
| // written is in the address register. |
| void RecordWriteStub::Generate(MacroAssembler* masm) { |
| - Label skip_non_incremental_part; |
| + Label skip_to_incremental_noncompacting; |
| + Label skip_to_incremental_compacting; |
| // The first instruction is generated as a label so as to get the offset |
| // fixed up correctly by the bind(Label*) call. We patch it back and forth |
| // between a 2-byte compare instruction (a nop in this position) and the real |
| // branch when we start and stop incremental heap marking. |
|
Erik Corry
2011/07/08 09:06:49
This comment does not mention compaction. I would
|
| - __ jmp(&skip_non_incremental_part, Label::kNear); |
| - if (!masm->isolate()->heap()->incremental_marking()->IsMarking()) { |
| - ASSERT(masm->byte_at(masm->pc_offset() - 2) == |
| - kSkipNonIncrementalPartInstruction); |
| - masm->set_byte_at(masm->pc_offset() - 2, kTwoByteNopInstruction); |
| - } |
| + __ jmp(&skip_to_incremental_noncompacting, Label::kNear); |
| + __ jmp(&skip_to_incremental_compacting, Label::kFar); |
| if (remembered_set_action_ == EMIT_REMEMBERED_SET) { |
| __ RememberedSetHelper( |
| @@ -5178,12 +5175,28 @@ void RecordWriteStub::Generate(MacroAssembler* masm) { |
| __ ret(0); |
| } |
| - __ bind(&skip_non_incremental_part); |
| - GenerateIncremental(masm); |
| + __ bind(&skip_to_incremental_noncompacting); |
| + GenerateIncremental(masm, INCREMENTAL); |
| + |
| + __ bind(&skip_to_incremental_compacting); |
| + GenerateIncremental(masm, INCREMENTAL_COMPACTION); |
| + |
| + // TODO(gc) ensure that GC can't happen after stub was generated by before |
| + // it was added to a stub cache. |
|
Erik Corry
2011/07/08 09:06:49
This looks nasty. Please file a bug and put the b
|
| + IncrementalMarking* marking = masm->isolate()->heap()->incremental_marking(); |
| + if (!marking->IsMarking() || marking->IsCompacting()) { |
| + ASSERT(masm->byte_at(0) == kTwoByteJumpInstruction); |
| + masm->set_byte_at(0, kTwoByteNopInstruction); |
| + } |
| + |
| + if (!marking->IsMarking()) { |
| + ASSERT(masm->byte_at(2) == kFiveByteJumpInstruction); |
| + masm->set_byte_at(2, kFiveByteNopInstruction); |
| + } |
| } |
| -void RecordWriteStub::GenerateIncremental(MacroAssembler* masm) { |
| +void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) { |
| regs_.Save(masm); |
| if (remembered_set_action_ == EMIT_REMEMBERED_SET) { |
| @@ -5203,8 +5216,8 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm) { |
| // First notify the incremental marker if necessary, then update the |
| // remembered set. |
| CheckNeedsToInformIncrementalMarker( |
| - masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker); |
| - InformIncrementalMarker(masm); |
| + masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker, mode); |
| + InformIncrementalMarker(masm, mode); |
| regs_.Restore(masm); |
| __ RememberedSetHelper( |
| address_, value_, save_fp_regs_mode_, MacroAssembler::kReturnAtEnd); |
| @@ -5213,14 +5226,14 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm) { |
| } |
| CheckNeedsToInformIncrementalMarker( |
| - masm, kReturnOnNoNeedToInformIncrementalMarker); |
| - InformIncrementalMarker(masm); |
| + masm, kReturnOnNoNeedToInformIncrementalMarker, mode); |
| + InformIncrementalMarker(masm, mode); |
| regs_.Restore(masm); |
| __ ret(0); |
| } |
| -void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { |
| +void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm, Mode mode) { |
| regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_); |
| #ifdef _WIN64 |
| Register arg3 = r8; |
| @@ -5231,32 +5244,44 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) { |
| Register arg2 = rsi; |
| Register arg1 = rdi; |
| #endif |
| - bool save_address = arg1.is(regs_.address()); |
| - if (save_address) { |
| - __ movq(arg3, regs_.address()); |
| - } |
| + Register address = |
| + arg1.is(regs_.address()) ? kScratchRegister : regs_.address(); |
| + ASSERT(!address.is(regs_.object())); |
| + ASSERT(!address.is(arg1)); |
| + __ Move(address, regs_.address()); |
| __ Move(arg1, regs_.object()); |
| - if (save_address) { |
| - __ movq(arg2, Operand(arg3, 0)); |
| + if (mode == INCREMENTAL_COMPACTION) { |
| + // TODO(gc) Can we just set address arg2 in the beginning? |
| + __ Move(arg2, address); |
| } else { |
| - __ movq(arg2, Operand(regs_.address(), 0)); |
| + ASSERT(mode == INCREMENTAL); |
| + __ movq(arg2, Operand(address, 0)); |
| } |
| __ LoadAddress(arg3, ExternalReference::isolate_address()); |
| // TODO(gc): Create a fast version of this C function that does not duplicate |
| // the checks done in the stub. |
| int argument_count = 3; |
| __ PrepareCallCFunction(argument_count); |
| - __ CallCFunction( |
| - ExternalReference::incremental_marking_record_write_function( |
| - masm->isolate()), |
| - argument_count); |
| + if (mode == INCREMENTAL_COMPACTION) { |
| + __ CallCFunction( |
| + ExternalReference::incremental_evacuation_record_write_function( |
| + masm->isolate()), |
| + argument_count); |
| + } else { |
| + ASSERT(mode == INCREMENTAL); |
| + __ CallCFunction( |
| + ExternalReference::incremental_marking_record_write_function( |
| + masm->isolate()), |
| + argument_count); |
| + } |
| regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_); |
| } |
| void RecordWriteStub::CheckNeedsToInformIncrementalMarker( |
| MacroAssembler* masm, |
| - RecordWriteStub::OnNoNeedToInformIncrementalMarker on_no_need) { |
| + OnNoNeedToInformIncrementalMarker on_no_need, |
| + Mode mode) { |
| Label on_black; |
| // Let's look at the color of the object: If it is not black we don't have |