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

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

Issue 1696063002: X87: [runtime] Optimize and unify rest parameters. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/interface-descriptors-x87.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 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 __ bind(&runtime); 783 __ bind(&runtime);
784 __ pop(eax); // Pop return address. 784 __ pop(eax); // Pop return address.
785 __ push(edi); // Push function. 785 __ push(edi); // Push function.
786 __ push(edx); // Push parameters pointer. 786 __ push(edx); // Push parameters pointer.
787 __ push(ecx); // Push parameter count. 787 __ push(ecx); // Push parameter count.
788 __ push(eax); // Push return address. 788 __ push(eax); // Push return address.
789 __ TailCallRuntime(Runtime::kNewStrictArguments); 789 __ TailCallRuntime(Runtime::kNewStrictArguments);
790 } 790 }
791 791
792 792
793 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) {
794 // ecx : number of parameters (tagged)
795 // edx : parameters pointer
796 // ebx : rest parameter index (tagged)
797 // esp[0] : return address
798
799 // Check if the calling frame is an arguments adaptor frame.
800 Label runtime;
801 __ mov(edi, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
802 __ mov(eax, Operand(edi, StandardFrameConstants::kContextOffset));
803 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
804 __ j(not_equal, &runtime);
805
806 // Patch the arguments.length and the parameters pointer.
807 __ mov(ecx, Operand(edi, ArgumentsAdaptorFrameConstants::kLengthOffset));
808 __ lea(edx,
809 Operand(edi, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
810
811 __ bind(&runtime);
812 __ pop(eax); // Save return address.
813 __ push(ecx); // Push number of parameters.
814 __ push(edx); // Push parameters pointer.
815 __ push(ebx); // Push rest parameter index.
816 __ push(eax); // Push return address.
817 __ TailCallRuntime(Runtime::kNewRestParam);
818 }
819
820
821 void RegExpExecStub::Generate(MacroAssembler* masm) { 793 void RegExpExecStub::Generate(MacroAssembler* masm) {
822 // Just jump directly to runtime if native RegExp is not selected at compile 794 // Just jump directly to runtime if native RegExp is not selected at compile
823 // time or if regexp entry in generated code is turned off runtime switch or 795 // time or if regexp entry in generated code is turned off runtime switch or
824 // at compilation. 796 // at compilation.
825 #ifdef V8_INTERPRETED_REGEXP 797 #ifdef V8_INTERPRETED_REGEXP
826 __ TailCallRuntime(Runtime::kRegExpExec); 798 __ TailCallRuntime(Runtime::kRegExpExec);
827 #else // V8_INTERPRETED_REGEXP 799 #else // V8_INTERPRETED_REGEXP
828 800
829 // Stack frame on entry. 801 // Stack frame on entry.
830 // esp[0]: return address 802 // esp[0]: return address
(...skipping 3979 matching lines...) Expand 10 before | Expand all | Expand 10 after
4810 4782
4811 Label fast_elements_case; 4783 Label fast_elements_case;
4812 __ cmp(ecx, Immediate(FAST_ELEMENTS)); 4784 __ cmp(ecx, Immediate(FAST_ELEMENTS));
4813 __ j(equal, &fast_elements_case); 4785 __ j(equal, &fast_elements_case);
4814 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 4786 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
4815 4787
4816 __ bind(&fast_elements_case); 4788 __ bind(&fast_elements_case);
4817 GenerateCase(masm, FAST_ELEMENTS); 4789 GenerateCase(masm, FAST_ELEMENTS);
4818 } 4790 }
4819 4791
4792 void FastNewRestParameterStub::Generate(MacroAssembler* masm) {
4793 // ----------- S t a t e -------------
4794 // -- edi : function
4795 // -- esi : context
4796 // -- ebp : frame pointer
4797 // -- esp[0] : return address
4798 // -----------------------------------
4799 __ AssertFunction(edi);
4800
4801 // For Ignition we need to skip all possible handler/stub frames until
4802 // we reach the JavaScript frame for the function (similar to what the
4803 // runtime fallback implementation does). So make edx point to that
4804 // JavaScript frame.
4805 {
4806 Label loop, loop_entry;
4807 __ mov(edx, ebp);
4808 __ jmp(&loop_entry, Label::kNear);
4809 __ bind(&loop);
4810 __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset));
4811 __ bind(&loop_entry);
4812 __ cmp(edi, Operand(edx, StandardFrameConstants::kMarkerOffset));
4813 __ j(not_equal, &loop);
4814 }
4815
4816 // Check if we have rest parameters (only possible if we have an
4817 // arguments adaptor frame below the function frame).
4818 Label no_rest_parameters;
4819 __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset));
4820 __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset),
4821 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4822 __ j(not_equal, &no_rest_parameters, Label::kNear);
4823
4824 // Check if the arguments adaptor frame contains more arguments than
4825 // specified by the function's internal formal parameter count.
4826 Label rest_parameters;
4827 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
4828 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
4829 __ sub(eax,
4830 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset));
4831 __ j(greater, &rest_parameters);
4832
4833 // Return an empty rest parameter array.
4834 __ bind(&no_rest_parameters);
4835 {
4836 // ----------- S t a t e -------------
4837 // -- esi : context
4838 // -- esp[0] : return address
4839 // -----------------------------------
4840
4841 // Allocate an empty rest parameter array.
4842 Label allocate, done_allocate;
4843 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, TAG_OBJECT);
4844 __ bind(&done_allocate);
4845
4846 // Setup the rest parameter array in rax.
4847 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx);
4848 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx);
4849 __ mov(ecx, isolate()->factory()->empty_fixed_array());
4850 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx);
4851 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx);
4852 __ mov(FieldOperand(eax, JSArray::kLengthOffset),
4853 Immediate(Smi::FromInt(0)));
4854 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
4855 __ Ret();
4856
4857 // Fall back to %AllocateInNewSpace.
4858 __ bind(&allocate);
4859 {
4860 FrameScope scope(masm, StackFrame::INTERNAL);
4861 __ Push(Smi::FromInt(JSArray::kSize));
4862 __ CallRuntime(Runtime::kAllocateInNewSpace);
4863 }
4864 __ jmp(&done_allocate);
4865 }
4866
4867 __ bind(&rest_parameters);
4868 {
4869 // Compute the pointer to the first rest parameter (skippping the receiver).
4870 __ lea(ebx,
4871 Operand(ebx, eax, times_half_pointer_size,
4872 StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize));
4873
4874 // ----------- S t a t e -------------
4875 // -- esi : context
4876 // -- eax : number of rest parameters (tagged)
4877 // -- ebx : pointer to first rest parameters
4878 // -- esp[0] : return address
4879 // -----------------------------------
4880
4881 // Allocate space for the rest parameter array plus the backing store.
4882 Label allocate, done_allocate;
4883 __ lea(ecx, Operand(eax, times_half_pointer_size,
4884 JSArray::kSize + FixedArray::kHeaderSize));
4885 __ Allocate(ecx, edx, edi, no_reg, &allocate, TAG_OBJECT);
4886 __ bind(&done_allocate);
4887
4888 // Setup the elements array in edx.
4889 __ mov(FieldOperand(edx, FixedArray::kMapOffset),
4890 isolate()->factory()->fixed_array_map());
4891 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax);
4892 {
4893 Label loop, done_loop;
4894 __ Move(ecx, Smi::FromInt(0));
4895 __ bind(&loop);
4896 __ cmp(ecx, eax);
4897 __ j(equal, &done_loop, Label::kNear);
4898 __ mov(edi, Operand(ebx, 0 * kPointerSize));
4899 __ mov(FieldOperand(edx, ecx, times_half_pointer_size,
4900 FixedArray::kHeaderSize),
4901 edi);
4902 __ sub(ebx, Immediate(1 * kPointerSize));
4903 __ add(ecx, Immediate(Smi::FromInt(1)));
4904 __ jmp(&loop);
4905 __ bind(&done_loop);
4906 }
4907
4908 // Setup the rest parameter array in edi.
4909 __ lea(edi,
4910 Operand(edx, eax, times_half_pointer_size, FixedArray::kHeaderSize));
4911 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx);
4912 __ mov(FieldOperand(edi, JSArray::kMapOffset), ecx);
4913 __ mov(FieldOperand(edi, JSArray::kPropertiesOffset),
4914 isolate()->factory()->empty_fixed_array());
4915 __ mov(FieldOperand(edi, JSArray::kElementsOffset), edx);
4916 __ mov(FieldOperand(edi, JSArray::kLengthOffset), eax);
4917 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
4918 __ mov(eax, edi);
4919 __ Ret();
4920
4921 // Fall back to %AllocateInNewSpace.
4922 __ bind(&allocate);
4923 {
4924 FrameScope scope(masm, StackFrame::INTERNAL);
4925 __ SmiTag(ecx);
4926 __ Push(eax);
4927 __ Push(ebx);
4928 __ Push(ecx);
4929 __ CallRuntime(Runtime::kAllocateInNewSpace);
4930 __ mov(edx, eax);
4931 __ Pop(ebx);
4932 __ Pop(eax);
4933 }
4934 __ jmp(&done_allocate);
4935 }
4936 }
4820 4937
4821 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { 4938 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) {
4822 Register context_reg = esi; 4939 Register context_reg = esi;
4823 Register slot_reg = ebx; 4940 Register slot_reg = ebx;
4824 Register result_reg = eax; 4941 Register result_reg = eax;
4825 Label slow_case; 4942 Label slow_case;
4826 4943
4827 // Go up context chain to the script context. 4944 // Go up context chain to the script context.
4828 for (int i = 0; i < depth(); ++i) { 4945 for (int i = 0; i < depth(); ++i) {
4829 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); 4946 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX));
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
5369 return_value_operand, NULL); 5486 return_value_operand, NULL);
5370 } 5487 }
5371 5488
5372 5489
5373 #undef __ 5490 #undef __
5374 5491
5375 } // namespace internal 5492 } // namespace internal
5376 } // namespace v8 5493 } // namespace v8
5377 5494
5378 #endif // V8_TARGET_ARCH_X87 5495 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698