From c8583b59dcbc866e39cabaf1a5b4fc848ea1199d Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Wed, 18 Dec 2013 17:40:53 +0000 Subject: [PATCH] HLoadKeyed for Smis optimized for x64 R=verwaest@chromium.org Review URL: https://codereview.chromium.org/108933002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18359 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-instructions.h | 6 +++++- src/x64/lithium-codegen-x64.cc | 28 +++++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index df8d2dc..6d595ad 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -6407,7 +6407,11 @@ class HLoadKeyed V8_FINAL (!IsHoleyElementsKind(elements_kind) || mode == NEVER_RETURN_HOLE)) { set_type(HType::Smi()); - set_representation(Representation::Smi()); + if (SmiValuesAre32Bits() && !RequiresHoleCheck()) { + set_representation(Representation::Integer32()); + } else { + set_representation(Representation::Smi()); + } } else { set_representation(Representation::Tagged()); } diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index c392b45..560c4db 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -3057,6 +3057,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { + HLoadKeyed* hinstr = instr->hydrogen(); Register result = ToRegister(instr->result()); LOperand* key = instr->key(); if (!key->IsConstantOperand()) { @@ -3066,24 +3067,37 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { // gets replaced during bound check elimination with the index // argument to the bounds check, which can be tagged, so that // case must be handled here, too. - if (instr->hydrogen()->IsDehoisted()) { + if (hinstr->IsDehoisted()) { // Sign extend key because it could be a 32 bit negative value // and the dehoisted address computation happens in 64 bits __ movsxlq(key_reg, key_reg); } } - // Load the result. - __ movq(result, + bool requires_hole_check = hinstr->RequiresHoleCheck(); + int offset = FixedArray::kHeaderSize - kHeapObjectTag; + Representation representation = hinstr->representation(); + + if (representation.IsInteger32() && + hinstr->elements_kind() == FAST_SMI_ELEMENTS) { + ASSERT(!requires_hole_check); + // Read int value directly from upper half of the smi. + STATIC_ASSERT(kSmiTag == 0); + STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); + offset += kPointerSize / 2; + } + + __ Load(result, BuildFastArrayOperand(instr->elements(), key, FAST_ELEMENTS, - FixedArray::kHeaderSize - kHeapObjectTag, - instr->additional_index())); + offset, + instr->additional_index()), + representation); // Check for the hole value. - if (instr->hydrogen()->RequiresHoleCheck()) { - if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { + if (requires_hole_check) { + if (IsFastSmiElementsKind(hinstr->elements_kind())) { Condition smi = __ CheckSmi(result); DeoptimizeIf(NegateCondition(smi), instr->environment()); } else { -- 2.7.4