Commit a8bd2260 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Rescan cells at the end of mark-sweep. This means they don't need a

write barrier.
Review URL: http://codereview.chromium.org/8816021

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10187 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c5c32e18
...@@ -4657,7 +4657,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4657,7 +4657,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// megamorphic. // megamorphic.
__ cmp(ecx, Immediate(UninitializedSentinel(isolate))); __ cmp(ecx, Immediate(UninitializedSentinel(isolate)));
__ j(equal, &initialize, Label::kNear); __ j(equal, &initialize, Label::kNear);
// MegamorphicSentinel is a root so no write-barrier is needed. // MegamorphicSentinel is an immortal immovable object (undefined) so no
// write-barrier is needed.
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
Immediate(MegamorphicSentinel(isolate))); Immediate(MegamorphicSentinel(isolate)));
__ jmp(&call, Label::kNear); __ jmp(&call, Label::kNear);
...@@ -4665,14 +4666,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4665,14 +4666,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// An uninitialized cache is patched with the function. // An uninitialized cache is patched with the function.
__ bind(&initialize); __ bind(&initialize);
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi); __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi);
__ mov(ecx, edi); // No need for a write barrier here - cells are rescanned.
__ RecordWriteField(ebx,
JSGlobalPropertyCell::kValueOffset,
ecx,
edx,
kDontSaveFPRegs,
OMIT_REMEMBERED_SET, // Cells are rescanned.
OMIT_SMI_CHECK);
__ bind(&call); __ bind(&call);
} }
...@@ -4704,6 +4698,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4704,6 +4698,8 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// non-function case. // non-function case.
__ mov(ebx, Operand(esp, 0)); __ mov(ebx, Operand(esp, 0));
__ mov(ebx, Operand(ebx, 1)); __ mov(ebx, Operand(ebx, 1));
// MegamorphicSentinel is an immortal immovable object (undefined) so no
// write barrier is needed.
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
Immediate(MegamorphicSentinel(isolate))); Immediate(MegamorphicSentinel(isolate)));
} }
......
...@@ -2144,20 +2144,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { ...@@ -2144,20 +2144,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
// Store the value. // Store the value.
__ mov(FieldOperand(object, offset), value); __ mov(FieldOperand(object, offset), value);
// Cells are always rescanned, so no write barrier here.
// Cells are always in the remembered set.
if (instr->hydrogen()->NeedsWriteBarrier()) {
HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
__ RecordWriteField(object,
offset,
value,
address,
kSaveFPRegs,
OMIT_REMEMBERED_SET,
check_needed);
}
} }
......
...@@ -2522,23 +2522,9 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal( ...@@ -2522,23 +2522,9 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal(
// Store the value in the cell. // Store the value in the cell.
__ mov(cell_operand, eax); __ mov(cell_operand, eax);
Label done; // No write barrier here, because cells are always rescanned.
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &done);
__ mov(ecx, eax);
__ lea(edx, cell_operand);
// Cells are always in the remembered set.
__ RecordWrite(ebx, // Object.
edx, // Address.
ecx, // Value.
kDontSaveFPRegs,
OMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
// Return the value (register eax). // Return the value (register eax).
__ bind(&done);
Counters* counters = isolate()->counters(); Counters* counters = isolate()->counters();
__ IncrementCounter(counters->named_store_global_inline(), 1); __ IncrementCounter(counters->named_store_global_inline(), 1);
__ ret(0); __ ret(0);
......
...@@ -2081,6 +2081,24 @@ void MarkCompactCollector::MarkLiveObjects() { ...@@ -2081,6 +2081,24 @@ void MarkCompactCollector::MarkLiveObjects() {
PrepareForCodeFlushing(); PrepareForCodeFlushing();
if (was_marked_incrementally_) {
// There is no write barrier on cells so we have to scan them now at the end
// of the incremental marking.
{
HeapObjectIterator cell_iterator(heap()->cell_space());
HeapObject* cell;
while ((cell = cell_iterator.Next()) != NULL) {
ASSERT(cell->IsJSGlobalPropertyCell());
if (IsMarked(cell)) {
int offset = JSGlobalPropertyCell::kValueOffset;
StaticMarkingVisitor::VisitPointer(
heap(),
reinterpret_cast<Object**>(cell->address() + offset));
}
}
}
}
RootMarkingVisitor root_visitor(heap()); RootMarkingVisitor root_visitor(heap());
MarkRoots(&root_visitor); MarkRoots(&root_visitor);
......
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