X87: Don't MISS if you read the hole from certain FastHoley arrays.
authorchunyang.dai <chunyang.dai@intel.com>
Wed, 29 Apr 2015 10:34:19 +0000 (03:34 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 29 Apr 2015 10:34:25 +0000 (10:34 +0000)
port caeb9004f0bfc2a916fc63e9d27100a3110016d4 (r28056)

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=

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

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

src/x87/lithium-codegen-x87.cc
src/x87/lithium-x87.cc

index 62bb190..fd2d3bb 100644 (file)
@@ -3452,6 +3452,22 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
       __ cmp(result, factory()->the_hole_value());
       DeoptimizeIf(equal, instr, Deoptimizer::kHole);
     }
+  } else if (instr->hydrogen()->hole_mode() == CONVERT_HOLE_TO_UNDEFINED) {
+    DCHECK(instr->hydrogen()->elements_kind() == FAST_HOLEY_ELEMENTS);
+    Label done;
+    __ cmp(result, factory()->the_hole_value());
+    __ j(not_equal, &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.
+      __ mov(result, isolate()->factory()->array_protector());
+      __ cmp(FieldOperand(result, PropertyCell::kValueOffset),
+             Immediate(Smi::FromInt(Isolate::kArrayProtectorValid)));
+      DeoptimizeIf(not_equal, instr, Deoptimizer::kHole);
+    }
+    __ mov(result, isolate()->factory()->undefined_value());
+    __ bind(&done);
   }
 }
 
index a1bf2f1..83aa33c 100644 (file)
@@ -2237,14 +2237,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
-      ((instr->elements_kind() == EXTERNAL_UINT32_ELEMENTS ||
-        instr->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;