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

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: Address comments. Created 7 years, 4 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 3948 matching lines...) Expand 10 before | Expand all | Expand 10 after
3959 __ AssertString(r0); 3959 __ AssertString(r0);
3960 3960
3961 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); 3961 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset));
3962 __ IndexFromHash(r0, r0); 3962 __ IndexFromHash(r0, r0);
3963 3963
3964 context()->Plug(r0); 3964 context()->Plug(r0);
3965 } 3965 }
3966 3966
3967 3967
3968 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { 3968 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) {
3969 Label bailout, done, one_char_separator, long_separator, 3969 Label bailout, pop_and_bailout, done, one_char_separator,
3970 non_trivial_array, not_size_one_array, loop, 3970 long_separator, non_trivial_array, not_size_one_array, loop,
3971 empty_separator_loop, one_char_separator_loop, 3971 empty_separator_loop, one_char_separator_loop,
3972 one_char_separator_loop_entry, long_separator_loop; 3972 one_char_separator_loop_entry, long_separator_loop;
3973 ZoneList<Expression*>* args = expr->arguments(); 3973 ZoneList<Expression*>* args = expr->arguments();
3974 ASSERT(args->length() == 2); 3974 ASSERT(args->length() == 2);
3975 VisitForStackValue(args->at(1)); 3975 VisitForStackValue(args->at(1));
3976 VisitForAccumulatorValue(args->at(0)); 3976 VisitForAccumulatorValue(args->at(0));
3977 3977
3978 // All aliases of the same register have disjoint lifetimes. 3978 // All aliases of the same register have disjoint lifetimes.
3979 Register array = r0; 3979 Register array = r0;
3980 Register elements = no_reg; // Will be r0. 3980 Register elements = no_reg; // Will be r0.
3981 Register result = no_reg; // Will be r0. 3981 Register result = no_reg; // Will be r0.
3982 Register separator = r1; 3982 Register separator = r1;
3983 Register array_length = r2; 3983 Register array_length = r2;
3984 Register result_pos = no_reg; // Will be r2 3984 Register result_pos = no_reg; // Will be r2
3985 Register string_length = r3; 3985 Register string_length = r3;
3986 Register string = r4; 3986 Register string = r4;
3987 Register element = r5; 3987 Register element = r5;
3988 Register elements_end = r6; 3988 Register elements_end = r6;
3989 Register scratch1 = r7; 3989 Register scratch = r9;
3990 Register scratch2 = r9;
3991 3990
3992 // Separator operand is on the stack. 3991 // Separator operand is on the stack.
3993 __ pop(separator); 3992 __ pop(separator);
3994 3993
3995 // Check that the array is a JSArray. 3994 // Check that the array is a JSArray.
3996 __ JumpIfSmi(array, &bailout); 3995 __ JumpIfSmi(array, &bailout);
3997 __ CompareObjectType(array, scratch1, scratch2, JS_ARRAY_TYPE); 3996 __ CompareObjectType(array, scratch, array_length, JS_ARRAY_TYPE);
3998 __ b(ne, &bailout); 3997 __ b(ne, &bailout);
3999 3998
4000 // Check that the array has fast elements. 3999 // Check that the array has fast elements.
4001 __ CheckFastElements(scratch1, scratch2, &bailout); 4000 __ CheckFastElements(scratch, array_length, &bailout);
4002 4001
4003 // If the array has length zero, return the empty string. 4002 // If the array has length zero, return the empty string.
4004 __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset)); 4003 __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
4005 __ SmiUntag(array_length, SetCC); 4004 __ SmiUntag(array_length, SetCC);
4006 __ b(ne, &non_trivial_array); 4005 __ b(ne, &non_trivial_array);
4007 __ LoadRoot(r0, Heap::kempty_stringRootIndex); 4006 __ LoadRoot(r0, Heap::kempty_stringRootIndex);
4008 __ b(&done); 4007 __ b(&done);
4009 4008
4010 __ bind(&non_trivial_array); 4009 __ bind(&non_trivial_array);
4011 4010
(...skipping 16 matching lines...) Expand all
4028 // string_length: Accumulated sum of string lengths (smi). 4027 // string_length: Accumulated sum of string lengths (smi).
4029 // element: Current array element. 4028 // element: Current array element.
4030 // elements_end: Array end. 4029 // elements_end: Array end.
4031 if (generate_debug_code_) { 4030 if (generate_debug_code_) {
4032 __ cmp(array_length, Operand::Zero()); 4031 __ cmp(array_length, Operand::Zero());
4033 __ Assert(gt, "No empty arrays here in EmitFastAsciiArrayJoin"); 4032 __ Assert(gt, "No empty arrays here in EmitFastAsciiArrayJoin");
4034 } 4033 }
4035 __ bind(&loop); 4034 __ bind(&loop);
4036 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4035 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4037 __ JumpIfSmi(string, &bailout); 4036 __ JumpIfSmi(string, &bailout);
4038 __ ldr(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); 4037 __ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
4039 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 4038 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4040 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); 4039 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &bailout);
4041 __ ldr(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset)); 4040 __ ldr(scratch, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
4042 __ add(string_length, string_length, Operand(scratch1), SetCC); 4041 __ add(string_length, string_length, Operand(scratch), SetCC);
4043 __ b(vs, &bailout); 4042 __ b(vs, &bailout);
4044 __ cmp(element, elements_end); 4043 __ cmp(element, elements_end);
4045 __ b(lt, &loop); 4044 __ b(lt, &loop);
4046 4045
4047 // If array_length is 1, return elements[0], a string. 4046 // If array_length is 1, return elements[0], a string.
4048 __ cmp(array_length, Operand(1)); 4047 __ cmp(array_length, Operand(1));
4049 __ b(ne, &not_size_one_array); 4048 __ b(ne, &not_size_one_array);
4050 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize)); 4049 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize));
4051 __ b(&done); 4050 __ b(&done);
4052 4051
4053 __ bind(&not_size_one_array); 4052 __ bind(&not_size_one_array);
4054 4053
4055 // Live values in registers: 4054 // Live values in registers:
4056 // separator: Separator string 4055 // separator: Separator string
4057 // array_length: Length of the array. 4056 // array_length: Length of the array.
4058 // string_length: Sum of string lengths (smi). 4057 // string_length: Sum of string lengths (smi).
4059 // elements: FixedArray of strings. 4058 // elements: FixedArray of strings.
4060 4059
4061 // Check that the separator is a flat ASCII string. 4060 // Check that the separator is a flat ASCII string.
4062 __ JumpIfSmi(separator, &bailout); 4061 __ JumpIfSmi(separator, &bailout);
4063 __ ldr(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset)); 4062 __ ldr(scratch, FieldMemOperand(separator, HeapObject::kMapOffset));
4064 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 4063 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
4065 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); 4064 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &bailout);
4066 4065
4067 // Add (separator length times array_length) - separator length to the 4066 // Add (separator length times array_length) - separator length to the
4068 // string_length to get the length of the result string. array_length is not 4067 // string_length to get the length of the result string. array_length is not
4069 // smi but the other values are, so the result is a smi 4068 // smi but the other values are, so the result is a smi
4070 __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); 4069 __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
4071 __ sub(string_length, string_length, Operand(scratch1)); 4070 __ sub(string_length, string_length, Operand(scratch));
4072 __ smull(scratch2, ip, array_length, scratch1); 4071 __ smull(scratch, ip, array_length, scratch);
4073 // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are 4072 // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
4074 // zero. 4073 // zero.
4075 __ cmp(ip, Operand::Zero()); 4074 __ cmp(ip, Operand::Zero());
4076 __ b(ne, &bailout); 4075 __ b(ne, &bailout);
4077 __ tst(scratch2, Operand(0x80000000)); 4076 __ tst(scratch, Operand(0x80000000));
4078 __ b(ne, &bailout); 4077 __ b(ne, &bailout);
4079 __ add(string_length, string_length, Operand(scratch2), SetCC); 4078 __ add(string_length, string_length, Operand(scratch), SetCC);
4080 __ b(vs, &bailout); 4079 __ b(vs, &bailout);
4081 __ SmiUntag(string_length); 4080 __ SmiUntag(string_length);
4082 4081
4083 // Get first element in the array to free up the elements register to be used 4082 // Get first element in the array to free up the elements register to be used
4084 // for the result. 4083 // for the result.
4085 __ add(element, 4084 __ add(element,
4086 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4085 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4087 result = elements; // End of live range for elements. 4086 result = elements; // End of live range for elements.
4088 elements = no_reg; 4087 elements = no_reg;
4089 // Live values in registers: 4088 // Live values in registers:
4090 // element: First array element 4089 // element: First array element
4091 // separator: Separator string 4090 // separator: Separator string
4092 // string_length: Length of result string (not smi) 4091 // string_length: Length of result string (not smi)
4093 // array_length: Length of the array. 4092 // array_length: Length of the array.
4093 __ push(separator); // Push separator to reuse register as a scratch.
Rodolph Perfetta 2013/07/30 15:19:08 If the comment above is correct then r4 is availab
rmcilroy 2013/07/30 17:12:37 Nice catch! I spent ages looking for a free reg he
4094 __ AllocateAsciiString(result, 4094 __ AllocateAsciiString(result,
4095 string_length, 4095 string_length,
4096 scratch1, 4096 scratch,
4097 scratch2, 4097 separator,
4098 elements_end, 4098 elements_end,
4099 &bailout); 4099 &pop_and_bailout);
4100 __ pop(separator);
4100 // Prepare for looping. Set up elements_end to end of the array. Set 4101 // Prepare for looping. Set up elements_end to end of the array. Set
4101 // result_pos to the position of the result where to write the first 4102 // result_pos to the position of the result where to write the first
4102 // character. 4103 // character.
4103 __ add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2)); 4104 __ add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
4104 result_pos = array_length; // End of live range for array_length. 4105 result_pos = array_length; // End of live range for array_length.
4105 array_length = no_reg; 4106 array_length = no_reg;
4106 __ add(result_pos, 4107 __ add(result_pos,
4107 result, 4108 result,
4108 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4109 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4109 4110
4110 // Check the length of the separator. 4111 // Check the length of the separator.
4111 __ ldr(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); 4112 __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
4112 __ cmp(scratch1, Operand(Smi::FromInt(1))); 4113 __ cmp(scratch, Operand(Smi::FromInt(1)));
4113 __ b(eq, &one_char_separator); 4114 __ b(eq, &one_char_separator);
4114 __ b(gt, &long_separator); 4115 __ b(gt, &long_separator);
4115 4116
4116 // Empty separator case 4117 // Empty separator case
4117 __ bind(&empty_separator_loop); 4118 __ bind(&empty_separator_loop);
4118 // Live values in registers: 4119 // Live values in registers:
4119 // result_pos: the position to which we are currently copying characters. 4120 // result_pos: the position to which we are currently copying characters.
4120 // element: Current array element. 4121 // element: Current array element.
4121 // elements_end: Array end. 4122 // elements_end: Array end.
4122 4123
4123 // Copy next array element to the result. 4124 // Copy next array element to the result.
4124 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4125 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4125 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); 4126 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
4126 __ SmiUntag(string_length); 4127 __ SmiUntag(string_length);
4127 __ add(string, 4128 __ add(string,
4128 string, 4129 string,
4129 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4130 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4130 __ CopyBytes(string, result_pos, string_length, scratch1); 4131 __ CopyBytes(string, result_pos, string_length, scratch);
4131 __ cmp(element, elements_end); 4132 __ cmp(element, elements_end);
4132 __ b(lt, &empty_separator_loop); // End while (element < elements_end). 4133 __ b(lt, &empty_separator_loop); // End while (element < elements_end).
4133 ASSERT(result.is(r0)); 4134 ASSERT(result.is(r0));
4134 __ b(&done); 4135 __ b(&done);
4135 4136
4136 // One-character separator case 4137 // One-character separator case
4137 __ bind(&one_char_separator); 4138 __ bind(&one_char_separator);
4138 // Replace separator with its ASCII character value. 4139 // Replace separator with its ASCII character value.
4139 __ ldrb(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize)); 4140 __ ldrb(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
4140 // Jump into the loop after the code that copies the separator, so the first 4141 // Jump into the loop after the code that copies the separator, so the first
(...skipping 11 matching lines...) Expand all
4152 __ strb(separator, MemOperand(result_pos, 1, PostIndex)); 4153 __ strb(separator, MemOperand(result_pos, 1, PostIndex));
4153 4154
4154 // Copy next array element to the result. 4155 // Copy next array element to the result.
4155 __ bind(&one_char_separator_loop_entry); 4156 __ bind(&one_char_separator_loop_entry);
4156 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4157 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4157 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); 4158 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
4158 __ SmiUntag(string_length); 4159 __ SmiUntag(string_length);
4159 __ add(string, 4160 __ add(string,
4160 string, 4161 string,
4161 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4162 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4162 __ CopyBytes(string, result_pos, string_length, scratch1); 4163 __ CopyBytes(string, result_pos, string_length, scratch);
4163 __ cmp(element, elements_end); 4164 __ cmp(element, elements_end);
4164 __ b(lt, &one_char_separator_loop); // End while (element < elements_end). 4165 __ b(lt, &one_char_separator_loop); // End while (element < elements_end).
4165 ASSERT(result.is(r0)); 4166 ASSERT(result.is(r0));
4166 __ b(&done); 4167 __ b(&done);
4167 4168
4168 // Long separator case (separator is more than one character). Entry is at the 4169 // Long separator case (separator is more than one character). Entry is at the
4169 // label long_separator below. 4170 // label long_separator below.
4170 __ bind(&long_separator_loop); 4171 __ bind(&long_separator_loop);
4171 // Live values in registers: 4172 // Live values in registers:
4172 // result_pos: the position to which we are currently copying characters. 4173 // result_pos: the position to which we are currently copying characters.
4173 // element: Current array element. 4174 // element: Current array element.
4174 // elements_end: Array end. 4175 // elements_end: Array end.
4175 // separator: Separator string. 4176 // separator: Separator string.
4176 4177
4177 // Copy the separator to the result. 4178 // Copy the separator to the result.
4178 __ ldr(string_length, FieldMemOperand(separator, String::kLengthOffset)); 4179 __ ldr(string_length, FieldMemOperand(separator, String::kLengthOffset));
4179 __ SmiUntag(string_length); 4180 __ SmiUntag(string_length);
4180 __ add(string, 4181 __ add(string,
4181 separator, 4182 separator,
4182 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4183 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4183 __ CopyBytes(string, result_pos, string_length, scratch1); 4184 __ CopyBytes(string, result_pos, string_length, scratch);
4184 4185
4185 __ bind(&long_separator); 4186 __ bind(&long_separator);
4186 __ ldr(string, MemOperand(element, kPointerSize, PostIndex)); 4187 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
4187 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset)); 4188 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
4188 __ SmiUntag(string_length); 4189 __ SmiUntag(string_length);
4189 __ add(string, 4190 __ add(string,
4190 string, 4191 string,
4191 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 4192 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
4192 __ CopyBytes(string, result_pos, string_length, scratch1); 4193 __ CopyBytes(string, result_pos, string_length, scratch);
4193 __ cmp(element, elements_end); 4194 __ cmp(element, elements_end);
4194 __ b(lt, &long_separator_loop); // End while (element < elements_end). 4195 __ b(lt, &long_separator_loop); // End while (element < elements_end).
4195 ASSERT(result.is(r0)); 4196 ASSERT(result.is(r0));
4196 __ b(&done); 4197 __ b(&done);
4197 4198
4199 __ bind(&pop_and_bailout);
4200 __ Drop(1, al);
4198 __ bind(&bailout); 4201 __ bind(&bailout);
4199 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 4202 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
4200 __ bind(&done); 4203 __ bind(&done);
4201 context()->Plug(r0); 4204 context()->Plug(r0);
4202 } 4205 }
4203 4206
4204 4207
4205 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 4208 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
4206 Handle<String> name = expr->name(); 4209 Handle<String> name = expr->name();
4207 if (name->length() > 0 && name->Get(0) == '_') { 4210 if (name->length() > 0 && name->Get(0) == '_') {
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
4915 *context_length = 0; 4918 *context_length = 0;
4916 return previous_; 4919 return previous_;
4917 } 4920 }
4918 4921
4919 4922
4920 #undef __ 4923 #undef __
4921 4924
4922 } } // namespace v8::internal 4925 } } // namespace v8::internal
4923 4926
4924 #endif // V8_TARGET_ARCH_ARM 4927 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698