PPC: Don't MISS if you read the hole from certain FastHoley arrays.
authormbrandy <mbrandy@us.ibm.com>
Mon, 27 Apr 2015 17:01:40 +0000 (10:01 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 27 Apr 2015 17:01:17 +0000 (17:01 +0000)
Port caeb9004f0bfc2a916fc63e9d27100a3110016d4

Original commit message:
If the array's map is the initial FastHoley array map, and the array prototype
chain is undisturbed and empty of elements, then keyed loads can convert the
load of a hole to undefined.

BUG=

R=dstence@us.ibm.com, michael_dawson@ca.ibm.com

Review URL: https://codereview.chromium.org/1110623002

Cr-Commit-Position: refs/heads/master@{#28089}

src/ppc/lithium-codegen-ppc.cc
src/ppc/lithium-ppc.cc

index 5ed2145..ae58f31 100644 (file)
@@ -3493,6 +3493,23 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
       __ cmp(result, scratch);
       DeoptimizeIf(eq, instr, Deoptimizer::kHole);
     }
+  } else if (instr->hydrogen()->hole_mode() == CONVERT_HOLE_TO_UNDEFINED) {
+    DCHECK(instr->hydrogen()->elements_kind() == FAST_HOLEY_ELEMENTS);
+    Label done;
+    __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+    __ cmp(result, scratch);
+    __ bne(&done);
+    if (info()->IsStub()) {
+      // A stub can safely convert the hole to undefined only if the array
+      // protector cell contains (Smi) Isolate::kArrayProtectorValid. Otherwise
+      // it needs to bail out.
+      __ LoadRoot(result, Heap::kArrayProtectorRootIndex);
+      __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset));
+      __ CmpSmiLiteral(result, Smi::FromInt(Isolate::kArrayProtectorValid), r0);
+      DeoptimizeIf(ne, instr, Deoptimizer::kHole);
+    }
+    __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+    __ bind(&done);
   }
 }
 
index d70143c..81eb3fd 100644 (file)
@@ -2190,16 +2190,21 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
     result = DefineAsRegister(new (zone()) LLoadKeyed(backing_store, key));
   }
 
-  if ((instr->is_external() || instr->is_fixed_typed_array())
-          ?
-          // see LCodeGen::DoLoadKeyedExternalArray
-          ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
-            elements_kind == UINT32_ELEMENTS) &&
-           !instr->CheckFlag(HInstruction::kUint32))
-          :
-          // see LCodeGen::DoLoadKeyedFixedDoubleArray and
-          // LCodeGen::DoLoadKeyedFixedArray
-          instr->RequiresHoleCheck()) {
+  bool needs_environment;
+  if (instr->is_external() || instr->is_fixed_typed_array()) {
+    // see LCodeGen::DoLoadKeyedExternalArray
+    needs_environment = (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+                         elements_kind == UINT32_ELEMENTS) &&
+                        !instr->CheckFlag(HInstruction::kUint32);
+  } else {
+    // see LCodeGen::DoLoadKeyedFixedDoubleArray and
+    // LCodeGen::DoLoadKeyedFixedArray
+    needs_environment =
+        instr->RequiresHoleCheck() ||
+        (instr->hole_mode() == CONVERT_HOLE_TO_UNDEFINED && info()->IsStub());
+  }
+
+  if (needs_environment) {
     result = AssignEnvironment(result);
   }
   return result;