From: chunyang.dai Date: Wed, 29 Apr 2015 10:34:19 +0000 (-0700) Subject: X87: Don't MISS if you read the hole from certain FastHoley arrays. X-Git-Tag: upstream/4.7.83~2912 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=77a2c15fb4016dfebf9cb5a1ef7e3c5c0b32f8ac;p=platform%2Fupstream%2Fv8.git X87: Don't MISS if you read the hole from certain FastHoley arrays. 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} --- diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc index 62bb190..fd2d3bb 100644 --- a/src/x87/lithium-codegen-x87.cc +++ b/src/x87/lithium-codegen-x87.cc @@ -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); } } diff --git a/src/x87/lithium-x87.cc b/src/x87/lithium-x87.cc index a1bf2f1..83aa33c 100644 --- a/src/x87/lithium-x87.cc +++ b/src/x87/lithium-x87.cc @@ -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;