OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2689 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); | 2689 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
2690 __ cmp(scratch, ip); | 2690 __ cmp(scratch, ip); |
2691 __ b(eq, &done); | 2691 __ b(eq, &done); |
2692 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); | 2692 __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); |
2693 __ cmp(scratch, ip); | 2693 __ cmp(scratch, ip); |
2694 __ b(eq, &done); | 2694 __ b(eq, &done); |
2695 // |scratch| still contains |input|'s map. | 2695 // |scratch| still contains |input|'s map. |
2696 __ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); | 2696 __ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); |
2697 __ ubfx(scratch, scratch, Map::kElementsKindShift, | 2697 __ ubfx(scratch, scratch, Map::kElementsKindShift, |
2698 Map::kElementsKindBitCount); | 2698 Map::kElementsKindBitCount); |
2699 __ cmp(scratch, Operand(FAST_ELEMENTS)); | 2699 __ cmp(scratch, Operand(GetInitialFastElementsKind())); |
2700 __ b(eq, &done); | 2700 __ b(lt, &fail); |
| 2701 __ cmp(scratch, Operand(TERMINAL_FAST_ELEMENTS_KIND)); |
| 2702 __ b(le, &done); |
2701 __ cmp(scratch, Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); | 2703 __ cmp(scratch, Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
2702 __ b(lt, &fail); | 2704 __ b(lt, &fail); |
2703 __ cmp(scratch, Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); | 2705 __ cmp(scratch, Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); |
2704 __ b(le, &done); | 2706 __ b(le, &done); |
2705 __ bind(&fail); | 2707 __ bind(&fail); |
2706 __ Abort("Check for fast or external elements failed."); | 2708 __ Abort("Check for fast or external elements failed."); |
2707 __ bind(&done); | 2709 __ bind(&done); |
2708 } | 2710 } |
2709 } | 2711 } |
2710 | 2712 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2781 ? Operand(((constant_key + instr->additional_index()) << shift_size) + | 2783 ? Operand(((constant_key + instr->additional_index()) << shift_size) + |
2782 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | 2784 FixedDoubleArray::kHeaderSize - kHeapObjectTag) |
2783 : Operand(key, LSL, shift_size); | 2785 : Operand(key, LSL, shift_size); |
2784 __ add(elements, elements, operand); | 2786 __ add(elements, elements, operand); |
2785 if (!key_is_constant) { | 2787 if (!key_is_constant) { |
2786 __ add(elements, elements, | 2788 __ add(elements, elements, |
2787 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 2789 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
2788 (instr->additional_index() << shift_size))); | 2790 (instr->additional_index() << shift_size))); |
2789 } | 2791 } |
2790 | 2792 |
2791 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 2793 if (instr->hydrogen()->RequiresHoleCheck()) { |
2792 __ cmp(scratch, Operand(kHoleNanUpper32)); | 2794 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
2793 DeoptimizeIf(eq, instr->environment()); | 2795 __ cmp(scratch, Operand(kHoleNanUpper32)); |
| 2796 DeoptimizeIf(eq, instr->environment()); |
| 2797 } |
2794 | 2798 |
2795 __ vldr(result, elements, 0); | 2799 __ vldr(result, elements, 0); |
2796 } | 2800 } |
2797 | 2801 |
2798 | 2802 |
2799 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2803 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2800 LLoadKeyedSpecializedArrayElement* instr) { | 2804 LLoadKeyedSpecializedArrayElement* instr) { |
2801 Register external_pointer = ToRegister(instr->external_pointer()); | 2805 Register external_pointer = ToRegister(instr->external_pointer()); |
2802 Register key = no_reg; | 2806 Register key = no_reg; |
2803 ElementsKind elements_kind = instr->elements_kind(); | 2807 ElementsKind elements_kind = instr->elements_kind(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2859 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2863 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
2860 __ ldr(result, mem_operand); | 2864 __ ldr(result, mem_operand); |
2861 __ cmp(result, Operand(0x80000000)); | 2865 __ cmp(result, Operand(0x80000000)); |
2862 // TODO(danno): we could be more clever here, perhaps having a special | 2866 // TODO(danno): we could be more clever here, perhaps having a special |
2863 // version of the stub that detects if the overflow case actually | 2867 // version of the stub that detects if the overflow case actually |
2864 // happens, and generate code that returns a double rather than int. | 2868 // happens, and generate code that returns a double rather than int. |
2865 DeoptimizeIf(cs, instr->environment()); | 2869 DeoptimizeIf(cs, instr->environment()); |
2866 break; | 2870 break; |
2867 case EXTERNAL_FLOAT_ELEMENTS: | 2871 case EXTERNAL_FLOAT_ELEMENTS: |
2868 case EXTERNAL_DOUBLE_ELEMENTS: | 2872 case EXTERNAL_DOUBLE_ELEMENTS: |
| 2873 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 2874 case FAST_HOLEY_ELEMENTS: |
| 2875 case FAST_HOLEY_SMI_ELEMENTS: |
2869 case FAST_DOUBLE_ELEMENTS: | 2876 case FAST_DOUBLE_ELEMENTS: |
2870 case FAST_ELEMENTS: | 2877 case FAST_ELEMENTS: |
2871 case FAST_SMI_ONLY_ELEMENTS: | 2878 case FAST_SMI_ELEMENTS: |
2872 case DICTIONARY_ELEMENTS: | 2879 case DICTIONARY_ELEMENTS: |
2873 case NON_STRICT_ARGUMENTS_ELEMENTS: | 2880 case NON_STRICT_ARGUMENTS_ELEMENTS: |
2874 UNREACHABLE(); | 2881 UNREACHABLE(); |
2875 break; | 2882 break; |
2876 } | 2883 } |
2877 } | 2884 } |
2878 } | 2885 } |
2879 | 2886 |
2880 | 2887 |
2881 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2888 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3864 __ strh(value, mem_operand); | 3871 __ strh(value, mem_operand); |
3865 break; | 3872 break; |
3866 case EXTERNAL_INT_ELEMENTS: | 3873 case EXTERNAL_INT_ELEMENTS: |
3867 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3874 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3868 __ str(value, mem_operand); | 3875 __ str(value, mem_operand); |
3869 break; | 3876 break; |
3870 case EXTERNAL_FLOAT_ELEMENTS: | 3877 case EXTERNAL_FLOAT_ELEMENTS: |
3871 case EXTERNAL_DOUBLE_ELEMENTS: | 3878 case EXTERNAL_DOUBLE_ELEMENTS: |
3872 case FAST_DOUBLE_ELEMENTS: | 3879 case FAST_DOUBLE_ELEMENTS: |
3873 case FAST_ELEMENTS: | 3880 case FAST_ELEMENTS: |
3874 case FAST_SMI_ONLY_ELEMENTS: | 3881 case FAST_SMI_ELEMENTS: |
| 3882 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 3883 case FAST_HOLEY_ELEMENTS: |
| 3884 case FAST_HOLEY_SMI_ELEMENTS: |
3875 case DICTIONARY_ELEMENTS: | 3885 case DICTIONARY_ELEMENTS: |
3876 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3886 case NON_STRICT_ARGUMENTS_ELEMENTS: |
3877 UNREACHABLE(); | 3887 UNREACHABLE(); |
3878 break; | 3888 break; |
3879 } | 3889 } |
3880 } | 3890 } |
3881 } | 3891 } |
3882 | 3892 |
3883 | 3893 |
3884 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 3894 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
(...skipping 16 matching lines...) Expand all Loading... |
3901 Handle<Map> from_map = instr->original_map(); | 3911 Handle<Map> from_map = instr->original_map(); |
3902 Handle<Map> to_map = instr->transitioned_map(); | 3912 Handle<Map> to_map = instr->transitioned_map(); |
3903 ElementsKind from_kind = from_map->elements_kind(); | 3913 ElementsKind from_kind = from_map->elements_kind(); |
3904 ElementsKind to_kind = to_map->elements_kind(); | 3914 ElementsKind to_kind = to_map->elements_kind(); |
3905 | 3915 |
3906 Label not_applicable; | 3916 Label not_applicable; |
3907 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); | 3917 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); |
3908 __ cmp(scratch, Operand(from_map)); | 3918 __ cmp(scratch, Operand(from_map)); |
3909 __ b(ne, ¬_applicable); | 3919 __ b(ne, ¬_applicable); |
3910 __ mov(new_map_reg, Operand(to_map)); | 3920 __ mov(new_map_reg, Operand(to_map)); |
3911 if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { | 3921 |
| 3922 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { |
3912 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); | 3923 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); |
3913 // Write barrier. | 3924 // Write barrier. |
3914 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, | 3925 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, |
3915 scratch, kLRHasBeenSaved, kDontSaveFPRegs); | 3926 scratch, kLRHasBeenSaved, kDontSaveFPRegs); |
3916 } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && | 3927 } else if (IsFastSmiElementsKind(from_kind) && |
3917 to_kind == FAST_DOUBLE_ELEMENTS) { | 3928 IsFastDoubleElementsKind(to_kind)) { |
3918 Register fixed_object_reg = ToRegister(instr->temp_reg()); | 3929 Register fixed_object_reg = ToRegister(instr->temp_reg()); |
3919 ASSERT(fixed_object_reg.is(r2)); | 3930 ASSERT(fixed_object_reg.is(r2)); |
3920 ASSERT(new_map_reg.is(r3)); | 3931 ASSERT(new_map_reg.is(r3)); |
3921 __ mov(fixed_object_reg, object_reg); | 3932 __ mov(fixed_object_reg, object_reg); |
3922 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), | 3933 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), |
3923 RelocInfo::CODE_TARGET, instr); | 3934 RelocInfo::CODE_TARGET, instr); |
3924 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { | 3935 } else if (IsFastDoubleElementsKind(from_kind) && |
| 3936 IsFastObjectElementsKind(to_kind)) { |
3925 Register fixed_object_reg = ToRegister(instr->temp_reg()); | 3937 Register fixed_object_reg = ToRegister(instr->temp_reg()); |
3926 ASSERT(fixed_object_reg.is(r2)); | 3938 ASSERT(fixed_object_reg.is(r2)); |
3927 ASSERT(new_map_reg.is(r3)); | 3939 ASSERT(new_map_reg.is(r3)); |
3928 __ mov(fixed_object_reg, object_reg); | 3940 __ mov(fixed_object_reg, object_reg); |
3929 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), | 3941 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), |
3930 RelocInfo::CODE_TARGET, instr); | 3942 RelocInfo::CODE_TARGET, instr); |
3931 } else { | 3943 } else { |
3932 UNREACHABLE(); | 3944 UNREACHABLE(); |
3933 } | 3945 } |
3934 __ bind(¬_applicable); | 3946 __ bind(¬_applicable); |
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4688 } | 4700 } |
4689 | 4701 |
4690 | 4702 |
4691 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 4703 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
4692 Heap* heap = isolate()->heap(); | 4704 Heap* heap = isolate()->heap(); |
4693 ElementsKind boilerplate_elements_kind = | 4705 ElementsKind boilerplate_elements_kind = |
4694 instr->hydrogen()->boilerplate_elements_kind(); | 4706 instr->hydrogen()->boilerplate_elements_kind(); |
4695 | 4707 |
4696 // Deopt if the array literal boilerplate ElementsKind is of a type different | 4708 // Deopt if the array literal boilerplate ElementsKind is of a type different |
4697 // than the expected one. The check isn't necessary if the boilerplate has | 4709 // than the expected one. The check isn't necessary if the boilerplate has |
4698 // already been converted to FAST_ELEMENTS. | 4710 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
4699 if (boilerplate_elements_kind != FAST_ELEMENTS) { | 4711 if (CanTransitionToMoreGeneralFastElementsKind( |
| 4712 boilerplate_elements_kind, true)) { |
4700 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate_object()); | 4713 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate_object()); |
4701 // Load map into r2. | 4714 // Load map into r2. |
4702 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 4715 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
4703 // Load the map's "bit field 2". | 4716 // Load the map's "bit field 2". |
4704 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); | 4717 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); |
4705 // Retrieve elements_kind from bit field 2. | 4718 // Retrieve elements_kind from bit field 2. |
4706 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); | 4719 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); |
4707 __ cmp(r2, Operand(boilerplate_elements_kind)); | 4720 __ cmp(r2, Operand(boilerplate_elements_kind)); |
4708 DeoptimizeIf(ne, instr->environment()); | 4721 DeoptimizeIf(ne, instr->environment()); |
4709 } | 4722 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4840 } | 4853 } |
4841 } | 4854 } |
4842 } | 4855 } |
4843 | 4856 |
4844 | 4857 |
4845 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { | 4858 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { |
4846 int size = instr->hydrogen()->total_size(); | 4859 int size = instr->hydrogen()->total_size(); |
4847 ElementsKind boilerplate_elements_kind = | 4860 ElementsKind boilerplate_elements_kind = |
4848 instr->hydrogen()->boilerplate()->GetElementsKind(); | 4861 instr->hydrogen()->boilerplate()->GetElementsKind(); |
4849 | 4862 |
4850 // Deopt if the literal boilerplate ElementsKind is of a type different than | 4863 // Deopt if the array literal boilerplate ElementsKind is of a type different |
4851 // the expected one. The check isn't necessary if the boilerplate has already | 4864 // than the expected one. The check isn't necessary if the boilerplate has |
4852 // been converted to FAST_ELEMENTS. | 4865 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
4853 if (boilerplate_elements_kind != FAST_ELEMENTS) { | 4866 if (CanTransitionToMoreGeneralFastElementsKind( |
| 4867 boilerplate_elements_kind, true)) { |
4854 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); | 4868 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); |
4855 // Load map into r2. | 4869 // Load map into r2. |
4856 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 4870 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
4857 // Load the map's "bit field 2". | 4871 // Load the map's "bit field 2". |
4858 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); | 4872 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); |
4859 // Retrieve elements_kind from bit field 2. | 4873 // Retrieve elements_kind from bit field 2. |
4860 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); | 4874 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); |
4861 __ cmp(r2, Operand(boilerplate_elements_kind)); | 4875 __ cmp(r2, Operand(boilerplate_elements_kind)); |
4862 DeoptimizeIf(ne, instr->environment()); | 4876 DeoptimizeIf(ne, instr->environment()); |
4863 } | 4877 } |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5331 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5345 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
5332 __ ldr(result, FieldMemOperand(scratch, | 5346 __ ldr(result, FieldMemOperand(scratch, |
5333 FixedArray::kHeaderSize - kPointerSize)); | 5347 FixedArray::kHeaderSize - kPointerSize)); |
5334 __ bind(&done); | 5348 __ bind(&done); |
5335 } | 5349 } |
5336 | 5350 |
5337 | 5351 |
5338 #undef __ | 5352 #undef __ |
5339 | 5353 |
5340 } } // namespace v8::internal | 5354 } } // namespace v8::internal |
OLD | NEW |