OLD | NEW |
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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
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 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 __ bind(&runtime); | 1142 __ bind(&runtime); |
1143 __ pop(eax); // Pop return address. | 1143 __ pop(eax); // Pop return address. |
1144 __ push(edi); // Push function. | 1144 __ push(edi); // Push function. |
1145 __ push(edx); // Push parameters pointer. | 1145 __ push(edx); // Push parameters pointer. |
1146 __ push(ecx); // Push parameter count. | 1146 __ push(ecx); // Push parameter count. |
1147 __ push(eax); // Push return address. | 1147 __ push(eax); // Push return address. |
1148 __ TailCallRuntime(Runtime::kNewStrictArguments); | 1148 __ TailCallRuntime(Runtime::kNewStrictArguments); |
1149 } | 1149 } |
1150 | 1150 |
1151 | 1151 |
1152 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { | |
1153 // ecx : number of parameters (tagged) | |
1154 // edx : parameters pointer | |
1155 // ebx : rest parameter index (tagged) | |
1156 // esp[0] : return address | |
1157 | |
1158 // Check if the calling frame is an arguments adaptor frame. | |
1159 Label runtime; | |
1160 __ mov(edi, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | |
1161 __ mov(eax, Operand(edi, StandardFrameConstants::kContextOffset)); | |
1162 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
1163 __ j(not_equal, &runtime); | |
1164 | |
1165 // Patch the arguments.length and the parameters pointer. | |
1166 __ mov(ecx, Operand(edi, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
1167 __ lea(edx, | |
1168 Operand(edi, ecx, times_2, StandardFrameConstants::kCallerSPOffset)); | |
1169 | |
1170 __ bind(&runtime); | |
1171 __ pop(eax); // Save return address. | |
1172 __ push(ecx); // Push number of parameters. | |
1173 __ push(edx); // Push parameters pointer. | |
1174 __ push(ebx); // Push rest parameter index. | |
1175 __ push(eax); // Push return address. | |
1176 __ TailCallRuntime(Runtime::kNewRestParam); | |
1177 } | |
1178 | |
1179 | |
1180 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1152 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1181 // Just jump directly to runtime if native RegExp is not selected at compile | 1153 // Just jump directly to runtime if native RegExp is not selected at compile |
1182 // time or if regexp entry in generated code is turned off runtime switch or | 1154 // time or if regexp entry in generated code is turned off runtime switch or |
1183 // at compilation. | 1155 // at compilation. |
1184 #ifdef V8_INTERPRETED_REGEXP | 1156 #ifdef V8_INTERPRETED_REGEXP |
1185 __ TailCallRuntime(Runtime::kRegExpExec); | 1157 __ TailCallRuntime(Runtime::kRegExpExec); |
1186 #else // V8_INTERPRETED_REGEXP | 1158 #else // V8_INTERPRETED_REGEXP |
1187 | 1159 |
1188 // Stack frame on entry. | 1160 // Stack frame on entry. |
1189 // esp[0]: return address | 1161 // esp[0]: return address |
(...skipping 3998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5188 Label fast_elements_case; | 5160 Label fast_elements_case; |
5189 __ cmp(ecx, Immediate(FAST_ELEMENTS)); | 5161 __ cmp(ecx, Immediate(FAST_ELEMENTS)); |
5190 __ j(equal, &fast_elements_case); | 5162 __ j(equal, &fast_elements_case); |
5191 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 5163 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
5192 | 5164 |
5193 __ bind(&fast_elements_case); | 5165 __ bind(&fast_elements_case); |
5194 GenerateCase(masm, FAST_ELEMENTS); | 5166 GenerateCase(masm, FAST_ELEMENTS); |
5195 } | 5167 } |
5196 | 5168 |
5197 | 5169 |
| 5170 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
| 5171 // ----------- S t a t e ------------- |
| 5172 // -- edi : function |
| 5173 // -- esi : context |
| 5174 // -- ebp : frame pointer |
| 5175 // -- esp[0] : return address |
| 5176 // ----------------------------------- |
| 5177 __ AssertFunction(edi); |
| 5178 |
| 5179 // For Ignition we need to skip all possible handler/stub frames until |
| 5180 // we reach the JavaScript frame for the function (similar to what the |
| 5181 // runtime fallback implementation does). So make edx point to that |
| 5182 // JavaScript frame. |
| 5183 { |
| 5184 Label loop, loop_entry; |
| 5185 __ mov(edx, ebp); |
| 5186 __ jmp(&loop_entry, Label::kNear); |
| 5187 __ bind(&loop); |
| 5188 __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
| 5189 __ bind(&loop_entry); |
| 5190 __ cmp(edi, Operand(edx, StandardFrameConstants::kMarkerOffset)); |
| 5191 __ j(not_equal, &loop); |
| 5192 } |
| 5193 |
| 5194 // Check if we have rest parameters (only possible if we have an |
| 5195 // arguments adaptor frame below the function frame). |
| 5196 Label no_rest_parameters; |
| 5197 __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); |
| 5198 __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset), |
| 5199 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 5200 __ j(not_equal, &no_rest_parameters, Label::kNear); |
| 5201 |
| 5202 // Check if the arguments adaptor frame contains more arguments than |
| 5203 // specified by the function's internal formal parameter count. |
| 5204 Label rest_parameters; |
| 5205 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 5206 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 5207 __ sub(eax, |
| 5208 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 5209 __ j(greater, &rest_parameters); |
| 5210 |
| 5211 // Return an empty rest parameter array. |
| 5212 __ bind(&no_rest_parameters); |
| 5213 { |
| 5214 // ----------- S t a t e ------------- |
| 5215 // -- esi : context |
| 5216 // -- esp[0] : return address |
| 5217 // ----------------------------------- |
| 5218 |
| 5219 // Allocate an empty rest parameter array. |
| 5220 Label allocate, done_allocate; |
| 5221 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, TAG_OBJECT); |
| 5222 __ bind(&done_allocate); |
| 5223 |
| 5224 // Setup the rest parameter array in rax. |
| 5225 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
| 5226 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); |
| 5227 __ mov(ecx, isolate()->factory()->empty_fixed_array()); |
| 5228 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); |
| 5229 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); |
| 5230 __ mov(FieldOperand(eax, JSArray::kLengthOffset), |
| 5231 Immediate(Smi::FromInt(0))); |
| 5232 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 5233 __ Ret(); |
| 5234 |
| 5235 // Fall back to %AllocateInNewSpace. |
| 5236 __ bind(&allocate); |
| 5237 { |
| 5238 FrameScope scope(masm, StackFrame::INTERNAL); |
| 5239 __ Push(Smi::FromInt(JSArray::kSize)); |
| 5240 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 5241 } |
| 5242 __ jmp(&done_allocate); |
| 5243 } |
| 5244 |
| 5245 __ bind(&rest_parameters); |
| 5246 { |
| 5247 // Compute the pointer to the first rest parameter (skippping the receiver). |
| 5248 __ lea(ebx, |
| 5249 Operand(ebx, eax, times_half_pointer_size, |
| 5250 StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize)); |
| 5251 |
| 5252 // ----------- S t a t e ------------- |
| 5253 // -- esi : context |
| 5254 // -- eax : number of rest parameters (tagged) |
| 5255 // -- ebx : pointer to first rest parameters |
| 5256 // -- esp[0] : return address |
| 5257 // ----------------------------------- |
| 5258 |
| 5259 // Allocate space for the rest parameter array plus the backing store. |
| 5260 Label allocate, done_allocate; |
| 5261 __ lea(ecx, Operand(eax, times_half_pointer_size, |
| 5262 JSArray::kSize + FixedArray::kHeaderSize)); |
| 5263 __ Allocate(ecx, edx, edi, no_reg, &allocate, TAG_OBJECT); |
| 5264 __ bind(&done_allocate); |
| 5265 |
| 5266 // Setup the elements array in edx. |
| 5267 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
| 5268 isolate()->factory()->fixed_array_map()); |
| 5269 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
| 5270 { |
| 5271 Label loop, done_loop; |
| 5272 __ Move(ecx, Smi::FromInt(0)); |
| 5273 __ bind(&loop); |
| 5274 __ cmp(ecx, eax); |
| 5275 __ j(equal, &done_loop, Label::kNear); |
| 5276 __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
| 5277 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
| 5278 FixedArray::kHeaderSize), |
| 5279 edi); |
| 5280 __ sub(ebx, Immediate(1 * kPointerSize)); |
| 5281 __ add(ecx, Immediate(Smi::FromInt(1))); |
| 5282 __ jmp(&loop); |
| 5283 __ bind(&done_loop); |
| 5284 } |
| 5285 |
| 5286 // Setup the rest parameter array in edi. |
| 5287 __ lea(edi, |
| 5288 Operand(edx, eax, times_half_pointer_size, FixedArray::kHeaderSize)); |
| 5289 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
| 5290 __ mov(FieldOperand(edi, JSArray::kMapOffset), ecx); |
| 5291 __ mov(FieldOperand(edi, JSArray::kPropertiesOffset), |
| 5292 isolate()->factory()->empty_fixed_array()); |
| 5293 __ mov(FieldOperand(edi, JSArray::kElementsOffset), edx); |
| 5294 __ mov(FieldOperand(edi, JSArray::kLengthOffset), eax); |
| 5295 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
| 5296 __ mov(eax, edi); |
| 5297 __ Ret(); |
| 5298 |
| 5299 // Fall back to %AllocateInNewSpace. |
| 5300 __ bind(&allocate); |
| 5301 { |
| 5302 FrameScope scope(masm, StackFrame::INTERNAL); |
| 5303 __ SmiTag(ecx); |
| 5304 __ Push(eax); |
| 5305 __ Push(ebx); |
| 5306 __ Push(ecx); |
| 5307 __ CallRuntime(Runtime::kAllocateInNewSpace); |
| 5308 __ mov(edx, eax); |
| 5309 __ Pop(ebx); |
| 5310 __ Pop(eax); |
| 5311 } |
| 5312 __ jmp(&done_allocate); |
| 5313 } |
| 5314 } |
| 5315 |
| 5316 |
5198 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { | 5317 void LoadGlobalViaContextStub::Generate(MacroAssembler* masm) { |
5199 Register context_reg = esi; | 5318 Register context_reg = esi; |
5200 Register slot_reg = ebx; | 5319 Register slot_reg = ebx; |
5201 Register result_reg = eax; | 5320 Register result_reg = eax; |
5202 Label slow_case; | 5321 Label slow_case; |
5203 | 5322 |
5204 // Go up context chain to the script context. | 5323 // Go up context chain to the script context. |
5205 for (int i = 0; i < depth(); ++i) { | 5324 for (int i = 0; i < depth(); ++i) { |
5206 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); | 5325 __ mov(result_reg, ContextOperand(context_reg, Context::PREVIOUS_INDEX)); |
5207 context_reg = result_reg; | 5326 context_reg = result_reg; |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5744 return_value_operand, NULL); | 5863 return_value_operand, NULL); |
5745 } | 5864 } |
5746 | 5865 |
5747 | 5866 |
5748 #undef __ | 5867 #undef __ |
5749 | 5868 |
5750 } // namespace internal | 5869 } // namespace internal |
5751 } // namespace v8 | 5870 } // namespace v8 |
5752 | 5871 |
5753 #endif // V8_TARGET_ARCH_IA32 | 5872 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |