Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index d224d24e5c4d8da8eaa8902199688776f06540f3..fd4b3e84085509a352f9f3fed4805585bfcb0549 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.cc |
@@ -2696,8 +2696,10 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) { |
__ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); |
__ ubfx(scratch, scratch, Map::kElementsKindShift, |
Map::kElementsKindBitCount); |
- __ cmp(scratch, Operand(FAST_ELEMENTS)); |
- __ b(eq, &done); |
+ __ cmp(scratch, Operand(GetInitialFastElementsKind())); |
+ __ b(lt, &fail); |
+ __ cmp(scratch, Operand(TERMINAL_FAST_ELEMENTS_KIND)); |
+ __ b(le, &done); |
__ cmp(scratch, Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
__ b(lt, &fail); |
__ cmp(scratch, Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
@@ -2788,9 +2790,11 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( |
(instr->additional_index() << shift_size))); |
} |
- __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
- __ cmp(scratch, Operand(kHoleNanUpper32)); |
- DeoptimizeIf(eq, instr->environment()); |
+ if (instr->hydrogen()->RequiresHoleCheck()) { |
+ __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
+ __ cmp(scratch, Operand(kHoleNanUpper32)); |
+ DeoptimizeIf(eq, instr->environment()); |
+ } |
__ vldr(result, elements, 0); |
} |
@@ -2866,9 +2870,12 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
break; |
case EXTERNAL_FLOAT_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
+ case FAST_HOLEY_DOUBLE_ELEMENTS: |
+ case FAST_HOLEY_ELEMENTS: |
+ case FAST_HOLEY_SMI_ELEMENTS: |
case FAST_DOUBLE_ELEMENTS: |
case FAST_ELEMENTS: |
- case FAST_SMI_ONLY_ELEMENTS: |
+ case FAST_SMI_ELEMENTS: |
case DICTIONARY_ELEMENTS: |
case NON_STRICT_ARGUMENTS_ELEMENTS: |
UNREACHABLE(); |
@@ -3871,7 +3878,10 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
case EXTERNAL_DOUBLE_ELEMENTS: |
case FAST_DOUBLE_ELEMENTS: |
case FAST_ELEMENTS: |
- case FAST_SMI_ONLY_ELEMENTS: |
+ case FAST_SMI_ELEMENTS: |
+ case FAST_HOLEY_DOUBLE_ELEMENTS: |
+ case FAST_HOLEY_ELEMENTS: |
+ case FAST_HOLEY_SMI_ELEMENTS: |
case DICTIONARY_ELEMENTS: |
case NON_STRICT_ARGUMENTS_ELEMENTS: |
UNREACHABLE(); |
@@ -3908,20 +3918,22 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
__ cmp(scratch, Operand(from_map)); |
__ b(ne, ¬_applicable); |
__ mov(new_map_reg, Operand(to_map)); |
- if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { |
+ |
+ if (IsSimpleMapChangeTransition(from_kind, to_kind)) { |
__ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); |
// Write barrier. |
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, |
scratch, kLRHasBeenSaved, 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(r2)); |
ASSERT(new_map_reg.is(r3)); |
__ mov(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(r2)); |
ASSERT(new_map_reg.is(r3)); |
@@ -4695,8 +4707,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(r1, instr->hydrogen()->boilerplate_object()); |
// Load map into r2. |
__ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
@@ -4847,10 +4860,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(r1, instr->hydrogen()->boilerplate()); |
// Load map into r2. |
__ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |