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

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: Also adjust the create memento branch 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
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 12 matching lines...) Expand all
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 two incoming parameters on the stack.
383 __ sll(a0, a0, kSmiTagSize); // Tag arguments count. 384 __ SmiTag(a0); // Tag arguments count.
384 __ MultiPushReversed(a0.bit() | a1.bit()); 385 if (use_new_target) {
386 __ MultiPushReversed(a0.bit() | a1.bit() | a3.bit());
paul.l... 2015/06/26 04:02:24 nit: this would be more readable as Push(a0, a1, a
387 } else {
388 __ MultiPushReversed(a0.bit() | a1.bit());
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
paul.l... 2015/06/26 04:02:24 Set up a3 as Smi-tagged loop counter. __ SmiTag(
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;
669 __ jmp(&entry); 679 __ jmp(&entry);
670 __ bind(&loop); 680 __ bind(&loop);
671 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); 681 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
672 __ Addu(t0, a2, Operand(t0)); 682 __ Addu(t0, a2, Operand(t0));
673 __ lw(t1, MemOperand(t0)); 683 __ lw(t1, MemOperand(t0));
674 __ push(t1); 684 __ push(t1);
675 __ bind(&entry); 685 __ bind(&entry);
676 __ Addu(a3, a3, Operand(-2)); 686 __ Addu(a3, a3, Operand(-2));
677 __ Branch(&loop, greater_equal, a3, Operand(zero_reg)); 687 __ Branch(&loop, greater_equal, a3, Operand(zero_reg));
678 688
679 // Call the function. 689 // Call the function.
680 // a0: number of arguments 690 // a0: number of arguments
681 // a1: constructor function 691 // a1: constructor function
682 if (is_api_function) { 692 if (is_api_function) {
683 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 693 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
684 Handle<Code> code = 694 Handle<Code> code =
685 masm->isolate()->builtins()->HandleApiCallConstruct(); 695 masm->isolate()->builtins()->HandleApiCallConstruct();
686 __ Call(code, RelocInfo::CODE_TARGET); 696 __ Call(code, RelocInfo::CODE_TARGET);
687 } else { 697 } else {
688 ParameterCount actual(a0); 698 ParameterCount actual(a0);
689 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); 699 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper());
690 } 700 }
691 701
692 // Store offset of return address for deoptimizer. 702 // Store offset of return address for deoptimizer.
693 if (!is_api_function) { 703 // TODO(arv): Remove the "!use_new_target" before supporting optimization
704 // of functions that reference new.target
705 if (!is_api_function && !use_new_target) {
694 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 706 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
695 } 707 }
696 708
697 // Restore context from the frame. 709 // Restore context from the frame.
698 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 710 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
699 711
700 // If the result is an object (in the ECMA sense), we should get rid 712 // 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 713 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
702 // on page 74. 714 // on page 74.
703 Label use_receiver, exit; 715 Label use_receiver, exit;
704 716
705 // If the result is a smi, it is *not* an object in the ECMA sense. 717 // If the result is a smi, it is *not* an object in the ECMA sense.
706 // v0: result 718 // v0: result
707 // sp[0]: receiver (newly allocated object) 719 // sp[0]: receiver (newly allocated object)
708 // sp[1]: number of arguments (smi-tagged) 720 // sp[1]: new.target (if used)
721 // sp[1/2]: number of arguments (smi-tagged)
709 __ JumpIfSmi(v0, &use_receiver); 722 __ JumpIfSmi(v0, &use_receiver);
710 723
711 // If the type of the result (stored in its map) is less than 724 // 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. 725 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
713 __ GetObjectType(v0, a1, a3); 726 __ GetObjectType(v0, a1, a3);
714 __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); 727 __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
715 728
716 // Throw away the result of the constructor invocation and use the 729 // Throw away the result of the constructor invocation and use the
717 // on-stack receiver as the result. 730 // on-stack receiver as the result.
718 __ bind(&use_receiver); 731 __ bind(&use_receiver);
719 __ lw(v0, MemOperand(sp)); 732 __ lw(v0, MemOperand(sp));
720 733
721 // Remove receiver from the stack, remove caller arguments, and 734 // Remove receiver from the stack, remove caller arguments, and
722 // return. 735 // return.
723 __ bind(&exit); 736 __ bind(&exit);
724 // v0: result 737 // v0: result
725 // sp[0]: receiver (newly allocated object) 738 // sp[0]: receiver (newly allocated object)
726 // sp[1]: number of arguments (smi-tagged) 739 // sp[1]: new.target (if used)
727 __ lw(a1, MemOperand(sp, kPointerSize)); 740 // sp[1/2]: number of arguments (smi-tagged)
741 int offset = (use_new_target ? 2 : 1) * kPointerSize;
742 __ lw(a1, MemOperand(sp, offset));
728 743
729 // Leave construct frame. 744 // Leave construct frame.
730 } 745 }
731 746
732 __ sll(t0, a1, kPointerSizeLog2 - 1); 747 __ sll(t0, a1, kPointerSizeLog2 - 1);
733 __ Addu(sp, sp, t0); 748 __ Addu(sp, sp, t0);
734 __ Addu(sp, sp, kPointerSize); 749 __ Addu(sp, sp, kPointerSize);
735 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2); 750 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
736 __ Ret(); 751 __ Ret();
737 } 752 }
738 753
739 754
740 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 755 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
741 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 756 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
742 } 757 }
743 758
744 759
745 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 760 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
746 Generate_JSConstructStubHelper(masm, true, false); 761 Generate_JSConstructStubHelper(masm, true, false, false);
747 } 762 }
748 763
749 764
765 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
766 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
767 }
768
769
750 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 770 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
751 // ----------- S t a t e ------------- 771 // ----------- S t a t e -------------
752 // -- a0 : number of arguments 772 // -- a0 : number of arguments
753 // -- a1 : constructor function 773 // -- a1 : constructor function
754 // -- a2 : allocation site or undefined 774 // -- a2 : allocation site or undefined
755 // -- a3 : original constructor 775 // -- a3 : original constructor
756 // -- ra : return address 776 // -- ra : return address
757 // -- sp[...]: constructor arguments 777 // -- sp[...]: constructor arguments
758 // ----------------------------------- 778 // -----------------------------------
759 779
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 } 1854 }
1835 } 1855 }
1836 1856
1837 1857
1838 #undef __ 1858 #undef __
1839 1859
1840 } // namespace internal 1860 } // namespace internal
1841 } // namespace v8 1861 } // namespace v8
1842 1862
1843 #endif // V8_TARGET_ARCH_MIPS 1863 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698