Handle holes in smi-untag from LoadKeyed requiring hole handling.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 22 May 2013 16:32:33 +0000 (16:32 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 22 May 2013 16:32:33 +0000 (16:32 +0000)
R=jkummerow@chromium.org

Review URL: https://chromiumcodereview.appspot.com/15737003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14756 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/lithium-arm.cc
src/arm/lithium-arm.h
src/arm/lithium-codegen-arm.cc
src/hydrogen-instructions.h
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 e1bb69e..54efacb 100644 (file)
@@ -1900,6 +1900,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
       if (instr->value()->type().IsSmi()) {
         value = UseRegisterAtStart(instr->value());
         res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
+        if (instr->value()->IsLoadKeyed()) {
+          HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value());
+          if (load_keyed->UsesMustHandleHole() &&
+              load_keyed->hole_mode() == NEVER_RETURN_HOLE) {
+            res = AssignEnvironment(res);
+          }
+        }
       } else {
         value = UseRegister(instr->value());
         LOperand* temp1 = TempRegister();
index 9bcd44a..c9d61b9 100644 (file)
@@ -2087,6 +2087,7 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
   LOperand* value() { return inputs_[0]; }
   bool needs_check() const { return needs_check_; }
 
+  DECLARE_HYDROGEN_ACCESSOR(Change);
   DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
 
  private:
index 09a0e9c..e12fcb7 100644 (file)
@@ -4905,6 +4905,21 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
     // If the input is a HeapObject, SmiUntag will set the carry flag.
     __ SmiUntag(result, input, SetCC);
     DeoptimizeIf(cs, instr->environment());
+  } else if (instr->hydrogen()->value()->IsLoadKeyed()) {
+    HLoadKeyed* load = HLoadKeyed::cast(instr->hydrogen()->value());
+    if (load->UsesMustHandleHole()) {
+      __ SmiUntag(result, input, SetCC);
+      if (load->hole_mode() == ALLOW_RETURN_HOLE) {
+        Label done;
+        __ b(cc, &done);
+        __ mov(result, Operand(Smi::FromInt(0)));
+        __ bind(&done);
+      } else {
+        DeoptimizeIf(cs, instr->environment());
+      }
+    } else {
+      __ SmiUntag(result, input);
+    }
   } else {
     __ SmiUntag(result, input);
   }
index c6a5111..f16efe6 100644 (file)
@@ -5411,7 +5411,7 @@ class HLoadKeyed
              IsFastDoubleElementsKind(elements_kind));
 
       if (IsFastSmiOrObjectElementsKind(elements_kind)) {
-        if (elements_kind == FAST_SMI_ELEMENTS) {
+        if (IsFastSmiElementsKind(elements_kind)) {
           set_type(HType::Smi());
         }
 
index b6244af..bf014da 100644 (file)
@@ -5026,14 +5026,30 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) {
 
 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
   LOperand* input = instr->value();
+  Register result = ToRegister(input);
   ASSERT(input->IsRegister() && input->Equals(instr->result()));
   if (instr->needs_check()) {
-    __ test(ToRegister(input), Immediate(kSmiTagMask));
+    __ test(result, Immediate(kSmiTagMask));
     DeoptimizeIf(not_zero, instr->environment());
+  } else if (instr->hydrogen()->value()->IsLoadKeyed()) {
+    HLoadKeyed* load = HLoadKeyed::cast(instr->hydrogen()->value());
+    if (load->UsesMustHandleHole()) {
+      __ test(result, Immediate(kSmiTagMask));
+      if (load->hole_mode() == ALLOW_RETURN_HOLE) {
+        Label done;
+        __ j(equal, &done);
+        __ xor_(result, result);
+        __ bind(&done);
+      } else {
+        DeoptimizeIf(not_zero, instr->environment());
+      }
+    } else {
+      __ AssertSmi(result);
+    }
   } else {
-    __ AssertSmi(ToRegister(input));
+    __ AssertSmi(result);
   }
-  __ SmiUntag(ToRegister(input));
+  __ SmiUntag(result);
 }
 
 
index dec5697..8179753 100644 (file)
@@ -1929,7 +1929,16 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
       ASSERT(to.IsInteger32());
       if (instr->value()->type().IsSmi()) {
         LOperand* value = UseRegister(instr->value());
-        return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
+        LInstruction* result =
+            DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
+        if (instr->value()->IsLoadKeyed()) {
+          HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value());
+          if (load_keyed->UsesMustHandleHole() &&
+              load_keyed->hole_mode() == NEVER_RETURN_HOLE) {
+            return AssignEnvironment(result);
+          }
+        }
+        return result;
       } else {
         bool truncating = instr->CanTruncateToInt32();
         if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
index b32ead9..a7d9fb4 100644 (file)
@@ -2153,6 +2153,7 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
   LOperand* value() { return inputs_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
+  DECLARE_HYDROGEN_ACCESSOR(Change);
 
   bool needs_check() const { return needs_check_; }
 
index 9a1ce98..42c6e91 100644 (file)
@@ -4606,6 +4606,21 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
   if (instr->needs_check()) {
     Condition is_smi = __ CheckSmi(input);
     DeoptimizeIf(NegateCondition(is_smi), instr->environment());
+  } else if (instr->hydrogen()->value()->IsLoadKeyed()) {
+    HLoadKeyed* load = HLoadKeyed::cast(instr->hydrogen()->value());
+    if (load->UsesMustHandleHole()) {
+      Condition cc = masm()->CheckSmi(input);
+      if (load->hole_mode() == ALLOW_RETURN_HOLE) {
+        Label done;
+        __ j(cc, &done);
+        __ xor_(input, input);
+        __ bind(&done);
+      } else {
+        DeoptimizeIf(NegateCondition(cc), instr->environment());
+      }
+    } else {
+      __ AssertSmi(input);
+    }
   } else {
     __ AssertSmi(input);
   }
index 1217a40..cde4e86 100644 (file)
@@ -1825,7 +1825,16 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
       ASSERT(to.IsInteger32());
       LOperand* value = UseRegister(instr->value());
       if (instr->value()->type().IsSmi()) {
-        return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
+        LInstruction* result =
+            DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
+        if (instr->value()->IsLoadKeyed()) {
+          HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value());
+          if (load_keyed->UsesMustHandleHole() &&
+              load_keyed->hole_mode() == NEVER_RETURN_HOLE) {
+            return AssignEnvironment(result);
+          }
+        }
+        return result;
       } else {
         bool truncating = instr->CanTruncateToInt32();
         LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
index 747d8e7..9926fc3 100644 (file)
@@ -2011,6 +2011,7 @@ class LSmiUntag: public LTemplateInstruction<1, 1, 0> {
   LOperand* value() { return inputs_[0]; }
   bool needs_check() const { return needs_check_; }
 
+  DECLARE_HYDROGEN_ACCESSOR(Change);
   DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
 
  private: