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