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

Side by Side Diff: src/arm/builtins-arm.cc

Issue 1335193002: [builtins] Simplify String constructor code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Jaro's comments. Created 5 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
« no previous file with comments | « no previous file | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 137
138 138
139 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 139 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
140 // ----------- S t a t e ------------- 140 // ----------- S t a t e -------------
141 // -- r0 : number of arguments 141 // -- r0 : number of arguments
142 // -- r1 : constructor function 142 // -- r1 : constructor function
143 // -- lr : return address 143 // -- lr : return address
144 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) 144 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
145 // -- sp[argc * 4] : receiver 145 // -- sp[argc * 4] : receiver
146 // ----------------------------------- 146 // -----------------------------------
147 Counters* counters = masm->isolate()->counters();
148 __ IncrementCounter(counters->string_ctor_calls(), 1, r2, r3);
149 147
150 Register function = r1; 148 // 1. Load the first argument into r2 and get rid of the rest (including the
151 if (FLAG_debug_code) { 149 // receiver).
152 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, r2); 150 {
153 __ cmp(function, Operand(r2)); 151 Label no_arguments, done;
154 __ Assert(eq, kUnexpectedStringFunction); 152 __ cmp(r0, Operand(0));
153 __ b(eq, &no_arguments);
154 __ sub(r0, r0, Operand(1));
155 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex));
156 __ Drop(2);
157 __ b(&done);
158 __ bind(&no_arguments);
159 __ LoadRoot(r2, Heap::kempty_stringRootIndex);
160 __ Drop(1);
161 __ bind(&done);
155 } 162 }
156 163
157 // Load the first arguments in r0 and get rid of the rest. 164 // 2. Make sure r2 is a string.
158 Label no_arguments; 165 {
159 __ cmp(r0, Operand::Zero()); 166 Label convert, done_convert;
160 __ b(eq, &no_arguments); 167 __ JumpIfSmi(r2, &convert);
161 // First args = sp[(argc - 1) * 4]. 168 __ CompareObjectType(r2, r3, r3, FIRST_NONSTRING_TYPE);
162 __ sub(r0, r0, Operand(1)); 169 __ b(lo, &done_convert);
163 __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); 170 __ bind(&convert);
164 // sp now point to args[0], drop args[0] + receiver. 171 {
165 __ Drop(2); 172 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
173 ToStringStub stub(masm->isolate());
174 __ Push(r1);
175 __ Move(r0, r2);
176 __ CallStub(&stub);
177 __ Move(r2, r0);
178 __ Pop(r1);
179 }
180 __ bind(&done_convert);
181 }
166 182
167 Register argument = r2; 183 // 3. Allocate a JSValue wrapper for the string.
168 Label not_cached, argument_is_string; 184 {
169 __ LookupNumberStringCache(r0, // Input. 185 // ----------- S t a t e -------------
170 argument, // Result. 186 // -- r1 : constructor function
171 r3, // Scratch. 187 // -- r2 : the first argument
172 r4, // Scratch. 188 // -- lr : return address
173 r5, // Scratch. 189 // -----------------------------------
174 &not_cached);
175 __ IncrementCounter(counters->string_ctor_cached_number(), 1, r3, r4);
176 __ bind(&argument_is_string);
177 190
178 // ----------- S t a t e ------------- 191 Label allocate, done_allocate;
179 // -- r2 : argument converted to string 192 __ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT);
180 // -- r1 : constructor function 193 __ bind(&done_allocate);
181 // -- lr : return address
182 // -----------------------------------
183 194
184 Label gc_required; 195 // Initialize the JSValue in eax.
185 __ Allocate(JSValue::kSize, 196 __ LoadGlobalFunctionInitialMap(r1, r3, r4);
186 r0, // Result. 197 __ str(r3, FieldMemOperand(r0, HeapObject::kMapOffset));
187 r3, // Scratch. 198 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex);
188 r4, // Scratch. 199 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset));
189 &gc_required, 200 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
190 TAG_OBJECT); 201 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset));
202 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
203 __ Ret();
191 204
192 // Initialising the String Object. 205 // Fallback to the runtime to allocate in new space.
193 Register map = r3; 206 __ bind(&allocate);
194 __ LoadGlobalFunctionInitialMap(function, map, r4); 207 {
195 if (FLAG_debug_code) { 208 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
196 __ ldrb(r4, FieldMemOperand(map, Map::kInstanceSizeOffset)); 209 __ Move(r3, Smi::FromInt(JSValue::kSize));
197 __ cmp(r4, Operand(JSValue::kSize >> kPointerSizeLog2)); 210 __ Push(r1, r2, r3);
198 __ Assert(eq, kUnexpectedStringWrapperInstanceSize); 211 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
199 __ ldrb(r4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); 212 __ Pop(r1, r2);
200 __ cmp(r4, Operand::Zero()); 213 }
201 __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper); 214 __ b(&done_allocate);
202 } 215 }
203 __ str(map, FieldMemOperand(r0, HeapObject::kMapOffset));
204
205 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex);
206 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset));
207 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
208
209 __ str(argument, FieldMemOperand(r0, JSValue::kValueOffset));
210
211 // Ensure the object is fully initialized.
212 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
213
214 __ Ret();
215
216 // The argument was not found in the number to string cache. Check
217 // if it's a string already before calling the conversion builtin.
218 Label convert_argument;
219 __ bind(&not_cached);
220 __ JumpIfSmi(r0, &convert_argument);
221
222 // Is it a String?
223 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
224 __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceTypeOffset));
225 STATIC_ASSERT(kNotStringTag != 0);
226 __ tst(r3, Operand(kIsNotStringMask));
227 __ b(ne, &convert_argument);
228 __ mov(argument, r0);
229 __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
230 __ b(&argument_is_string);
231
232 // Invoke the conversion builtin and put the result into r2.
233 __ bind(&convert_argument);
234 __ push(function); // Preserve the function.
235 __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
236 {
237 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
238 ToStringStub stub(masm->isolate());
239 __ CallStub(&stub);
240 }
241 __ pop(function);
242 __ mov(argument, r0);
243 __ b(&argument_is_string);
244
245 // Load the empty string into r2, remove the receiver from the
246 // stack, and jump back to the case where the argument is a string.
247 __ bind(&no_arguments);
248 __ LoadRoot(argument, Heap::kempty_stringRootIndex);
249 __ Drop(1);
250 __ b(&argument_is_string);
251
252 // At this point the argument is already a string. Call runtime to
253 // create a string wrapper.
254 __ bind(&gc_required);
255 __ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4);
256 {
257 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
258 __ push(argument);
259 __ CallRuntime(Runtime::kNewStringWrapper, 1);
260 }
261 __ Ret();
262 } 216 }
263 217
264 218
265 static void CallRuntimePassFunction( 219 static void CallRuntimePassFunction(
266 MacroAssembler* masm, Runtime::FunctionId function_id) { 220 MacroAssembler* masm, Runtime::FunctionId function_id) {
267 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 221 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
268 // Push a copy of the function onto the stack. 222 // Push a copy of the function onto the stack.
269 __ push(r1); 223 __ push(r1);
270 // Push function as parameter to the runtime call. 224 // Push function as parameter to the runtime call.
271 __ Push(r1); 225 __ Push(r1);
(...skipping 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 } 1753 }
1800 } 1754 }
1801 1755
1802 1756
1803 #undef __ 1757 #undef __
1804 1758
1805 } // namespace internal 1759 } // namespace internal
1806 } // namespace v8 1760 } // namespace v8
1807 1761
1808 #endif // V8_TARGET_ARCH_ARM 1762 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698