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

Side by Side Diff: src/arm64/builtins-arm64.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/arm/macro-assembler-arm.cc ('k') | src/arm64/macro-assembler-arm64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/arm64/frames-arm64.h" 7 #include "src/arm64/frames-arm64.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/debug/debug.h" 9 #include "src/debug/debug.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 133
134 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 134 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
135 // ----------- S t a t e ------------- 135 // ----------- S t a t e -------------
136 // -- x0 : number of arguments 136 // -- x0 : number of arguments
137 // -- x1 : constructor function 137 // -- x1 : constructor function
138 // -- lr : return address 138 // -- lr : return address
139 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based) 139 // -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
140 // -- sp[argc * 8] : receiver 140 // -- sp[argc * 8] : receiver
141 // ----------------------------------- 141 // -----------------------------------
142 ASM_LOCATION("Builtins::Generate_StringConstructCode"); 142 ASM_LOCATION("Builtins::Generate_StringConstructCode");
143 Counters* counters = masm->isolate()->counters();
144 __ IncrementCounter(counters->string_ctor_calls(), 1, x10, x11);
145 143
146 Register argc = x0; 144 // 1. Load the first argument into x2 and get rid of the rest (including the
147 Register function = x1; 145 // receiver).
148 if (FLAG_debug_code) { 146 {
149 __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, x10); 147 Label no_arguments, done;
150 __ Cmp(function, x10); 148 __ Cbz(x0, &no_arguments);
151 __ Assert(eq, kUnexpectedStringFunction); 149 __ Sub(x0, x0, 1);
150 __ Drop(x0, kXRegSize);
151 __ Ldr(x2, MemOperand(jssp, 2 * kPointerSize, PostIndex));
152 __ B(&done);
153 __ Bind(&no_arguments);
154 __ Drop(1);
155 __ LoadRoot(x2, Heap::kempty_stringRootIndex);
156 __ Bind(&done);
152 } 157 }
153 158
154 // Load the first arguments in x0 and get rid of the rest. 159 // 2. Make sure x2 is a string.
155 Label no_arguments; 160 {
156 __ Cbz(argc, &no_arguments); 161 Label convert, done_convert;
157 // First args = sp[(argc - 1) * 8]. 162 __ JumpIfSmi(x2, &convert);
158 __ Sub(argc, argc, 1); 163 __ JumpIfObjectType(x2, x3, x3, FIRST_NONSTRING_TYPE, &done_convert, lo);
159 __ Drop(argc, kXRegSize); 164 __ Bind(&convert);
160 // jssp now point to args[0], load and drop args[0] + receiver. 165 {
161 Register arg = argc; 166 FrameScope scope(masm, StackFrame::INTERNAL);
162 __ Ldr(arg, MemOperand(jssp, 2 * kPointerSize, PostIndex)); 167 ToStringStub stub(masm->isolate());
163 argc = NoReg; 168 __ Push(x1);
169 __ Move(x0, x2);
170 __ CallStub(&stub);
171 __ Move(x2, x0);
172 __ Pop(x1);
173 }
174 __ Bind(&done_convert);
175 }
164 176
165 Register argument = x2; 177 // 3. Allocate a JSValue wrapper for the string.
166 Label not_cached, argument_is_string; 178 {
167 __ LookupNumberStringCache(arg, // Input. 179 // ----------- S t a t e -------------
168 argument, // Result. 180 // -- x1 : constructor function
169 x10, // Scratch. 181 // -- x2 : the first argument
170 x11, // Scratch. 182 // -- lr : return address
171 x12, // Scratch. 183 // -----------------------------------
172 &not_cached);
173 __ IncrementCounter(counters->string_ctor_cached_number(), 1, x10, x11);
174 __ Bind(&argument_is_string);
175 184
176 // ----------- S t a t e ------------- 185 Label allocate, done_allocate;
177 // -- x2 : argument converted to string 186 __ Allocate(JSValue::kSize, x0, x3, x4, &allocate, TAG_OBJECT);
178 // -- x1 : constructor function 187 __ Bind(&done_allocate);
179 // -- lr : return address
180 // -----------------------------------
181 188
182 Label gc_required; 189 // Initialize the JSValue in eax.
183 Register new_obj = x0; 190 __ LoadGlobalFunctionInitialMap(x1, x3, x4);
184 __ Allocate(JSValue::kSize, new_obj, x10, x11, &gc_required, TAG_OBJECT); 191 __ Str(x3, FieldMemOperand(x0, HeapObject::kMapOffset));
192 __ LoadRoot(x3, Heap::kEmptyFixedArrayRootIndex);
193 __ Str(x3, FieldMemOperand(x0, JSObject::kPropertiesOffset));
194 __ Str(x3, FieldMemOperand(x0, JSObject::kElementsOffset));
195 __ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset));
196 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
197 __ Ret();
185 198
186 // Initialize the String object. 199 // Fallback to the runtime to allocate in new space.
187 Register map = x3; 200 __ Bind(&allocate);
188 __ LoadGlobalFunctionInitialMap(function, map, x10); 201 {
189 if (FLAG_debug_code) { 202 FrameScope scope(masm, StackFrame::INTERNAL);
190 __ Ldrb(x4, FieldMemOperand(map, Map::kInstanceSizeOffset)); 203 __ Push(x1, x2);
191 __ Cmp(x4, JSValue::kSize >> kPointerSizeLog2); 204 __ Push(Smi::FromInt(JSValue::kSize));
192 __ Assert(eq, kUnexpectedStringWrapperInstanceSize); 205 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
193 __ Ldrb(x4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); 206 __ Pop(x2, x1);
194 __ Cmp(x4, 0); 207 }
195 __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper); 208 __ B(&done_allocate);
196 } 209 }
197 __ Str(map, FieldMemOperand(new_obj, HeapObject::kMapOffset));
198
199 Register empty = x3;
200 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
201 __ Str(empty, FieldMemOperand(new_obj, JSObject::kPropertiesOffset));
202 __ Str(empty, FieldMemOperand(new_obj, JSObject::kElementsOffset));
203
204 __ Str(argument, FieldMemOperand(new_obj, JSValue::kValueOffset));
205
206 // Ensure the object is fully initialized.
207 STATIC_ASSERT(JSValue::kSize == (4 * kPointerSize));
208
209 __ Ret();
210
211 // The argument was not found in the number to string cache. Check
212 // if it's a string already before calling the conversion builtin.
213 Label convert_argument;
214 __ Bind(&not_cached);
215 __ JumpIfSmi(arg, &convert_argument);
216
217 // Is it a String?
218 __ Ldr(x10, FieldMemOperand(x0, HeapObject::kMapOffset));
219 __ Ldrb(x11, FieldMemOperand(x10, Map::kInstanceTypeOffset));
220 __ Tbnz(x11, MaskToBit(kIsNotStringMask), &convert_argument);
221 __ Mov(argument, arg);
222 __ IncrementCounter(counters->string_ctor_string_value(), 1, x10, x11);
223 __ B(&argument_is_string);
224
225 // Invoke the conversion builtin and put the result into x2.
226 __ Bind(&convert_argument);
227 __ Push(function); // Preserve the function.
228 __ IncrementCounter(counters->string_ctor_conversions(), 1, x10, x11);
229 {
230 FrameScope scope(masm, StackFrame::INTERNAL);
231 ToStringStub stub(masm->isolate());
232 __ CallStub(&stub);
233 }
234 __ Pop(function);
235 __ Mov(argument, x0);
236 __ B(&argument_is_string);
237
238 // Load the empty string into x2, remove the receiver from the
239 // stack, and jump back to the case where the argument is a string.
240 __ Bind(&no_arguments);
241 __ LoadRoot(argument, Heap::kempty_stringRootIndex);
242 __ Drop(1);
243 __ B(&argument_is_string);
244
245 // At this point the argument is already a string. Call runtime to create a
246 // string wrapper.
247 __ Bind(&gc_required);
248 __ IncrementCounter(counters->string_ctor_gc_required(), 1, x10, x11);
249 {
250 FrameScope scope(masm, StackFrame::INTERNAL);
251 __ Push(argument);
252 __ CallRuntime(Runtime::kNewStringWrapper, 1);
253 }
254 __ Ret();
255 } 210 }
256 211
257 212
258 static void CallRuntimePassFunction(MacroAssembler* masm, 213 static void CallRuntimePassFunction(MacroAssembler* masm,
259 Runtime::FunctionId function_id) { 214 Runtime::FunctionId function_id) {
260 FrameScope scope(masm, StackFrame::INTERNAL); 215 FrameScope scope(masm, StackFrame::INTERNAL);
261 // - Push a copy of the function onto the stack. 216 // - Push a copy of the function onto the stack.
262 // - Push another copy as a parameter to the runtime call. 217 // - Push another copy as a parameter to the runtime call.
263 __ Push(x1, x1); 218 __ Push(x1, x1);
264 219
(...skipping 1603 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 } 1823 }
1869 } 1824 }
1870 1825
1871 1826
1872 #undef __ 1827 #undef __
1873 1828
1874 } // namespace internal 1829 } // namespace internal
1875 } // namespace v8 1830 } // namespace v8
1876 1831
1877 #endif // V8_TARGET_ARCH_ARM 1832 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/arm64/macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698