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

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

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