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

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

Issue 21063002: Out-of-line constant pool on Arm: Stage 1 - Free up r7 for use as constant pool pointer register (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix typo in comment. Created 7 years, 3 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 3940 matching lines...) Expand 10 before | Expand all | Expand 10 after
3951 __ AssertString(r0); 3951 __ AssertString(r0);
3952 3952
3953 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); 3953 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset));
3954 __ IndexFromHash(r0, r0); 3954 __ IndexFromHash(r0, r0);
3955 3955
3956 context()->Plug(r0); 3956 context()->Plug(r0);
3957 } 3957 }
3958 3958
3959 3959
3960 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { 3960 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
3961 Label bailout, done, one_char_separator, long_separator, 3961 Label bailout, done, one_char_separator, long_separator, non_trivial_array,
3962 non_trivial_array, not_size_one_array, loop, 3962 not_size_one_array, loop, empty_separator_loop, one_char_separator_loop,
3963 empty_separator_loop, one_char_separator_loop,
3964 one_char_separator_loop_entry, long_separator_loop; 3963 one_char_separator_loop_entry, long_separator_loop;
3965 ZoneList<Expression*>* args = expr->arguments(); 3964 ZoneList<Expression*>* args = expr->arguments();
3966 ASSERT(args->length() == 2); 3965 ASSERT(args->length() == 2);
3967 VisitForStackValue(args->at(1)); 3966 VisitForStackValue(args->at(1));
3968 VisitForAccumulatorValue(args->at(0)); 3967 VisitForAccumulatorValue(args->at(0));
3969 3968
3970 // All aliases of the same register have disjoint lifetimes. 3969 // All aliases of the same register have disjoint lifetimes.
3971 Register array = r0; 3970 Register array = r0;
3972 Register elements = no_reg; // Will be r0. 3971 Register elements = no_reg; // Will be r0.
3973 Register result = no_reg; // Will be r0. 3972 Register result = no_reg; // Will be r0.
3974 Register separator = r1; 3973 Register separator = r1;
3975 Register array_length = r2; 3974 Register array_length = r2;
3976 Register result_pos = no_reg; // Will be r2 3975 Register result_pos = no_reg; // Will be r2
3977 Register string_length = r3; 3976 Register string_length = r3;
3978 Register string = r4; 3977 Register string = r4;
3979 Register element = r5; 3978 Register element = r5;
3980 Register elements_end = r6; 3979 Register elements_end = r6;
3981 Register scratch1 = r7; 3980 Register scratch = r9;
3982 Register scratch2 = r9;
3983 3981
3984 // Separator operand is on the stack. 3982 // Separator operand is on the stack.
3985 __ pop(separator); 3983 __ pop(separator);
3986 3984
3987 // Check that the array is a JSArray. 3985 // Check that the array is a JSArray.
3988 __ JumpIfSmi(array, &bailout); 3986 __ JumpIfSmi(array, &bailout);
3989 __ CompareObjectType(array, scratch1, scratch2, JS_ARRAY_TYPE); 3987 __ CompareObjectType(array, scratch, array_length, JS_ARRAY_TYPE);
3990 __ b(ne, &bailout); 3988 __ b(ne, &bailout);
3991 3989
3992 // Check that the array has fast elements. 3990 // Check that the array has fast elements.
3993 __ CheckFastElements(scratch1, scratch2, &bailout); 3991 __ CheckFastElements(scratch, array_length, &bailout);
3994 3992
3995 // If the array has length zero, return the empty string. 3993 // If the array has length zero, return the empty string.
3996 __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset)); 3994 __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
3997 __ SmiUntag(array_length, SetCC); 3995 __ SmiUntag(array_length, SetCC);
3998 __ b(ne, &non_trivial_array); 3996 __ b(ne, &non_trivial_array);
3999 __ LoadRoot(r0, Heap::kempty_stringRootIndex); 3997 __ LoadRoot(r0, Heap::kempty_stringRootIndex);
4000 __ b(&done); 3998 __ b(&done);
4001 3999
4002 __ bind(&non_trivial_array); 4000 __ bind(&non_trivial_array);
4003 4001
(...skipping 16 matching lines...) Expand all
4020 // string_length: Accumulated sum of string lengths (smi). 4018 // string_length: Accumulated sum of string lengths (smi).
4021 // element: Current array element. 4019 // element: Current array element.
4022 // elements_end: Array end. 4020 // elements_end: Array end.
4023 if (generate_debug_code_) { 4021 if (generate_debug_code_) {
4024 __ cmp(array_length, Operand::Zero()); 4022 __ cmp(array_length, Operand::Zero());
4025 __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); 4023 __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin);
4026 } 4024 }
4027 __ bind(&loop); 4025 __ bind(&loop);
4028 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4026 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4029 __ JumpIfSmi(string, &bailout); 4027 __ JumpIfSmi(string, &bailout);
4030 __ ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); 4028 __ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
4031 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 4029 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4032 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); 4030 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &bailout);
4033 __ ldr(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset)); 4031 __ ldr(scratch, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
4034 __ add(string_length, string_length, Operand(scratch1), SetCC); 4032 __ add(string_length, string_length, Operand(scratch), SetCC);
4035 __ b(vs, &bailout); 4033 __ b(vs, &bailout);
4036 __ cmp(element, elements_end); 4034 __ cmp(element, elements_end);
4037 __ b(lt, &loop); 4035 __ b(lt, &loop);
4038 4036
4039 // If array_length is 1, return elements[0], a string. 4037 // If array_length is 1, return elements[0], a string.
4040 __ cmp(array_length, Operand(1)); 4038 __ cmp(array_length, Operand(1));
4041 __ b(ne, &not_size_one_array); 4039 __ b(ne, &not_size_one_array);
4042 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize)); 4040 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize));
4043 __ b(&done); 4041 __ b(&done);
4044 4042
4045 __ bind(&not_size_one_array); 4043 __ bind(&not_size_one_array);
4046 4044
4047 // Live values in registers: 4045 // Live values in registers:
4048 // separator: Separator string 4046 // separator: Separator string
4049 // array_length: Length of the array. 4047 // array_length: Length of the array.
4050 // string_length: Sum of string lengths (smi). 4048 // string_length: Sum of string lengths (smi).
4051 // elements: FixedArray of strings. 4049 // elements: FixedArray of strings.
4052 4050
4053 // Check that the separator is a flat ASCII string. 4051 // Check that the separator is a flat ASCII string.
4054 __ JumpIfSmi(separator, &bailout); 4052 __ JumpIfSmi(separator, &bailout);
4055 __ ldr(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset)); 4053 __ ldr(scratch, FieldMemOperand(separator, HeapObject::kMapOffset));
4056 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 4054 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4057 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); 4055 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &bailout);
4058 4056
4059 // Add (separator length times array_length) - separator length to the 4057 // Add (separator length times array_length) - separator length to the
4060 // string_length to get the length of the result string. array_length is not 4058 // string_length to get the length of the result string. array_length is not
4061 // smi but the other values are, so the result is a smi 4059 // smi but the other values are, so the result is a smi
4062 __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); 4060 __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
4063 __ sub(string_length, string_length, Operand(scratch1)); 4061 __ sub(string_length, string_length, Operand(scratch));
4064 __ smull(scratch2, ip, array_length, scratch1); 4062 __ smull(scratch, ip, array_length, scratch);
4065 // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are 4063 // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
4066 // zero. 4064 // zero.
4067 __ cmp(ip, Operand::Zero()); 4065 __ cmp(ip, Operand::Zero());
4068 __ b(ne, &bailout); 4066 __ b(ne, &bailout);
4069 __ tst(scratch2, Operand(0x80000000)); 4067 __ tst(scratch, Operand(0x80000000));
4070 __ b(ne, &bailout); 4068 __ b(ne, &bailout);
4071 __ add(string_length, string_length, Operand(scratch2), SetCC); 4069 __ add(string_length, string_length, Operand(scratch), SetCC);
4072 __ b(vs, &bailout); 4070 __ b(vs, &bailout);
4073 __ SmiUntag(string_length); 4071 __ SmiUntag(string_length);
4074 4072
4075 // Get first element in the array to free up the elements register to be used 4073 // Get first element in the array to free up the elements register to be used
4076 // for the result. 4074 // for the result.
4077 __ add(element, 4075 __ add(element,
4078 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4076 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4079 result = elements; // End of live range for elements. 4077 result = elements; // End of live range for elements.
4080 elements = no_reg; 4078 elements = no_reg;
4081 // Live values in registers: 4079 // Live values in registers:
4082 // element: First array element 4080 // element: First array element
4083 // separator: Separator string 4081 // separator: Separator string
4084 // string_length: Length of result string (not smi) 4082 // string_length: Length of result string (not smi)
4085 // array_length: Length of the array. 4083 // array_length: Length of the array.
4086 __ AllocateAsciiString(result, 4084 __ AllocateAsciiString(result,
4087 string_length, 4085 string_length,
4088 scratch1, 4086 scratch,
4089 scratch2, 4087 string, // used as scratch
4090 elements_end, 4088 elements_end, // used as scratch
4091 &bailout); 4089 &bailout);
4092 // Prepare for looping. Set up elements_end to end of the array. Set 4090 // Prepare for looping. Set up elements_end to end of the array. Set
4093 // result_pos to the position of the result where to write the first 4091 // result_pos to the position of the result where to write the first
4094 // character. 4092 // character.
4095 __ add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2)); 4093 __ add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
4096 result_pos = array_length; // End of live range for array_length. 4094 result_pos = array_length; // End of live range for array_length.
4097 array_length = no_reg; 4095 array_length = no_reg;
4098 __ add(result_pos, 4096 __ add(result_pos,
4099 result, 4097 result,
4100 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4098 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4101 4099
4102 // Check the length of the separator. 4100 // Check the length of the separator.
4103 __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); 4101 __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
4104 __ cmp(scratch1, Operand(Smi::FromInt(1))); 4102 __ cmp(scratch, Operand(Smi::FromInt(1)));
4105 __ b(eq, &one_char_separator); 4103 __ b(eq, &one_char_separator);
4106 __ b(gt, &long_separator); 4104 __ b(gt, &long_separator);
4107 4105
4108 // Empty separator case 4106 // Empty separator case
4109 __ bind(&empty_separator_loop); 4107 __ bind(&empty_separator_loop);
4110 // Live values in registers: 4108 // Live values in registers:
4111 // result_pos: the position to which we are currently copying characters. 4109 // result_pos: the position to which we are currently copying characters.
4112 // element: Current array element. 4110 // element: Current array element.
4113 // elements_end: Array end. 4111 // elements_end: Array end.
4114 4112
4115 // Copy next array element to the result. 4113 // Copy next array element to the result.
4116 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4114 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4117 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); 4115 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
4118 __ SmiUntag(string_length); 4116 __ SmiUntag(string_length);
4119 __ add(string, 4117 __ add(string,
4120 string, 4118 string,
4121 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4119 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4122 __ CopyBytes(string, result_pos, string_length, scratch1); 4120 __ CopyBytes(string, result_pos, string_length, scratch);
4123 __ cmp(element, elements_end); 4121 __ cmp(element, elements_end);
4124 __ b(lt, &empty_separator_loop); // End while (element < elements_end). 4122 __ b(lt, &empty_separator_loop); // End while (element < elements_end).
4125 ASSERT(result.is(r0)); 4123 ASSERT(result.is(r0));
4126 __ b(&done); 4124 __ b(&done);
4127 4125
4128 // One-character separator case 4126 // One-character separator case
4129 __ bind(&one_char_separator); 4127 __ bind(&one_char_separator);
4130 // Replace separator with its ASCII character value. 4128 // Replace separator with its ASCII character value.
4131 __ ldrb(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize)); 4129 __ ldrb(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
4132 // Jump into the loop after the code that copies the separator, so the first 4130 // Jump into the loop after the code that copies the separator, so the first
(...skipping 11 matching lines...) Expand all
4144 __ strb(separator, MemOperand(result_pos, 1, PostIndex)); 4142 __ strb(separator, MemOperand(result_pos, 1, PostIndex));
4145 4143
4146 // Copy next array element to the result. 4144 // Copy next array element to the result.
4147 __ bind(&one_char_separator_loop_entry); 4145 __ bind(&one_char_separator_loop_entry);
4148 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4146 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4149 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); 4147 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
4150 __ SmiUntag(string_length); 4148 __ SmiUntag(string_length);
4151 __ add(string, 4149 __ add(string,
4152 string, 4150 string,
4153 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4151 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4154 __ CopyBytes(string, result_pos, string_length, scratch1); 4152 __ CopyBytes(string, result_pos, string_length, scratch);
4155 __ cmp(element, elements_end); 4153 __ cmp(element, elements_end);
4156 __ b(lt, &one_char_separator_loop); // End while (element < elements_end). 4154 __ b(lt, &one_char_separator_loop); // End while (element < elements_end).
4157 ASSERT(result.is(r0)); 4155 ASSERT(result.is(r0));
4158 __ b(&done); 4156 __ b(&done);
4159 4157
4160 // Long separator case (separator is more than one character). Entry is at the 4158 // Long separator case (separator is more than one character). Entry is at the
4161 // label long_separator below. 4159 // label long_separator below.
4162 __ bind(&long_separator_loop); 4160 __ bind(&long_separator_loop);
4163 // Live values in registers: 4161 // Live values in registers:
4164 // result_pos: the position to which we are currently copying characters. 4162 // result_pos: the position to which we are currently copying characters.
4165 // element: Current array element. 4163 // element: Current array element.
4166 // elements_end: Array end. 4164 // elements_end: Array end.
4167 // separator: Separator string. 4165 // separator: Separator string.
4168 4166
4169 // Copy the separator to the result. 4167 // Copy the separator to the result.
4170 __ ldr(string_length, FieldMemOperand(separator, String::kLengthOffset)); 4168 __ ldr(string_length, FieldMemOperand(separator, String::kLengthOffset));
4171 __ SmiUntag(string_length); 4169 __ SmiUntag(string_length);
4172 __ add(string, 4170 __ add(string,
4173 separator, 4171 separator,
4174 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4172 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4175 __ CopyBytes(string, result_pos, string_length, scratch1); 4173 __ CopyBytes(string, result_pos, string_length, scratch);
4176 4174
4177 __ bind(&long_separator); 4175 __ bind(&long_separator);
4178 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4176 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4179 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); 4177 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
4180 __ SmiUntag(string_length); 4178 __ SmiUntag(string_length);
4181 __ add(string, 4179 __ add(string,
4182 string, 4180 string,
4183 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4181 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4184 __ CopyBytes(string, result_pos, string_length, scratch1); 4182 __ CopyBytes(string, result_pos, string_length, scratch);
4185 __ cmp(element, elements_end); 4183 __ cmp(element, elements_end);
4186 __ b(lt, &long_separator_loop); // End while (element < elements_end). 4184 __ b(lt, &long_separator_loop); // End while (element < elements_end).
4187 ASSERT(result.is(r0)); 4185 ASSERT(result.is(r0));
4188 __ b(&done); 4186 __ b(&done);
4189 4187
4190 __ bind(&bailout); 4188 __ bind(&bailout);
4191 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 4189 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
4192 __ bind(&done); 4190 __ bind(&done);
4193 context()->Plug(r0); 4191 context()->Plug(r0);
4194 } 4192 }
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
4884 *context_length = 0; 4882 *context_length = 0;
4885 return previous_; 4883 return previous_;
4886 } 4884 }
4887 4885
4888 4886
4889 #undef __ 4887 #undef __
4890 4888
4891 } } // namespace v8::internal 4889 } } // namespace v8::internal
4892 4890
4893 #endif // V8_TARGET_ARCH_ARM 4891 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698