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

Side by Side Diff: src/mips/builtins-mips.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 | « src/ia32/macro-assembler-ia32.cc ('k') | src/mips/macro-assembler-mips.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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 142
143 143
144 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 144 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
145 // ----------- S t a t e ------------- 145 // ----------- S t a t e -------------
146 // -- a0 : number of arguments 146 // -- a0 : number of arguments
147 // -- a1 : constructor function 147 // -- a1 : constructor function
148 // -- ra : return address 148 // -- ra : return address
149 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) 149 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
150 // -- sp[argc * 4] : receiver 150 // -- sp[argc * 4] : receiver
151 // ----------------------------------- 151 // -----------------------------------
152 Counters* counters = masm->isolate()->counters();
153 __ IncrementCounter(counters->string_ctor_calls(), 1, a2, a3);
154 152
155 Register function = a1; 153 // 1. Load the first argument into a0 and get rid of the rest (including the
156 if (FLAG_debug_code) { 154 // receiver).
157 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, a2); 155 {
158 __ Assert(eq, kUnexpectedStringFunction, function, Operand(a2)); 156 Label no_arguments, done;
157 __ Branch(&no_arguments, eq, a0, Operand(zero_reg));
158 __ Subu(a0, a0, Operand(1));
159 __ sll(a0, a0, kPointerSizeLog2);
160 __ Addu(sp, a0, sp);
161 __ lw(a0, MemOperand(sp));
162 __ Drop(2);
163 __ jmp(&done);
164 __ bind(&no_arguments);
165 __ LoadRoot(a0, Heap::kempty_stringRootIndex);
166 __ Drop(1);
167 __ bind(&done);
159 } 168 }
160 169
161 // Load the first arguments in a0 and get rid of the rest. 170 // 2. Make sure a0 is a string.
162 Label no_arguments; 171 {
163 __ Branch(&no_arguments, eq, a0, Operand(zero_reg)); 172 Label convert, done_convert;
164 // First args = sp[(argc - 1) * 4]. 173 __ JumpIfSmi(a0, &convert);
165 __ Subu(a0, a0, Operand(1)); 174 __ GetObjectType(a0, a2, a2);
166 __ sll(a0, a0, kPointerSizeLog2); 175 __ And(t0, a2, Operand(kIsNotStringMask));
167 __ Addu(sp, a0, sp); 176 __ Branch(&done_convert, eq, t0, Operand(zero_reg));
168 __ lw(a0, MemOperand(sp)); 177 __ bind(&convert);
169 // sp now point to args[0], drop args[0] + receiver. 178 {
170 __ Drop(2); 179 FrameScope scope(masm, StackFrame::INTERNAL);
180 ToStringStub stub(masm->isolate());
181 __ Push(a1);
182 __ CallStub(&stub);
183 __ Move(a0, v0);
184 __ Pop(a1);
185 }
186 __ bind(&done_convert);
187 }
171 188
172 Register argument = a2; 189 // 3. Allocate a JSValue wrapper for the string.
173 Label not_cached, argument_is_string; 190 {
174 __ LookupNumberStringCache(a0, // Input. 191 // ----------- S t a t e -------------
175 argument, // Result. 192 // -- a0 : the first argument
176 a3, // Scratch. 193 // -- a1 : constructor function
177 t0, // Scratch. 194 // -- ra : return address
178 t1, // Scratch. 195 // -----------------------------------
179 &not_cached);
180 __ IncrementCounter(counters->string_ctor_cached_number(), 1, a3, t0);
181 __ bind(&argument_is_string);
182 196
183 // ----------- S t a t e ------------- 197 Label allocate, done_allocate;
184 // -- a2 : argument converted to string 198 __ Allocate(JSValue::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
185 // -- a1 : constructor function 199 __ bind(&done_allocate);
186 // -- ra : return address
187 // -----------------------------------
188 200
189 Label gc_required; 201 // Initialize the JSValue in eax.
190 __ Allocate(JSValue::kSize, 202 __ LoadGlobalFunctionInitialMap(a1, a2, a3);
191 v0, // Result. 203 __ sw(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
192 a3, // Scratch. 204 __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex);
193 t0, // Scratch. 205 __ sw(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset));
194 &gc_required, 206 __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset));
195 TAG_OBJECT); 207 __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset));
208 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
209 __ Ret();
196 210
197 // Initialising the String Object. 211 // Fallback to the runtime to allocate in new space.
198 Register map = a3; 212 __ bind(&allocate);
199 __ LoadGlobalFunctionInitialMap(function, map, t0); 213 {
200 if (FLAG_debug_code) { 214 FrameScope scope(masm, StackFrame::INTERNAL);
201 __ lbu(t0, FieldMemOperand(map, Map::kInstanceSizeOffset)); 215 __ Move(a2, Smi::FromInt(JSValue::kSize));
202 __ Assert(eq, kUnexpectedStringWrapperInstanceSize, 216 __ Push(a0, a1, a2);
203 t0, Operand(JSValue::kSize >> kPointerSizeLog2)); 217 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
204 __ lbu(t0, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); 218 __ Pop(a0, a1);
205 __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper, 219 }
206 t0, Operand(zero_reg)); 220 __ jmp(&done_allocate);
207 } 221 }
208 __ sw(map, FieldMemOperand(v0, HeapObject::kMapOffset));
209
210 __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex);
211 __ sw(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset));
212 __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset));
213
214 __ sw(argument, FieldMemOperand(v0, JSValue::kValueOffset));
215
216 // Ensure the object is fully initialized.
217 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
218
219 __ Ret();
220
221 // The argument was not found in the number to string cache. Check
222 // if it's a string already before calling the conversion builtin.
223 Label convert_argument;
224 __ bind(&not_cached);
225 __ JumpIfSmi(a0, &convert_argument);
226
227 // Is it a String?
228 __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset));
229 __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
230 STATIC_ASSERT(kNotStringTag != 0);
231 __ And(t0, a3, Operand(kIsNotStringMask));
232 __ Branch(&convert_argument, ne, t0, Operand(zero_reg));
233 __ mov(argument, a0);
234 __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, t0);
235 __ Branch(&argument_is_string);
236
237 // Invoke the conversion builtin and put the result into a2.
238 __ bind(&convert_argument);
239 __ push(function); // Preserve the function.
240 __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, t0);
241 {
242 FrameScope scope(masm, StackFrame::INTERNAL);
243 ToStringStub stub(masm->isolate());
244 __ CallStub(&stub);
245 }
246 __ pop(function);
247 __ mov(argument, v0);
248 __ Branch(&argument_is_string);
249
250 // Load the empty string into a2, remove the receiver from the
251 // stack, and jump back to the case where the argument is a string.
252 __ bind(&no_arguments);
253 __ LoadRoot(argument, Heap::kempty_stringRootIndex);
254 __ Drop(1);
255 __ Branch(&argument_is_string);
256
257 // At this point the argument is already a string. Call runtime to
258 // create a string wrapper.
259 __ bind(&gc_required);
260 __ IncrementCounter(counters->string_ctor_gc_required(), 1, a3, t0);
261 {
262 FrameScope scope(masm, StackFrame::INTERNAL);
263 __ push(argument);
264 __ CallRuntime(Runtime::kNewStringWrapper, 1);
265 }
266 __ Ret();
267 } 222 }
268 223
269 224
270 static void CallRuntimePassFunction( 225 static void CallRuntimePassFunction(
271 MacroAssembler* masm, Runtime::FunctionId function_id) { 226 MacroAssembler* masm, Runtime::FunctionId function_id) {
272 FrameScope scope(masm, StackFrame::INTERNAL); 227 FrameScope scope(masm, StackFrame::INTERNAL);
273 // Push a copy of the function onto the stack. 228 // Push a copy of the function onto the stack.
274 // Push call kind information and function as parameter to the runtime call. 229 // Push call kind information and function as parameter to the runtime call.
275 __ Push(a1, a1); 230 __ Push(a1, a1);
276 231
(...skipping 1539 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 } 1771 }
1817 } 1772 }
1818 1773
1819 1774
1820 #undef __ 1775 #undef __
1821 1776
1822 } // namespace internal 1777 } // namespace internal
1823 } // namespace v8 1778 } // namespace v8
1824 1779
1825 #endif // V8_TARGET_ARCH_MIPS 1780 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/mips/macro-assembler-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698