| OLD | NEW |
| 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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); | 206 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 | 209 |
| 210 | 210 |
| 211 // static | 211 // static |
| 212 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 212 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
| 213 // ----------- S t a t e ------------- | 213 // ----------- S t a t e ------------- |
| 214 // -- r0 : number of arguments | 214 // -- r0 : number of arguments |
| 215 // -- r1 : constructor function | 215 // -- r1 : constructor function |
| 216 // -- r3 : original constructor | |
| 217 // -- lr : return address | 216 // -- lr : return address |
| 218 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) | 217 // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) |
| 219 // -- sp[argc * 4] : receiver | 218 // -- sp[argc * 4] : receiver |
| 220 // ----------------------------------- | 219 // ----------------------------------- |
| 221 | 220 |
| 222 // 1. Load the first argument into r2 and get rid of the rest (including the | 221 // 1. Load the first argument into r0 and get rid of the rest (including the |
| 223 // receiver). | 222 // receiver). |
| 224 { | 223 { |
| 225 Label no_arguments, done; | 224 Label no_arguments, done; |
| 226 __ sub(r0, r0, Operand(1), SetCC); | 225 __ sub(r0, r0, Operand(1), SetCC); |
| 227 __ b(lo, &no_arguments); | 226 __ b(lo, &no_arguments); |
| 228 __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); | 227 __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); |
| 229 __ Drop(2); | 228 __ Drop(2); |
| 230 __ b(&done); | 229 __ b(&done); |
| 231 __ bind(&no_arguments); | 230 __ bind(&no_arguments); |
| 232 __ LoadRoot(r2, Heap::kempty_stringRootIndex); | 231 __ LoadRoot(r0, Heap::kempty_stringRootIndex); |
| 233 __ Drop(1); | 232 __ Drop(1); |
| 234 __ bind(&done); | 233 __ bind(&done); |
| 235 } | 234 } |
| 236 | 235 |
| 237 // 2. Make sure r2 is a string. | 236 // 2. Make sure r0 is a string. |
| 238 { | 237 { |
| 239 Label convert, done_convert; | 238 Label convert, done_convert; |
| 240 __ JumpIfSmi(r2, &convert); | 239 __ JumpIfSmi(r0, &convert); |
| 241 __ CompareObjectType(r2, r4, r4, FIRST_NONSTRING_TYPE); | 240 __ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE); |
| 242 __ b(lo, &done_convert); | 241 __ b(lo, &done_convert); |
| 243 __ bind(&convert); | 242 __ bind(&convert); |
| 244 { | 243 { |
| 245 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 244 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 246 ToStringStub stub(masm->isolate()); | 245 ToStringStub stub(masm->isolate()); |
| 247 __ Push(r1, r3); | 246 __ Push(r1); |
| 248 __ Move(r0, r2); | |
| 249 __ CallStub(&stub); | 247 __ CallStub(&stub); |
| 250 __ Move(r2, r0); | 248 __ Pop(r1); |
| 251 __ Pop(r1, r3); | |
| 252 } | 249 } |
| 253 __ bind(&done_convert); | 250 __ bind(&done_convert); |
| 254 } | 251 } |
| 255 | 252 |
| 256 // 3. Allocate a JSValue wrapper for the string. | 253 // 3. Allocate a JSValue wrapper for the string. |
| 257 { | 254 { |
| 258 // ----------- S t a t e ------------- | 255 // ----------- S t a t e ------------- |
| 259 // -- r2 : the first argument | 256 // -- r0 : the first argument |
| 260 // -- r1 : constructor function | 257 // -- r1 : constructor function |
| 261 // -- r3 : original constructor | |
| 262 // -- lr : return address | 258 // -- lr : return address |
| 263 // ----------------------------------- | 259 // ----------------------------------- |
| 264 | 260 |
| 265 Label allocate, done_allocate, rt_call; | 261 Label allocate, done_allocate; |
| 266 | 262 __ Move(r2, r0); |
| 267 // Fall back to runtime if the original constructor and function differ. | |
| 268 __ cmp(r1, r3); | |
| 269 __ b(ne, &rt_call); | |
| 270 | |
| 271 __ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT); | 263 __ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT); |
| 272 __ bind(&done_allocate); | 264 __ bind(&done_allocate); |
| 273 | 265 |
| 274 // Initialize the JSValue in r0. | 266 // Initialize the JSValue in r0. |
| 275 __ LoadGlobalFunctionInitialMap(r1, r3, r4); | 267 __ LoadGlobalFunctionInitialMap(r1, r3, r4); |
| 276 __ str(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); | 268 __ str(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 277 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); | 269 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); |
| 278 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | 270 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); |
| 279 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); | 271 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); |
| 280 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | 272 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); |
| 281 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 273 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
| 282 __ Ret(); | 274 __ Ret(); |
| 283 | 275 |
| 284 // Fallback to the runtime to allocate in new space. | 276 // Fallback to the runtime to allocate in new space. |
| 285 __ bind(&allocate); | 277 __ bind(&allocate); |
| 286 { | 278 { |
| 287 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 279 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 288 __ Move(r3, Smi::FromInt(JSValue::kSize)); | 280 __ Move(r3, Smi::FromInt(JSValue::kSize)); |
| 289 __ Push(r1, r2, r3); | 281 __ Push(r1, r2, r3); |
| 290 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 282 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
| 291 __ Pop(r1, r2); | 283 __ Pop(r1, r2); |
| 292 } | 284 } |
| 293 __ b(&done_allocate); | 285 __ b(&done_allocate); |
| 294 | |
| 295 // Fallback to the runtime to create new object. | |
| 296 __ bind(&rt_call); | |
| 297 { | |
| 298 FrameScope scope(masm, StackFrame::INTERNAL); | |
| 299 __ Push(r1, r2); | |
| 300 __ Push(r1, r3); // constructor function, original constructor | |
| 301 __ CallRuntime(Runtime::kNewObject, 2); | |
| 302 __ Pop(r1, r2); | |
| 303 } | |
| 304 __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset)); | |
| 305 __ Ret(); | |
| 306 } | 286 } |
| 307 } | 287 } |
| 308 | 288 |
| 309 | 289 |
| 310 static void CallRuntimePassFunction( | 290 static void CallRuntimePassFunction( |
| 311 MacroAssembler* masm, Runtime::FunctionId function_id) { | 291 MacroAssembler* masm, Runtime::FunctionId function_id) { |
| 312 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 292 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 313 // Push a copy of the function onto the stack. | 293 // Push a copy of the function onto the stack. |
| 314 __ push(r1); | 294 __ push(r1); |
| 315 // Push function as parameter to the runtime call. | 295 // Push function as parameter to the runtime call. |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 // Reload the original constructor and fall-through. | 493 // Reload the original constructor and fall-through. |
| 514 __ bind(&rt_call_reload_new_target); | 494 __ bind(&rt_call_reload_new_target); |
| 515 __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); | 495 __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); |
| 516 } | 496 } |
| 517 | 497 |
| 518 // Allocate the new receiver object using the runtime call. | 498 // Allocate the new receiver object using the runtime call. |
| 519 // r1: constructor function | 499 // r1: constructor function |
| 520 // r3: original constructor | 500 // r3: original constructor |
| 521 __ bind(&rt_call); | 501 __ bind(&rt_call); |
| 522 | 502 |
| 523 __ push(r1); // constructor function | 503 __ push(r1); // argument 2/1: constructor function |
| 524 __ push(r3); // original constructor | 504 __ push(r3); // argument 3/2: original constructor |
| 525 __ CallRuntime(Runtime::kNewObject, 2); | 505 __ CallRuntime(Runtime::kNewObject, 2); |
| 526 __ mov(r4, r0); | 506 __ mov(r4, r0); |
| 527 | 507 |
| 528 // Receiver for constructor call allocated. | 508 // Receiver for constructor call allocated. |
| 529 // r4: JSObject | 509 // r4: JSObject |
| 530 __ bind(&allocated); | 510 __ bind(&allocated); |
| 531 | 511 |
| 532 // Restore the parameters. | 512 // Restore the parameters. |
| 533 __ pop(r3); | 513 __ pop(r3); |
| 534 __ pop(r1); | 514 __ pop(r1); |
| (...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 } | 1898 } |
| 1919 } | 1899 } |
| 1920 | 1900 |
| 1921 | 1901 |
| 1922 #undef __ | 1902 #undef __ |
| 1923 | 1903 |
| 1924 } // namespace internal | 1904 } // namespace internal |
| 1925 } // namespace v8 | 1905 } // namespace v8 |
| 1926 | 1906 |
| 1927 #endif // V8_TARGET_ARCH_ARM | 1907 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |