Reviewers: ulan, jochen (OOO until March 10),

Description:
A64: Improve constraints for StoreNamedField

Improve register constraints for cases that don't need write barriers, and
remove TODOs.

BUG=

Please review this at https://codereview.chromium.org/189373006/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+48, -34 lines):
  M src/a64/lithium-a64.cc
  M src/a64/lithium-codegen-a64.cc


Index: src/a64/lithium-a64.cc
diff --git a/src/a64/lithium-a64.cc b/src/a64/lithium-a64.cc
index cf89c09f5b2515d2dbc0b6cabe667b10245eb9ea..ce77209910d33131d5ea6607a585d9ccd6f05df2 100644
--- a/src/a64/lithium-a64.cc
+++ b/src/a64/lithium-a64.cc
@@ -2231,17 +2231,27 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {


 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
- // TODO(jbramley): Optimize register usage in this instruction. For now, it - // allocates everything that it might need because it keeps changing in the
-  // merge and keeping it valid is time-consuming.
-
// TODO(jbramley): It might be beneficial to allow value to be a constant in
   // some cases. x64 makes use of this with FLAG_track_fields, for example.

   LOperand* object = UseRegister(instr->object());
-  LOperand* value = UseRegisterAndClobber(instr->value());
-  LOperand* temp0 = TempRegister();
-  LOperand* temp1 = TempRegister();
+  LOperand* value;
+  LOperand* temp0 = NULL;
+  LOperand* temp1 = NULL;
+  if (instr->NeedsWriteBarrier()) {
+    value = UseRegisterAndClobber(instr->value());
+    temp0 = TempRegister();
+    temp1 = TempRegister();
+  } else {
+    value = UseRegister(instr->value());
+    if (!(instr->access().IsExternalMemory() ||
+          instr->field_representation().IsDouble())) {
+      temp0 = TempRegister();
+      if (instr->NeedsWriteBarrierForMap()) {
+        temp1 = TempRegister();
+      }
+    }
+  }

   LStoreNamedField* result =
       new(zone()) LStoreNamedField(object, value, temp0, temp1);
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index ad8d742abac2cc894d292e026d7005b67933e834..aca060f75d1cae9d03f0343ea030dee6accb8696 100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -5146,36 +5146,20 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
 }


-// TODO(jbramley): Once the merge is done and we're tracking bleeding_edge, try
-// to tidy up this function.
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Representation representation = instr->representation();

   Register object = ToRegister(instr->object());
-  Register temp0 = ToRegister(instr->temp0());
-  Register temp1 = ToRegister(instr->temp1());
   HObjectAccess access = instr->hydrogen()->access();
+  Handle<Map> transition = instr->transition();
   int offset = access.offset();

   if (access.IsExternalMemory()) {
+    ASSERT(transition.is_null());
+    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     Register value = ToRegister(instr->value());
     __ Store(value, MemOperand(object, offset), representation);
     return;
-  }
-
-  Handle<Map> transition = instr->transition();
-  SmiCheck check_needed =
-      instr->hydrogen()->value()->IsHeapObject()
-          ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
-
-  if (representation.IsHeapObject()) {
-    Register value = ToRegister(instr->value());
-    if (!instr->hydrogen()->value()->type().IsHeapObject()) {
-      DeoptimizeIfSmi(value, instr->environment());
-
-      // We know that value is a smi now, so we can omit the check below.
-      check_needed = OMIT_SMI_CHECK;
-    }
   } else if (representation.IsDouble()) {
     ASSERT(transition.is_null());
     ASSERT(access.IsInobject());
@@ -5185,9 +5169,22 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
     return;
   }

+  Register value = ToRegister(instr->value());
+
+  SmiCheck check_needed = instr->hydrogen()->value()->IsHeapObject()
+      ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+
+  if (representation.IsHeapObject() &&
+      !instr->hydrogen()->value()->type().IsHeapObject()) {
+    DeoptimizeIfSmi(value, instr->environment());
+
+    // We know that value is a smi now, so we can omit the check below.
+    check_needed = OMIT_SMI_CHECK;
+  }
+
   if (!transition.is_null()) {
     // Store the new map value.
-    Register new_map_value = temp0;
+    Register new_map_value = ToRegister(instr->temp0());
     __ Mov(new_map_value, Operand(transition));
     __ Str(new_map_value, FieldMemOperand(object, HeapObject::kMapOffset));
     if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
@@ -5195,7 +5192,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
       __ RecordWriteField(object,
                           HeapObject::kMapOffset,
                           new_map_value,
-                          temp1,
+                          ToRegister(instr->temp1()),
                           GetLinkRegisterState(),
                           kSaveFPRegs,
                           OMIT_REMEMBERED_SET,
@@ -5204,21 +5201,28 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   }

   // Do the store.
-  Register value = ToRegister(instr->value());
   Register destination;
   if (access.IsInobject()) {
     destination = object;
   } else {
+    Register temp0 = ToRegister(instr->temp0());
     __ Ldr(temp0, FieldMemOperand(object, JSObject::kPropertiesOffset));
     destination = temp0;
   }

   if (representation.IsSmi() &&
-      instr->hydrogen()->value()->representation().IsInteger32()) {
+     instr->hydrogen()->value()->representation().IsInteger32()) {
     ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
 #ifdef DEBUG
-    __ Ldr(temp1, FieldMemOperand(destination, offset));
-    __ AssertSmi(temp1);
+    Register temp0 = ToRegister(instr->temp0());
+    __ Ldr(temp0, FieldMemOperand(destination, offset));
+    __ AssertSmi(temp0);
+    // If destination aliased temp0, restore it to the address calculated
+    // earlier.
+    if (destination.Is(temp0)) {
+      ASSERT(!access.IsInobject());
+ __ Ldr(destination, FieldMemOperand(object, JSObject::kPropertiesOffset));
+    }
 #endif
     STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0);
     __ Store(value, UntagSmiFieldMemOperand(destination, offset),
@@ -5229,8 +5233,8 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   if (instr->hydrogen()->NeedsWriteBarrier()) {
     __ RecordWriteField(destination,
                         offset,
-                        value,      // Clobbered.
-                        temp1,      // Clobbered.
+                        value,                        // Clobbered.
+                        ToRegister(instr->temp1()),   // Clobbered.
                         GetLinkRegisterState(),
                         kSaveFPRegs,
                         EMIT_REMEMBERED_SET,


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to