Clean up handling of global cell stores in the optimizing compiler.

Tell the register allocator the value is not overwritten.  Never use
temporary registers on ia32, avoid them on x64 and ARM.  Restore the
original copyright date on assembler.cc.

R=fschneider@chromium.org
BUG=v8:1870
TEST=

Review URL: http://codereview.chromium.org/8965038

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10280 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 04f0e332
......@@ -1779,11 +1779,12 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LOperand* temp = TempRegister();
LOperand* value = UseTempRegister(instr->value());
LInstruction* result = new LStoreGlobalCell(value, temp);
if (instr->RequiresHoleCheck()) result = AssignEnvironment(result);
return result;
LOperand* value = UseRegister(instr->value());
// Use a temp to check the value in the cell in the case where we perform
// a hole check.
return instr->RequiresHoleCheck()
? AssignEnvironment(new LStoreGlobalCell(value, TempRegister()))
: new LStoreGlobalCell(value, NULL);
}
......
......@@ -1242,6 +1242,8 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
LOperand* value() { return inputs_[0]; }
};
......
......@@ -2262,27 +2262,26 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
Register value = ToRegister(instr->InputAt(0));
Register scratch = scratch0();
Register scratch2 = ToRegister(instr->TempAt(0));
Register value = ToRegister(instr->value());
Register cell = scratch0();
// Load the cell.
__ mov(scratch, Operand(Handle<Object>(instr->hydrogen()->cell())));
__ mov(cell, Operand(instr->hydrogen()->cell()));
// If the cell we are storing to contains the hole it could have
// been deleted from the property dictionary. In that case, we need
// to update the property details in the property dictionary to mark
// it as no longer deleted.
if (instr->hydrogen()->RequiresHoleCheck()) {
__ ldr(scratch2,
FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
__ cmp(scratch2, ip);
// We use a temp to check the payload (CompareRoot might clobber ip).
Register payload = ToRegister(instr->TempAt(0));
__ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
__ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
DeoptimizeIf(eq, instr->environment());
}
// Store the value.
__ str(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
__ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset));
// Cells are always rescanned, so no write barrier here.
}
......
// Copyright (c) 2011 Sun Microsystems Inc.
// Copyright (c) 1994-2006 Sun Microsystems Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
......
......@@ -2124,26 +2124,20 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
Register object = ToRegister(instr->TempAt(0));
Register address = ToRegister(instr->TempAt(1));
Register value = ToRegister(instr->InputAt(0));
ASSERT(!value.is(object));
Handle<JSGlobalPropertyCell> cell_handle(instr->hydrogen()->cell());
int offset = JSGlobalPropertyCell::kValueOffset;
__ mov(object, Immediate(cell_handle));
Register value = ToRegister(instr->value());
Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell();
// If the cell we are storing to contains the hole it could have
// been deleted from the property dictionary. In that case, we need
// to update the property details in the property dictionary to mark
// it as no longer deleted. We deoptimize in that case.
if (instr->hydrogen()->RequiresHoleCheck()) {
__ cmp(FieldOperand(object, offset), factory()->the_hole_value());
__ cmp(Operand::Cell(cell_handle), factory()->the_hole_value());
DeoptimizeIf(equal, instr->environment());
}
// Store the value.
__ mov(FieldOperand(object, offset), value);
__ mov(Operand::Cell(cell_handle), value);
// Cells are always rescanned, so no write barrier here.
}
......
......@@ -1856,9 +1856,7 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LStoreGlobalCell* result =
new(zone()) LStoreGlobalCell(UseTempRegister(instr->value()),
TempRegister(),
TempRegister());
new(zone()) LStoreGlobalCell(UseRegister(instr->value()));
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
}
......
......@@ -1269,16 +1269,16 @@ class LLoadGlobalGeneric: public LTemplateInstruction<1, 2, 0> {
};
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 2> {
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 0> {
public:
explicit LStoreGlobalCell(LOperand* value, LOperand* temp1, LOperand* temp2) {
explicit LStoreGlobalCell(LOperand* value) {
inputs_[0] = value;
temps_[0] = temp1;
temps_[1] = temp2;
}
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
LOperand* value() { return inputs_[0]; }
};
......
......@@ -2028,25 +2028,27 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
Register object = ToRegister(instr->TempAt(0));
Register address = ToRegister(instr->TempAt(1));
Register value = ToRegister(instr->InputAt(0));
ASSERT(!value.is(object));
Handle<JSGlobalPropertyCell> cell_handle(instr->hydrogen()->cell());
__ movq(address, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
Register value = ToRegister(instr->value());
Handle<JSGlobalPropertyCell> cell_handle = instr->hydrogen()->cell();
// If the cell we are storing to contains the hole it could have
// been deleted from the property dictionary. In that case, we need
// to update the property details in the property dictionary to mark
// it as no longer deleted. We deoptimize in that case.
if (instr->hydrogen()->RequiresHoleCheck()) {
__ CompareRoot(Operand(address, 0), Heap::kTheHoleValueRootIndex);
// We have a temp because CompareRoot might clobber kScratchRegister.
Register cell = ToRegister(instr->TempAt(0));
ASSERT(!value.is(cell));
__ movq(cell, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
__ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex);
DeoptimizeIf(equal, instr->environment());
// Store the value.
__ movq(Operand(cell, 0), value);
} else {
// Store the value.
__ movq(kScratchRegister, cell_handle, RelocInfo::GLOBAL_PROPERTY_CELL);
__ movq(Operand(kScratchRegister, 0), value);
}
// Store the value.
__ movq(Operand(address, 0), value);
// Cells are always rescanned, so no write barrier here.
}
......
......@@ -1768,11 +1768,12 @@ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
LStoreGlobalCell* result =
new LStoreGlobalCell(UseTempRegister(instr->value()),
TempRegister(),
TempRegister());
return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
LOperand* value = UseRegister(instr->value());
// Use a temp to avoid reloading the cell value address in the case where
// we perform a hole check.
return instr->RequiresHoleCheck()
? AssignEnvironment(new LStoreGlobalCell(value, TempRegister()))
: new LStoreGlobalCell(value, NULL);
}
......
......@@ -1231,16 +1231,17 @@ class LLoadGlobalGeneric: public LTemplateInstruction<1, 1, 0> {
};
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 2> {
class LStoreGlobalCell: public LTemplateInstruction<0, 1, 1> {
public:
explicit LStoreGlobalCell(LOperand* value, LOperand* temp1, LOperand* temp2) {
explicit LStoreGlobalCell(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp1;
temps_[1] = temp2;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
LOperand* value() { return inputs_[0]; }
};
......
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