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

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

Powered by Google App Engine
This is Rietveld 408576698