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

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