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

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

Issue 1213303002: PPC: [es6] Make new.target work in functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_PPC 7 #if V8_TARGET_ARCH_PPC
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 __ Push(r4, original_constructor); 330 __ Push(r4, original_constructor);
331 __ CallRuntime(Runtime::kNewObject, 2); 331 __ CallRuntime(Runtime::kNewObject, 2);
332 __ mr(result, r3); 332 __ mr(result, r3);
333 __ b(allocated); 333 __ b(allocated);
334 } 334 }
335 } 335 }
336 336
337 337
338 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 338 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
339 bool is_api_function, 339 bool is_api_function,
340 bool use_new_target,
340 bool create_memento) { 341 bool create_memento) {
341 // ----------- S t a t e ------------- 342 // ----------- S t a t e -------------
342 // -- r3 : number of arguments 343 // -- r3 : number of arguments
343 // -- r4 : constructor function 344 // -- r4 : constructor function
344 // -- r5 : allocation site or undefined 345 // -- r5 : allocation site or undefined
345 // -- r6 : original constructor 346 // -- r6 : original constructor
346 // -- lr : return address 347 // -- lr : return address
347 // -- sp[...]: constructor arguments 348 // -- sp[...]: constructor arguments
348 // ----------------------------------- 349 // -----------------------------------
349 350
350 // Should never create mementos for api functions. 351 // Should never create mementos for api functions.
351 DCHECK(!is_api_function || !create_memento); 352 DCHECK(!is_api_function || !create_memento);
352 353
353 Isolate* isolate = masm->isolate(); 354 Isolate* isolate = masm->isolate();
354 355
355 // Enter a construct frame. 356 // Enter a construct frame.
356 { 357 {
357 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); 358 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
358 359
359 if (create_memento) { 360 if (create_memento) {
360 __ AssertUndefinedOrAllocationSite(r5, r7); 361 __ AssertUndefinedOrAllocationSite(r5, r7);
361 __ push(r5); 362 __ push(r5);
362 } 363 }
363 364
364 // Preserve the two incoming parameters on the stack. 365 // Preserve the incoming parameters on the stack.
365 __ SmiTag(r3); 366 __ SmiTag(r3);
366 __ Push(r3, r4); 367 if (use_new_target) {
368 __ Push(r3, r4, r6);
369 } else {
370 __ Push(r3, r4);
371 }
367 372
368 Label rt_call, allocated, normal_new, count_incremented; 373 Label rt_call, allocated, normal_new, count_incremented;
369 __ cmp(r4, r6); 374 __ cmp(r4, r6);
370 __ beq(&normal_new); 375 __ beq(&normal_new);
371 376
372 // Original constructor and function are different. 377 // Original constructor and function are different.
373 Generate_Runtime_NewObject(masm, create_memento, r6, &count_incremented, 378 Generate_Runtime_NewObject(masm, create_memento, r6, &count_incremented,
374 &allocated); 379 &allocated);
375 __ bind(&normal_new); 380 __ bind(&normal_new);
376 381
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 // r4: constructor function 609 // r4: constructor function
605 __ bind(&rt_call); 610 __ bind(&rt_call);
606 Generate_Runtime_NewObject(masm, create_memento, r4, &count_incremented, 611 Generate_Runtime_NewObject(masm, create_memento, r4, &count_incremented,
607 &allocated); 612 &allocated);
608 613
609 // Receiver for constructor call allocated. 614 // Receiver for constructor call allocated.
610 // r7: JSObject 615 // r7: JSObject
611 __ bind(&allocated); 616 __ bind(&allocated);
612 617
613 if (create_memento) { 618 if (create_memento) {
614 __ LoadP(r5, MemOperand(sp, kPointerSize * 2)); 619 int offset = (use_new_target ? 3 : 2) * kPointerSize;
620 __ LoadP(r5, MemOperand(sp, offset));
615 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); 621 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex);
616 __ cmp(r5, r8); 622 __ cmp(r5, r8);
617 __ beq(&count_incremented); 623 __ beq(&count_incremented);
618 // r5 is an AllocationSite. We are creating a memento from it, so we 624 // r5 is an AllocationSite. We are creating a memento from it, so we
619 // need to increment the memento create count. 625 // need to increment the memento create count.
620 __ LoadP( 626 __ LoadP(
621 r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset)); 627 r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset));
622 __ AddSmiLiteral(r6, r6, Smi::FromInt(1), r0); 628 __ AddSmiLiteral(r6, r6, Smi::FromInt(1), r0);
623 __ StoreP( 629 __ StoreP(
624 r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset), 630 r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset),
625 r0); 631 r0);
626 __ bind(&count_incremented); 632 __ bind(&count_incremented);
627 } 633 }
628 634
629 __ pop(r4); // Constructor function. 635 // Restore the parameters.
636 if (use_new_target) {
637 __ Pop(r4, ip);
638 } else {
639 __ pop(r4);
640 }
630 641
631 __ Push(r7, r7); 642 // Retrieve smi-tagged arguments count from the stack.
643 __ LoadP(r6, MemOperand(sp));
644 __ SmiUntag(r3, r6);
632 645
633 // Reload the number of arguments from the stack. 646 // Push new.target onto the construct frame. This is stored just below the
634 // sp[0]: receiver 647 // receiver on the stack.
635 // sp[1]: receiver 648 if (use_new_target) {
636 // sp[2]: number of arguments (smi-tagged) 649 __ Push(ip, r7, r7);
637 __ LoadP(r6, MemOperand(sp, 2 * kPointerSize)); 650 } else {
651 __ Push(r7, r7);
652 }
638 653
639 // Set up pointer to last argument. 654 // Set up pointer to last argument.
640 __ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset)); 655 __ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset));
641 656
642 // Set up number of arguments for function call below
643 __ SmiUntag(r3, r6);
644
645 // Copy arguments and receiver to the expression stack. 657 // Copy arguments and receiver to the expression stack.
646 // r3: number of arguments 658 // r3: number of arguments
647 // r4: constructor function 659 // r4: constructor function
648 // r5: address of last argument (caller sp) 660 // r5: address of last argument (caller sp)
649 // r6: number of arguments (smi-tagged) 661 // r6: number of arguments (smi-tagged)
650 // sp[0]: receiver 662 // sp[0]: receiver
651 // sp[1]: receiver 663 // sp[1]: receiver
652 // sp[2]: number of arguments (smi-tagged) 664 // sp[2]: new.target (if used)
665 // sp[2/3]: number of arguments (smi-tagged)
653 Label loop, no_args; 666 Label loop, no_args;
654 __ cmpi(r3, Operand::Zero()); 667 __ cmpi(r3, Operand::Zero());
655 __ beq(&no_args); 668 __ beq(&no_args);
656 __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2)); 669 __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2));
657 __ mtctr(r3); 670 __ mtctr(r3);
658 __ bind(&loop); 671 __ bind(&loop);
659 __ subi(ip, ip, Operand(kPointerSize)); 672 __ subi(ip, ip, Operand(kPointerSize));
660 __ LoadPX(r0, MemOperand(r5, ip)); 673 __ LoadPX(r0, MemOperand(r5, ip));
661 __ push(r0); 674 __ push(r0);
662 __ bdnz(&loop); 675 __ bdnz(&loop);
663 __ bind(&no_args); 676 __ bind(&no_args);
664 677
665 // Call the function. 678 // Call the function.
666 // r3: number of arguments 679 // r3: number of arguments
667 // r4: constructor function 680 // r4: constructor function
668 if (is_api_function) { 681 if (is_api_function) {
669 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); 682 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
670 Handle<Code> code = masm->isolate()->builtins()->HandleApiCallConstruct(); 683 Handle<Code> code = masm->isolate()->builtins()->HandleApiCallConstruct();
671 __ Call(code, RelocInfo::CODE_TARGET); 684 __ Call(code, RelocInfo::CODE_TARGET);
672 } else { 685 } else {
673 ParameterCount actual(r3); 686 ParameterCount actual(r3);
674 __ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper()); 687 __ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper());
675 } 688 }
676 689
677 // Store offset of return address for deoptimizer. 690 // Store offset of return address for deoptimizer.
678 if (!is_api_function) { 691 // TODO(arv): Remove the "!use_new_target" before supporting optimization
692 // of functions that reference new.target
693 if (!is_api_function && !use_new_target) {
679 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 694 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
680 } 695 }
681 696
682 // Restore context from the frame. 697 // Restore context from the frame.
683 // r3: result 698 // r3: result
684 // sp[0]: receiver 699 // sp[0]: receiver
685 // sp[1]: number of arguments (smi-tagged) 700 // sp[1]: new.target (if used)
701 // sp[1/2]: number of arguments (smi-tagged)
686 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 702 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
687 703
688 // If the result is an object (in the ECMA sense), we should get rid 704 // If the result is an object (in the ECMA sense), we should get rid
689 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 705 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
690 // on page 74. 706 // on page 74.
691 Label use_receiver, exit; 707 Label use_receiver, exit;
692 708
693 // If the result is a smi, it is *not* an object in the ECMA sense. 709 // If the result is a smi, it is *not* an object in the ECMA sense.
694 // r3: result 710 // r3: result
695 // sp[0]: receiver (newly allocated object) 711 // sp[0]: receiver (newly allocated object)
696 // sp[1]: number of arguments (smi-tagged) 712 // sp[1]: new.target (if used)
713 // sp[1/2]: number of arguments (smi-tagged)
697 __ JumpIfSmi(r3, &use_receiver); 714 __ JumpIfSmi(r3, &use_receiver);
698 715
699 // If the type of the result (stored in its map) is less than 716 // If the type of the result (stored in its map) is less than
700 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 717 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
701 __ CompareObjectType(r3, r4, r6, FIRST_SPEC_OBJECT_TYPE); 718 __ CompareObjectType(r3, r4, r6, FIRST_SPEC_OBJECT_TYPE);
702 __ bge(&exit); 719 __ bge(&exit);
703 720
704 // Throw away the result of the constructor invocation and use the 721 // Throw away the result of the constructor invocation and use the
705 // on-stack receiver as the result. 722 // on-stack receiver as the result.
706 __ bind(&use_receiver); 723 __ bind(&use_receiver);
707 __ LoadP(r3, MemOperand(sp)); 724 __ LoadP(r3, MemOperand(sp));
708 725
709 // Remove receiver from the stack, remove caller arguments, and 726 // Remove receiver from the stack, remove caller arguments, and
710 // return. 727 // return.
711 __ bind(&exit); 728 __ bind(&exit);
712 // r3: result 729 // r3: result
713 // sp[0]: receiver (newly allocated object) 730 // sp[0]: receiver (newly allocated object)
714 // sp[1]: number of arguments (smi-tagged) 731 // sp[1]: new.target (if used)
715 __ LoadP(r4, MemOperand(sp, kPointerSize)); 732 // sp[1/2]: number of arguments (smi-tagged)
733 int offset = (use_new_target ? 2 : 1) * kPointerSize;
734 __ LoadP(r4, MemOperand(sp, offset));
716 735
717 // Leave construct frame. 736 // Leave construct frame.
718 } 737 }
719 738
720 __ SmiToPtrArrayOffset(r4, r4); 739 __ SmiToPtrArrayOffset(r4, r4);
721 __ add(sp, sp, r4); 740 __ add(sp, sp, r4);
722 __ addi(sp, sp, Operand(kPointerSize)); 741 __ addi(sp, sp, Operand(kPointerSize));
723 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5); 742 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5);
724 __ blr(); 743 __ blr();
725 } 744 }
726 745
727 746
728 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 747 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
729 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 748 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
730 } 749 }
731 750
732 751
733 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 752 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
734 Generate_JSConstructStubHelper(masm, true, false); 753 Generate_JSConstructStubHelper(masm, true, false, false);
735 } 754 }
736 755
737 756
757 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
758 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
759 }
760
761
738 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 762 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
739 // ----------- S t a t e ------------- 763 // ----------- S t a t e -------------
740 // -- r3 : number of arguments 764 // -- r3 : number of arguments
741 // -- r4 : constructor function 765 // -- r4 : constructor function
742 // -- r5 : allocation site or undefined 766 // -- r5 : allocation site or undefined
743 // -- r6 : original constructor 767 // -- r6 : original constructor
744 // -- lr : return address 768 // -- lr : return address
745 // -- sp[...]: constructor arguments 769 // -- sp[...]: constructor arguments
746 // ----------------------------------- 770 // -----------------------------------
747 771
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 __ bkpt(0); 1899 __ bkpt(0);
1876 } 1900 }
1877 } 1901 }
1878 1902
1879 1903
1880 #undef __ 1904 #undef __
1881 } // namespace internal 1905 } // namespace internal
1882 } // namespace v8 1906 } // namespace v8
1883 1907
1884 #endif // V8_TARGET_ARCH_PPC 1908 #endif // V8_TARGET_ARCH_PPC
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698