Revision: 10280
Author:   [email protected]
Date:     Tue Dec 20 02:57:12 2011
Log: 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.

[email protected]
BUG=v8:1870
TEST=

Review URL: http://codereview.chromium.org/8965038
http://code.google.com/p/v8/source/detail?r=10280

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/assembler.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Fri Dec  9 01:50:30 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Tue Dec 20 02:57:12 2011
@@ -1779,11 +1779,12 @@


 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);
 }


=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h       Tue Dec  6 04:11:08 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h       Tue Dec 20 02:57:12 2011
@@ -1242,6 +1242,8 @@

   DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
   DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
+
+  LOperand* value() { return inputs_[0]; }
 };


=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Dec 13 09:10:34 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Dec 20 02:57:12 2011
@@ -2262,27 +2262,26 @@


 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.
 }

=======================================
--- /branches/bleeding_edge/src/assembler.cc    Tue Dec 13 06:20:03 2011
+++ /branches/bleeding_edge/src/assembler.cc    Tue Dec 20 02:57:12 2011
@@ -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
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Dec 13 09:10:34 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Dec 20 02:57:12 2011
@@ -2124,26 +2124,20 @@


 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.
 }

=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri Dec 9 01:50:30 2011 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Dec 20 02:57:12 2011
@@ -1856,9 +1856,7 @@

 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;
 }

=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Mon Dec  5 07:58:25 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Tue Dec 20 02:57:12 2011
@@ -1269,16 +1269,16 @@
 };


-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]; }
 };


=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Dec 14 00:43:55 2011 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Dec 20 02:57:12 2011
@@ -2028,25 +2028,27 @@


 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(address, 0), value);
+    // 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);
+  }
   // Cells are always rescanned, so no write barrier here.
 }

=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Fri Dec  9 01:50:30 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Tue Dec 20 02:57:12 2011
@@ -1768,11 +1768,12 @@


 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);
 }


=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h       Tue Dec  6 04:11:08 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h       Tue Dec 20 02:57:12 2011
@@ -1231,16 +1231,17 @@
 };


-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]; }
 };


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to