| 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 |