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

Side by Side Diff: src/arm/builtins-arm.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 | « no previous file | src/arm64/builtins-arm64.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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 if (create_memento) { 336 if (create_memento) {
337 __ jmp(count_incremented); 337 __ jmp(count_incremented);
338 } else { 338 } else {
339 __ jmp(allocated); 339 __ jmp(allocated);
340 } 340 }
341 } 341 }
342 342
343 343
344 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 344 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
345 bool is_api_function, 345 bool is_api_function,
346 bool use_new_target,
346 bool create_memento) { 347 bool create_memento) {
347 // ----------- S t a t e ------------- 348 // ----------- S t a t e -------------
348 // -- r0 : number of arguments 349 // -- r0 : number of arguments
349 // -- r1 : constructor function 350 // -- r1 : constructor function
350 // -- r2 : allocation site or undefined 351 // -- r2 : allocation site or undefined
351 // -- r3 : original constructor 352 // -- r3 : original constructor
352 // -- lr : return address 353 // -- lr : return address
353 // -- sp[...]: constructor arguments 354 // -- sp[...]: constructor arguments
354 // ----------------------------------- 355 // -----------------------------------
355 356
356 // Should never create mementos for api functions. 357 // Should never create mementos for api functions.
357 DCHECK(!is_api_function || !create_memento); 358 DCHECK(!is_api_function || !create_memento);
358 359
359 Isolate* isolate = masm->isolate(); 360 Isolate* isolate = masm->isolate();
360 361
361 // Enter a construct frame. 362 // Enter a construct frame.
362 { 363 {
363 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT); 364 FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
364 365
365 if (create_memento) { 366 if (create_memento) {
366 __ AssertUndefinedOrAllocationSite(r2, r4); 367 __ AssertUndefinedOrAllocationSite(r2, r4);
367 __ push(r2); 368 __ push(r2);
368 } 369 }
369 370
370 // Preserve the two incoming parameters on the stack. 371 // Preserve the incoming parameters on the stack.
371 __ SmiTag(r0); 372 __ SmiTag(r0);
372 __ push(r0); // Smi-tagged arguments count. 373 __ push(r0);
373 __ push(r1); // Constructor function. 374 __ push(r1);
375 if (use_new_target) {
376 __ push(r3);
377 }
374 378
375 Label rt_call, allocated, normal_new, count_incremented; 379 Label rt_call, allocated, normal_new, count_incremented;
376 __ cmp(r1, r3); 380 __ cmp(r1, r3);
377 __ b(eq, &normal_new); 381 __ b(eq, &normal_new);
378 382
379 // Original constructor and function are different. 383 // Original constructor and function are different.
380 Generate_Runtime_NewObject(masm, create_memento, r3, &count_incremented, 384 Generate_Runtime_NewObject(masm, create_memento, r3, &count_incremented,
381 &allocated); 385 &allocated);
382 __ bind(&normal_new); 386 __ bind(&normal_new);
383 387
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 // r1: constructor function 607 // r1: constructor function
604 __ bind(&rt_call); 608 __ bind(&rt_call);
605 Generate_Runtime_NewObject(masm, create_memento, r1, &count_incremented, 609 Generate_Runtime_NewObject(masm, create_memento, r1, &count_incremented,
606 &allocated); 610 &allocated);
607 611
608 // Receiver for constructor call allocated. 612 // Receiver for constructor call allocated.
609 // r4: JSObject 613 // r4: JSObject
610 __ bind(&allocated); 614 __ bind(&allocated);
611 615
612 if (create_memento) { 616 if (create_memento) {
613 __ ldr(r2, MemOperand(sp, kPointerSize * 2)); 617 int offset = (use_new_target ? 3 : 2) * kPointerSize;
618 __ ldr(r2, MemOperand(sp, offset));
614 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); 619 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
615 __ cmp(r2, r5); 620 __ cmp(r2, r5);
616 __ b(eq, &count_incremented); 621 __ b(eq, &count_incremented);
617 // r2 is an AllocationSite. We are creating a memento from it, so we 622 // r2 is an AllocationSite. We are creating a memento from it, so we
618 // need to increment the memento create count. 623 // need to increment the memento create count.
619 __ ldr(r3, FieldMemOperand(r2, 624 __ ldr(r3, FieldMemOperand(r2,
620 AllocationSite::kPretenureCreateCountOffset)); 625 AllocationSite::kPretenureCreateCountOffset));
621 __ add(r3, r3, Operand(Smi::FromInt(1))); 626 __ add(r3, r3, Operand(Smi::FromInt(1)));
622 __ str(r3, FieldMemOperand(r2, 627 __ str(r3, FieldMemOperand(r2,
623 AllocationSite::kPretenureCreateCountOffset)); 628 AllocationSite::kPretenureCreateCountOffset));
624 __ bind(&count_incremented); 629 __ bind(&count_incremented);
625 } 630 }
626 631
627 __ pop(r1); // Constructor function. 632 // Restore the parameters.
633 if (use_new_target) {
634 __ pop(r3);
635 }
636 __ pop(r1);
628 637
638 // Retrieve smi-tagged arguments count from the stack.
639 __ ldr(r0, MemOperand(sp));
640 __ SmiUntag(r0);
641
642 // Push new.target onto the construct frame. This is stored just below the
643 // receiver on the stack.
644 if (use_new_target) {
645 __ push(r3);
646 }
629 __ push(r4); 647 __ push(r4);
630 __ push(r4); 648 __ push(r4);
631 649
632 // Reload the number of arguments from the stack.
633 // sp[0]: receiver
634 // sp[1]: receiver
635 // sp[2]: number of arguments (smi-tagged)
636 __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
637
638 // Set up pointer to last argument. 650 // Set up pointer to last argument.
639 __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); 651 __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
640 652
641 // Set up number of arguments for function call below
642 __ SmiUntag(r0, r3);
643
644 // Copy arguments and receiver to the expression stack. 653 // Copy arguments and receiver to the expression stack.
645 // r0: number of arguments 654 // r0: number of arguments
646 // r1: constructor function 655 // r1: constructor function
647 // r2: address of last argument (caller sp) 656 // r2: address of last argument (caller sp)
648 // r3: number of arguments (smi-tagged) 657 // r3: number of arguments (smi-tagged)
649 // sp[0]: receiver 658 // sp[0]: receiver
650 // sp[1]: receiver 659 // sp[1]: receiver
651 // sp[2]: number of arguments (smi-tagged) 660 // sp[2]: new.target (if used)
661 // sp[2/3]: number of arguments (smi-tagged)
652 Label loop, entry; 662 Label loop, entry;
663 __ SmiTag(r3, r0);
653 __ b(&entry); 664 __ b(&entry);
654 __ bind(&loop); 665 __ bind(&loop);
655 __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1)); 666 __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1));
656 __ push(ip); 667 __ push(ip);
657 __ bind(&entry); 668 __ bind(&entry);
658 __ sub(r3, r3, Operand(2), SetCC); 669 __ sub(r3, r3, Operand(2), SetCC);
659 __ b(ge, &loop); 670 __ b(ge, &loop);
660 671
661 // Call the function. 672 // Call the function.
662 // r0: number of arguments 673 // r0: number of arguments
663 // r1: constructor function 674 // r1: constructor function
664 if (is_api_function) { 675 if (is_api_function) {
665 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 676 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
666 Handle<Code> code = 677 Handle<Code> code =
667 masm->isolate()->builtins()->HandleApiCallConstruct(); 678 masm->isolate()->builtins()->HandleApiCallConstruct();
668 __ Call(code, RelocInfo::CODE_TARGET); 679 __ Call(code, RelocInfo::CODE_TARGET);
669 } else { 680 } else {
670 ParameterCount actual(r0); 681 ParameterCount actual(r0);
671 __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper()); 682 __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper());
672 } 683 }
673 684
674 // Store offset of return address for deoptimizer. 685 // Store offset of return address for deoptimizer.
675 if (!is_api_function) { 686 // TODO(arv): Remove the "!use_new_target" before supporting optimization
687 // of functions that reference new.target
688 if (!is_api_function && !use_new_target) {
676 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 689 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
677 } 690 }
678 691
679 // Restore context from the frame. 692 // Restore context from the frame.
680 // r0: result 693 // r0: result
681 // sp[0]: receiver 694 // sp[0]: receiver
682 // sp[1]: number of arguments (smi-tagged) 695 // sp[1]: new.target (if used)
696 // sp[1/2]: number of arguments (smi-tagged)
683 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 697 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
684 698
685 // 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
686 // 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
687 // on page 74. 701 // on page 74.
688 Label use_receiver, exit; 702 Label use_receiver, exit;
689 703
690 // 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.
691 // r0: result 705 // r0: result
692 // sp[0]: receiver (newly allocated object) 706 // sp[0]: receiver (newly allocated object)
693 // sp[1]: number of arguments (smi-tagged) 707 // sp[1]: new.target (if used)
708 // sp[1/2]: number of arguments (smi-tagged)
694 __ JumpIfSmi(r0, &use_receiver); 709 __ JumpIfSmi(r0, &use_receiver);
695 710
696 // 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
697 // 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.
698 __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE); 713 __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE);
699 __ b(ge, &exit); 714 __ b(ge, &exit);
700 715
701 // Throw away the result of the constructor invocation and use the 716 // Throw away the result of the constructor invocation and use the
702 // on-stack receiver as the result. 717 // on-stack receiver as the result.
703 __ bind(&use_receiver); 718 __ bind(&use_receiver);
704 __ ldr(r0, MemOperand(sp)); 719 __ ldr(r0, MemOperand(sp));
705 720
706 // Remove receiver from the stack, remove caller arguments, and 721 // Remove receiver from the stack, remove caller arguments, and
707 // return. 722 // return.
708 __ bind(&exit); 723 __ bind(&exit);
709 // r0: result 724 // r0: result
710 // sp[0]: receiver (newly allocated object) 725 // sp[0]: receiver (newly allocated object)
711 // sp[1]: number of arguments (smi-tagged) 726 // sp[1]: new.target (if used)
712 __ ldr(r1, MemOperand(sp, kPointerSize)); 727 // sp[1/2]: number of arguments (smi-tagged)
728 int offset = (use_new_target ? 2 : 1) * kPointerSize;
729 __ ldr(r1, MemOperand(sp, offset));
713 730
714 // Leave construct frame. 731 // Leave construct frame.
715 } 732 }
716 733
717 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); 734 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
718 __ add(sp, sp, Operand(kPointerSize)); 735 __ add(sp, sp, Operand(kPointerSize));
719 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2); 736 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2);
720 __ Jump(lr); 737 __ Jump(lr);
721 } 738 }
722 739
723 740
724 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 741 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
725 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 742 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new);
726 } 743 }
727 744
728 745
729 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 746 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
730 Generate_JSConstructStubHelper(masm, true, false); 747 Generate_JSConstructStubHelper(masm, true, false, false);
731 } 748 }
732 749
733 750
751 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
752 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
753 }
754
755
734 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 756 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
735 // ----------- S t a t e ------------- 757 // ----------- S t a t e -------------
736 // -- r0 : number of arguments 758 // -- r0 : number of arguments
737 // -- r1 : constructor function 759 // -- r1 : constructor function
738 // -- r2 : allocation site or undefined 760 // -- r2 : allocation site or undefined
739 // -- r3 : original constructor 761 // -- r3 : original constructor
740 // -- lr : return address 762 // -- lr : return address
741 // -- sp[...]: constructor arguments 763 // -- sp[...]: constructor arguments
742 // ----------------------------------- 764 // -----------------------------------
743 765
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 } 1828 }
1807 } 1829 }
1808 1830
1809 1831
1810 #undef __ 1832 #undef __
1811 1833
1812 } // namespace internal 1834 } // namespace internal
1813 } // namespace v8 1835 } // namespace v8
1814 1836
1815 #endif // V8_TARGET_ARCH_ARM 1837 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/builtins-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698