Remember to update the write barrier when storing into
the context in the full compiler. Clobber all input registers in the RecordWrite code when the debug-code flag is set. Review URL: http://codereview.chromium.org/569008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3761 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
41865cd677
commit
325d3ef224
@ -95,8 +95,14 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
|
||||
(num_parameters - 1 - i) * kPointerSize;
|
||||
// Load parameter from stack.
|
||||
__ ldr(r0, MemOperand(fp, parameter_offset));
|
||||
// Store it in the context
|
||||
__ str(r0, MemOperand(cp, Context::SlotOffset(slot->index())));
|
||||
// Store it in the context.
|
||||
__ mov(r1, Operand(Context::SlotOffset(slot->index())));
|
||||
__ str(r0, MemOperand(cp, r1));
|
||||
// Update the write barrier. This clobbers all involved
|
||||
// registers, so we have use a third register to avoid
|
||||
// clobbering cp.
|
||||
__ mov(r2, Operand(cp));
|
||||
__ RecordWrite(r2, r1, r0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -113,7 +119,7 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
|
||||
}
|
||||
// Receiver is just before the parameters on the caller's stack.
|
||||
__ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset +
|
||||
fun->num_parameters() * kPointerSize));
|
||||
fun->num_parameters() * kPointerSize));
|
||||
__ mov(r1, Operand(Smi::FromInt(fun->num_parameters())));
|
||||
__ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit());
|
||||
|
||||
|
@ -277,6 +277,14 @@ void MacroAssembler::RecordWrite(Register object, Register offset,
|
||||
str(scratch, MemOperand(object));
|
||||
|
||||
bind(&done);
|
||||
|
||||
// Clobber all input registers when running with the debug-code flag
|
||||
// turned on to provoke errors.
|
||||
if (FLAG_debug_code) {
|
||||
mov(object, Operand(bit_cast<int32_t>(kZapValue)));
|
||||
mov(offset, Operand(bit_cast<int32_t>(kZapValue)));
|
||||
mov(scratch, Operand(bit_cast<int32_t>(kZapValue)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,18 +54,6 @@ namespace internal {
|
||||
|
||||
void FullCodeGenSyntaxChecker::Check(FunctionLiteral* fun) {
|
||||
Scope* scope = fun->scope();
|
||||
|
||||
if (scope->num_heap_slots() > 0) {
|
||||
// We support functions with a local context if they do not have
|
||||
// parameters that need to be copied into the context.
|
||||
for (int i = 0, len = scope->num_parameters(); i < len; i++) {
|
||||
Slot* slot = scope->parameter(i)->slot();
|
||||
if (slot != NULL && slot->type() == Slot::CONTEXT) {
|
||||
BAILOUT("Function has context-allocated parameters.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisitDeclarations(scope->declarations());
|
||||
CHECK_BAILOUT;
|
||||
|
||||
|
@ -95,8 +95,14 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
|
||||
(num_parameters - 1 - i) * kPointerSize;
|
||||
// Load parameter from stack.
|
||||
__ mov(eax, Operand(ebp, parameter_offset));
|
||||
// Store it in the context
|
||||
__ mov(Operand(esi, Context::SlotOffset(slot->index())), eax);
|
||||
// Store it in the context.
|
||||
int context_offset = Context::SlotOffset(slot->index());
|
||||
__ mov(Operand(esi, context_offset), eax);
|
||||
// Update the write barrier. This clobbers all involved
|
||||
// registers, so we have use a third register to avoid
|
||||
// clobbering esi.
|
||||
__ mov(ecx, esi);
|
||||
__ RecordWrite(ecx, context_offset, eax, ebx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,7 +118,7 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
|
||||
}
|
||||
// Receiver is just before the parameters on the caller's stack.
|
||||
__ lea(edx, Operand(ebp, StandardFrameConstants::kCallerSPOffset +
|
||||
fun->num_parameters() * kPointerSize));
|
||||
fun->num_parameters() * kPointerSize));
|
||||
__ push(edx);
|
||||
__ push(Immediate(Smi::FromInt(fun->num_parameters())));
|
||||
// Arguments to ArgumentsAccessStub:
|
||||
|
@ -215,6 +215,14 @@ void MacroAssembler::RecordWrite(Register object, int offset,
|
||||
}
|
||||
|
||||
bind(&done);
|
||||
|
||||
// Clobber all input registers when running with the debug-code flag
|
||||
// turned on to provoke errors.
|
||||
if (FLAG_debug_code) {
|
||||
mov(object, Immediate(bit_cast<int32_t>(kZapValue)));
|
||||
mov(value, Immediate(bit_cast<int32_t>(kZapValue)));
|
||||
mov(scratch, Immediate(bit_cast<int32_t>(kZapValue)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,8 +95,14 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
|
||||
(num_parameters - 1 - i) * kPointerSize;
|
||||
// Load parameter from stack.
|
||||
__ movq(rax, Operand(rbp, parameter_offset));
|
||||
// Store it in the context
|
||||
__ movq(Operand(rsi, Context::SlotOffset(slot->index())), rax);
|
||||
// Store it in the context.
|
||||
int context_offset = Context::SlotOffset(slot->index());
|
||||
__ movq(Operand(rsi, context_offset), rax);
|
||||
// Update the write barrier. This clobbers all involved
|
||||
// registers, so we have use a third register to avoid
|
||||
// clobbering rsi.
|
||||
__ movq(rcx, rsi);
|
||||
__ RecordWrite(rcx, context_offset, rax, rbx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,7 +120,7 @@ void FullCodeGenerator::Generate(FunctionLiteral* fun, Mode mode) {
|
||||
}
|
||||
// The receiver is just before the parameters on the caller's stack.
|
||||
__ lea(rdx, Operand(rbp, StandardFrameConstants::kCallerSPOffset +
|
||||
fun->num_parameters() * kPointerSize));
|
||||
fun->num_parameters() * kPointerSize));
|
||||
__ push(rdx);
|
||||
__ Push(Smi::FromInt(fun->num_parameters()));
|
||||
// Arguments to ArgumentsAccessStub:
|
||||
|
@ -191,6 +191,17 @@ void MacroAssembler::RecordWrite(Register object,
|
||||
|
||||
RecordWriteNonSmi(object, offset, value, smi_index);
|
||||
bind(&done);
|
||||
|
||||
// Clobber all input registers when running with the debug-code flag
|
||||
// turned on to provoke errors. This clobbering repeats the
|
||||
// clobbering done inside RecordWriteNonSmi but it's necessary to
|
||||
// avoid having the fast case for smis leave the registers
|
||||
// unchanged.
|
||||
if (FLAG_debug_code) {
|
||||
movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(value, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -199,6 +210,14 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
|
||||
Register scratch,
|
||||
Register smi_index) {
|
||||
Label done;
|
||||
|
||||
if (FLAG_debug_code) {
|
||||
Label okay;
|
||||
JumpIfNotSmi(object, &okay);
|
||||
Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis");
|
||||
bind(&okay);
|
||||
}
|
||||
|
||||
// Test that the object address is not in the new space. We cannot
|
||||
// set remembered set bits in the new space.
|
||||
movq(scratch, object);
|
||||
@ -248,6 +267,14 @@ void MacroAssembler::RecordWriteNonSmi(Register object,
|
||||
}
|
||||
|
||||
bind(&done);
|
||||
|
||||
// Clobber all input registers when running with the debug-code flag
|
||||
// turned on to provoke errors.
|
||||
if (FLAG_debug_code) {
|
||||
movq(object, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(scratch, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
movq(smi_index, bit_cast<int64_t>(kZapValue), RelocInfo::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user