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

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

Powered by Google App Engine
This is Rietveld 408576698