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

Side by Side Diff: src/arm64/builtins-arm64.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/arm/builtins-arm.cc ('k') | src/builtins.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 } 302 }
303 303
304 304
305 static void Generate_Runtime_NewObject(MacroAssembler* masm, 305 static void Generate_Runtime_NewObject(MacroAssembler* masm,
306 bool create_memento, 306 bool create_memento,
307 Register original_constructor, 307 Register original_constructor,
308 Label* count_incremented, 308 Label* count_incremented,
309 Label* allocated) { 309 Label* allocated) {
310 if (create_memento) { 310 if (create_memento) {
311 // Get the cell or allocation site. 311 // Get the cell or allocation site.
312 __ Peek(x4, 2 * kXRegSize); 312 __ Peek(x4, 3 * kXRegSize);
313 __ Push(x4); 313 __ Push(x4);
314 __ Push(x1); // Argument for Runtime_NewObject. 314 __ Push(x1); // Argument for Runtime_NewObject.
315 __ Push(original_constructor); 315 __ Push(original_constructor);
316 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); 316 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
317 __ Mov(x4, x0); 317 __ Mov(x4, x0);
318 // If we ended up using the runtime, and we want a memento, then the 318 // If we ended up using the runtime, and we want a memento, then the
319 // runtime call made it for us, and we shouldn't do create count 319 // runtime call made it for us, and we shouldn't do create count
320 // increment. 320 // increment.
321 __ jmp(count_incremented); 321 __ jmp(count_incremented);
322 } else { 322 } else {
323 __ Push(x1); // Argument for Runtime_NewObject. 323 __ Push(x1); // Argument for Runtime_NewObject.
324 __ Push(original_constructor); 324 __ Push(original_constructor);
325 __ CallRuntime(Runtime::kNewObject, 2); 325 __ CallRuntime(Runtime::kNewObject, 2);
326 __ Mov(x4, x0); 326 __ Mov(x4, x0);
327 __ jmp(allocated); 327 __ jmp(allocated);
328 } 328 }
329 } 329 }
330 330
331 331
332 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 332 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
333 bool is_api_function, 333 bool is_api_function,
334 bool use_new_target,
335 bool create_memento) { 334 bool create_memento) {
336 // ----------- S t a t e ------------- 335 // ----------- S t a t e -------------
337 // -- x0 : number of arguments 336 // -- x0 : number of arguments
338 // -- x1 : constructor function 337 // -- x1 : constructor function
339 // -- x2 : allocation site or undefined 338 // -- x2 : allocation site or undefined
340 // -- x3 : original constructor 339 // -- x3 : original constructor
341 // -- lr : return address 340 // -- lr : return address
342 // -- sp[...]: constructor arguments 341 // -- sp[...]: constructor arguments
343 // ----------------------------------- 342 // -----------------------------------
344 343
(...skipping 12 matching lines...) Expand all
357 __ AssertUndefinedOrAllocationSite(x2, x10); 356 __ AssertUndefinedOrAllocationSite(x2, x10);
358 __ Push(x2); 357 __ Push(x2);
359 } 358 }
360 359
361 Register argc = x0; 360 Register argc = x0;
362 Register constructor = x1; 361 Register constructor = x1;
363 Register original_constructor = x3; 362 Register original_constructor = x3;
364 363
365 // Preserve the incoming parameters on the stack. 364 // Preserve the incoming parameters on the stack.
366 __ SmiTag(argc); 365 __ SmiTag(argc);
367 if (use_new_target) { 366 __ Push(argc, constructor, original_constructor);
368 __ Push(argc, constructor, original_constructor); 367 // sp[0]: new.target
369 } else { 368 // sp[1]: Constructor function.
370 __ Push(argc, constructor); 369 // sp[2]: number of arguments (smi-tagged)
371 }
372 // sp[0]: new.target (if used)
373 // sp[0/1]: Constructor function.
374 // sp[1/2]: number of arguments (smi-tagged)
375 370
376 Label rt_call, count_incremented, allocated, normal_new; 371 Label rt_call, count_incremented, allocated, normal_new;
377 __ Cmp(constructor, original_constructor); 372 __ Cmp(constructor, original_constructor);
378 __ B(eq, &normal_new); 373 __ B(eq, &normal_new);
379 Generate_Runtime_NewObject(masm, create_memento, original_constructor, 374 Generate_Runtime_NewObject(masm, create_memento, original_constructor,
380 &count_incremented, &allocated); 375 &count_incremented, &allocated);
381 376
382 __ Bind(&normal_new); 377 __ Bind(&normal_new);
383 378
384 // Try to allocate the object without transitioning into C code. If any of 379 // Try to allocate the object without transitioning into C code. If any of
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 // Allocate the new receiver object using the runtime call. 575 // Allocate the new receiver object using the runtime call.
581 __ Bind(&rt_call); 576 __ Bind(&rt_call);
582 Generate_Runtime_NewObject(masm, create_memento, constructor, 577 Generate_Runtime_NewObject(masm, create_memento, constructor,
583 &count_incremented, &allocated); 578 &count_incremented, &allocated);
584 579
585 // Receiver for constructor call allocated. 580 // Receiver for constructor call allocated.
586 // x4: JSObject 581 // x4: JSObject
587 __ Bind(&allocated); 582 __ Bind(&allocated);
588 583
589 if (create_memento) { 584 if (create_memento) {
590 int offset = (use_new_target ? 3 : 2) * kXRegSize; 585 __ Peek(x10, 3 * kXRegSize);
591 __ Peek(x10, offset);
592 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); 586 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented);
593 // r2 is an AllocationSite. We are creating a memento from it, so we 587 // r2 is an AllocationSite. We are creating a memento from it, so we
594 // need to increment the memento create count. 588 // need to increment the memento create count.
595 __ Ldr(x5, FieldMemOperand(x10, 589 __ Ldr(x5, FieldMemOperand(x10,
596 AllocationSite::kPretenureCreateCountOffset)); 590 AllocationSite::kPretenureCreateCountOffset));
597 __ Add(x5, x5, Operand(Smi::FromInt(1))); 591 __ Add(x5, x5, Operand(Smi::FromInt(1)));
598 __ Str(x5, FieldMemOperand(x10, 592 __ Str(x5, FieldMemOperand(x10,
599 AllocationSite::kPretenureCreateCountOffset)); 593 AllocationSite::kPretenureCreateCountOffset));
600 __ bind(&count_incremented); 594 __ bind(&count_incremented);
601 } 595 }
602 596
603 // Restore the parameters. 597 // Restore the parameters.
604 if (use_new_target) { 598 __ Pop(original_constructor);
605 __ Pop(original_constructor);
606 }
607 __ Pop(constructor); 599 __ Pop(constructor);
608 600
609 // Reload the number of arguments from the stack. 601 // Reload the number of arguments from the stack.
610 // Set it up in x0 for the function call below. 602 // Set it up in x0 for the function call below.
611 // jssp[0]: number of arguments (smi-tagged) 603 // jssp[0]: number of arguments (smi-tagged)
612 __ Peek(argc, 0); // Load number of arguments. 604 __ Peek(argc, 0); // Load number of arguments.
613 __ SmiUntag(argc); 605 __ SmiUntag(argc);
614 606
615 if (use_new_target) { 607 __ Push(original_constructor, x4, x4);
616 __ Push(original_constructor, x4, x4);
617 } else {
618 __ Push(x4, x4);
619 }
620 608
621 // Set up pointer to last argument. 609 // Set up pointer to last argument.
622 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); 610 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset);
623 611
624 // Copy arguments and receiver to the expression stack. 612 // Copy arguments and receiver to the expression stack.
625 // Copy 2 values every loop to use ldp/stp. 613 // Copy 2 values every loop to use ldp/stp.
626 // x0: number of arguments 614 // x0: number of arguments
627 // x1: constructor function 615 // x1: constructor function
628 // x2: address of last argument (caller sp) 616 // x2: address of last argument (caller sp)
629 // jssp[0]: receiver 617 // jssp[0]: receiver
630 // jssp[1]: receiver 618 // jssp[1]: receiver
631 // jssp[2]: new.target (if used) 619 // jssp[2]: new.target
632 // jssp[2/3]: number of arguments (smi-tagged) 620 // jssp[3]: number of arguments (smi-tagged)
633 // Compute the start address of the copy in x3. 621 // Compute the start address of the copy in x3.
634 __ Add(x3, x2, Operand(argc, LSL, kPointerSizeLog2)); 622 __ Add(x3, x2, Operand(argc, LSL, kPointerSizeLog2));
635 Label loop, entry, done_copying_arguments; 623 Label loop, entry, done_copying_arguments;
636 __ B(&entry); 624 __ B(&entry);
637 __ Bind(&loop); 625 __ Bind(&loop);
638 __ Ldp(x10, x11, MemOperand(x3, -2 * kPointerSize, PreIndex)); 626 __ Ldp(x10, x11, MemOperand(x3, -2 * kPointerSize, PreIndex));
639 __ Push(x11, x10); 627 __ Push(x11, x10);
640 __ Bind(&entry); 628 __ Bind(&entry);
641 __ Cmp(x3, x2); 629 __ Cmp(x3, x2);
642 __ B(gt, &loop); 630 __ B(gt, &loop);
(...skipping 10 matching lines...) Expand all
653 __ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset)); 641 __ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset));
654 Handle<Code> code = 642 Handle<Code> code =
655 masm->isolate()->builtins()->HandleApiCallConstruct(); 643 masm->isolate()->builtins()->HandleApiCallConstruct();
656 __ Call(code, RelocInfo::CODE_TARGET); 644 __ Call(code, RelocInfo::CODE_TARGET);
657 } else { 645 } else {
658 ParameterCount actual(argc); 646 ParameterCount actual(argc);
659 __ InvokeFunction(constructor, actual, CALL_FUNCTION, NullCallWrapper()); 647 __ InvokeFunction(constructor, actual, CALL_FUNCTION, NullCallWrapper());
660 } 648 }
661 649
662 // Store offset of return address for deoptimizer. 650 // Store offset of return address for deoptimizer.
663 // TODO(arv): Remove the "!use_new_target" before supporting optimization 651 if (!is_api_function) {
664 // of functions that reference new.target
665 if (!is_api_function && !use_new_target) {
666 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 652 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
667 } 653 }
668 654
669 // Restore the context from the frame. 655 // Restore the context from the frame.
670 // x0: result 656 // x0: result
671 // jssp[0]: receiver 657 // jssp[0]: receiver
672 // jssp[1]: new.target (if used) 658 // jssp[1]: new.target
673 // jssp[1/2]: number of arguments (smi-tagged) 659 // jssp[2]: number of arguments (smi-tagged)
674 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 660 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
675 661
676 // If the result is an object (in the ECMA sense), we should get rid 662 // If the result is an object (in the ECMA sense), we should get rid
677 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 663 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
678 // on page 74. 664 // on page 74.
679 Label use_receiver, exit; 665 Label use_receiver, exit;
680 666
681 // If the result is a smi, it is *not* an object in the ECMA sense. 667 // If the result is a smi, it is *not* an object in the ECMA sense.
682 // x0: result 668 // x0: result
683 // jssp[0]: receiver (newly allocated object) 669 // jssp[0]: receiver (newly allocated object)
684 // jssp[1]: number of arguments (smi-tagged) 670 // jssp[1]: number of arguments (smi-tagged)
685 __ JumpIfSmi(x0, &use_receiver); 671 __ JumpIfSmi(x0, &use_receiver);
686 672
687 // If the type of the result (stored in its map) is less than 673 // If the type of the result (stored in its map) is less than
688 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 674 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
689 __ JumpIfObjectType(x0, x1, x3, FIRST_SPEC_OBJECT_TYPE, &exit, ge); 675 __ JumpIfObjectType(x0, x1, x3, FIRST_SPEC_OBJECT_TYPE, &exit, ge);
690 676
691 // Throw away the result of the constructor invocation and use the 677 // Throw away the result of the constructor invocation and use the
692 // on-stack receiver as the result. 678 // on-stack receiver as the result.
693 __ Bind(&use_receiver); 679 __ Bind(&use_receiver);
694 __ Peek(x0, 0); 680 __ Peek(x0, 0);
695 681
696 // Remove the receiver from the stack, remove caller arguments, and 682 // Remove the receiver from the stack, remove caller arguments, and
697 // return. 683 // return.
698 __ Bind(&exit); 684 __ Bind(&exit);
699 // x0: result 685 // x0: result
700 // jssp[0]: receiver (newly allocated object) 686 // jssp[0]: receiver (newly allocated object)
701 // jssp[1]: new.target (if used) 687 // jssp[1]: new.target (original constructor)
702 // jssp[1/2]: number of arguments (smi-tagged) 688 // jssp[2]: number of arguments (smi-tagged)
703 int offset = (use_new_target ? 2 : 1) * kXRegSize; 689 __ Peek(x1, 2 * kXRegSize);
704 __ Peek(x1, offset);
705 690
706 // Leave construct frame. 691 // Leave construct frame.
707 } 692 }
708 693
709 __ DropBySMI(x1); 694 __ DropBySMI(x1);
710 __ Drop(1); 695 __ Drop(1);
711 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); 696 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2);
712 __ Ret(); 697 __ Ret();
713 } 698 }
714 699
715 700
716 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 701 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
717 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new); 702 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
718 } 703 }
719 704
720 705
721 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 706 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
722 Generate_JSConstructStubHelper(masm, true, false, false); 707 Generate_JSConstructStubHelper(masm, true, false);
723 } 708 }
724 709
725 710
726 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
727 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
728 }
729
730
731 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 711 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
732 // ----------- S t a t e ------------- 712 // ----------- S t a t e -------------
733 // -- x0 : number of arguments 713 // -- x0 : number of arguments
734 // -- x1 : constructor function 714 // -- x1 : constructor function
735 // -- x2 : allocation site or undefined 715 // -- x2 : allocation site or undefined
736 // -- x3 : original constructor 716 // -- x3 : original constructor
737 // -- lr : return address 717 // -- lr : return address
738 // -- sp[...]: constructor arguments 718 // -- sp[...]: constructor arguments
739 // ----------------------------------- 719 // -----------------------------------
740 ASM_LOCATION("Builtins::Generate_JSConstructStubForDerived"); 720 ASM_LOCATION("Builtins::Generate_JSConstructStubForDerived");
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 } 1839 }
1860 } 1840 }
1861 1841
1862 1842
1863 #undef __ 1843 #undef __
1864 1844
1865 } // namespace internal 1845 } // namespace internal
1866 } // namespace v8 1846 } // namespace v8
1867 1847
1868 #endif // V8_TARGET_ARCH_ARM 1848 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/builtins.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698