| Index: src/mips/full-codegen-mips.cc
|
| diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
|
| index 0e03b8e3fdd4c428c1e480b7ac408643f19f144f..dca171359ff0897152e7dc3d9fb80da622538895 100644
|
| --- a/src/mips/full-codegen-mips.cc
|
| +++ b/src/mips/full-codegen-mips.cc
|
| @@ -47,6 +47,7 @@
|
| #include "stub-cache.h"
|
|
|
| #include "mips/code-stubs-mips.h"
|
| +#include "mips/macro-assembler-mips.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -214,14 +215,12 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
| // Load parameter from stack.
|
| __ lw(a0, MemOperand(fp, parameter_offset));
|
| // Store it in the context.
|
| - __ li(a1, Operand(Context::SlotOffset(var->index())));
|
| - __ addu(a2, cp, a1);
|
| - __ sw(a0, MemOperand(a2, 0));
|
| - // Update the write barrier. This clobbers all involved
|
| - // registers, so we have to use two more registers to avoid
|
| - // clobbering cp.
|
| - __ mov(a2, cp);
|
| - __ RecordWrite(a2, a1, a3);
|
| + MemOperand target = ContextOperand(cp, var->index());
|
| + __ sw(a0, target);
|
| +
|
| + // Update the write barrier.
|
| + __ RecordWriteContextSlot(
|
| + cp, target.offset(), a0, a3, kRAHasBeenSaved, kDontSaveFPRegs);
|
| }
|
| }
|
| }
|
| @@ -685,10 +684,12 @@ void FullCodeGenerator::SetVar(Variable* var,
|
| __ sw(src, location);
|
| // Emit the write barrier code if the location is in the heap.
|
| if (var->IsContextSlot()) {
|
| - __ RecordWrite(scratch0,
|
| - Operand(Context::SlotOffset(var->index())),
|
| - scratch1,
|
| - src);
|
| + __ RecordWriteContextSlot(scratch0,
|
| + location.offset(),
|
| + src,
|
| + scratch1,
|
| + kRAHasBeenSaved,
|
| + kDontSaveFPRegs);
|
| }
|
| }
|
|
|
| @@ -765,8 +766,14 @@ void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy,
|
| __ sw(result_register(), ContextOperand(cp, variable->index()));
|
| int offset = Context::SlotOffset(variable->index());
|
| // We know that we have written a function, which is not a smi.
|
| - __ mov(a1, cp);
|
| - __ RecordWrite(a1, Operand(offset), a2, result_register());
|
| + __ RecordWriteContextSlot(cp,
|
| + offset,
|
| + result_register(),
|
| + a2,
|
| + kRAHasBeenSaved,
|
| + kDontSaveFPRegs,
|
| + EMIT_REMEMBERED_SET,
|
| + OMIT_SMI_CHECK);
|
| PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
|
| } else if (mode == Variable::CONST || mode == Variable::LET) {
|
| Comment cmnt(masm_, "[ Declaration");
|
| @@ -1513,7 +1520,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
|
|
| // Update the write barrier for the array store with v0 as the scratch
|
| // register.
|
| - __ RecordWrite(a1, Operand(offset), a2, result_register());
|
| + __ RecordWriteField(
|
| + a1, offset, result_register(), a2, kRAHasBeenSaved, kDontSaveFPRegs);
|
|
|
| PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
|
| }
|
| @@ -1890,7 +1898,8 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
| // RecordWrite may destroy all its register arguments.
|
| __ mov(a3, result_register());
|
| int offset = Context::SlotOffset(var->index());
|
| - __ RecordWrite(a1, Operand(offset), a2, a3);
|
| + __ RecordWriteContextSlot(
|
| + a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
|
| }
|
| }
|
|
|
| @@ -1908,7 +1917,9 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
| __ sw(v0, location);
|
| if (var->IsContextSlot()) {
|
| __ mov(a3, v0);
|
| - __ RecordWrite(a1, Operand(Context::SlotOffset(var->index())), a2, a3);
|
| + int offset = Context::SlotOffset(var->index());
|
| + __ RecordWriteContextSlot(
|
| + a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
|
| }
|
| } else {
|
| ASSERT(var->IsLookupSlot());
|
| @@ -2874,7 +2885,9 @@ void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
|
| __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset));
|
| // Update the write barrier. Save the value as it will be
|
| // overwritten by the write barrier code and is needed afterward.
|
| - __ RecordWrite(a1, Operand(JSValue::kValueOffset - kHeapObjectTag), a2, a3);
|
| + __ mov(a2, v0);
|
| + __ RecordWriteField(
|
| + a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs);
|
|
|
| __ bind(&done);
|
| context()->Plug(v0);
|
| @@ -3167,16 +3180,25 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
| __ sw(scratch1, MemOperand(index2, 0));
|
| __ sw(scratch2, MemOperand(index1, 0));
|
|
|
| - Label new_space;
|
| - __ InNewSpace(elements, scratch1, eq, &new_space);
|
| + Label no_remembered_set;
|
| + __ CheckPageFlag(elements,
|
| + scratch1,
|
| + 1 << MemoryChunk::SCAN_ON_SCAVENGE,
|
| + ne,
|
| + &no_remembered_set);
|
| // Possible optimization: do a check that both values are Smis
|
| // (or them and test against Smi mask).
|
|
|
| - __ mov(scratch1, elements);
|
| - __ RecordWriteHelper(elements, index1, scratch2);
|
| - __ RecordWriteHelper(scratch1, index2, scratch2); // scratch1 holds elements.
|
| + // We are swapping two objects in an array and the incremental marker never
|
| + // pauses in the middle of scanning a single object. Therefore the
|
| + // incremental marker is not disturbed, so we don't need to call the
|
| + // RecordWrite stub that notifies the incremental marker.
|
| + __ RememberedSetHelper(
|
| + index1, scratch2, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
|
| + __ RememberedSetHelper(
|
| + index2, scratch2, kDontSaveFPRegs, MacroAssembler::kFallThroughAtEnd);
|
|
|
| - __ bind(&new_space);
|
| + __ bind(&no_remembered_set);
|
| // We are done. Drop elements from the stack, and return undefined.
|
| __ Drop(3);
|
| __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
|
|
|