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

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

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