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

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

Issue 14576005: Adapt hydrogen-based Array constructor to also support InternalArray and function call (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Adapt to bugfix for 244461 Created 7 years, 6 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
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/isolate.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 // 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 descriptor->stack_parameter_count_ = &eax; 135 descriptor->stack_parameter_count_ = &eax;
136 } 136 }
137 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; 137 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
138 descriptor->register_params_ = registers; 138 descriptor->register_params_ = registers;
139 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 139 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
140 descriptor->deoptimization_handler_ = 140 descriptor->deoptimization_handler_ =
141 FUNCTION_ADDR(ArrayConstructor_StubFailure); 141 FUNCTION_ADDR(ArrayConstructor_StubFailure);
142 } 142 }
143 143
144 144
145 static void InitializeInternalArrayConstructorDescriptor(
146 Isolate* isolate,
147 CodeStubInterfaceDescriptor* descriptor,
148 int constant_stack_parameter_count) {
149 // register state
150 // eax -- number of arguments
151 // edi -- constructor function
152 static Register registers[] = { edi };
153 descriptor->register_param_count_ = 1;
154
155 if (constant_stack_parameter_count != 0) {
156 // stack param count needs (constructor pointer, and single argument)
157 descriptor->stack_parameter_count_ = &eax;
158 }
159 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
160 descriptor->register_params_ = registers;
161 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
162 descriptor->deoptimization_handler_ =
163 FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
164 }
165
166
145 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 167 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
146 Isolate* isolate, 168 Isolate* isolate,
147 CodeStubInterfaceDescriptor* descriptor) { 169 CodeStubInterfaceDescriptor* descriptor) {
148 InitializeArrayConstructorDescriptor(isolate, descriptor, 0); 170 InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
149 } 171 }
150 172
151 173
152 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( 174 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
153 Isolate* isolate, 175 Isolate* isolate,
154 CodeStubInterfaceDescriptor* descriptor) { 176 CodeStubInterfaceDescriptor* descriptor) {
155 InitializeArrayConstructorDescriptor(isolate, descriptor, 1); 177 InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
156 } 178 }
157 179
158 180
159 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( 181 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
160 Isolate* isolate, 182 Isolate* isolate,
161 CodeStubInterfaceDescriptor* descriptor) { 183 CodeStubInterfaceDescriptor* descriptor) {
162 InitializeArrayConstructorDescriptor(isolate, descriptor, -1); 184 InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
163 } 185 }
164 186
165 187
188 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
189 Isolate* isolate,
190 CodeStubInterfaceDescriptor* descriptor) {
191 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
192 }
193
194
195 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
196 Isolate* isolate,
197 CodeStubInterfaceDescriptor* descriptor) {
198 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
199 }
200
201
202 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
203 Isolate* isolate,
204 CodeStubInterfaceDescriptor* descriptor) {
205 InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
206 }
207
208
166 void CompareNilICStub::InitializeInterfaceDescriptor( 209 void CompareNilICStub::InitializeInterfaceDescriptor(
167 Isolate* isolate, 210 Isolate* isolate,
168 CodeStubInterfaceDescriptor* descriptor) { 211 CodeStubInterfaceDescriptor* descriptor) {
169 static Register registers[] = { eax }; 212 static Register registers[] = { eax };
170 descriptor->register_param_count_ = 1; 213 descriptor->register_param_count_ = 1;
171 descriptor->register_params_ = registers; 214 descriptor->register_params_ = registers;
172 descriptor->deoptimization_handler_ = 215 descriptor->deoptimization_handler_ =
173 FUNCTION_ADDR(CompareNilIC_Miss); 216 FUNCTION_ADDR(CompareNilIC_Miss);
174 descriptor->SetMissHandler( 217 descriptor->SetMissHandler(
175 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate)); 218 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate));
(...skipping 4594 matching lines...) Expand 10 before | Expand all | Expand 10 after
4770 __ bind(&receiver_ok); 4813 __ bind(&receiver_ok);
4771 } 4814 }
4772 4815
4773 // Check that the function really is a JavaScript function. 4816 // Check that the function really is a JavaScript function.
4774 __ JumpIfSmi(edi, &non_function); 4817 __ JumpIfSmi(edi, &non_function);
4775 // Goto slow case if we do not have a function. 4818 // Goto slow case if we do not have a function.
4776 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 4819 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
4777 __ j(not_equal, &slow); 4820 __ j(not_equal, &slow);
4778 4821
4779 if (RecordCallTarget()) { 4822 if (RecordCallTarget()) {
4780 GenerateRecordCallTargetNoArray(masm); 4823 if (FLAG_optimize_constructed_arrays) {
4824 GenerateRecordCallTarget(masm);
4825 } else {
4826 GenerateRecordCallTargetNoArray(masm);
4827 }
4781 } 4828 }
4782 4829
4783 // Fast-case: Just invoke the function. 4830 // Fast-case: Just invoke the function.
4784 ParameterCount actual(argc_); 4831 ParameterCount actual(argc_);
4785 4832
4786 if (ReceiverMightBeImplicit()) { 4833 if (ReceiverMightBeImplicit()) {
4787 Label call_as_function; 4834 Label call_as_function;
4788 __ cmp(eax, isolate->factory()->the_hole_value()); 4835 __ cmp(eax, isolate->factory()->the_hole_value());
4789 __ j(equal, &call_as_function); 4836 __ j(equal, &call_as_function);
4790 __ InvokeFunction(edi, 4837 __ InvokeFunction(edi,
(...skipping 3036 matching lines...) Expand 10 before | Expand all | Expand 10 after
7827 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { 7874 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
7828 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( 7875 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
7829 isolate); 7876 isolate);
7830 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( 7877 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
7831 isolate); 7878 isolate);
7832 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>( 7879 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
7833 isolate); 7880 isolate);
7834 } 7881 }
7835 7882
7836 7883
7884 void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
7885 Isolate* isolate) {
7886 ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
7887 for (int i = 0; i < 2; i++) {
7888 // For internal arrays we only need a few things
7889 InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
7890 stubh1.GetCode(isolate)->set_is_pregenerated(true);
7891 InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
7892 stubh2.GetCode(isolate)->set_is_pregenerated(true);
7893 InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
7894 stubh3.GetCode(isolate)->set_is_pregenerated(true);
7895 }
7896 }
7897
7898
7837 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 7899 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
7838 // ----------- S t a t e ------------- 7900 // ----------- S t a t e -------------
7839 // -- eax : argc (only if argument_count_ == ANY) 7901 // -- eax : argc (only if argument_count_ == ANY)
7840 // -- ebx : type info cell 7902 // -- ebx : type info cell
7841 // -- edi : constructor 7903 // -- edi : constructor
7842 // -- esp[0] : return address 7904 // -- esp[0] : return address
7843 // -- esp[4] : last argument 7905 // -- esp[4] : last argument
7844 // ----------------------------------- 7906 // -----------------------------------
7845 Handle<Object> undefined_sentinel( 7907 Handle<Object> undefined_sentinel(
7846 masm->isolate()->heap()->undefined_value(), 7908 masm->isolate()->heap()->undefined_value(),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
7912 // Jump to the generic construct code in case the specialized code cannot 7974 // Jump to the generic construct code in case the specialized code cannot
7913 // handle the construction. 7975 // handle the construction.
7914 __ bind(&generic_constructor); 7976 __ bind(&generic_constructor);
7915 Handle<Code> generic_construct_stub = 7977 Handle<Code> generic_construct_stub =
7916 masm->isolate()->builtins()->JSConstructStubGeneric(); 7978 masm->isolate()->builtins()->JSConstructStubGeneric();
7917 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 7979 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
7918 } 7980 }
7919 } 7981 }
7920 7982
7921 7983
7984 void InternalArrayConstructorStub::GenerateCase(
7985 MacroAssembler* masm, ElementsKind kind) {
7986 Label not_zero_case, not_one_case;
7987 Label normal_sequence;
7988
7989 __ test(eax, eax);
7990 __ j(not_zero, &not_zero_case);
7991 InternalArrayNoArgumentConstructorStub stub0(kind);
7992 __ TailCallStub(&stub0);
7993
7994 __ bind(&not_zero_case);
7995 __ cmp(eax, 1);
7996 __ j(greater, &not_one_case);
7997
7998 if (IsFastPackedElementsKind(kind)) {
7999 // We might need to create a holey array
8000 // look at the first argument
8001 __ mov(ecx, Operand(esp, kPointerSize));
8002 __ test(ecx, ecx);
8003 __ j(zero, &normal_sequence);
8004
8005 InternalArraySingleArgumentConstructorStub
8006 stub1_holey(GetHoleyElementsKind(kind));
8007 __ TailCallStub(&stub1_holey);
8008 }
8009
8010 __ bind(&normal_sequence);
8011 InternalArraySingleArgumentConstructorStub stub1(kind);
8012 __ TailCallStub(&stub1);
8013
8014 __ bind(&not_one_case);
8015 InternalArrayNArgumentsConstructorStub stubN(kind);
8016 __ TailCallStub(&stubN);
8017 }
8018
8019
8020 void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
8021 // ----------- S t a t e -------------
8022 // -- eax : argc
8023 // -- ebx : type info cell
8024 // -- edi : constructor
8025 // -- esp[0] : return address
8026 // -- esp[4] : last argument
8027 // -----------------------------------
8028
8029 if (FLAG_debug_code) {
8030 // The array construct code is only set for the global and natives
8031 // builtin Array functions which always have maps.
8032
8033 // Initial map for the builtin Array function should be a map.
8034 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
8035 // Will both indicate a NULL and a Smi.
8036 __ test(ecx, Immediate(kSmiTagMask));
8037 __ Assert(not_zero, "Unexpected initial map for Array function");
8038 __ CmpObjectType(ecx, MAP_TYPE, ecx);
8039 __ Assert(equal, "Unexpected initial map for Array function");
8040 }
8041
8042 if (FLAG_optimize_constructed_arrays) {
8043 // Figure out the right elements kind
8044 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
8045
8046 // Load the map's "bit field 2" into |result|. We only need the first byte,
8047 // but the following masking takes care of that anyway.
8048 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
8049 // Retrieve elements_kind from bit field 2.
8050 __ and_(ecx, Map::kElementsKindMask);
8051 __ shr(ecx, Map::kElementsKindShift);
8052
8053 if (FLAG_debug_code) {
8054 Label done;
8055 __ cmp(ecx, Immediate(FAST_ELEMENTS));
8056 __ j(equal, &done);
8057 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS));
8058 __ Assert(equal,
8059 "Invalid ElementsKind for InternalArray or InternalPackedArray");
8060 __ bind(&done);
8061 }
8062
8063 Label fast_elements_case;
8064 __ cmp(ecx, Immediate(FAST_ELEMENTS));
8065 __ j(equal, &fast_elements_case);
8066 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
8067
8068 __ bind(&fast_elements_case);
8069 GenerateCase(masm, FAST_ELEMENTS);
8070 } else {
8071 Label generic_constructor;
8072 // Run the native code for the Array function called as constructor.
8073 ArrayNativeCode(masm, true, &generic_constructor);
8074
8075 // Jump to the generic construct code in case the specialized code cannot
8076 // handle the construction.
8077 __ bind(&generic_constructor);
8078 Handle<Code> generic_construct_stub =
8079 masm->isolate()->builtins()->JSConstructStubGeneric();
8080 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
8081 }
8082 }
8083
8084
7922 #undef __ 8085 #undef __
7923 8086
7924 } } // namespace v8::internal 8087 } } // namespace v8::internal
7925 8088
7926 #endif // V8_TARGET_ARCH_IA32 8089 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698