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

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

Issue 7104107: Incremental mode now works for x64. The only difference (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 6 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
Index: src/x64/code-stubs-x64.cc
===================================================================
--- src/x64/code-stubs-x64.cc (revision 8221)
+++ src/x64/code-stubs-x64.cc (working copy)
@@ -298,24 +298,7 @@
void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
- // We don't allow a GC during a store buffer overflow so there is no need to
- // store the registers in any particular way, but we do have to store and
- // restore them.
- Register saved_regs[] =
- { rax, rcx, rdx, rbx, rbp, rsi, rdi, r8, r9, r10, r11 };
- const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register);
- for (int i = 0; i < kNumberOfSavedRegs; i++) {
- __ push(saved_regs[i]);
- }
- // R12 to r15 are callee save on all platforms.
- if (save_doubles_ == kSaveFPRegs) {
- CpuFeatures::Scope scope(SSE2);
- __ subq(rsp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
- for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
- XMMRegister reg = XMMRegister::from_code(i);
- __ movsd(Operand(rsp, i * kDoubleSize), reg);
- }
- }
+ __ PushCallerSaved(save_doubles_);
const int argument_count = 1;
__ PrepareCallCFunction(argument_count);
#ifdef _WIN64
@@ -326,17 +309,7 @@
__ CallCFunction(
ExternalReference::store_buffer_overflow_function(masm->isolate()),
argument_count);
- if (save_doubles_ == kSaveFPRegs) {
- CpuFeatures::Scope scope(SSE2);
- for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
- XMMRegister reg = XMMRegister::from_code(i);
- __ movsd(reg, Operand(rsp, i * kDoubleSize));
- }
- __ addq(rsp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
- }
- for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) {
- __ pop(saved_regs[i]);
- }
+ __ PopCallerSaved(save_doubles_);
__ ret(0);
}
@@ -5206,10 +5179,108 @@
}
__ bind(&skip_non_incremental_part);
- __ int3();
+ GenerateIncremental(masm);
}
+void RecordWriteStub::GenerateIncremental(MacroAssembler* masm) {
+ regs_.Save(masm);
+
+ if (remembered_set_action_ == EMIT_REMEMBERED_SET) {
+ Label dont_need_remembered_set;
+
+ __ movq(regs_.scratch0(), Operand(regs_.address(), 0));
+ __ JumpIfNotInNewSpace(regs_.scratch0(),
+ regs_.scratch0(),
+ &dont_need_remembered_set);
+
+ __ CheckPageFlag(regs_.object(),
+ regs_.scratch0(),
+ MemoryChunk::SCAN_ON_SCAVENGE,
+ not_zero,
+ &dont_need_remembered_set);
+
+ // First notify the incremental marker if necessary, then update the
+ // remembered set.
+ CheckNeedsToInformIncrementalMarker(
+ masm, kRememberedSetOnNoNeedToInformIncrementalMarker);
+ InformIncrementalMarker(masm);
+ regs_.Restore(masm);
+ __ RememberedSetHelper(
+ address_, value_, save_fp_regs_mode_, MacroAssembler::kReturnAtEnd);
+
+ __ bind(&dont_need_remembered_set);
+ }
+
+ CheckNeedsToInformIncrementalMarker(
+ masm, kReturnOnNoNeedToInformIncrementalMarker);
+ InformIncrementalMarker(masm);
+ regs_.Restore(masm);
+ __ ret(0);
+}
+
+
+void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
+ regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
+#ifdef _WIN64
+ Register arg3 = r8;
+ Register arg2 = rdx;
+ Register arg1 = rcx;
+#else
+ Register arg3 = rdx;
+ Register arg2 = rsi;
+ Register arg1 = rdi;
+#endif
+ bool save_address = arg1.is(regs_.address());
+ if (save_address) __ push(regs_.address());
Lasse Reichstein 2011/06/10 13:55:44 Put braces around then-block. Don't trust that __
Erik Corry 2011/06/10 21:57:29 Done.
+ __ Move(arg1, regs_.object());
+ if (save_address) {
+ __ pop(arg2);
+ __ movq(arg2, Operand(arg2, 0));
+ } else {
+ __ movq(arg2, Operand(regs_.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);
+ regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
+}
+
+
+void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
+ MacroAssembler* masm,
+ RecordWriteStub::OnNoNeedToInformIncrementalMarker on_no_need) {
+ Label object_is_black;
+
+ // Let's look at the color of the object: If it is not black we don't have
+ // to inform the incremental marker.
+ __ IsBlack(regs_.object(),
+ regs_.scratch0(),
+ regs_.scratch1(),
+ &object_is_black,
+ Label::kNear);
+
+ regs_.Restore(masm);
+ if (on_no_need == kRememberedSetOnNoNeedToInformIncrementalMarker) {
+ __ RememberedSetHelper(
+ address_, value_, save_fp_regs_mode_, MacroAssembler::kReturnAtEnd);
+ } else {
+ __ ret(0);
+ }
+
+ __ bind(&object_is_black);
+
+ // TODO(gc): Add call to EnsureNotWhite here.
+ // Fall through when we need to inform the incremental marker.
+}
+
+
#undef __
} } // namespace v8::internal

Powered by Google App Engine
This is Rietveld 408576698