diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 9dc239bc65..96b7f0dc8d 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -2029,12 +2029,6 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } -LInstruction* LChunkBuilder::DoCheckSmiOrInt32(HCheckSmiOrInt32* instr) { - LOperand* value = UseRegisterAtStart(instr->value()); - return AssignEnvironment(new(zone()) LCheckSmi(value)); -} - - LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { LOperand* value = UseRegisterAtStart(instr->value()); return AssignEnvironment(new(zone()) LCheckFunction(value)); @@ -2079,7 +2073,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { return DefineAsRegister(new(zone()) LConstantI); } else if (r.IsDouble()) { return DefineAsRegister(new(zone()) LConstantD); - } else if (r.IsTagged() || r.IsSmi()) { + } else if (r.IsSmiOrTagged()) { return DefineAsRegister(new(zone()) LConstantT); } else { UNREACHABLE(); @@ -2191,7 +2185,7 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { ASSERT(instr->key()->representation().IsInteger32() || - instr->key()->representation().IsTagged()); + instr->key()->representation().IsSmi()); ElementsKind elements_kind = instr->elements_kind(); LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LLoadKeyed* result = NULL; diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 04661d326b..b175c58d07 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -3276,7 +3276,7 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { key = ToRegister(instr->key()); } int element_size_shift = ElementsKindToShiftSize(elements_kind); - int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) + int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) ? (element_size_shift - kSmiTagSize) : element_size_shift; int additional_offset = instr->additional_index() << element_size_shift; @@ -3348,7 +3348,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { Register scratch = scratch0(); int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); - int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) + int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) ? (element_size_shift - kSmiTagSize) : element_size_shift; int constant_key = 0; if (key_is_constant) { @@ -3393,7 +3393,7 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { // representation for the key to be an integer, the input 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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); } else { __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); @@ -4329,7 +4329,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { if (instr->index()->IsConstantOperand()) { int constant_index = ToInteger32(LConstantOperand::cast(instr->index())); - if (instr->hydrogen()->length()->representation().IsTagged()) { + if (instr->hydrogen()->length()->representation().IsSmi()) { __ mov(ip, Operand(Smi::FromInt(constant_index))); } else { __ mov(ip, Operand(constant_index)); @@ -4357,7 +4357,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { key = ToRegister(instr->key()); } int element_size_shift = ElementsKindToShiftSize(elements_kind); - int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) + int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) ? (element_size_shift - kSmiTagSize) : element_size_shift; int additional_offset = instr->additional_index() << element_size_shift; @@ -4430,7 +4430,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { key = ToRegister(instr->key()); } int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); - int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) + int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) ? (element_size_shift - kSmiTagSize) : element_size_shift; Operand operand = key_is_constant ? Operand((constant_key << element_size_shift) + @@ -4476,7 +4476,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { // representation for the key to be an integer, the input 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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); } else { __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 52cbfaea20..d5f32b88a1 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -410,7 +410,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { HInstruction* load = BuildUncheckedMonomorphicElementAccess( GetParameter(0), GetParameter(1), NULL, NULL, casted_stub()->is_js_array(), casted_stub()->elements_kind(), - false, NEVER_RETURN_HOLE, STANDARD_STORE, Representation::Tagged()); + false, NEVER_RETURN_HOLE, STANDARD_STORE, Representation::Smi()); return load; } @@ -456,7 +456,7 @@ HValue* CodeStubGraphBuilder::BuildCodeStub() { GetParameter(0), GetParameter(1), GetParameter(2), NULL, casted_stub()->is_js_array(), casted_stub()->elements_kind(), true, NEVER_RETURN_HOLE, casted_stub()->store_mode(), - Representation::Tagged()); + Representation::Smi()); return GetParameter(2); } @@ -572,11 +572,9 @@ HValue* CodeStubGraphBuilder:: new(zone()) HConstant(initial_capacity, Representation::Tagged()); AddInstruction(initial_capacity_node); - // Since we're forcing Integer32 representation for this HBoundsCheck, - // there's no need to Smi-check the index. HBoundsCheck* checked_arg = AddBoundsCheck(argument, max_alloc_length, ALLOW_SMI_KEY, - Representation::Tagged()); + Representation::Smi()); IfBuilder if_builder(this); if_builder.IfCompare(checked_arg, constant_zero, Token::EQ); if_builder.Then(); diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 0c03b5908e..fa8ee8646f 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1143,16 +1143,15 @@ void HBoundsCheck::InferRepresentation(HInferRepresentation* h_infer) { HValue* actual_length = length()->ActualValue(); HValue* actual_index = index()->ActualValue(); if (key_mode_ == DONT_ALLOW_SMI_KEY || - !actual_length->representation().IsTagged()) { + !actual_length->representation().IsSmiOrTagged()) { r = Representation::Integer32(); - } else if (actual_index->representation().IsTagged() || - (actual_index->IsConstant() && - HConstant::cast(actual_index)->HasSmiValue())) { - // If the index is tagged, or a constant that holds a Smi, allow the length - // to be tagged, since it is usually already tagged from loading it out of - // the length field of a JSArray. This allows for direct comparison without - // untagging. - r = Representation::Tagged(); + } else if (actual_index->representation().IsSmiOrTagged() || + (actual_index->IsConstant() && + HConstant::cast(actual_index)->HasSmiValue())) { + // If the index is smi, or a constant that holds a Smi, allow the length to + // be smi, since it is usually already smi from loading it out of the length + // field of a JSArray. This allows for direct comparison without untagging. + r = Representation::Smi(); } else { r = Representation::Integer32(); } @@ -2945,15 +2944,6 @@ HType HCheckSmi::CalculateInferredType() { } -void HCheckSmiOrInt32::InferRepresentation(HInferRepresentation* h_infer) { - ASSERT(CheckFlag(kFlexibleRepresentation)); - ASSERT(UseCount() == 1); - HUseIterator use = uses(); - Representation r = use.value()->RequiredInputRepresentation(use.index()); - UpdateRepresentation(r, h_infer, "checksmiorint32"); -} - - HType HPhi::CalculateInferredType() { HType result = HType::Uninitialized(); for (int i = 0; i < OperandCount(); ++i) { diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 775a0e25df..116c4e7aa7 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -93,7 +93,6 @@ class LChunkBuilder; V(CheckNonSmi) \ V(CheckPrototypeMaps) \ V(CheckSmi) \ - V(CheckSmiOrInt32) \ V(ClampToUint8) \ V(ClassOfTestAndBranch) \ V(CompareIDAndBranch) \ @@ -1721,7 +1720,7 @@ class HChange: public HUnaryOperation { SetFlag(kUseGVN); if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined); if (is_truncating) SetFlag(kTruncatingToInt32); - if (value->type().IsSmi()) { + if (value->representation().IsSmi() || value->type().IsSmi()) { set_type(HType::Smi()); } else { set_type(HType::TaggedNumber()); @@ -2952,38 +2951,6 @@ class HCheckSmi: public HUnaryOperation { }; -class HCheckSmiOrInt32: public HUnaryOperation { - public: - explicit HCheckSmiOrInt32(HValue* value) : HUnaryOperation(value) { - SetFlag(kFlexibleRepresentation); - SetFlag(kUseGVN); - } - - virtual int RedefinedOperandIndex() { return 0; } - virtual Representation RequiredInputRepresentation(int index) { - return representation(); - } - virtual void InferRepresentation(HInferRepresentation* h_infer); - - virtual Representation observed_input_representation(int index) { - return Representation::Integer32(); - } - - virtual HValue* Canonicalize() { - if (representation().IsTagged() && !value()->type().IsSmi()) { - return this; - } else { - return value(); - } - } - - DECLARE_CONCRETE_INSTRUCTION(CheckSmiOrInt32) - - protected: - virtual bool DataEquals(HValue* other) { return true; } -}; - - class HPhi: public HValue { public: HPhi(int merged_index, Zone* zone) @@ -3578,8 +3545,7 @@ class HBoundsCheckBaseIndexInformation; class HBoundsCheck: public HTemplateInstruction<2> { public: // Normally HBoundsCheck should be created using the - // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with - // a HCheckSmiOrInt32 check. + // HGraphBuilder::AddBoundsCheck() helper. // However when building stubs, where we know that the arguments are Int32, // it makes sense to invoke this constructor directly. HBoundsCheck(HValue* index, @@ -5459,7 +5425,7 @@ class ArrayInstructionInterface { static Representation KeyedAccessIndexRequirement(Representation r) { return r.IsInteger32() ? Representation::Integer32() - : Representation::Tagged(); + : Representation::Smi(); } }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 8954e61df0..54ae31f0f2 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -1003,14 +1003,6 @@ HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length, BoundsCheckKeyMode key_mode, Representation r) { - if (!index->type().IsSmi()) { - index = new(graph()->zone()) HCheckSmiOrInt32(index); - AddInstruction(HCheckSmiOrInt32::cast(index)); - } - if (!length->type().IsSmi()) { - length = new(graph()->zone()) HCheckSmiOrInt32(length); - AddInstruction(HCheckSmiOrInt32::cast(length)); - } HBoundsCheck* result = new(graph()->zone()) HBoundsCheck( index, length, key_mode, r); AddInstruction(result); @@ -1333,11 +1325,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( elements = BuildCheckForCapacityGrow(object, elements, elements_kind, length, key, is_js_array); - if (!key->type().IsSmi()) { - checked_key = AddInstruction(new(zone) HCheckSmiOrInt32(key)); - } else { - checked_key = key; - } + checked_key = key; } else { checked_key = AddBoundsCheck( key, length, ALLOW_SMI_KEY, checked_index_representation); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 26e7103466..3e237638d7 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -3364,7 +3364,7 @@ Operand LCodeGen::BuildFastArrayOperand( + offset); } else { // Take the tag bit into account while computing the shift size. - if (key_representation.IsTagged() && (shift_size >= 1)) { + if (key_representation.IsSmi() && (shift_size >= 1)) { shift_size -= kSmiTagSize; } ScaleFactor scale_factor = static_cast(shift_size); @@ -4359,7 +4359,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { if (instr->index()->IsConstantOperand()) { int constant_index = ToInteger32(LConstantOperand::cast(instr->index())); - if (instr->hydrogen()->length()->representation().IsTagged()) { + if (instr->hydrogen()->length()->representation().IsSmi()) { __ cmp(ToOperand(instr->length()), Immediate(Smi::FromInt(constant_index))); } else { diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 8981c4d328..ffec17b6ee 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2068,12 +2068,6 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } -LInstruction* LChunkBuilder::DoCheckSmiOrInt32(HCheckSmiOrInt32* instr) { - LOperand* value = UseAtStart(instr->value()); - return AssignEnvironment(new(zone()) LCheckSmi(value)); -} - - LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { // If the target is in new space, we'll emit a global cell compare and so // want the value in a register. If the target gets promoted before we @@ -2144,7 +2138,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { } else { return DefineX87TOS(new(zone()) LConstantD(NULL)); } - } else if (r.IsTagged()) { + } else if (r.IsSmiOrTagged()) { return DefineAsRegister(new(zone()) LConstantT); } else { UNREACHABLE(); @@ -2261,7 +2255,7 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { ASSERT(instr->key()->representation().IsInteger32() || - instr->key()->representation().IsTagged()); + instr->key()->representation().IsSmi()); ElementsKind elements_kind = instr->elements_kind(); bool clobbers_key = ExternalArrayOpRequiresTemp( instr->key()->representation(), elements_kind); @@ -2330,7 +2324,7 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { if (!instr->is_external()) { ASSERT(instr->elements()->representation().IsTagged()); ASSERT(instr->key()->representation().IsInteger32() || - instr->key()->representation().IsTagged()); + instr->key()->representation().IsSmi()); if (instr->value()->representation().IsDouble()) { LOperand* object = UseRegisterAtStart(instr->elements()); diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 47d8601cdb..6712e760e5 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -1596,7 +1596,7 @@ inline static bool ExternalArrayOpRequiresTemp( // Operations that require the key to be divided by two to be converted into // an index cannot fold the scale operation into a load and need an extra // temp register to do the work. - return key_representation.IsTagged() && + return key_representation.IsSmi() && (elements_kind == EXTERNAL_BYTE_ELEMENTS || elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS || elements_kind == EXTERNAL_PIXEL_ELEMENTS); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 109c25ad5e..44d056fe13 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -2922,7 +2922,7 @@ void LCodeGen::DoLoadKeyedExternalArray(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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ SmiToInteger64(key_reg, key_reg); } else if (instr->hydrogen()->IsDehoisted()) { // Sign extend key because it could be a 32 bit negative value @@ -2995,7 +2995,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { // representation for the key to be an integer, the input 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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ SmiToInteger64(key_reg, key_reg); } else if (instr->hydrogen()->IsDehoisted()) { // Sign extend key because it could be a 32 bit negative value @@ -3037,7 +3037,7 @@ 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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ SmiToInteger64(key_reg, key_reg); } else if (instr->hydrogen()->IsDehoisted()) { // Sign extend key because it could be a 32 bit negative value @@ -4042,20 +4042,20 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { if (instr->length()->IsRegister()) { Register reg = ToRegister(instr->length()); - if (!instr->hydrogen()->length()->representation().IsTagged()) { + if (!instr->hydrogen()->length()->representation().IsSmi()) { __ AssertZeroExtended(reg); } if (instr->index()->IsConstantOperand()) { int constant_index = ToInteger32(LConstantOperand::cast(instr->index())); - if (instr->hydrogen()->length()->representation().IsTagged()) { + if (instr->hydrogen()->length()->representation().IsSmi()) { __ Cmp(reg, Smi::FromInt(constant_index)); } else { __ cmpq(reg, Immediate(constant_index)); } } else { Register reg2 = ToRegister(instr->index()); - if (!instr->hydrogen()->index()->representation().IsTagged()) { + if (!instr->hydrogen()->index()->representation().IsSmi()) { __ AssertZeroExtended(reg2); } __ cmpq(reg, reg2); @@ -4065,7 +4065,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { if (instr->index()->IsConstantOperand()) { int constant_index = ToInteger32(LConstantOperand::cast(instr->index())); - if (instr->hydrogen()->length()->representation().IsTagged()) { + if (instr->hydrogen()->length()->representation().IsSmi()) { __ Cmp(length, Smi::FromInt(constant_index)); } else { __ cmpq(length, Immediate(constant_index)); @@ -4088,7 +4088,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* 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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ SmiToInteger64(key_reg, key_reg); } else if (instr->hydrogen()->IsDehoisted()) { // Sign extend key because it could be a 32 bit negative value @@ -4152,7 +4152,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { // input 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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ SmiToInteger64(key_reg, key_reg); } else if (instr->hydrogen()->IsDehoisted()) { // Sign extend key because it could be a 32 bit negative value @@ -4195,7 +4195,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { // input 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()->key()->representation().IsTagged()) { + if (instr->hydrogen()->key()->representation().IsSmi()) { __ SmiToInteger64(key_reg, key_reg); } else if (instr->hydrogen()->IsDehoisted()) { // Sign extend key because it could be a 32 bit negative value diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index b74b1a8a9a..de21c10946 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1946,12 +1946,6 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } -LInstruction* LChunkBuilder::DoCheckSmiOrInt32(HCheckSmiOrInt32* instr) { - LOperand* value = UseRegisterAtStart(instr->value()); - return AssignEnvironment(new(zone()) LCheckSmi(value)); -} - - LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { LOperand* value = UseRegisterAtStart(instr->value()); return AssignEnvironment(new(zone()) LCheckFunction(value)); @@ -1998,7 +1992,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { } else if (r.IsDouble()) { LOperand* temp = TempRegister(); return DefineAsRegister(new(zone()) LConstantD(temp)); - } else if (r.IsTagged()) { + } else if (r.IsSmiOrTagged()) { return DefineAsRegister(new(zone()) LConstantT); } else { UNREACHABLE(); @@ -2113,9 +2107,9 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { ASSERT(instr->key()->representation().IsInteger32() || - instr->key()->representation().IsTagged()); + instr->key()->representation().IsSmi()); ElementsKind elements_kind = instr->elements_kind(); - bool clobbers_key = instr->key()->representation().IsTagged(); + bool clobbers_key = instr->key()->representation().IsSmi(); LOperand* key = clobbers_key ? UseTempRegister(instr->key()) : UseRegisterOrConstantAtStart(instr->key()); @@ -2156,7 +2150,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { ElementsKind elements_kind = instr->elements_kind(); - bool clobbers_key = instr->key()->representation().IsTagged(); + bool clobbers_key = instr->key()->representation().IsSmi(); if (!instr->is_external()) { ASSERT(instr->elements()->representation().IsTagged());