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

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: Platforms ports and 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
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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2778 Operand operand = key_is_constant 2780 Operand operand = key_is_constant
2779 ? Operand(constant_key * (1 << shift_size) + 2781 ? Operand(constant_key * (1 << shift_size) +
2780 FixedDoubleArray::kHeaderSize - kHeapObjectTag) 2782 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
2781 : Operand(key, LSL, shift_size); 2783 : Operand(key, LSL, shift_size);
2782 __ add(elements, elements, operand); 2784 __ add(elements, elements, operand);
2783 if (!key_is_constant) { 2785 if (!key_is_constant) {
2784 __ add(elements, elements, 2786 __ add(elements, elements,
2785 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 2787 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
2786 } 2788 }
2787 2789
2788 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 2790 if (instr->hydrogen()->RequiresHoleCheck()) {
2789 __ cmp(scratch, Operand(kHoleNanUpper32)); 2791 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2790 DeoptimizeIf(eq, instr->environment()); 2792 __ cmp(scratch, Operand(kHoleNanUpper32));
2793 DeoptimizeIf(eq, instr->environment());
2794 }
2791 2795
2792 __ vldr(result, elements, 0); 2796 __ vldr(result, elements, 0);
2793 } 2797 }
2794 2798
2795 2799
2796 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2800 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2797 LLoadKeyedSpecializedArrayElement* instr) { 2801 LLoadKeyedSpecializedArrayElement* instr) {
2798 Register external_pointer = ToRegister(instr->external_pointer()); 2802 Register external_pointer = ToRegister(instr->external_pointer());
2799 Register key = no_reg; 2803 Register key = no_reg;
2800 ElementsKind elements_kind = instr->elements_kind(); 2804 ElementsKind elements_kind = instr->elements_kind();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2849 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2853 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2850 __ ldr(result, mem_operand); 2854 __ ldr(result, mem_operand);
2851 __ cmp(result, Operand(0x80000000)); 2855 __ cmp(result, Operand(0x80000000));
2852 // TODO(danno): we could be more clever here, perhaps having a special 2856 // TODO(danno): we could be more clever here, perhaps having a special
2853 // version of the stub that detects if the overflow case actually 2857 // version of the stub that detects if the overflow case actually
2854 // happens, and generate code that returns a double rather than int. 2858 // happens, and generate code that returns a double rather than int.
2855 DeoptimizeIf(cs, instr->environment()); 2859 DeoptimizeIf(cs, instr->environment());
2856 break; 2860 break;
2857 case EXTERNAL_FLOAT_ELEMENTS: 2861 case EXTERNAL_FLOAT_ELEMENTS:
2858 case EXTERNAL_DOUBLE_ELEMENTS: 2862 case EXTERNAL_DOUBLE_ELEMENTS:
2863 case FAST_HOLEY_DOUBLE_ELEMENTS:
2864 case FAST_HOLEY_ELEMENTS:
2865 case FAST_HOLEY_SMI_ELEMENTS:
2859 case FAST_DOUBLE_ELEMENTS: 2866 case FAST_DOUBLE_ELEMENTS:
2860 case FAST_ELEMENTS: 2867 case FAST_ELEMENTS:
2861 case FAST_SMI_ONLY_ELEMENTS: 2868 case FAST_SMI_ELEMENTS:
2862 case DICTIONARY_ELEMENTS: 2869 case DICTIONARY_ELEMENTS:
2863 case NON_STRICT_ARGUMENTS_ELEMENTS: 2870 case NON_STRICT_ARGUMENTS_ELEMENTS:
2864 UNREACHABLE(); 2871 UNREACHABLE();
2865 break; 2872 break;
2866 } 2873 }
2867 } 2874 }
2868 } 2875 }
2869 2876
2870 2877
2871 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2878 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
3840 __ strh(value, mem_operand); 3847 __ strh(value, mem_operand);
3841 break; 3848 break;
3842 case EXTERNAL_INT_ELEMENTS: 3849 case EXTERNAL_INT_ELEMENTS:
3843 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3850 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3844 __ str(value, mem_operand); 3851 __ str(value, mem_operand);
3845 break; 3852 break;
3846 case EXTERNAL_FLOAT_ELEMENTS: 3853 case EXTERNAL_FLOAT_ELEMENTS:
3847 case EXTERNAL_DOUBLE_ELEMENTS: 3854 case EXTERNAL_DOUBLE_ELEMENTS:
3848 case FAST_DOUBLE_ELEMENTS: 3855 case FAST_DOUBLE_ELEMENTS:
3849 case FAST_ELEMENTS: 3856 case FAST_ELEMENTS:
3850 case FAST_SMI_ONLY_ELEMENTS: 3857 case FAST_SMI_ELEMENTS:
3858 case FAST_HOLEY_DOUBLE_ELEMENTS:
3859 case FAST_HOLEY_ELEMENTS:
3860 case FAST_HOLEY_SMI_ELEMENTS:
3851 case DICTIONARY_ELEMENTS: 3861 case DICTIONARY_ELEMENTS:
3852 case NON_STRICT_ARGUMENTS_ELEMENTS: 3862 case NON_STRICT_ARGUMENTS_ELEMENTS:
3853 UNREACHABLE(); 3863 UNREACHABLE();
3854 break; 3864 break;
3855 } 3865 }
3856 } 3866 }
3857 } 3867 }
3858 3868
3859 3869
3860 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3870 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
(...skipping 16 matching lines...) Expand all
3877 Handle<Map> from_map = instr->original_map(); 3887 Handle<Map> from_map = instr->original_map();
3878 Handle<Map> to_map = instr->transitioned_map(); 3888 Handle<Map> to_map = instr->transitioned_map();
3879 ElementsKind from_kind = from_map->elements_kind(); 3889 ElementsKind from_kind = from_map->elements_kind();
3880 ElementsKind to_kind = to_map->elements_kind(); 3890 ElementsKind to_kind = to_map->elements_kind();
3881 3891
3882 Label not_applicable; 3892 Label not_applicable;
3883 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 3893 __ ldr(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset));
3884 __ cmp(scratch, Operand(from_map)); 3894 __ cmp(scratch, Operand(from_map));
3885 __ b(ne, &not_applicable); 3895 __ b(ne, &not_applicable);
3886 __ mov(new_map_reg, Operand(to_map)); 3896 __ mov(new_map_reg, Operand(to_map));
3887 if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { 3897
3898 bool simple_map_change = (GetHoleyElementsKind(from_kind) == to_kind) ||
3899 (IsFastSmiElementsKind(from_kind) &&
3900 IsFastObjectElementsKind(to_kind));
3901 if (simple_map_change) {
3888 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 3902 __ str(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
3889 // Write barrier. 3903 // Write barrier.
3890 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3904 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3891 scratch, kLRHasBeenSaved, kDontSaveFPRegs); 3905 scratch, kLRHasBeenSaved, kDontSaveFPRegs);
3892 } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && 3906 } else if (IsFastSmiElementsKind(from_kind) &&
3893 to_kind == FAST_DOUBLE_ELEMENTS) { 3907 IsFastDoubleElementsKind(to_kind)) {
3894 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3908 Register fixed_object_reg = ToRegister(instr->temp_reg());
3895 ASSERT(fixed_object_reg.is(r2)); 3909 ASSERT(fixed_object_reg.is(r2));
3896 ASSERT(new_map_reg.is(r3)); 3910 ASSERT(new_map_reg.is(r3));
3897 __ mov(fixed_object_reg, object_reg); 3911 __ mov(fixed_object_reg, object_reg);
3898 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3912 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3899 RelocInfo::CODE_TARGET, instr); 3913 RelocInfo::CODE_TARGET, instr);
3900 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 3914 } else if (IsFastDoubleElementsKind(from_kind) &&
3915 IsFastElementsKind(to_kind)) {
Jakob Kummerow 2012/05/22 17:36:49 IsFastObjectElementsKind(to_kind) ?
danno 2012/05/23 14:25:36 Done.
3901 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3916 Register fixed_object_reg = ToRegister(instr->temp_reg());
3902 ASSERT(fixed_object_reg.is(r2)); 3917 ASSERT(fixed_object_reg.is(r2));
3903 ASSERT(new_map_reg.is(r3)); 3918 ASSERT(new_map_reg.is(r3));
3904 __ mov(fixed_object_reg, object_reg); 3919 __ mov(fixed_object_reg, object_reg);
3905 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3920 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3906 RelocInfo::CODE_TARGET, instr); 3921 RelocInfo::CODE_TARGET, instr);
3907 } else { 3922 } else {
3908 UNREACHABLE(); 3923 UNREACHABLE();
3909 } 3924 }
3910 __ bind(&not_applicable); 3925 __ bind(&not_applicable);
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
4664 } 4679 }
4665 4680
4666 4681
4667 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4682 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4668 Heap* heap = isolate()->heap(); 4683 Heap* heap = isolate()->heap();
4669 ElementsKind boilerplate_elements_kind = 4684 ElementsKind boilerplate_elements_kind =
4670 instr->hydrogen()->boilerplate_elements_kind(); 4685 instr->hydrogen()->boilerplate_elements_kind();
4671 4686
4672 // Deopt if the array literal boilerplate ElementsKind is of a type different 4687 // Deopt if the array literal boilerplate ElementsKind is of a type different
4673 // than the expected one. The check isn't necessary if the boilerplate has 4688 // than the expected one. The check isn't necessary if the boilerplate has
4674 // already been converted to FAST_ELEMENTS. 4689 // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4675 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4690 if (CanTransitionToMoreGeneralFastElementsKind(
4691 boilerplate_elements_kind, true)) {
4676 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate_object()); 4692 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate_object());
4677 // Load map into r2. 4693 // Load map into r2.
4678 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 4694 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
4679 // Load the map's "bit field 2". 4695 // Load the map's "bit field 2".
4680 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); 4696 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset));
4681 // Retrieve elements_kind from bit field 2. 4697 // Retrieve elements_kind from bit field 2.
4682 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); 4698 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount);
4683 __ cmp(r2, Operand(boilerplate_elements_kind)); 4699 __ cmp(r2, Operand(boilerplate_elements_kind));
4684 DeoptimizeIf(ne, instr->environment()); 4700 DeoptimizeIf(ne, instr->environment());
4685 } 4701 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 } 4832 }
4817 } 4833 }
4818 } 4834 }
4819 4835
4820 4836
4821 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { 4837 void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
4822 int size = instr->hydrogen()->total_size(); 4838 int size = instr->hydrogen()->total_size();
4823 ElementsKind boilerplate_elements_kind = 4839 ElementsKind boilerplate_elements_kind =
4824 instr->hydrogen()->boilerplate()->GetElementsKind(); 4840 instr->hydrogen()->boilerplate()->GetElementsKind();
4825 4841
4826 // Deopt if the literal boilerplate ElementsKind is of a type different than 4842 // Deopt if the array literal boilerplate ElementsKind is of a type different
4827 // the expected one. The check isn't necessary if the boilerplate has already 4843 // than the expected one. The check isn't necessary if the boilerplate has
4828 // been converted to FAST_ELEMENTS. 4844 // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4829 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4845 if (CanTransitionToMoreGeneralFastElementsKind(
4846 boilerplate_elements_kind, true)) {
4830 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate()); 4847 __ LoadHeapObject(r1, instr->hydrogen()->boilerplate());
4831 // Load map into r2. 4848 // Load map into r2.
4832 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); 4849 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
4833 // Load the map's "bit field 2". 4850 // Load the map's "bit field 2".
4834 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset)); 4851 __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset));
4835 // Retrieve elements_kind from bit field 2. 4852 // Retrieve elements_kind from bit field 2.
4836 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount); 4853 __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount);
4837 __ cmp(r2, Operand(boilerplate_elements_kind)); 4854 __ cmp(r2, Operand(boilerplate_elements_kind));
4838 DeoptimizeIf(ne, instr->environment()); 4855 DeoptimizeIf(ne, instr->environment());
4839 } 4856 }
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
5307 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5324 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5308 __ ldr(result, FieldMemOperand(scratch, 5325 __ ldr(result, FieldMemOperand(scratch,
5309 FixedArray::kHeaderSize - kPointerSize)); 5326 FixedArray::kHeaderSize - kPointerSize));
5310 __ bind(&done); 5327 __ bind(&done);
5311 } 5328 }
5312 5329
5313 5330
5314 #undef __ 5331 #undef __
5315 5332
5316 } } // namespace v8::internal 5333 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | src/codegen.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698