Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index d1cf33899d5b307fd4571f9c3abf7378bcf0b0e0..f1c631bc5fd4ae905431c923c91bf4ee20c55614 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -2324,8 +2324,10 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) { |
__ movzxbq(temp, FieldOperand(temp, Map::kBitField2Offset)); |
__ and_(temp, Immediate(Map::kElementsKindMask)); |
__ shr(temp, Immediate(Map::kElementsKindShift)); |
- __ cmpl(temp, Immediate(FAST_ELEMENTS)); |
- __ j(equal, &ok, Label::kNear); |
+ __ cmpl(temp, Immediate(GetInitialFastElementsKind())); |
+ __ j(less, &fail, Label::kNear); |
+ __ cmpl(temp, Immediate(TERMINAL_FAST_ELEMENTS_KIND)); |
+ __ j(less_equal, &ok, Label::kNear); |
__ cmpl(temp, Immediate(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
__ j(less, &fail, Label::kNear); |
__ cmpl(temp, Immediate(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
@@ -2403,16 +2405,18 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( |
__ movsxlq(key_reg, key_reg); |
} |
- int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
- sizeof(kHoleNanLower32); |
- Operand hole_check_operand = BuildFastArrayOperand( |
- instr->elements(), |
- instr->key(), |
- FAST_DOUBLE_ELEMENTS, |
- offset, |
- instr->additional_index()); |
- __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
- DeoptimizeIf(equal, instr->environment()); |
+ if (instr->hydrogen()->RequiresHoleCheck()) { |
+ int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
+ sizeof(kHoleNanLower32); |
+ Operand hole_check_operand = BuildFastArrayOperand( |
+ instr->elements(), |
+ instr->key(), |
+ FAST_DOUBLE_ELEMENTS, |
+ offset, |
+ instr->additional_index()); |
+ __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
+ DeoptimizeIf(equal, instr->environment()); |
+ } |
Operand double_load_operand = BuildFastArrayOperand( |
instr->elements(), |
@@ -2501,8 +2505,11 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
case EXTERNAL_FLOAT_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
case FAST_ELEMENTS: |
- case FAST_SMI_ONLY_ELEMENTS: |
+ case FAST_SMI_ELEMENTS: |
case FAST_DOUBLE_ELEMENTS: |
+ case FAST_HOLEY_ELEMENTS: |
+ case FAST_HOLEY_SMI_ELEMENTS: |
+ case FAST_HOLEY_DOUBLE_ELEMENTS: |
case DICTIONARY_ELEMENTS: |
case NON_STRICT_ARGUMENTS_ELEMENTS: |
UNREACHABLE(); |
@@ -3403,8 +3410,11 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
case EXTERNAL_FLOAT_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
case FAST_ELEMENTS: |
- case FAST_SMI_ONLY_ELEMENTS: |
+ case FAST_SMI_ELEMENTS: |
case FAST_DOUBLE_ELEMENTS: |
+ case FAST_HOLEY_ELEMENTS: |
+ case FAST_HOLEY_SMI_ELEMENTS: |
+ case FAST_HOLEY_DOUBLE_ELEMENTS: |
case DICTIONARY_ELEMENTS: |
case NON_STRICT_ARGUMENTS_ELEMENTS: |
UNREACHABLE(); |
@@ -3539,21 +3549,22 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
__ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); |
__ j(not_equal, ¬_applicable); |
__ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); |
- if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { |
+ if (IsSimpleMapChangeTransition(from_kind, to_kind)) { |
__ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); |
// Write barrier. |
ASSERT_NE(instr->temp_reg(), NULL); |
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, |
ToRegister(instr->temp_reg()), kDontSaveFPRegs); |
- } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && |
- to_kind == FAST_DOUBLE_ELEMENTS) { |
+ } else if (IsFastSmiElementsKind(from_kind) && |
+ IsFastDoubleElementsKind(to_kind)) { |
Register fixed_object_reg = ToRegister(instr->temp_reg()); |
ASSERT(fixed_object_reg.is(rdx)); |
ASSERT(new_map_reg.is(rbx)); |
__ movq(fixed_object_reg, object_reg); |
CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), |
RelocInfo::CODE_TARGET, instr); |
- } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { |
+ } else if (IsFastDoubleElementsKind(from_kind) && |
+ IsFastObjectElementsKind(to_kind)) { |
Register fixed_object_reg = ToRegister(instr->temp_reg()); |
ASSERT(fixed_object_reg.is(rdx)); |
ASSERT(new_map_reg.is(rbx)); |
@@ -4227,8 +4238,9 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
// Deopt if the array literal boilerplate ElementsKind is of a type different |
// than the expected one. The check isn't necessary if the boilerplate has |
- // already been converted to FAST_ELEMENTS. |
- if (boilerplate_elements_kind != FAST_ELEMENTS) { |
+ // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
+ if (CanTransitionToMoreGeneralFastElementsKind( |
+ boilerplate_elements_kind, true)) { |
__ LoadHeapObject(rax, instr->hydrogen()->boilerplate_object()); |
__ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); |
// Load the map's "bit field 2". |
@@ -4374,10 +4386,11 @@ void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
ElementsKind boilerplate_elements_kind = |
instr->hydrogen()->boilerplate()->GetElementsKind(); |
- // Deopt if the literal boilerplate ElementsKind is of a type different than |
- // the expected one. The check isn't necessary if the boilerplate has already |
- // been converted to FAST_ELEMENTS. |
- if (boilerplate_elements_kind != FAST_ELEMENTS) { |
+ // Deopt if the array literal boilerplate ElementsKind is of a type different |
+ // than the expected one. The check isn't necessary if the boilerplate has |
+ // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
+ if (CanTransitionToMoreGeneralFastElementsKind( |
+ boilerplate_elements_kind, true)) { |
__ LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); |
__ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset)); |
// Load the map's "bit field 2". |