PPC: Don't MISS if you read the hole from certain FastHoley arrays.

Port caeb9004f0

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}
This commit is contained in:
mbrandy 2015-04-27 10:01:40 -07:00 committed by Commit bot
parent 3f27bb2188
commit 63d14580d8
2 changed files with 32 additions and 10 deletions

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

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