OLD | NEW |
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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 } | 301 } |
302 | 302 |
303 | 303 |
304 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 304 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
305 bool is_api_function, | 305 bool is_api_function, |
306 bool create_memento) { | 306 bool create_memento) { |
307 // ----------- S t a t e ------------- | 307 // ----------- S t a t e ------------- |
308 // -- x0 : number of arguments | 308 // -- x0 : number of arguments |
309 // -- x1 : constructor function | 309 // -- x1 : constructor function |
310 // -- x2 : allocation site or undefined | 310 // -- x2 : allocation site or undefined |
| 311 // -- x3 : original constructor |
311 // -- lr : return address | 312 // -- lr : return address |
312 // -- sp[...]: constructor arguments | 313 // -- sp[...]: constructor arguments |
313 // ----------------------------------- | 314 // ----------------------------------- |
314 | 315 |
315 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); | 316 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); |
316 // Should never create mementos for api functions. | 317 // Should never create mementos for api functions. |
317 DCHECK(!is_api_function || !create_memento); | 318 DCHECK(!is_api_function || !create_memento); |
318 | 319 |
319 Isolate* isolate = masm->isolate(); | 320 Isolate* isolate = masm->isolate(); |
320 | 321 |
321 // Enter a construct frame. | 322 // Enter a construct frame. |
322 { | 323 { |
323 FrameScope scope(masm, StackFrame::CONSTRUCT); | 324 FrameScope scope(masm, StackFrame::CONSTRUCT); |
324 | 325 |
325 // Preserve the three incoming parameters on the stack. | 326 // Preserve the three incoming parameters on the stack. |
326 if (create_memento) { | 327 if (create_memento) { |
327 __ AssertUndefinedOrAllocationSite(x2, x10); | 328 __ AssertUndefinedOrAllocationSite(x2, x10); |
328 __ Push(x2); | 329 __ Push(x2); |
329 } | 330 } |
330 | 331 |
331 Register argc = x0; | 332 Register argc = x0; |
332 Register constructor = x1; | 333 Register constructor = x1; |
| 334 Register original_constructor = x3; |
333 // x1: constructor function | 335 // x1: constructor function |
334 __ SmiTag(argc); | 336 __ SmiTag(argc); |
335 __ Push(argc, constructor); | 337 __ Push(argc, constructor); |
336 // sp[0] : Constructor function. | 338 // sp[0] : Constructor function. |
337 // sp[1]: number of arguments (smi-tagged) | 339 // sp[1]: number of arguments (smi-tagged) |
338 | 340 |
| 341 Label rt_call, count_incremented, allocated, normal_new; |
| 342 __ Cmp(constructor, original_constructor); |
| 343 __ B(eq, &normal_new); |
| 344 { |
| 345 if (create_memento) { |
| 346 // Get the cell or allocation site. |
| 347 __ Peek(x4, 2 * kXRegSize); |
| 348 __ Push(x4); |
| 349 __ Push(constructor); // Argument for Runtime_NewObject. |
| 350 __ Push(original_constructor); |
| 351 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); |
| 352 __ Mov(x4, x0); |
| 353 // If we ended up using the runtime, and we want a memento, then the |
| 354 // runtime call made it for us, and we shouldn't do create count |
| 355 // increment. |
| 356 __ jmp(&count_incremented); |
| 357 } else { |
| 358 __ Push(constructor); // Argument for Runtime_NewObject. |
| 359 __ Push(original_constructor); |
| 360 __ CallRuntime(Runtime::kNewObject, 2); |
| 361 __ Mov(x4, x0); |
| 362 __ jmp(&allocated); |
| 363 } |
| 364 } |
| 365 |
| 366 __ Bind(&normal_new); |
| 367 |
339 // Try to allocate the object without transitioning into C code. If any of | 368 // Try to allocate the object without transitioning into C code. If any of |
340 // the preconditions is not met, the code bails out to the runtime call. | 369 // the preconditions is not met, the code bails out to the runtime call. |
341 Label rt_call, allocated; | |
342 if (FLAG_inline_new) { | 370 if (FLAG_inline_new) { |
343 Label undo_allocation; | 371 Label undo_allocation; |
344 ExternalReference debug_step_in_fp = | 372 ExternalReference debug_step_in_fp = |
345 ExternalReference::debug_step_in_fp_address(isolate); | 373 ExternalReference::debug_step_in_fp_address(isolate); |
346 __ Mov(x2, Operand(debug_step_in_fp)); | 374 __ Mov(x2, Operand(debug_step_in_fp)); |
347 __ Ldr(x2, MemOperand(x2)); | 375 __ Ldr(x2, MemOperand(x2)); |
348 __ Cbnz(x2, &rt_call); | 376 __ Cbnz(x2, &rt_call); |
349 // Load the initial map and verify that it is in fact a map. | 377 // Load the initial map and verify that it is in fact a map. |
350 Register init_map = x2; | 378 Register init_map = x2; |
351 __ Ldr(init_map, | 379 __ Ldr(init_map, |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 | 556 |
529 // Undo the setting of the new top so that the heap is verifiable. For | 557 // Undo the setting of the new top so that the heap is verifiable. For |
530 // example, the map's unused properties potentially do not match the | 558 // example, the map's unused properties potentially do not match the |
531 // allocated objects unused properties. | 559 // allocated objects unused properties. |
532 __ Bind(&undo_allocation); | 560 __ Bind(&undo_allocation); |
533 __ UndoAllocationInNewSpace(new_obj, x14); | 561 __ UndoAllocationInNewSpace(new_obj, x14); |
534 } | 562 } |
535 | 563 |
536 // Allocate the new receiver object using the runtime call. | 564 // Allocate the new receiver object using the runtime call. |
537 __ Bind(&rt_call); | 565 __ Bind(&rt_call); |
538 Label count_incremented; | |
539 if (create_memento) { | 566 if (create_memento) { |
540 // Get the cell or allocation site. | 567 // Get the cell or allocation site. |
541 __ Peek(x4, 2 * kXRegSize); | 568 __ Peek(x4, 2 * kXRegSize); |
542 __ Push(x4); | 569 __ Push(x4); |
543 __ Push(constructor); // Argument for Runtime_NewObject. | 570 __ Push(constructor); // Argument for Runtime_NewObject. |
544 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2); | 571 __ Push(constructor); |
| 572 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); |
545 __ Mov(x4, x0); | 573 __ Mov(x4, x0); |
546 // If we ended up using the runtime, and we want a memento, then the | 574 // If we ended up using the runtime, and we want a memento, then the |
547 // runtime call made it for us, and we shouldn't do create count | 575 // runtime call made it for us, and we shouldn't do create count |
548 // increment. | 576 // increment. |
549 __ jmp(&count_incremented); | 577 __ jmp(&count_incremented); |
550 } else { | 578 } else { |
551 __ Push(constructor); // Argument for Runtime_NewObject. | 579 __ Push(constructor); // Argument for Runtime_NewObject. |
552 __ CallRuntime(Runtime::kNewObject, 1); | 580 __ Push(constructor); |
| 581 __ CallRuntime(Runtime::kNewObject, 2); |
553 __ Mov(x4, x0); | 582 __ Mov(x4, x0); |
554 } | 583 } |
555 | 584 |
556 // Receiver for constructor call allocated. | 585 // Receiver for constructor call allocated. |
557 // x4: JSObject | 586 // x4: JSObject |
558 __ Bind(&allocated); | 587 __ Bind(&allocated); |
559 | 588 |
560 if (create_memento) { | 589 if (create_memento) { |
561 __ Peek(x10, 2 * kXRegSize); | 590 __ Peek(x10, 2 * kXRegSize); |
562 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); | 591 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); |
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 __ Unreachable(); | 1584 __ Unreachable(); |
1556 } | 1585 } |
1557 } | 1586 } |
1558 | 1587 |
1559 | 1588 |
1560 #undef __ | 1589 #undef __ |
1561 | 1590 |
1562 } } // namespace v8::internal | 1591 } } // namespace v8::internal |
1563 | 1592 |
1564 #endif // V8_TARGET_ARCH_ARM | 1593 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |