Clean up handling of global cell stores in the optimizing compiler.
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 20 Dec 2011 10:57:12 +0000 (10:57 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 20 Dec 2011 10:57:12 +0000 (10:57 +0000)
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

src/arm/lithium-arm.cc
src/arm/lithium-arm.h
src/arm/lithium-codegen-arm.cc
src/assembler.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-ia32.cc
src/ia32/lithium-ia32.h
src/x64/lithium-codegen-x64.cc
src/x64/lithium-x64.cc
src/x64/lithium-x64.h

index 1ac152d6a7ec605d725dc8c5adfe4d8dbe853d89..643d0ebe606a422998d3c8fc4dee5986b5b2ebac 100644 (file)
@@ -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);
 }
 
 
index 628c3d1a593a83007bf734f58a7c5eaba3cb9680..703666c4a15514a5f4d306617450c85272a50ddd 100644 (file)
@@ -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]; }
 };
 
 
index cdc464c32226e3ee2ebd40147b32c0ef953be8b7..4b68438300e32f8da20f84b9bb001ae7ba203c2b 100644 (file)
@@ -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.
 }
 
index b66f448407c8c1982bfc1336f32eb9c756f3e39e..2de7b92f5ef2f0aa25375a5fa284e71b0155d3ad 100644 (file)
@@ -1,4 +1,4 @@
-// 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
index 788348104110b5bfec90e9ed627c194171fe03b9..ab3850276891022b6823cb0f56a14c172f003898 100644 (file)
@@ -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.
 }
 
index f364439f10921d5ee47dbbd47771aa4c53bf10c5..c50378514a6bf1d25548be68c771a08c0d6e1d81 100644 (file)
@@ -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;
 }
 
index 7e126ff03c4c24ee56fc561cef9a3e3c2fc60d8e..cc3762d7ab42e0dbda448370ecd5b5da321c8f84 100644 (file)
@@ -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]; }
 };
 
 
index a96d140d49b967f9b62fa3d75fb31f2ffaf75fe7..70f5874b5c50e33ea02353563d09227311328eda 100644 (file)
@@ -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.
 }
 
index 7fa8a3999c91f797c05b4b7778d283f931f099dd..ac4d5f5d3e6ffae92863dc35d3877a663cfd1585 100644 (file)
@@ -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);
 }
 
 
index 280d2358c4c243942e42dbf65bc9dcae79353358..c6fcfeb81ea867f8d9a82b0888ff8cc429996bd0 100644 (file)
@@ -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]; }
 };