Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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, &not_applicable); 3919 __ b(ne, &not_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(&not_applicable); 3946 __ bind(&not_applicable);
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698