Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Unified Diff: src/ia32/code-stubs-ia32.cc

Issue 7302003: Support slots recording for compaction during incremental marking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: fix presubmit, remove last debug check Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 59538db13fa7a1d9c4f092befa768d1d40d1333b..b52a6c0c1154100abe5a5e3918d63ed1d3ab5e0b 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -6235,18 +6235,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.
- __ 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);
- }
+ // 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
+ // forth between a 2-byte compare instruction (a nop in this position) and the
+ // real branch when we start and stop incremental heap marking.
+ __ jmp(&skip_to_incremental_noncompacting, Label::kNear);
+ __ jmp(&skip_to_incremental_compacting, Label::kFar);
if (remembered_set_action_ == EMIT_REMEMBERED_SET) {
__ RememberedSetHelper(
@@ -6255,12 +6252,25 @@ 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);
+
+ if (!masm->isolate()->heap()->incremental_marking()->IsMarking()) {
+ ASSERT(masm->byte_at(0) == kTwoByteJumpInstruction);
+ masm->set_byte_at(0, kTwoByteNopInstruction);
+ }
+
+ if (!masm->isolate()->heap()->incremental_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) {
@@ -6273,15 +6283,17 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm) {
__ CheckPageFlag(regs_.object(),
regs_.scratch0(),
- MemoryChunk::SCAN_ON_SCAVENGE,
+ 1 << MemoryChunk::SCAN_ON_SCAVENGE,
not_zero,
&dont_need_remembered_set);
// 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);
@@ -6290,36 +6302,55 @@ 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,
+ RecordWriteStub::Mode mode) {
regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
int argument_count = 3;
__ PrepareCallCFunction(argument_count, regs_.scratch0());
__ mov(Operand(esp, 0 * kPointerSize), regs_.object());
- __ mov(regs_.scratch0(), Operand(regs_.address(), 0));
- __ mov(Operand(esp, 1 * kPointerSize), regs_.scratch0()); // Value.
+ if (mode == INCREMENTAL_COMPACTION) {
+ __ mov(Operand(esp, 1 * kPointerSize), regs_.address()); // Slot.
+ } else {
+ ASSERT(mode == INCREMENTAL);
+ __ mov(regs_.scratch0(), Operand(regs_.address(), 0));
+ __ mov(Operand(esp, 1 * kPointerSize), regs_.scratch0()); // Value.
+ }
__ mov(Operand(esp, 2 * kPointerSize),
Immediate(ExternalReference::isolate_address()));
+
// TODO(gc): Create a fast version of this C function that does not duplicate
// the checks done in the stub.
- __ 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) {
- Label object_is_black, need_incremental;
+ RecordWriteStub::OnNoNeedToInformIncrementalMarker on_no_need,
+ RecordWriteStub::Mode mode) {
+ Label object_is_black, need_incremental, need_incremental_pop_object;
// Let's look at the color of the object: If it is not black we don't have
// to inform the incremental marker.
@@ -6342,16 +6373,38 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
// Get the value from the slot.
__ mov(regs_.scratch0(), Operand(regs_.address(), 0));
+ if (mode == INCREMENTAL_COMPACTION) {
+ Label ensure_not_white;
+
+ __ CheckPageFlag(regs_.scratch0(), // Contains value.
+ regs_.scratch1(), // Scratch.
+ MemoryChunk::kEvacuationCandidateMask,
+ zero,
+ &ensure_not_white,
+ Label::kNear);
+
+ __ CheckPageFlag(regs_.object(),
+ regs_.scratch1(), // Scratch.
+ MemoryChunk::kEvacuationCandidateOrNewSpaceMask,
+ not_zero,
+ &ensure_not_white,
+ Label::kNear);
+
+ __ jmp(&need_incremental);
+
+ __ bind(&ensure_not_white);
+ }
+
// We need an extra register for this, so we push the object register
// temporarily.
__ push(regs_.object());
__ EnsureNotWhite(regs_.scratch0(), // The value.
regs_.scratch1(), // Scratch.
regs_.object(), // Scratch.
- &need_incremental,
+ &need_incremental_pop_object,
Label::kNear);
-
__ pop(regs_.object());
+
regs_.Restore(masm);
if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) {
__ RememberedSetHelper(
@@ -6360,9 +6413,11 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
__ ret(0);
}
- __ bind(&need_incremental);
+ __ bind(&need_incremental_pop_object);
__ pop(regs_.object());
+ __ bind(&need_incremental);
+
// Fall through when we need to inform the incremental marker.
}
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698