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

Side by Side Diff: src/mips/builtins-mips.cc

Issue 1203813002: [es6] Make new.target work in functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add test again. It got lost in last patchset Created 5 years, 5 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/builtins-ia32.cc ('k') | src/mips64/builtins-mips64.cc » ('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 5
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #if V8_TARGET_ARCH_MIPS 9 #if V8_TARGET_ARCH_MIPS
10 10
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 if (create_memento) { 341 if (create_memento) {
342 __ jmp(count_incremented); 342 __ jmp(count_incremented);
343 } else { 343 } else {
344 __ jmp(allocated); 344 __ jmp(allocated);
345 } 345 }
346 } 346 }
347 347
348 348
349 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 349 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
350 bool is_api_function, 350 bool is_api_function,
351 bool use_new_target,
351 bool create_memento) { 352 bool create_memento) {
352 // ----------- S t a t e ------------- 353 // ----------- S t a t e -------------
353 // -- a0 : number of arguments 354 // -- a0 : number of arguments
354 // -- a1 : constructor function 355 // -- a1 : constructor function
355 // -- a2 : allocation site or undefined 356 // -- a2 : allocation site or undefined
356 // -- a3 : original constructor 357 // -- a3 : original constructor
357 // -- ra : return address 358 // -- ra : return address
358 // -- sp[...]: constructor arguments 359 // -- sp[...]: constructor arguments
359 // ----------------------------------- 360 // -----------------------------------
360 361
(...skipping 11 matching lines...) Expand all
372 373
373 // Enter a construct frame. 374 // Enter a construct frame.
374 { 375 {
375 FrameScope scope(masm, StackFrame::CONSTRUCT); 376 FrameScope scope(masm, StackFrame::CONSTRUCT);
376 377
377 if (create_memento) { 378 if (create_memento) {
378 __ AssertUndefinedOrAllocationSite(a2, t0); 379 __ AssertUndefinedOrAllocationSite(a2, t0);
379 __ push(a2); 380 __ push(a2);
380 } 381 }
381 382
382 // Preserve the two incoming parameters on the stack. 383 // Preserve the incoming parameters on the stack.
383 __ sll(a0, a0, kSmiTagSize); // Tag arguments count. 384 __ SmiTag(a0);
384 __ MultiPushReversed(a0.bit() | a1.bit()); 385 if (use_new_target) {
386 __ Push(a0, a1, a3);
387 } else {
388 __ Push(a0, a1);
389 }
385 390
386 Label rt_call, allocated, normal_new, count_incremented; 391 Label rt_call, allocated, normal_new, count_incremented;
387 __ Branch(&normal_new, eq, a1, Operand(a3)); 392 __ Branch(&normal_new, eq, a1, Operand(a3));
388 393
389 // Original constructor and function are different. 394 // Original constructor and function are different.
390 Generate_Runtime_NewObject(masm, create_memento, a3, &count_incremented, 395 Generate_Runtime_NewObject(masm, create_memento, a3, &count_incremented,
391 &allocated); 396 &allocated);
392 __ bind(&normal_new); 397 __ bind(&normal_new);
393 398
394 // Try to allocate the object without transitioning into C code. If any of 399 // Try to allocate the object without transitioning into C code. If any of
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 // a1: constructor function 626 // a1: constructor function
622 __ bind(&rt_call); 627 __ bind(&rt_call);
623 Generate_Runtime_NewObject(masm, create_memento, a1, &count_incremented, 628 Generate_Runtime_NewObject(masm, create_memento, a1, &count_incremented,
624 &allocated); 629 &allocated);
625 630
626 // Receiver for constructor call allocated. 631 // Receiver for constructor call allocated.
627 // t4: JSObject 632 // t4: JSObject
628 __ bind(&allocated); 633 __ bind(&allocated);
629 634
630 if (create_memento) { 635 if (create_memento) {
631 __ lw(a2, MemOperand(sp, kPointerSize * 2)); 636 int offset = (use_new_target ? 3 : 2) * kPointerSize;
637 __ lw(a2, MemOperand(sp, offset));
632 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); 638 __ LoadRoot(t5, Heap::kUndefinedValueRootIndex);
633 __ Branch(&count_incremented, eq, a2, Operand(t5)); 639 __ Branch(&count_incremented, eq, a2, Operand(t5));
634 // a2 is an AllocationSite. We are creating a memento from it, so we 640 // a2 is an AllocationSite. We are creating a memento from it, so we
635 // need to increment the memento create count. 641 // need to increment the memento create count.
636 __ lw(a3, FieldMemOperand(a2, 642 __ lw(a3, FieldMemOperand(a2,
637 AllocationSite::kPretenureCreateCountOffset)); 643 AllocationSite::kPretenureCreateCountOffset));
638 __ Addu(a3, a3, Operand(Smi::FromInt(1))); 644 __ Addu(a3, a3, Operand(Smi::FromInt(1)));
639 __ sw(a3, FieldMemOperand(a2, 645 __ sw(a3, FieldMemOperand(a2,
640 AllocationSite::kPretenureCreateCountOffset)); 646 AllocationSite::kPretenureCreateCountOffset));
641 __ bind(&count_incremented); 647 __ bind(&count_incremented);
642 } 648 }
643 649
650 // Restore the parameters.
651 if (use_new_target) {
652 __ Pop(a3); // new.target
653 }
644 __ Pop(a1); 654 __ Pop(a1);
645 655
646 __ Push(t4, t4); 656 // Retrieve smi-tagged arguments count from the stack.
657 __ lw(a0, MemOperand(sp));
658 __ SmiUntag(a0);
647 659
648 // Reload the number of arguments from the stack. 660 if (use_new_target) {
649 // sp[0]: receiver 661 __ Push(a3, t4, t4);
650 // sp[1]: receiver 662 } else {
651 // sp[2]: number of arguments (smi-tagged) 663 __ Push(t4, t4);
652 __ lw(a3, MemOperand(sp, 2 * kPointerSize)); 664 }
653 665
654 // Set up pointer to last argument. 666 // Set up pointer to last argument.
655 __ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); 667 __ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
656 668
657 // Set up number of arguments for function call below.
658 __ srl(a0, a3, kSmiTagSize);
659
660 // Copy arguments and receiver to the expression stack. 669 // Copy arguments and receiver to the expression stack.
661 // a0: number of arguments 670 // a0: number of arguments
662 // a1: constructor function 671 // a1: constructor function
663 // a2: address of last argument (caller sp) 672 // a2: address of last argument (caller sp)
664 // a3: number of arguments (smi-tagged) 673 // a3: number of arguments (smi-tagged)
665 // sp[0]: receiver 674 // sp[0]: receiver
666 // sp[1]: receiver 675 // sp[1]: receiver
667 // sp[2]: number of arguments (smi-tagged) 676 // sp[2]: new.target (if used)
677 // sp[2/3]: number of arguments (smi-tagged)
668 Label loop, entry; 678 Label loop, entry;
679 __ SmiTag(a3, a0);
669 __ jmp(&entry); 680 __ jmp(&entry);
670 __ bind(&loop); 681 __ bind(&loop);
671 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); 682 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
672 __ Addu(t0, a2, Operand(t0)); 683 __ Addu(t0, a2, Operand(t0));
673 __ lw(t1, MemOperand(t0)); 684 __ lw(t1, MemOperand(t0));
674 __ push(t1); 685 __ push(t1);
675 __ bind(&entry); 686 __ bind(&entry);
676 __ Addu(a3, a3, Operand(-2)); 687 __ Addu(a3, a3, Operand(-2));
677 __ Branch(&loop, greater_equal, a3, Operand(zero_reg)); 688 __ Branch(&loop, greater_equal, a3, Operand(zero_reg));
678 689
679 // Call the function. 690 // Call the function.
680 // a0: number of arguments 691 // a0: number of arguments
681 // a1: constructor function 692 // a1: constructor function
682 if (is_api_function) { 693 if (is_api_function) {
683 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 694 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
684 Handle<Code> code = 695 Handle<Code> code =
685 masm->isolate()->builtins()->HandleApiCallConstruct(); 696 masm->isolate()->builtins()->HandleApiCallConstruct();
686 __ Call(code, RelocInfo::CODE_TARGET); 697 __ Call(code, RelocInfo::CODE_TARGET);
687 } else { 698 } else {
688 ParameterCount actual(a0); 699 ParameterCount actual(a0);
689 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); 700 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
690 } 701 }
691 702
692 // Store offset of return address for deoptimizer. 703 // Store offset of return address for deoptimizer.
693 if (!is_api_function) { 704 // TODO(arv): Remove the "!use_new_target" before supporting optimization
705 // of functions that reference new.target
706 if (!is_api_function && !use_new_target) {
694 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 707 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
695 } 708 }
696 709
697 // Restore context from the frame. 710 // Restore context from the frame.
698 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 711 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
699 712
700 // If the result is an object (in the ECMA sense), we should get rid 713 // If the result is an object (in the ECMA sense), we should get rid
701 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 714 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
702 // on page 74. 715 // on page 74.
703 Label use_receiver, exit; 716 Label use_receiver, exit;
704 717
705 // If the result is a smi, it is *not* an object in the ECMA sense. 718 // If the result is a smi, it is *not* an object in the ECMA sense.
706 // v0: result 719 // v0: result
707 // sp[0]: receiver (newly allocated object) 720 // sp[0]: receiver (newly allocated object)
708 // sp[1]: number of arguments (smi-tagged) 721 // sp[1]: new.target (if used)
722 // sp[1/2]: number of arguments (smi-tagged)
709 __ JumpIfSmi(v0, &use_receiver); 723 __ JumpIfSmi(v0, &use_receiver);
710 724
711 // If the type of the result (stored in its map) is less than 725 // If the type of the result (stored in its map) is less than
712 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 726 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
713 __ GetObjectType(v0, a1, a3); 727 __ GetObjectType(v0, a1, a3);
714 __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); 728 __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
715 729
716 // Throw away the result of the constructor invocation and use the 730 // Throw away the result of the constructor invocation and use the
717 // on-stack receiver as the result. 731 // on-stack receiver as the result.
718 __ bind(&use_receiver); 732 __ bind(&use_receiver);
719 __ lw(v0, MemOperand(sp)); 733 __ lw(v0, MemOperand(sp));
720 734
721 // Remove receiver from the stack, remove caller arguments, and 735 // Remove receiver from the stack, remove caller arguments, and
722 // return. 736 // return.
723 __ bind(&exit); 737 __ bind(&exit);
724 // v0: result 738 // v0: result
725 // sp[0]: receiver (newly allocated object) 739 // sp[0]: receiver (newly allocated object)
726 // sp[1]: number of arguments (smi-tagged) 740 // sp[1]: new.target (if used)
727 __ lw(a1, MemOperand(sp, kPointerSize)); 741 // sp[1/2]: number of arguments (smi-tagged)
742 int offset = (use_new_target ? 2 : 1) * kPointerSize;
743 __ lw(a1, MemOperand(sp, offset));
728 744
729 // Leave construct frame. 745 // Leave construct frame.
730 } 746 }
731 747
732 __ sll(t0, a1, kPointerSizeLog2 - 1); 748 __ sll(t0, a1, kPointerSizeLog2 - 1);
733 __ Addu(sp, sp, t0); 749 __ Addu(sp, sp, t0);
734 __ Addu(sp, sp, kPointerSize); 750 __ Addu(sp, sp, kPointerSize);
735 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2); 751 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
736 __ Ret(); 752 __ Ret();
737 } 753 }
738 754
739 755
740 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 756 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
741 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 757 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
742 } 758 }
743 759
744 760
745 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 761 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
746 Generate_JSConstructStubHelper(masm, true, false); 762 Generate_JSConstructStubHelper(masm, true, false, false);
747 } 763 }
748 764
749 765
766 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
767 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
768 }
769
770
750 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 771 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
751 // ----------- S t a t e ------------- 772 // ----------- S t a t e -------------
752 // -- a0 : number of arguments 773 // -- a0 : number of arguments
753 // -- a1 : constructor function 774 // -- a1 : constructor function
754 // -- a2 : allocation site or undefined 775 // -- a2 : allocation site or undefined
755 // -- a3 : original constructor 776 // -- a3 : original constructor
756 // -- ra : return address 777 // -- ra : return address
757 // -- sp[...]: constructor arguments 778 // -- sp[...]: constructor arguments
758 // ----------------------------------- 779 // -----------------------------------
759 780
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 } 1855 }
1835 } 1856 }
1836 1857
1837 1858
1838 #undef __ 1859 #undef __
1839 1860
1840 } // namespace internal 1861 } // namespace internal
1841 } // namespace v8 1862 } // namespace v8
1842 1863
1843 #endif // V8_TARGET_ARCH_MIPS 1864 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/mips64/builtins-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698