OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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, ¬_zero_case); |
| 7991 InternalArrayNoArgumentConstructorStub stub0(kind); |
| 7992 __ TailCallStub(&stub0); |
| 7993 |
| 7994 __ bind(¬_zero_case); |
| 7995 __ cmp(eax, 1); |
| 7996 __ j(greater, ¬_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(¬_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 |
OLD | NEW |