| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 053bcb642431a50897839f3244f8cde95ea7a453..2397ca70ca99efb46e543b3ed11ab41df5810f90 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -2384,6 +2384,8 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
|
| __ shr(temp, Map::kElementsKindShift);
|
| __ cmp(temp, FAST_ELEMENTS);
|
| __ j(equal, &ok, Label::kNear);
|
| + __ cmp(temp, FAST_HOLEY_ELEMENTS);
|
| + __ j(equal, &ok, Label::kNear);
|
| __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
|
| __ j(less, &fail, Label::kNear);
|
| __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND);
|
| @@ -2442,14 +2444,16 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
|
| LLoadKeyedFastDoubleElement* instr) {
|
| XMMRegister result = ToDoubleRegister(instr->result());
|
|
|
| - int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
|
| - sizeof(kHoleNanLower32);
|
| - Operand hole_check_operand = BuildFastArrayOperand(
|
| - instr->elements(), instr->key(),
|
| - FAST_DOUBLE_ELEMENTS,
|
| - offset);
|
| - __ cmp(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);
|
| + __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
|
| + DeoptimizeIf(equal, instr->environment());
|
| + }
|
|
|
| Operand double_load_operand = BuildFastArrayOperand(
|
| instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
|
| @@ -2519,9 +2523,12 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
| break;
|
| case EXTERNAL_FLOAT_ELEMENTS:
|
| case EXTERNAL_DOUBLE_ELEMENTS:
|
| - case FAST_SMI_ONLY_ELEMENTS:
|
| + case FAST_SMI_ELEMENTS:
|
| case FAST_ELEMENTS:
|
| case FAST_DOUBLE_ELEMENTS:
|
| + case FAST_HOLEY_SMI_ELEMENTS:
|
| + case FAST_HOLEY_ELEMENTS:
|
| + case FAST_HOLEY_DOUBLE_ELEMENTS:
|
| case DICTIONARY_ELEMENTS:
|
| case NON_STRICT_ARGUMENTS_ELEMENTS:
|
| UNREACHABLE();
|
| @@ -3444,9 +3451,12 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
|
| break;
|
| case EXTERNAL_FLOAT_ELEMENTS:
|
| case EXTERNAL_DOUBLE_ELEMENTS:
|
| - case FAST_SMI_ONLY_ELEMENTS:
|
| + case FAST_SMI_ELEMENTS:
|
| case FAST_ELEMENTS:
|
| case FAST_DOUBLE_ELEMENTS:
|
| + case FAST_HOLEY_SMI_ELEMENTS:
|
| + case FAST_HOLEY_ELEMENTS:
|
| + case FAST_HOLEY_DOUBLE_ELEMENTS:
|
| case DICTIONARY_ELEMENTS:
|
| case NON_STRICT_ARGUMENTS_ELEMENTS:
|
| UNREACHABLE();
|
| @@ -3524,7 +3534,6 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
|
| ASSERT(ToRegister(instr->object()).is(edx));
|
| ASSERT(ToRegister(instr->key()).is(ecx));
|
| ASSERT(ToRegister(instr->value()).is(eax));
|
| -
|
| Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
|
| ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
| : isolate()->builtins()->KeyedStoreIC_Initialize();
|
| @@ -3545,22 +3554,26 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
|
| __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
|
| __ j(not_equal, ¬_applicable);
|
| __ mov(new_map_reg, to_map);
|
| - if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) {
|
| + bool simple_map_change = (GetHoleyElementsKind(from_kind) == to_kind) ||
|
| + (IsFastSmiElementsKind(from_kind) &&
|
| + IsFastObjectElementsKind(to_kind));
|
| + if (simple_map_change) {
|
| Register object_reg = ToRegister(instr->object());
|
| __ mov(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(edx));
|
| ASSERT(new_map_reg.is(ebx));
|
| __ 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) &&
|
| + IsFastElementsKind(to_kind)) {
|
| Register fixed_object_reg = ToRegister(instr->temp_reg());
|
| ASSERT(fixed_object_reg.is(edx));
|
| ASSERT(new_map_reg.is(ebx));
|
| @@ -4420,8 +4433,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(eax, instr->hydrogen()->boilerplate_object());
|
| __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
| // Load the map's "bit field 2". We only need the first byte,
|
|
|