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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 1693513002: [runtime] Introduce FastNewStrictArgumentsStub to optimize strict arguments. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix mips and mips64. Created 4 years, 10 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/x64/builtins-x64.cc ('k') | src/x64/interface-descriptors-x64.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 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 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 __ xorp(r8, r8); 644 __ xorp(r8, r8);
645 __ testp(rbx, rbx); 645 __ testp(rbx, rbx);
646 __ j(zero, &no_parameter_map, Label::kNear); 646 __ j(zero, &no_parameter_map, Label::kNear);
647 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); 647 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize));
648 __ bind(&no_parameter_map); 648 __ bind(&no_parameter_map);
649 649
650 // 2. Backing store. 650 // 2. Backing store.
651 __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize)); 651 __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize));
652 652
653 // 3. Arguments object. 653 // 3. Arguments object.
654 __ addp(r8, Immediate(Heap::kSloppyArgumentsObjectSize)); 654 __ addp(r8, Immediate(JSSloppyArgumentsObject::kSize));
655 655
656 // Do the allocation of all three objects in one go. 656 // Do the allocation of all three objects in one go.
657 __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT); 657 __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT);
658 658
659 // rax = address of new object(s) (tagged) 659 // rax = address of new object(s) (tagged)
660 // r11 = argument count (untagged) 660 // r11 = argument count (untagged)
661 // Get the arguments map from the current native context into r9. 661 // Get the arguments map from the current native context into r9.
662 Label has_mapped_parameters, instantiate; 662 Label has_mapped_parameters, instantiate;
663 __ movp(r9, NativeContextOperand()); 663 __ movp(r9, NativeContextOperand());
664 __ testp(rbx, rbx); 664 __ testp(rbx, rbx);
(...skipping 11 matching lines...) Expand all
676 // rax = address of new object (tagged) 676 // rax = address of new object (tagged)
677 // rbx = mapped parameter count (untagged) 677 // rbx = mapped parameter count (untagged)
678 // r11 = argument count (untagged) 678 // r11 = argument count (untagged)
679 // r9 = address of arguments map (tagged) 679 // r9 = address of arguments map (tagged)
680 __ movp(FieldOperand(rax, JSObject::kMapOffset), r9); 680 __ movp(FieldOperand(rax, JSObject::kMapOffset), r9);
681 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); 681 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
682 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); 682 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
683 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); 683 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
684 684
685 // Set up the callee in-object property. 685 // Set up the callee in-object property.
686 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
687 __ AssertNotSmi(rdi); 686 __ AssertNotSmi(rdi);
688 __ movp(FieldOperand(rax, JSObject::kHeaderSize + 687 __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kCalleeOffset), rdi);
689 Heap::kArgumentsCalleeIndex * kPointerSize),
690 rdi);
691 688
692 // Use the length (smi tagged) and set that as an in-object property too. 689 // Use the length (smi tagged) and set that as an in-object property too.
693 // Note: r11 is tagged from here on. 690 // Note: r11 is tagged from here on.
694 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
695 __ Integer32ToSmi(r11, r11); 691 __ Integer32ToSmi(r11, r11);
696 __ movp(FieldOperand(rax, JSObject::kHeaderSize + 692 __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kLengthOffset), r11);
697 Heap::kArgumentsLengthIndex * kPointerSize),
698 r11);
699 693
700 // Set up the elements pointer in the allocated arguments object. 694 // Set up the elements pointer in the allocated arguments object.
701 // If we allocated a parameter map, rdi will point there, otherwise to the 695 // If we allocated a parameter map, rdi will point there, otherwise to the
702 // backing store. 696 // backing store.
703 __ leap(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize)); 697 __ leap(rdi, Operand(rax, JSSloppyArgumentsObject::kSize));
704 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); 698 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
705 699
706 // rax = address of new object (tagged) 700 // rax = address of new object (tagged)
707 // rbx = mapped parameter count (untagged) 701 // rbx = mapped parameter count (untagged)
708 // r11 = argument count (tagged) 702 // r11 = argument count (tagged)
709 // rdi = address of parameter map or backing store (tagged) 703 // rdi = address of parameter map or backing store (tagged)
710 704
711 // Initialize parameter map. If there are no mapped arguments, we're done. 705 // Initialize parameter map. If there are no mapped arguments, we're done.
712 Label skip_parameter_map; 706 Label skip_parameter_map;
713 __ testp(rbx, rbx); 707 __ testp(rbx, rbx);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 886
893 StubRuntimeCallHelper call_helper; 887 StubRuntimeCallHelper call_helper;
894 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); 888 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper);
895 889
896 __ bind(&miss); 890 __ bind(&miss);
897 PropertyAccessCompiler::TailCallBuiltin( 891 PropertyAccessCompiler::TailCallBuiltin(
898 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); 892 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
899 } 893 }
900 894
901 895
902 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
903 // rcx : number of parameters (tagged)
904 // rdx : parameters pointer
905 // rdi : function
906 // rsp[0] : return address
907
908 DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
909 DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count()));
910 DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
911
912 // Check if the calling frame is an arguments adaptor frame.
913 Label adaptor_frame, try_allocate, runtime;
914 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
915 __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset));
916 __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
917 __ j(equal, &adaptor_frame);
918
919 // Get the length from the frame.
920 __ SmiToInteger64(rax, rcx);
921 __ jmp(&try_allocate);
922
923 // Patch the arguments.length and the parameters pointer.
924 __ bind(&adaptor_frame);
925 __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
926 __ SmiToInteger64(rax, rcx);
927 __ leap(rdx, Operand(rbx, rax, times_pointer_size,
928 StandardFrameConstants::kCallerSPOffset));
929
930 // Try the new space allocation. Start out with computing the size of
931 // the arguments object and the elements array.
932 Label add_arguments_object;
933 __ bind(&try_allocate);
934 __ testp(rax, rax);
935 __ j(zero, &add_arguments_object, Label::kNear);
936 __ leap(rax, Operand(rax, times_pointer_size, FixedArray::kHeaderSize));
937 __ bind(&add_arguments_object);
938 __ addp(rax, Immediate(Heap::kStrictArgumentsObjectSize));
939
940 // Do the allocation of both objects in one go.
941 __ Allocate(rax, rax, rbx, no_reg, &runtime, TAG_OBJECT);
942
943 // Get the arguments map from the current native context.
944 __ movp(rdi, NativeContextOperand());
945 __ movp(rdi, ContextOperand(rdi, Context::STRICT_ARGUMENTS_MAP_INDEX));
946
947 __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi);
948 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
949 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
950 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
951
952 // Get the length (smi tagged) and set that as an in-object property too.
953 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
954 __ movp(FieldOperand(rax, JSObject::kHeaderSize +
955 Heap::kArgumentsLengthIndex * kPointerSize),
956 rcx);
957
958 // If there are no actual arguments, we're done.
959 Label done;
960 __ testp(rcx, rcx);
961 __ j(zero, &done);
962
963 // Set up the elements pointer in the allocated arguments object and
964 // initialize the header in the elements fixed array.
965 __ leap(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize));
966 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
967 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
968 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
969 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
970
971 // Untag the length for the loop below.
972 __ SmiToInteger64(rcx, rcx);
973
974 // Copy the fixed array slots.
975 Label loop;
976 __ bind(&loop);
977 __ movp(rbx, Operand(rdx, -1 * kPointerSize)); // Skip receiver.
978 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize), rbx);
979 __ addp(rdi, Immediate(kPointerSize));
980 __ subp(rdx, Immediate(kPointerSize));
981 __ decp(rcx);
982 __ j(not_zero, &loop);
983
984 // Return.
985 __ bind(&done);
986 __ ret(0);
987
988 // Do the runtime call to allocate the arguments object.
989 __ bind(&runtime);
990 __ PopReturnAddressTo(rax);
991 __ Push(rdi); // Push function.
992 __ Push(rdx); // Push parameters pointer.
993 __ Push(rcx); // Push parameter count.
994 __ PushReturnAddressFrom(rax);
995 __ TailCallRuntime(Runtime::kNewStrictArguments);
996 }
997
998
999 void RegExpExecStub::Generate(MacroAssembler* masm) { 896 void RegExpExecStub::Generate(MacroAssembler* masm) {
1000 // Just jump directly to runtime if native RegExp is not selected at compile 897 // Just jump directly to runtime if native RegExp is not selected at compile
1001 // time or if regexp entry in generated code is turned off runtime switch or 898 // time or if regexp entry in generated code is turned off runtime switch or
1002 // at compilation. 899 // at compilation.
1003 #ifdef V8_INTERPRETED_REGEXP 900 #ifdef V8_INTERPRETED_REGEXP
1004 __ TailCallRuntime(Runtime::kRegExpExec); 901 __ TailCallRuntime(Runtime::kRegExpExec);
1005 #else // V8_INTERPRETED_REGEXP 902 #else // V8_INTERPRETED_REGEXP
1006 903
1007 // Stack frame on entry. 904 // Stack frame on entry.
1008 // rsp[0] : return address 905 // rsp[0] : return address
(...skipping 4019 matching lines...) Expand 10 before | Expand all | Expand 10 after
5028 __ movp(rdx, rax); 4925 __ movp(rdx, rax);
5029 __ Pop(rbx); 4926 __ Pop(rbx);
5030 __ Pop(rax); 4927 __ Pop(rax);
5031 __ SmiToInteger32(rax, rax); 4928 __ SmiToInteger32(rax, rax);
5032 } 4929 }
5033 __ jmp(&done_allocate); 4930 __ jmp(&done_allocate);
5034 } 4931 }
5035 } 4932 }
5036 4933
5037 4934
4935 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
4936 // ----------- S t a t e -------------
4937 // -- rdi : function
4938 // -- rsi : context
4939 // -- rbp : frame pointer
4940 // -- rsp[0] : return address
4941 // -----------------------------------
4942 __ AssertFunction(rdi);
4943
4944 // For Ignition we need to skip all possible handler/stub frames until
4945 // we reach the JavaScript frame for the function (similar to what the
4946 // runtime fallback implementation does). So make rdx point to that
4947 // JavaScript frame.
4948 {
4949 Label loop, loop_entry;
4950 __ movp(rdx, rbp);
4951 __ jmp(&loop_entry, Label::kNear);
4952 __ bind(&loop);
4953 __ movp(rdx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
4954 __ bind(&loop_entry);
4955 __ cmpp(rdi, Operand(rdx, StandardFrameConstants::kMarkerOffset));
4956 __ j(not_equal, &loop);
4957 }
4958
4959 // Check if we have an arguments adaptor frame below the function frame.
4960 Label arguments_adaptor, arguments_done;
4961 __ movp(rbx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
4962 __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset),
4963 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
4964 __ j(equal, &arguments_adaptor, Label::kNear);
4965 {
4966 __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
4967 __ LoadSharedFunctionInfoSpecialField(
4968 rax, rax, SharedFunctionInfo::kFormalParameterCountOffset);
4969 __ leap(rbx, Operand(rdx, rax, times_pointer_size,
4970 StandardFrameConstants::kCallerSPOffset -
4971 1 * kPointerSize));
4972 }
4973 __ jmp(&arguments_done, Label::kNear);
4974 __ bind(&arguments_adaptor);
4975 {
4976 __ SmiToInteger32(
4977 rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
4978 __ leap(rbx, Operand(rbx, rax, times_pointer_size,
4979 StandardFrameConstants::kCallerSPOffset -
4980 1 * kPointerSize));
4981 }
4982 __ bind(&arguments_done);
4983
4984 // ----------- S t a t e -------------
4985 // -- rax : number of arguments
4986 // -- rbx : pointer to the first argument
4987 // -- rsi : context
4988 // -- rsp[0] : return address
4989 // -----------------------------------
4990
4991 // Allocate space for the strict arguments object plus the backing store.
4992 Label allocate, done_allocate;
4993 __ leal(rcx, Operand(rax, times_pointer_size, JSStrictArgumentsObject::kSize +
4994 FixedArray::kHeaderSize));
4995 __ Allocate(rcx, rdx, rdi, no_reg, &allocate, TAG_OBJECT);
4996 __ bind(&done_allocate);
4997
4998 // Compute the arguments.length in rdi.
4999 __ Integer32ToSmi(rdi, rax);
5000
5001 // Setup the elements array in rdx.
5002 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex);
5003 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx);
5004 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi);
5005 {
5006 Label loop, done_loop;
5007 __ Set(rcx, 0);
5008 __ bind(&loop);
5009 __ cmpl(rcx, rax);
5010 __ j(equal, &done_loop, Label::kNear);
5011 __ movp(kScratchRegister, Operand(rbx, 0 * kPointerSize));
5012 __ movp(
5013 FieldOperand(rdx, rcx, times_pointer_size, FixedArray::kHeaderSize),
5014 kScratchRegister);
5015 __ subp(rbx, Immediate(1 * kPointerSize));
5016 __ addl(rcx, Immediate(1));
5017 __ jmp(&loop);
5018 __ bind(&done_loop);
5019 }
5020
5021 // Setup the strict arguments object in rax.
5022 __ leap(rax,
5023 Operand(rdx, rax, times_pointer_size, FixedArray::kHeaderSize));
5024 __ LoadNativeContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX, rcx);
5025 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kMapOffset), rcx);
5026 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
5027 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kPropertiesOffset), rcx);
5028 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kElementsOffset), rdx);
5029 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kLengthOffset), rdi);
5030 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
5031 __ Ret();
5032
5033 // Fall back to %AllocateInNewSpace.
5034 __ bind(&allocate);
5035 {
5036 FrameScope scope(masm, StackFrame::INTERNAL);
5037 __ Integer32ToSmi(rax, rax);
5038 __ Integer32ToSmi(rcx, rcx);
5039 __ Push(rax);
5040 __ Push(rbx);
5041 __ Push(rcx);
5042 __ CallRuntime(Runtime::kAllocateInNewSpace);
5043 __ movp(rdx, rax);
5044 __ Pop(rbx);
5045 __ Pop(rax);
5046 __ SmiToInteger32(rax, rax);
5047 }
5048 __ jmp(&done_allocate);
5049 }
5050
5051
5038 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { 5052 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) {
5039 Register context_reg = rsi; 5053 Register context_reg = rsi;
5040 Register slot_reg = rbx; 5054 Register slot_reg = rbx;
5041 Register result_reg = rax; 5055 Register result_reg = rax;
5042 Label slow_case; 5056 Label slow_case;
5043 5057
5044 // Go up context chain to the script context. 5058 // Go up context chain to the script context.
5045 for (int i = 0; i < depth(); ++i) { 5059 for (int i = 0; i < depth(); ++i) {
5046 __ movp(rdi, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); 5060 __ movp(rdi, ContextOperand(context_reg, Context::PREVIOUS_INDEX));
5047 context_reg = rdi; 5061 context_reg = rdi;
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
5587 NULL); 5601 NULL);
5588 } 5602 }
5589 5603
5590 5604
5591 #undef __ 5605 #undef __
5592 5606
5593 } // namespace internal 5607 } // namespace internal
5594 } // namespace v8 5608 } // namespace v8
5595 5609
5596 #endif // V8_TARGET_ARCH_X64 5610 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698