Chromium Code Reviews| Index: src/x64/lithium-codegen-x64.cc |
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
| index 5f5c2af3a45851bd73fcce8cfa3bbe603f8f488c..190df5fd02e068bf44d79ffe7da7d5a9a5d063e9 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)); |
| @@ -2387,15 +2389,17 @@ 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); |
| - __ 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); |
| + __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
| + DeoptimizeIf(equal, instr->environment()); |
| + } |
| Operand double_load_operand = BuildFastArrayOperand( |
| instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, |
| @@ -2467,8 +2471,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(); |
| @@ -3358,8 +3365,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(); |
| @@ -3484,21 +3494,25 @@ 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) { |
| + bool simple_map_change = (GetHoleyElementsKind(from_kind) == to_kind) || |
| + (IsFastSmiElementsKind(from_kind) && |
| + IsFastObjectElementsKind(to_kind)); |
| + if (simple_map_change) { |
| __ 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) && |
| + IsFastElementsKind(to_kind)) { |
|
Jakob Kummerow
2012/05/22 17:36:49
IsFastObjectElementsKind(to_kind) ?
danno
2012/05/23 14:25:36
Done.
|
| Register fixed_object_reg = ToRegister(instr->temp_reg()); |
| ASSERT(fixed_object_reg.is(rdx)); |
| ASSERT(new_map_reg.is(rbx)); |
| @@ -4172,8 +4186,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". |
| @@ -4319,10 +4334,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 FAST_ELEMENTS. |
|
Jakob Kummerow
2012/05/22 17:36:49
nit: s/FAST_ELEMENTS/TERMINAL_FAST_ELEMENTS_KIND/
danno
2012/05/23 14:25:36
Done.
|
| + if (CanTransitionToMoreGeneralFastElementsKind( |
| + boilerplate_elements_kind, true)) { |
| __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); |
| __ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset)); |
| // Load the map's "bit field 2". |