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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 // r2 is an AllocationSite. We are creating a memento from it, so we | 585 // r2 is an AllocationSite. We are creating a memento from it, so we |
586 // need to increment the memento create count. | 586 // need to increment the memento create count. |
587 __ Ldr(x5, FieldMemOperand(x10, | 587 __ Ldr(x5, FieldMemOperand(x10, |
588 AllocationSite::kPretenureCreateCountOffset)); | 588 AllocationSite::kPretenureCreateCountOffset)); |
589 __ Add(x5, x5, Operand(Smi::FromInt(1))); | 589 __ Add(x5, x5, Operand(Smi::FromInt(1))); |
590 __ Str(x5, FieldMemOperand(x10, | 590 __ Str(x5, FieldMemOperand(x10, |
591 AllocationSite::kPretenureCreateCountOffset)); | 591 AllocationSite::kPretenureCreateCountOffset)); |
592 __ bind(&count_incremented); | 592 __ bind(&count_incremented); |
593 } | 593 } |
594 | 594 |
| 595 __ Pop(constructor); |
| 596 |
595 __ Push(x4, x4); | 597 __ Push(x4, x4); |
596 | 598 |
597 // Reload the number of arguments from the stack. | 599 // Reload the number of arguments from the stack. |
598 // Set it up in x0 for the function call below. | 600 // Set it up in x0 for the function call below. |
599 // jssp[0]: receiver | 601 // jssp[0]: receiver |
600 // jssp[1]: receiver | 602 // jssp[1]: receiver |
601 // jssp[2]: constructor function | 603 // jssp[2]: number of arguments (smi-tagged) |
602 // jssp[3]: number of arguments (smi-tagged) | 604 __ Peek(argc, 2 * kXRegSize); // Load number of arguments. |
603 __ Peek(constructor, 2 * kXRegSize); // Load constructor. | |
604 __ Peek(argc, 3 * kXRegSize); // Load number of arguments. | |
605 __ SmiUntag(argc); | 605 __ SmiUntag(argc); |
606 | 606 |
607 // Set up pointer to last argument. | 607 // Set up pointer to last argument. |
608 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); | 608 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); |
609 | 609 |
610 // Copy arguments and receiver to the expression stack. | 610 // Copy arguments and receiver to the expression stack. |
611 // Copy 2 values every loop to use ldp/stp. | 611 // Copy 2 values every loop to use ldp/stp. |
612 // x0: number of arguments | 612 // x0: number of arguments |
613 // x1: constructor function | 613 // x1: constructor function |
614 // x2: address of last argument (caller sp) | 614 // x2: address of last argument (caller sp) |
615 // jssp[0]: receiver | 615 // jssp[0]: receiver |
616 // jssp[1]: receiver | 616 // jssp[1]: receiver |
617 // jssp[2]: constructor function | 617 // jssp[2]: number of arguments (smi-tagged) |
618 // jssp[3]: number of arguments (smi-tagged) | |
619 // Compute the start address of the copy in x3. | 618 // Compute the start address of the copy in x3. |
620 __ Add(x3, x2, Operand(argc, LSL, kPointerSizeLog2)); | 619 __ Add(x3, x2, Operand(argc, LSL, kPointerSizeLog2)); |
621 Label loop, entry, done_copying_arguments; | 620 Label loop, entry, done_copying_arguments; |
622 __ B(&entry); | 621 __ B(&entry); |
623 __ Bind(&loop); | 622 __ Bind(&loop); |
624 __ Ldp(x10, x11, MemOperand(x3, -2 * kPointerSize, PreIndex)); | 623 __ Ldp(x10, x11, MemOperand(x3, -2 * kPointerSize, PreIndex)); |
625 __ Push(x11, x10); | 624 __ Push(x11, x10); |
626 __ Bind(&entry); | 625 __ Bind(&entry); |
627 __ Cmp(x3, x2); | 626 __ Cmp(x3, x2); |
628 __ B(gt, &loop); | 627 __ B(gt, &loop); |
(...skipping 17 matching lines...) Expand all Loading... |
646 } | 645 } |
647 | 646 |
648 // Store offset of return address for deoptimizer. | 647 // Store offset of return address for deoptimizer. |
649 if (!is_api_function) { | 648 if (!is_api_function) { |
650 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 649 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
651 } | 650 } |
652 | 651 |
653 // Restore the context from the frame. | 652 // Restore the context from the frame. |
654 // x0: result | 653 // x0: result |
655 // jssp[0]: receiver | 654 // jssp[0]: receiver |
656 // jssp[1]: constructor function | 655 // jssp[1]: number of arguments (smi-tagged) |
657 // jssp[2]: number of arguments (smi-tagged) | |
658 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 656 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
659 | 657 |
660 // If the result is an object (in the ECMA sense), we should get rid | 658 // If the result is an object (in the ECMA sense), we should get rid |
661 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 659 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
662 // on page 74. | 660 // on page 74. |
663 Label use_receiver, exit; | 661 Label use_receiver, exit; |
664 | 662 |
665 // If the result is a smi, it is *not* an object in the ECMA sense. | 663 // If the result is a smi, it is *not* an object in the ECMA sense. |
666 // x0: result | 664 // x0: result |
667 // jssp[0]: receiver (newly allocated object) | 665 // jssp[0]: receiver (newly allocated object) |
668 // jssp[1]: constructor function | 666 // jssp[1]: number of arguments (smi-tagged) |
669 // jssp[2]: number of arguments (smi-tagged) | |
670 __ JumpIfSmi(x0, &use_receiver); | 667 __ JumpIfSmi(x0, &use_receiver); |
671 | 668 |
672 // If the type of the result (stored in its map) is less than | 669 // If the type of the result (stored in its map) is less than |
673 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. | 670 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. |
674 __ JumpIfObjectType(x0, x1, x3, FIRST_SPEC_OBJECT_TYPE, &exit, ge); | 671 __ JumpIfObjectType(x0, x1, x3, FIRST_SPEC_OBJECT_TYPE, &exit, ge); |
675 | 672 |
676 // Throw away the result of the constructor invocation and use the | 673 // Throw away the result of the constructor invocation and use the |
677 // on-stack receiver as the result. | 674 // on-stack receiver as the result. |
678 __ Bind(&use_receiver); | 675 __ Bind(&use_receiver); |
679 __ Peek(x0, 0); | 676 __ Peek(x0, 0); |
680 | 677 |
681 // Remove the receiver from the stack, remove caller arguments, and | 678 // Remove the receiver from the stack, remove caller arguments, and |
682 // return. | 679 // return. |
683 __ Bind(&exit); | 680 __ Bind(&exit); |
684 // x0: result | 681 // x0: result |
685 // jssp[0]: receiver (newly allocated object) | 682 // jssp[0]: receiver (newly allocated object) |
686 // jssp[1]: constructor function | 683 // jssp[1]: number of arguments (smi-tagged) |
687 // jssp[2]: number of arguments (smi-tagged) | 684 __ Peek(x1, kXRegSize); |
688 __ Peek(x1, 2 * kXRegSize); | |
689 | 685 |
690 // Leave construct frame. | 686 // Leave construct frame. |
691 } | 687 } |
692 | 688 |
693 __ DropBySMI(x1); | 689 __ DropBySMI(x1); |
694 __ Drop(1); | 690 __ Drop(1); |
695 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); | 691 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); |
696 __ Ret(); | 692 __ Ret(); |
697 } | 693 } |
698 | 694 |
(...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 } | 1833 } |
1838 } | 1834 } |
1839 | 1835 |
1840 | 1836 |
1841 #undef __ | 1837 #undef __ |
1842 | 1838 |
1843 } // namespace internal | 1839 } // namespace internal |
1844 } // namespace v8 | 1840 } // namespace v8 |
1845 | 1841 |
1846 #endif // V8_TARGET_ARCH_ARM | 1842 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |