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

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

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 Isolate* isolate, 89 Isolate* isolate,
90 CodeStubInterfaceDescriptor* descriptor) { 90 CodeStubInterfaceDescriptor* descriptor) {
91 static Register registers[] = { rax, rbx }; 91 static Register registers[] = { rax, rbx };
92 descriptor->register_param_count_ = 2; 92 descriptor->register_param_count_ = 2;
93 descriptor->register_params_ = registers; 93 descriptor->register_params_ = registers;
94 descriptor->deoptimization_handler_ = 94 descriptor->deoptimization_handler_ =
95 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; 95 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
96 } 96 }
97 97
98 98
99 static void InitializeArrayConstructorDescriptor(Isolate* isolate, 99 static void InitializeArrayConstructorDescriptor(
100 CodeStubInterfaceDescriptor* descriptor) { 100 Isolate* isolate,
101 CodeStubInterfaceDescriptor* descriptor,
102 int constant_stack_parameter_count) {
101 // register state 103 // register state
102 // rdi -- constructor function
103 // rbx -- type info cell with elements kind 104 // rbx -- type info cell with elements kind
104 // rax -- number of arguments to the constructor function 105 static Register registers[] = { rbx };
105 static Register registers[] = { rdi, rbx }; 106 descriptor->register_param_count_ = 1;
106 descriptor->register_param_count_ = 2; 107 if (constant_stack_parameter_count != 0) {
107 // stack param count needs (constructor pointer, and single argument) 108 // stack param count needs (constructor pointer, and single argument)
108 descriptor->stack_parameter_count_ = &rax; 109 descriptor->stack_parameter_count_ = &rax;
110 }
111 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
109 descriptor->register_params_ = registers; 112 descriptor->register_params_ = registers;
110 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 113 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
111 descriptor->deoptimization_handler_ = 114 descriptor->deoptimization_handler_ =
112 FUNCTION_ADDR(ArrayConstructor_StubFailure); 115 FUNCTION_ADDR(ArrayConstructor_StubFailure);
113 } 116 }
114 117
115 118
116 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 119 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
117 Isolate* isolate, 120 Isolate* isolate,
118 CodeStubInterfaceDescriptor* descriptor) { 121 CodeStubInterfaceDescriptor* descriptor) {
119 InitializeArrayConstructorDescriptor(isolate, descriptor); 122 InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
120 } 123 }
121 124
122 125
123 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( 126 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
124 Isolate* isolate, 127 Isolate* isolate,
125 CodeStubInterfaceDescriptor* descriptor) { 128 CodeStubInterfaceDescriptor* descriptor) {
126 InitializeArrayConstructorDescriptor(isolate, descriptor); 129 InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
127 } 130 }
128 131
129 132
130 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( 133 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
131 Isolate* isolate, 134 Isolate* isolate,
132 CodeStubInterfaceDescriptor* descriptor) { 135 CodeStubInterfaceDescriptor* descriptor) {
133 InitializeArrayConstructorDescriptor(isolate, descriptor); 136 InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
134 } 137 }
135 138
136 139
137 #define __ ACCESS_MASM(masm) 140 #define __ ACCESS_MASM(masm)
138 141
139 142
140 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 143 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
141 // Update the static counter each time a new code stub is generated. 144 // Update the static counter each time a new code stub is generated.
142 Isolate* isolate = masm->isolate(); 145 Isolate* isolate = masm->isolate();
143 isolate->counters()->code_stubs()->Increment(); 146 isolate->counters()->code_stubs()->Increment();
(...skipping 3670 matching lines...) Expand 10 before | Expand all | Expand 10 after
3814 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); 3817 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate));
3815 __ j(equal, &done); 3818 __ j(equal, &done);
3816 3819
3817 // Special handling of the Array() function, which caches not only the 3820 // Special handling of the Array() function, which caches not only the
3818 // monomorphic Array function but the initial ElementsKind with special 3821 // monomorphic Array function but the initial ElementsKind with special
3819 // sentinels 3822 // sentinels
3820 Handle<Object> terminal_kind_sentinel = 3823 Handle<Object> terminal_kind_sentinel =
3821 TypeFeedbackCells::MonomorphicArraySentinel(isolate, 3824 TypeFeedbackCells::MonomorphicArraySentinel(isolate,
3822 LAST_FAST_ELEMENTS_KIND); 3825 LAST_FAST_ELEMENTS_KIND);
3823 __ Cmp(rcx, terminal_kind_sentinel); 3826 __ Cmp(rcx, terminal_kind_sentinel);
3824 __ j(not_equal, &miss); 3827 __ j(above, &miss);
3825 // Make sure the function is the Array() function 3828 // Make sure the function is the Array() function
3826 __ LoadArrayFunction(rcx); 3829 __ LoadArrayFunction(rcx);
3827 __ cmpq(rdi, rcx); 3830 __ cmpq(rdi, rcx);
3828 __ j(not_equal, &megamorphic); 3831 __ j(not_equal, &megamorphic);
3829 __ jmp(&done); 3832 __ jmp(&done);
3830 3833
3831 __ bind(&miss); 3834 __ bind(&miss);
3832 3835
3833 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 3836 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
3834 // megamorphic. 3837 // megamorphic.
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
4026 #endif 4029 #endif
4027 } 4030 }
4028 4031
4029 4032
4030 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 4033 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
4031 CEntryStub::GenerateAheadOfTime(isolate); 4034 CEntryStub::GenerateAheadOfTime(isolate);
4032 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); 4035 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
4033 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); 4036 StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
4034 // It is important that the store buffer overflow stubs are generated first. 4037 // It is important that the store buffer overflow stubs are generated first.
4035 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); 4038 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate);
4039 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
4036 } 4040 }
4037 4041
4038 4042
4039 void CodeStub::GenerateFPStubs(Isolate* isolate) { 4043 void CodeStub::GenerateFPStubs(Isolate* isolate) {
4040 } 4044 }
4041 4045
4042 4046
4043 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 4047 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
4044 CEntryStub stub(1, kDontSaveFPRegs); 4048 CEntryStub stub(1, kDontSaveFPRegs);
4045 stub.GetCode(isolate)->set_is_pregenerated(true); 4049 stub.GetCode(isolate)->set_is_pregenerated(true);
(...skipping 2717 matching lines...) Expand 10 before | Expand all | Expand 10 after
6763 __ pop(rcx); 6767 __ pop(rcx);
6764 #else 6768 #else
6765 __ pop(rsi); 6769 __ pop(rsi);
6766 __ pop(rdi); 6770 __ pop(rdi);
6767 __ pop(rcx); 6771 __ pop(rcx);
6768 #endif 6772 #endif
6769 6773
6770 __ Ret(); 6774 __ Ret();
6771 } 6775 }
6772 6776
6777
6778 template<class T>
6779 static void CreateArrayDispatch(MacroAssembler* masm) {
6780 int last_index = GetSequenceIndexFromFastElementsKind(
6781 TERMINAL_FAST_ELEMENTS_KIND);
6782 for (int i = 0; i <= last_index; ++i) {
6783 Label next;
6784 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6785 __ cmpl(rdx, Immediate(kind));
6786 __ j(not_equal, &next);
6787 T stub(kind);
6788 __ TailCallStub(&stub);
6789 __ bind(&next);
6790 }
6791
6792 // If we reached this point there is a problem.
6793 __ Abort("Unexpected ElementsKind in array constructor");
6794 }
6795
6796
6797 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
6798 // rbx - type info cell
6799 // rdx - kind
6800 // rax - number of arguments
6801 // rdi - constructor?
6802 // esp[0] - return address
6803 // esp[4] - last argument
6804 ASSERT(FAST_SMI_ELEMENTS == 0);
6805 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
6806 ASSERT(FAST_ELEMENTS == 2);
6807 ASSERT(FAST_HOLEY_ELEMENTS == 3);
6808 ASSERT(FAST_DOUBLE_ELEMENTS == 4);
6809 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
6810
6811 Handle<Object> undefined_sentinel(
6812 masm->isolate()->heap()->undefined_value(),
6813 masm->isolate());
6814
6815 // is the low bit set? If so, we are holey and that is good.
6816 __ testb(rdx, Immediate(1));
6817 Label normal_sequence;
6818 __ j(not_zero, &normal_sequence);
6819
6820 // look at the first argument
6821 __ movq(rcx, Operand(rsp, kPointerSize));
6822 __ testq(rcx, rcx);
6823 __ j(zero, &normal_sequence);
6824
6825 // We are going to create a holey array, but our kind is non-holey.
6826 // Fix kind and retry
6827 __ incl(rdx);
6828 __ Cmp(rbx, undefined_sentinel);
6829 __ j(equal, &normal_sequence);
6830
6831 // Save the resulting elements kind in type info
6832 __ Integer32ToSmi(rdx, rdx);
6833 __ movq(FieldOperand(rbx, kPointerSize), rdx);
6834 __ SmiToInteger32(rdx, rdx);
6835
6836 __ bind(&normal_sequence);
6837 int last_index = GetSequenceIndexFromFastElementsKind(
6838 TERMINAL_FAST_ELEMENTS_KIND);
6839 for (int i = 0; i <= last_index; ++i) {
6840 Label next;
6841 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6842 __ cmpl(rdx, Immediate(kind));
6843 __ j(not_equal, &next);
6844 ArraySingleArgumentConstructorStub stub(kind);
6845 __ TailCallStub(&stub);
6846 __ bind(&next);
6847 }
6848
6849 // If we reached this point there is a problem.
6850 __ Abort("Unexpected ElementsKind in array constructor");
6851 }
6852
6853
6854 template<class T>
6855 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
6856 int to_index = GetSequenceIndexFromFastElementsKind(
6857 TERMINAL_FAST_ELEMENTS_KIND);
6858 for (int i = 0; i <= to_index; ++i) {
6859 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6860 T stub(kind);
6861 stub.GetCode(isolate)->set_is_pregenerated(true);
6862 }
6863 }
6864
6865
6866 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
6867 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
6868 isolate);
6869 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
6870 isolate);
6871 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
6872 isolate);
6873 }
6874
6875
6876
6877 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
6878 // ----------- S t a t e -------------
6879 // -- rax : argc
6880 // -- rbx : type info cell
6881 // -- rdi : constructor
6882 // -- rsp[0] : return address
6883 // -- rsp[4] : last argument
6884 // -----------------------------------
6885 Handle<Object> undefined_sentinel(
6886 masm->isolate()->heap()->undefined_value(),
6887 masm->isolate());
6888
6889 if (FLAG_debug_code) {
6890 // The array construct code is only set for the global and natives
6891 // builtin Array functions which always have maps.
6892
6893 // Initial map for the builtin Array function should be a map.
6894 __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
6895 // Will both indicate a NULL and a Smi.
6896 STATIC_ASSERT(kSmiTag == 0);
6897 Condition not_smi = NegateCondition(masm->CheckSmi(rcx));
6898 __ Check(not_smi, "Unexpected initial map for Array function");
6899 __ CmpObjectType(rcx, MAP_TYPE, rcx);
6900 __ Check(equal, "Unexpected initial map for Array function");
6901
6902 // We should either have undefined in ebx or a valid jsglobalpropertycell
6903 Label okay_here;
6904 Handle<Map> global_property_cell_map(
6905 masm->isolate()->heap()->global_property_cell_map());
6906 __ Cmp(rbx, undefined_sentinel);
6907 __ j(equal, &okay_here);
6908 __ Cmp(FieldOperand(rbx, 0), global_property_cell_map);
6909 __ Assert(equal, "Expected property cell in register rbx");
6910 __ bind(&okay_here);
6911 }
6912
6913 if (FLAG_optimize_constructed_arrays) {
6914 Label no_info, switch_ready;
6915 // Get the elements kind and case on that.
6916 __ Cmp(rbx, undefined_sentinel);
6917 __ j(equal, &no_info);
6918 __ movq(rdx, FieldOperand(rbx, kPointerSize));
6919
6920 // There is no info if the call site went megamorphic either
6921
6922 // TODO(mvstanton): Really? I thought if it was the array function that
6923 // the cell wouldn't get stamped as megamorphic.
6924 __ Cmp(rdx, TypeFeedbackCells::MegamorphicSentinel(masm->isolate()));
6925 __ j(equal, &no_info);
6926 __ SmiToInteger32(rdx, rdx);
6927 __ jmp(&switch_ready);
6928 __ bind(&no_info);
6929 __ movq(rdx, Immediate(GetInitialFastElementsKind()));
6930 __ bind(&switch_ready);
6931
6932 if (argument_count_ == ANY) {
6933 Label not_zero_case, not_one_case;
6934 __ testq(rax, rax);
6935 __ j(not_zero, &not_zero_case);
6936 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
6937
6938 __ bind(&not_zero_case);
6939 __ cmpl(rax, Immediate(1));
6940 __ j(greater, &not_one_case);
6941 CreateArrayDispatchOneArgument(masm);
6942
6943 __ bind(&not_one_case);
6944 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
6945 } else if (argument_count_ == NONE) {
6946 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
6947 } else if (argument_count_ == ONE) {
6948 CreateArrayDispatchOneArgument(masm);
6949 } else if (argument_count_ == MORE_THAN_ONE) {
6950 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
6951 } else {
6952 UNREACHABLE();
6953 }
6954 } else {
6955 Label generic_constructor;
6956 // Run the native code for the Array function called as constructor.
6957 ArrayNativeCode(masm, &generic_constructor);
6958
6959 // Jump to the generic construct code in case the specialized code cannot
6960 // handle the construction.
6961 __ bind(&generic_constructor);
6962 Handle<Code> generic_construct_stub =
6963 masm->isolate()->builtins()->JSConstructStubGeneric();
6964 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
6965 }
6966 }
6967
6968
6773 #undef __ 6969 #undef __
6774 6970
6775 } } // namespace v8::internal 6971 } } // namespace v8::internal
6776 6972
6777 #endif // V8_TARGET_ARCH_X64 6973 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/code-stubs.h ('K') | « src/x64/code-stubs-x64.h ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698