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/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
11 #include "src/ia32/frames-ia32.h" | 11 #include "src/ia32/frames-ia32.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 | |
17 #define __ ACCESS_MASM(masm) | 16 #define __ ACCESS_MASM(masm) |
18 | 17 |
19 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, | 18 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, |
20 ExitFrameType exit_frame_type) { | 19 ExitFrameType exit_frame_type) { |
21 // ----------- S t a t e ------------- | 20 // ----------- S t a t e ------------- |
22 // -- eax : number of arguments excluding receiver | 21 // -- eax : number of arguments excluding receiver |
23 // -- edi : target | 22 // -- edi : target |
24 // -- edx : new.target | 23 // -- edx : new.target |
25 // -- esp[0] : return address | 24 // -- esp[0] : return address |
26 // -- esp[4] : last argument | 25 // -- esp[4] : last argument |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 237 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
239 __ pop(ecx); | 238 __ pop(ecx); |
240 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 239 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
241 __ push(ecx); | 240 __ push(ecx); |
242 if (create_implicit_receiver) { | 241 if (create_implicit_receiver) { |
243 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); | 242 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); |
244 } | 243 } |
245 __ ret(0); | 244 __ ret(0); |
246 } | 245 } |
247 | 246 |
248 | |
249 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 247 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
250 Generate_JSConstructStubHelper(masm, false, true, false); | 248 Generate_JSConstructStubHelper(masm, false, true, false); |
251 } | 249 } |
252 | 250 |
253 | |
254 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 251 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
255 Generate_JSConstructStubHelper(masm, true, false, false); | 252 Generate_JSConstructStubHelper(masm, true, false, false); |
256 } | 253 } |
257 | 254 |
258 | |
259 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { | 255 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
260 Generate_JSConstructStubHelper(masm, false, false, false); | 256 Generate_JSConstructStubHelper(masm, false, false, false); |
261 } | 257 } |
262 | 258 |
263 | |
264 void Builtins::Generate_JSBuiltinsConstructStubForDerived( | 259 void Builtins::Generate_JSBuiltinsConstructStubForDerived( |
265 MacroAssembler* masm) { | 260 MacroAssembler* masm) { |
266 Generate_JSConstructStubHelper(masm, false, false, true); | 261 Generate_JSConstructStubHelper(masm, false, false, true); |
267 } | 262 } |
268 | 263 |
269 | |
270 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { | 264 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { |
271 FrameScope scope(masm, StackFrame::INTERNAL); | 265 FrameScope scope(masm, StackFrame::INTERNAL); |
272 __ push(edi); | 266 __ push(edi); |
273 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); | 267 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); |
274 } | 268 } |
275 | 269 |
276 | |
277 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; | 270 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; |
278 | 271 |
279 | |
280 // Clobbers ecx, edx, edi; preserves all other registers. | 272 // Clobbers ecx, edx, edi; preserves all other registers. |
281 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 273 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
282 IsTagged eax_is_tagged) { | 274 IsTagged eax_is_tagged) { |
283 // eax : the number of items to be pushed to the stack | 275 // eax : the number of items to be pushed to the stack |
284 // | 276 // |
285 // Check the stack for overflow. We are not trying to catch | 277 // Check the stack for overflow. We are not trying to catch |
286 // interruptions (e.g. debug break and preemption) here, so the "real stack | 278 // interruptions (e.g. debug break and preemption) here, so the "real stack |
287 // limit" is checked. | 279 // limit" is checked. |
288 Label okay; | 280 Label okay; |
289 ExternalReference real_stack_limit = | 281 ExternalReference real_stack_limit = |
(...skipping 11 matching lines...) Expand all Loading... |
301 // Check if the arguments will overflow the stack. | 293 // Check if the arguments will overflow the stack. |
302 __ cmp(ecx, edx); | 294 __ cmp(ecx, edx); |
303 __ j(greater, &okay); // Signed comparison. | 295 __ j(greater, &okay); // Signed comparison. |
304 | 296 |
305 // Out of stack space. | 297 // Out of stack space. |
306 __ CallRuntime(Runtime::kThrowStackOverflow); | 298 __ CallRuntime(Runtime::kThrowStackOverflow); |
307 | 299 |
308 __ bind(&okay); | 300 __ bind(&okay); |
309 } | 301 } |
310 | 302 |
311 | |
312 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 303 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
313 bool is_construct) { | 304 bool is_construct) { |
314 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 305 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
315 | 306 |
316 { | 307 { |
317 FrameScope scope(masm, StackFrame::INTERNAL); | 308 FrameScope scope(masm, StackFrame::INTERNAL); |
318 | 309 |
319 // Setup the context (we need to use the caller context from the isolate). | 310 // Setup the context (we need to use the caller context from the isolate). |
320 ExternalReference context_address(Isolate::kContextAddress, | 311 ExternalReference context_address(Isolate::kContextAddress, |
321 masm->isolate()); | 312 masm->isolate()); |
(...skipping 13 matching lines...) Expand all Loading... |
335 // Check if we have enough stack space to push all arguments. | 326 // Check if we have enough stack space to push all arguments. |
336 // Expects argument count in eax. Clobbers ecx, edx, edi. | 327 // Expects argument count in eax. Clobbers ecx, edx, edi. |
337 Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt); | 328 Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt); |
338 | 329 |
339 // Copy arguments to the stack in a loop. | 330 // Copy arguments to the stack in a loop. |
340 Label loop, entry; | 331 Label loop, entry; |
341 __ Move(ecx, Immediate(0)); | 332 __ Move(ecx, Immediate(0)); |
342 __ jmp(&entry, Label::kNear); | 333 __ jmp(&entry, Label::kNear); |
343 __ bind(&loop); | 334 __ bind(&loop); |
344 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv | 335 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv |
345 __ push(Operand(edx, 0)); // dereference handle | 336 __ push(Operand(edx, 0)); // dereference handle |
346 __ inc(ecx); | 337 __ inc(ecx); |
347 __ bind(&entry); | 338 __ bind(&entry); |
348 __ cmp(ecx, eax); | 339 __ cmp(ecx, eax); |
349 __ j(not_equal, &loop); | 340 __ j(not_equal, &loop); |
350 | 341 |
351 // Load the previous frame pointer (ebx) to access C arguments | 342 // Load the previous frame pointer (ebx) to access C arguments |
352 __ mov(ebx, Operand(ebp, 0)); | 343 __ mov(ebx, Operand(ebp, 0)); |
353 | 344 |
354 // Get the new.target and function from the frame. | 345 // Get the new.target and function from the frame. |
355 __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset)); | 346 __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset)); |
356 __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); | 347 __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); |
357 | 348 |
358 // Invoke the code. | 349 // Invoke the code. |
359 Handle<Code> builtin = is_construct | 350 Handle<Code> builtin = is_construct |
360 ? masm->isolate()->builtins()->Construct() | 351 ? masm->isolate()->builtins()->Construct() |
361 : masm->isolate()->builtins()->Call(); | 352 : masm->isolate()->builtins()->Call(); |
362 __ Call(builtin, RelocInfo::CODE_TARGET); | 353 __ Call(builtin, RelocInfo::CODE_TARGET); |
363 | 354 |
364 // Exit the internal frame. Notice that this also removes the empty. | 355 // Exit the internal frame. Notice that this also removes the empty. |
365 // context and the function left on the stack by the code | 356 // context and the function left on the stack by the code |
366 // invocation. | 357 // invocation. |
367 } | 358 } |
368 __ ret(kPointerSize); // Remove receiver. | 359 __ ret(kPointerSize); // Remove receiver. |
369 } | 360 } |
370 | 361 |
371 | |
372 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 362 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
373 Generate_JSEntryTrampolineHelper(masm, false); | 363 Generate_JSEntryTrampolineHelper(masm, false); |
374 } | 364 } |
375 | 365 |
376 | |
377 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 366 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
378 Generate_JSEntryTrampolineHelper(masm, true); | 367 Generate_JSEntryTrampolineHelper(masm, true); |
379 } | 368 } |
380 | 369 |
381 // static | 370 // static |
382 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { | 371 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { |
383 // ----------- S t a t e ------------- | 372 // ----------- S t a t e ------------- |
384 // -- eax : the value to pass to the generator | 373 // -- eax : the value to pass to the generator |
385 // -- ebx : the JSGeneratorObject to resume | 374 // -- ebx : the JSGeneratorObject to resume |
386 // -- edx : the resume mode (tagged) | 375 // -- edx : the resume mode (tagged) |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 442 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
454 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset)); | 443 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset)); |
455 __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx); | 444 __ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx); |
456 __ j(not_equal, &old_generator); | 445 __ j(not_equal, &old_generator); |
457 | 446 |
458 // New-style (ignition/turbofan) generator object | 447 // New-style (ignition/turbofan) generator object |
459 { | 448 { |
460 __ PushReturnAddressFrom(eax); | 449 __ PushReturnAddressFrom(eax); |
461 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 450 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
462 __ mov(eax, | 451 __ mov(eax, |
463 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); | 452 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); |
464 // We abuse new.target both to indicate that this is a resume call and to | 453 // We abuse new.target both to indicate that this is a resume call and to |
465 // pass in the generator object. In ordinary calls, new.target is always | 454 // pass in the generator object. In ordinary calls, new.target is always |
466 // undefined because generator functions are non-constructable. | 455 // undefined because generator functions are non-constructable. |
467 __ mov(edx, ebx); | 456 __ mov(edx, ebx); |
468 __ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 457 __ jmp(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
469 } | 458 } |
470 | 459 |
471 // Old-style (full-codegen) generator object | 460 // Old-style (full-codegen) generator object |
472 __ bind(&old_generator); | 461 __ bind(&old_generator); |
473 { | 462 { |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 tail_call_mode), | 750 tail_call_mode), |
762 RelocInfo::CODE_TARGET); | 751 RelocInfo::CODE_TARGET); |
763 } else { | 752 } else { |
764 DCHECK_EQ(function_type, CallableType::kAny); | 753 DCHECK_EQ(function_type, CallableType::kAny); |
765 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 754 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
766 tail_call_mode), | 755 tail_call_mode), |
767 RelocInfo::CODE_TARGET); | 756 RelocInfo::CODE_TARGET); |
768 } | 757 } |
769 } | 758 } |
770 | 759 |
771 | |
772 // static | 760 // static |
773 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 761 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
774 // ----------- S t a t e ------------- | 762 // ----------- S t a t e ------------- |
775 // -- eax : the number of arguments (not including the receiver) | 763 // -- eax : the number of arguments (not including the receiver) |
776 // -- edx : the new target | 764 // -- edx : the new target |
777 // -- edi : the constructor | 765 // -- edi : the constructor |
778 // -- ebx : the address of the first argument to be pushed. Subsequent | 766 // -- ebx : the address of the first argument to be pushed. Subsequent |
779 // arguments should be consecutive above this, in the same order as | 767 // arguments should be consecutive above this, in the same order as |
780 // they are to be pushed onto the stack. | 768 // they are to be pushed onto the stack. |
781 // ----------------------------------- | 769 // ----------------------------------- |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1019 | 1007 |
1020 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { | 1008 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { |
1021 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); | 1009 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); |
1022 } | 1010 } |
1023 | 1011 |
1024 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 1012 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
1025 GenerateTailCallToReturnedCode(masm, | 1013 GenerateTailCallToReturnedCode(masm, |
1026 Runtime::kCompileOptimized_NotConcurrent); | 1014 Runtime::kCompileOptimized_NotConcurrent); |
1027 } | 1015 } |
1028 | 1016 |
1029 | |
1030 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { | 1017 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { |
1031 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); | 1018 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); |
1032 } | 1019 } |
1033 | 1020 |
1034 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { | 1021 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { |
1035 // ----------- S t a t e ------------- | 1022 // ----------- S t a t e ------------- |
1036 // -- eax : argument count (preserved for callee) | 1023 // -- eax : argument count (preserved for callee) |
1037 // -- edx : new target (preserved for callee) | 1024 // -- edx : new target (preserved for callee) |
1038 // -- edi : target function (preserved for callee) | 1025 // -- edi : target function (preserved for callee) |
1039 // ----------------------------------- | 1026 // ----------------------------------- |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 __ mov(Operand(esp, 1 * kPointerSize), | 1077 __ mov(Operand(esp, 1 * kPointerSize), |
1091 Immediate(ExternalReference::isolate_address(masm->isolate()))); | 1078 Immediate(ExternalReference::isolate_address(masm->isolate()))); |
1092 __ mov(Operand(esp, 0), eax); | 1079 __ mov(Operand(esp, 0), eax); |
1093 __ CallCFunction( | 1080 __ CallCFunction( |
1094 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 1081 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
1095 } | 1082 } |
1096 __ popad(); | 1083 __ popad(); |
1097 __ ret(0); | 1084 __ ret(0); |
1098 } | 1085 } |
1099 | 1086 |
1100 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ | 1087 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ |
1101 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ | 1088 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ |
1102 MacroAssembler* masm) { \ | 1089 MacroAssembler* masm) { \ |
1103 GenerateMakeCodeYoungAgainCommon(masm); \ | 1090 GenerateMakeCodeYoungAgainCommon(masm); \ |
1104 } \ | 1091 } \ |
1105 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ | 1092 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ |
1106 MacroAssembler* masm) { \ | 1093 MacroAssembler* masm) { \ |
1107 GenerateMakeCodeYoungAgainCommon(masm); \ | 1094 GenerateMakeCodeYoungAgainCommon(masm); \ |
1108 } | 1095 } |
1109 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) | 1096 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) |
1110 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR | 1097 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR |
1111 | 1098 |
1112 | |
1113 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 1099 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { |
1114 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 1100 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact |
1115 // that make_code_young doesn't do any garbage collection which allows us to | 1101 // that make_code_young doesn't do any garbage collection which allows us to |
1116 // save/restore the registers without worrying about which of them contain | 1102 // save/restore the registers without worrying about which of them contain |
1117 // pointers. | 1103 // pointers. |
1118 __ pushad(); | 1104 __ pushad(); |
1119 __ mov(eax, Operand(esp, 8 * kPointerSize)); | 1105 __ mov(eax, Operand(esp, 8 * kPointerSize)); |
1120 __ sub(eax, Immediate(Assembler::kCallInstructionLength)); | 1106 __ sub(eax, Immediate(Assembler::kCallInstructionLength)); |
1121 { // NOLINT | 1107 { // NOLINT |
1122 FrameScope scope(masm, StackFrame::MANUAL); | 1108 FrameScope scope(masm, StackFrame::MANUAL); |
(...skipping 12 matching lines...) Expand all Loading... |
1135 __ push(ebp); // Caller's frame pointer. | 1121 __ push(ebp); // Caller's frame pointer. |
1136 __ mov(ebp, esp); | 1122 __ mov(ebp, esp); |
1137 __ push(esi); // Callee's context. | 1123 __ push(esi); // Callee's context. |
1138 __ push(edi); // Callee's JS Function. | 1124 __ push(edi); // Callee's JS Function. |
1139 __ push(eax); // Push return address after frame prologue. | 1125 __ push(eax); // Push return address after frame prologue. |
1140 | 1126 |
1141 // Jump to point after the code-age stub. | 1127 // Jump to point after the code-age stub. |
1142 __ ret(0); | 1128 __ ret(0); |
1143 } | 1129 } |
1144 | 1130 |
1145 | |
1146 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 1131 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { |
1147 GenerateMakeCodeYoungAgainCommon(masm); | 1132 GenerateMakeCodeYoungAgainCommon(masm); |
1148 } | 1133 } |
1149 | 1134 |
1150 | |
1151 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { | 1135 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { |
1152 Generate_MarkCodeAsExecutedOnce(masm); | 1136 Generate_MarkCodeAsExecutedOnce(masm); |
1153 } | 1137 } |
1154 | 1138 |
1155 | |
1156 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 1139 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, |
1157 SaveFPRegsMode save_doubles) { | 1140 SaveFPRegsMode save_doubles) { |
1158 // Enter an internal frame. | 1141 // Enter an internal frame. |
1159 { | 1142 { |
1160 FrameScope scope(masm, StackFrame::INTERNAL); | 1143 FrameScope scope(masm, StackFrame::INTERNAL); |
1161 | 1144 |
1162 // Preserve registers across notification, this is important for compiled | 1145 // Preserve registers across notification, this is important for compiled |
1163 // stubs that tail call the runtime on deopts passing their parameters in | 1146 // stubs that tail call the runtime on deopts passing their parameters in |
1164 // registers. | 1147 // registers. |
1165 __ pushad(); | 1148 __ pushad(); |
1166 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); | 1149 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); |
1167 __ popad(); | 1150 __ popad(); |
1168 // Tear down internal frame. | 1151 // Tear down internal frame. |
1169 } | 1152 } |
1170 | 1153 |
1171 __ pop(MemOperand(esp, 0)); // Ignore state offset | 1154 __ pop(MemOperand(esp, 0)); // Ignore state offset |
1172 __ ret(0); // Return to IC Miss stub, continuation still on stack. | 1155 __ ret(0); // Return to IC Miss stub, continuation still on stack. |
1173 } | 1156 } |
1174 | 1157 |
1175 | |
1176 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 1158 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { |
1177 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 1159 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); |
1178 } | 1160 } |
1179 | 1161 |
1180 | |
1181 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 1162 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { |
1182 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 1163 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); |
1183 } | 1164 } |
1184 | 1165 |
1185 | |
1186 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 1166 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
1187 Deoptimizer::BailoutType type) { | 1167 Deoptimizer::BailoutType type) { |
1188 { | 1168 { |
1189 FrameScope scope(masm, StackFrame::INTERNAL); | 1169 FrameScope scope(masm, StackFrame::INTERNAL); |
1190 | 1170 |
1191 // Pass deoptimization type to the runtime system. | 1171 // Pass deoptimization type to the runtime system. |
1192 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); | 1172 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); |
1193 __ CallRuntime(Runtime::kNotifyDeoptimized); | 1173 __ CallRuntime(Runtime::kNotifyDeoptimized); |
1194 | 1174 |
1195 // Tear down internal frame. | 1175 // Tear down internal frame. |
(...skipping 13 matching lines...) Expand all Loading... |
1209 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code()); | 1189 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code()); |
1210 __ mov(eax, Operand(esp, 2 * kPointerSize)); | 1190 __ mov(eax, Operand(esp, 2 * kPointerSize)); |
1211 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)); | 1191 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)); |
1212 __ j(not_equal, ¬_tos_eax, Label::kNear); | 1192 __ j(not_equal, ¬_tos_eax, Label::kNear); |
1213 __ ret(2 * kPointerSize); // Remove state, eax. | 1193 __ ret(2 * kPointerSize); // Remove state, eax. |
1214 | 1194 |
1215 __ bind(¬_tos_eax); | 1195 __ bind(¬_tos_eax); |
1216 __ Abort(kNoCasesLeft); | 1196 __ Abort(kNoCasesLeft); |
1217 } | 1197 } |
1218 | 1198 |
1219 | |
1220 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 1199 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { |
1221 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); | 1200 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); |
1222 } | 1201 } |
1223 | 1202 |
1224 | |
1225 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 1203 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { |
1226 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 1204 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); |
1227 } | 1205 } |
1228 | 1206 |
1229 | |
1230 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 1207 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
1231 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 1208 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
1232 } | 1209 } |
1233 | 1210 |
1234 | |
1235 // static | 1211 // static |
1236 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, | 1212 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, |
1237 int field_index) { | 1213 int field_index) { |
1238 // ----------- S t a t e ------------- | 1214 // ----------- S t a t e ------------- |
1239 // -- eax : number of arguments | 1215 // -- eax : number of arguments |
1240 // -- edi : function | 1216 // -- edi : function |
1241 // -- esi : context | 1217 // -- esi : context |
1242 // -- esp[0] : return address | 1218 // -- esp[0] : return address |
1243 // -- esp[4] : receiver | 1219 // -- esp[4] : receiver |
1244 // ----------------------------------- | 1220 // ----------------------------------- |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 } | 1333 } |
1358 | 1334 |
1359 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1335 // 4c. The receiver is not callable, throw an appropriate TypeError. |
1360 __ bind(&receiver_not_callable); | 1336 __ bind(&receiver_not_callable); |
1361 { | 1337 { |
1362 __ mov(Operand(esp, kPointerSize), edi); | 1338 __ mov(Operand(esp, kPointerSize), edi); |
1363 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 1339 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1364 } | 1340 } |
1365 } | 1341 } |
1366 | 1342 |
1367 | |
1368 // static | 1343 // static |
1369 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { | 1344 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { |
1370 // Stack Layout: | 1345 // Stack Layout: |
1371 // esp[0] : Return address | 1346 // esp[0] : Return address |
1372 // esp[8] : Argument n | 1347 // esp[8] : Argument n |
1373 // esp[16] : Argument n-1 | 1348 // esp[16] : Argument n-1 |
1374 // ... | 1349 // ... |
1375 // esp[8 * n] : Argument 1 | 1350 // esp[8 * n] : Argument 1 |
1376 // esp[8 * (n + 1)] : Receiver (callable to call) | 1351 // esp[8 * (n + 1)] : Receiver (callable to call) |
1377 // | 1352 // |
(...skipping 26 matching lines...) Expand all Loading... |
1404 __ dec(ecx); | 1379 __ dec(ecx); |
1405 __ j(not_sign, &loop); // While non-negative (to copy return address). | 1380 __ j(not_sign, &loop); // While non-negative (to copy return address). |
1406 __ pop(ebx); // Discard copy of return address. | 1381 __ pop(ebx); // Discard copy of return address. |
1407 __ dec(eax); // One fewer argument (first argument is new receiver). | 1382 __ dec(eax); // One fewer argument (first argument is new receiver). |
1408 } | 1383 } |
1409 | 1384 |
1410 // 4. Call the callable. | 1385 // 4. Call the callable. |
1411 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1386 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1412 } | 1387 } |
1413 | 1388 |
1414 | |
1415 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 1389 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |
1416 // ----------- S t a t e ------------- | 1390 // ----------- S t a t e ------------- |
1417 // -- eax : argc | 1391 // -- eax : argc |
1418 // -- esp[0] : return address | 1392 // -- esp[0] : return address |
1419 // -- esp[4] : argumentsList | 1393 // -- esp[4] : argumentsList |
1420 // -- esp[8] : thisArgument | 1394 // -- esp[8] : thisArgument |
1421 // -- esp[12] : target | 1395 // -- esp[12] : target |
1422 // -- esp[16] : receiver | 1396 // -- esp[16] : receiver |
1423 // ----------------------------------- | 1397 // ----------------------------------- |
1424 | 1398 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 } | 1519 } |
1546 | 1520 |
1547 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1521 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
1548 __ bind(&new_target_not_constructor); | 1522 __ bind(&new_target_not_constructor); |
1549 { | 1523 { |
1550 __ mov(Operand(esp, kPointerSize), edx); | 1524 __ mov(Operand(esp, kPointerSize), edx); |
1551 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); | 1525 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
1552 } | 1526 } |
1553 } | 1527 } |
1554 | 1528 |
1555 | |
1556 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1529 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
1557 // ----------- S t a t e ------------- | 1530 // ----------- S t a t e ------------- |
1558 // -- eax : argc | 1531 // -- eax : argc |
1559 // -- esp[0] : return address | 1532 // -- esp[0] : return address |
1560 // -- esp[4] : last argument | 1533 // -- esp[4] : last argument |
1561 // ----------------------------------- | 1534 // ----------------------------------- |
1562 Label generic_array_code; | 1535 Label generic_array_code; |
1563 | 1536 |
1564 // Get the InternalArray function. | 1537 // Get the InternalArray function. |
1565 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); | 1538 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); |
1566 | 1539 |
1567 if (FLAG_debug_code) { | 1540 if (FLAG_debug_code) { |
1568 // Initial map for the builtin InternalArray function should be a map. | 1541 // Initial map for the builtin InternalArray function should be a map. |
1569 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 1542 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
1570 // Will both indicate a NULL and a Smi. | 1543 // Will both indicate a NULL and a Smi. |
1571 __ test(ebx, Immediate(kSmiTagMask)); | 1544 __ test(ebx, Immediate(kSmiTagMask)); |
1572 __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction); | 1545 __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction); |
1573 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1546 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
1574 __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction); | 1547 __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction); |
1575 } | 1548 } |
1576 | 1549 |
1577 // Run the native code for the InternalArray function called as a normal | 1550 // Run the native code for the InternalArray function called as a normal |
1578 // function. | 1551 // function. |
1579 // tail call a stub | 1552 // tail call a stub |
1580 InternalArrayConstructorStub stub(masm->isolate()); | 1553 InternalArrayConstructorStub stub(masm->isolate()); |
1581 __ TailCallStub(&stub); | 1554 __ TailCallStub(&stub); |
1582 } | 1555 } |
1583 | 1556 |
1584 | |
1585 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 1557 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |
1586 // ----------- S t a t e ------------- | 1558 // ----------- S t a t e ------------- |
1587 // -- eax : argc | 1559 // -- eax : argc |
1588 // -- esp[0] : return address | 1560 // -- esp[0] : return address |
1589 // -- esp[4] : last argument | 1561 // -- esp[4] : last argument |
1590 // ----------------------------------- | 1562 // ----------------------------------- |
1591 Label generic_array_code; | 1563 Label generic_array_code; |
1592 | 1564 |
1593 // Get the Array function. | 1565 // Get the Array function. |
1594 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); | 1566 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); |
1595 __ mov(edx, edi); | 1567 __ mov(edx, edi); |
1596 | 1568 |
1597 if (FLAG_debug_code) { | 1569 if (FLAG_debug_code) { |
1598 // Initial map for the builtin Array function should be a map. | 1570 // Initial map for the builtin Array function should be a map. |
1599 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 1571 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
1600 // Will both indicate a NULL and a Smi. | 1572 // Will both indicate a NULL and a Smi. |
1601 __ test(ebx, Immediate(kSmiTagMask)); | 1573 __ test(ebx, Immediate(kSmiTagMask)); |
1602 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); | 1574 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); |
1603 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1575 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
1604 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); | 1576 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); |
1605 } | 1577 } |
1606 | 1578 |
1607 // Run the native code for the Array function called as a normal function. | 1579 // Run the native code for the Array function called as a normal function. |
1608 // tail call a stub | 1580 // tail call a stub |
1609 __ mov(ebx, masm->isolate()->factory()->undefined_value()); | 1581 __ mov(ebx, masm->isolate()->factory()->undefined_value()); |
1610 ArrayConstructorStub stub(masm->isolate()); | 1582 ArrayConstructorStub stub(masm->isolate()); |
1611 __ TailCallStub(&stub); | 1583 __ TailCallStub(&stub); |
1612 } | 1584 } |
1613 | 1585 |
1614 | |
1615 // static | 1586 // static |
1616 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { | 1587 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { |
1617 // ----------- S t a t e ------------- | 1588 // ----------- S t a t e ------------- |
1618 // -- eax : number of arguments | 1589 // -- eax : number of arguments |
1619 // -- edi : function | 1590 // -- edi : function |
1620 // -- esi : context | 1591 // -- esi : context |
1621 // -- esp[0] : return address | 1592 // -- esp[0] : return address |
1622 // -- esp[(argc - n) * 8] : arg[n] (zero-based) | 1593 // -- esp[(argc - n) * 8] : arg[n] (zero-based) |
1623 // -- esp[(argc + 1) * 8] : receiver | 1594 // -- esp[(argc + 1) * 8] : receiver |
1624 // ----------------------------------- | 1595 // ----------------------------------- |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1738 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
1768 __ PushReturnAddressFrom(ecx); | 1739 __ PushReturnAddressFrom(ecx); |
1769 __ Ret(); | 1740 __ Ret(); |
1770 } | 1741 } |
1771 | 1742 |
1772 // 2b. No arguments, return +0 (already in eax). | 1743 // 2b. No arguments, return +0 (already in eax). |
1773 __ bind(&no_arguments); | 1744 __ bind(&no_arguments); |
1774 __ ret(1 * kPointerSize); | 1745 __ ret(1 * kPointerSize); |
1775 } | 1746 } |
1776 | 1747 |
1777 | |
1778 // static | 1748 // static |
1779 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { | 1749 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
1780 // ----------- S t a t e ------------- | 1750 // ----------- S t a t e ------------- |
1781 // -- eax : number of arguments | 1751 // -- eax : number of arguments |
1782 // -- edi : constructor function | 1752 // -- edi : constructor function |
1783 // -- edx : new target | 1753 // -- edx : new target |
1784 // -- esi : context | 1754 // -- esi : context |
1785 // -- esp[0] : return address | 1755 // -- esp[0] : return address |
1786 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1756 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1787 // -- esp[(argc + 1) * 4] : receiver | 1757 // -- esp[(argc + 1) * 4] : receiver |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1854 { | 1824 { |
1855 // Drop all arguments including the receiver. | 1825 // Drop all arguments including the receiver. |
1856 __ PopReturnAddressTo(esi); | 1826 __ PopReturnAddressTo(esi); |
1857 __ SmiUntag(ecx); | 1827 __ SmiUntag(ecx); |
1858 __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize)); | 1828 __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize)); |
1859 __ PushReturnAddressFrom(esi); | 1829 __ PushReturnAddressFrom(esi); |
1860 __ Ret(); | 1830 __ Ret(); |
1861 } | 1831 } |
1862 } | 1832 } |
1863 | 1833 |
1864 | |
1865 // static | 1834 // static |
1866 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1835 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
1867 // ----------- S t a t e ------------- | 1836 // ----------- S t a t e ------------- |
1868 // -- eax : number of arguments | 1837 // -- eax : number of arguments |
1869 // -- edi : constructor function | 1838 // -- edi : constructor function |
1870 // -- esi : context | 1839 // -- esi : context |
1871 // -- esp[0] : return address | 1840 // -- esp[0] : return address |
1872 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1841 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1873 // -- esp[(argc + 1) * 4] : receiver | 1842 // -- esp[(argc + 1) * 4] : receiver |
1874 // ----------------------------------- | 1843 // ----------------------------------- |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1927 __ bind(&drop_frame_and_ret); | 1896 __ bind(&drop_frame_and_ret); |
1928 { | 1897 { |
1929 // Drop all arguments including the receiver. | 1898 // Drop all arguments including the receiver. |
1930 __ PopReturnAddressTo(ecx); | 1899 __ PopReturnAddressTo(ecx); |
1931 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1900 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
1932 __ PushReturnAddressFrom(ecx); | 1901 __ PushReturnAddressFrom(ecx); |
1933 __ Ret(); | 1902 __ Ret(); |
1934 } | 1903 } |
1935 } | 1904 } |
1936 | 1905 |
1937 | |
1938 // static | 1906 // static |
1939 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1907 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1940 // ----------- S t a t e ------------- | 1908 // ----------- S t a t e ------------- |
1941 // -- eax : number of arguments | 1909 // -- eax : number of arguments |
1942 // -- edi : constructor function | 1910 // -- edi : constructor function |
1943 // -- edx : new target | 1911 // -- edx : new target |
1944 // -- esi : context | 1912 // -- esi : context |
1945 // -- esp[0] : return address | 1913 // -- esp[0] : return address |
1946 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1914 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1947 // -- esp[(argc + 1) * 4] : receiver | 1915 // -- esp[(argc + 1) * 4] : receiver |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 __ bind(&drop_frame_and_ret); | 1989 __ bind(&drop_frame_and_ret); |
2022 { | 1990 { |
2023 // Drop all arguments including the receiver. | 1991 // Drop all arguments including the receiver. |
2024 __ PopReturnAddressTo(ecx); | 1992 __ PopReturnAddressTo(ecx); |
2025 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1993 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
2026 __ PushReturnAddressFrom(ecx); | 1994 __ PushReturnAddressFrom(ecx); |
2027 __ Ret(); | 1995 __ Ret(); |
2028 } | 1996 } |
2029 } | 1997 } |
2030 | 1998 |
2031 | |
2032 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1999 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
2033 Label* stack_overflow) { | 2000 Label* stack_overflow) { |
2034 // ----------- S t a t e ------------- | 2001 // ----------- S t a t e ------------- |
2035 // -- eax : actual number of arguments | 2002 // -- eax : actual number of arguments |
2036 // -- ebx : expected number of arguments | 2003 // -- ebx : expected number of arguments |
2037 // -- edx : new target (passed through to callee) | 2004 // -- edx : new target (passed through to callee) |
2038 // ----------------------------------- | 2005 // ----------------------------------- |
2039 // Check the stack for overflow. We are not trying to catch | 2006 // Check the stack for overflow. We are not trying to catch |
2040 // interruptions (e.g. debug break and preemption) here, so the "real stack | 2007 // interruptions (e.g. debug break and preemption) here, so the "real stack |
2041 // limit" is checked. | 2008 // limit" is checked. |
2042 ExternalReference real_stack_limit = | 2009 ExternalReference real_stack_limit = |
2043 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 2010 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
2044 __ mov(edi, Operand::StaticVariable(real_stack_limit)); | 2011 __ mov(edi, Operand::StaticVariable(real_stack_limit)); |
2045 // Make ecx the space we have left. The stack might already be overflowed | 2012 // Make ecx the space we have left. The stack might already be overflowed |
2046 // here which will cause ecx to become negative. | 2013 // here which will cause ecx to become negative. |
2047 __ mov(ecx, esp); | 2014 __ mov(ecx, esp); |
2048 __ sub(ecx, edi); | 2015 __ sub(ecx, edi); |
2049 // Make edi the space we need for the array when it is unrolled onto the | 2016 // Make edi the space we need for the array when it is unrolled onto the |
2050 // stack. | 2017 // stack. |
2051 __ mov(edi, ebx); | 2018 __ mov(edi, ebx); |
2052 __ shl(edi, kPointerSizeLog2); | 2019 __ shl(edi, kPointerSizeLog2); |
2053 // Check if the arguments will overflow the stack. | 2020 // Check if the arguments will overflow the stack. |
2054 __ cmp(ecx, edi); | 2021 __ cmp(ecx, edi); |
2055 __ j(less_equal, stack_overflow); // Signed comparison. | 2022 __ j(less_equal, stack_overflow); // Signed comparison. |
2056 } | 2023 } |
2057 | 2024 |
2058 | |
2059 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 2025 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
2060 __ push(ebp); | 2026 __ push(ebp); |
2061 __ mov(ebp, esp); | 2027 __ mov(ebp, esp); |
2062 | 2028 |
2063 // Store the arguments adaptor context sentinel. | 2029 // Store the arguments adaptor context sentinel. |
2064 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2030 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
2065 | 2031 |
2066 // Push the function on the stack. | 2032 // Push the function on the stack. |
2067 __ push(edi); | 2033 __ push(edi); |
2068 | 2034 |
2069 // Preserve the number of arguments on the stack. Must preserve eax, | 2035 // Preserve the number of arguments on the stack. Must preserve eax, |
2070 // ebx and ecx because these registers are used when copying the | 2036 // ebx and ecx because these registers are used when copying the |
2071 // arguments and the receiver. | 2037 // arguments and the receiver. |
2072 STATIC_ASSERT(kSmiTagSize == 1); | 2038 STATIC_ASSERT(kSmiTagSize == 1); |
2073 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); | 2039 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); |
2074 __ push(edi); | 2040 __ push(edi); |
2075 } | 2041 } |
2076 | 2042 |
2077 | |
2078 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 2043 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
2079 // Retrieve the number of arguments from the stack. | 2044 // Retrieve the number of arguments from the stack. |
2080 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2045 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
2081 | 2046 |
2082 // Leave the frame. | 2047 // Leave the frame. |
2083 __ leave(); | 2048 __ leave(); |
2084 | 2049 |
2085 // Remove caller arguments from the stack. | 2050 // Remove caller arguments from the stack. |
2086 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 2051 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
2087 __ pop(ecx); | 2052 __ pop(ecx); |
2088 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 2053 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
2089 __ push(ecx); | 2054 __ push(ecx); |
2090 } | 2055 } |
2091 | 2056 |
2092 | |
2093 // static | 2057 // static |
2094 void Builtins::Generate_Apply(MacroAssembler* masm) { | 2058 void Builtins::Generate_Apply(MacroAssembler* masm) { |
2095 // ----------- S t a t e ------------- | 2059 // ----------- S t a t e ------------- |
2096 // -- eax : argumentsList | 2060 // -- eax : argumentsList |
2097 // -- edi : target | 2061 // -- edi : target |
2098 // -- edx : new.target (checked to be constructor or undefined) | 2062 // -- edx : new.target (checked to be constructor or undefined) |
2099 // -- esp[0] : return address. | 2063 // -- esp[0] : return address. |
2100 // -- esp[4] : thisArgument | 2064 // -- esp[4] : thisArgument |
2101 // ----------------------------------- | 2065 // ----------------------------------- |
2102 | 2066 |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2417 CheckDebugStepCallWrapper()); | 2381 CheckDebugStepCallWrapper()); |
2418 // The function is a "classConstructor", need to raise an exception. | 2382 // The function is a "classConstructor", need to raise an exception. |
2419 __ bind(&class_constructor); | 2383 __ bind(&class_constructor); |
2420 { | 2384 { |
2421 FrameScope frame(masm, StackFrame::INTERNAL); | 2385 FrameScope frame(masm, StackFrame::INTERNAL); |
2422 __ push(edi); | 2386 __ push(edi); |
2423 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); | 2387 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); |
2424 } | 2388 } |
2425 } | 2389 } |
2426 | 2390 |
2427 | |
2428 namespace { | 2391 namespace { |
2429 | 2392 |
2430 void Generate_PushBoundArguments(MacroAssembler* masm) { | 2393 void Generate_PushBoundArguments(MacroAssembler* masm) { |
2431 // ----------- S t a t e ------------- | 2394 // ----------- S t a t e ------------- |
2432 // -- eax : the number of arguments (not including the receiver) | 2395 // -- eax : the number of arguments (not including the receiver) |
2433 // -- edx : new.target (only in case of [[Construct]]) | 2396 // -- edx : new.target (only in case of [[Construct]]) |
2434 // -- edi : target (checked to be a JSBoundFunction) | 2397 // -- edi : target (checked to be a JSBoundFunction) |
2435 // ----------------------------------- | 2398 // ----------------------------------- |
2436 | 2399 |
2437 // Load [[BoundArguments]] into ecx and length of that into ebx. | 2400 // Load [[BoundArguments]] into ecx and length of that into ebx. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2504 // Adjust effective number of arguments (eax contains the number of | 2467 // Adjust effective number of arguments (eax contains the number of |
2505 // arguments from the call plus return address plus the number of | 2468 // arguments from the call plus return address plus the number of |
2506 // [[BoundArguments]]), so we need to subtract one for the return address. | 2469 // [[BoundArguments]]), so we need to subtract one for the return address. |
2507 __ dec(eax); | 2470 __ dec(eax); |
2508 } | 2471 } |
2509 __ bind(&no_bound_arguments); | 2472 __ bind(&no_bound_arguments); |
2510 } | 2473 } |
2511 | 2474 |
2512 } // namespace | 2475 } // namespace |
2513 | 2476 |
2514 | |
2515 // static | 2477 // static |
2516 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, | 2478 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, |
2517 TailCallMode tail_call_mode) { | 2479 TailCallMode tail_call_mode) { |
2518 // ----------- S t a t e ------------- | 2480 // ----------- S t a t e ------------- |
2519 // -- eax : the number of arguments (not including the receiver) | 2481 // -- eax : the number of arguments (not including the receiver) |
2520 // -- edi : the function to call (checked to be a JSBoundFunction) | 2482 // -- edi : the function to call (checked to be a JSBoundFunction) |
2521 // ----------------------------------- | 2483 // ----------------------------------- |
2522 __ AssertBoundFunction(edi); | 2484 __ AssertBoundFunction(edi); |
2523 | 2485 |
2524 if (tail_call_mode == TailCallMode::kAllow) { | 2486 if (tail_call_mode == TailCallMode::kAllow) { |
2525 PrepareForTailCall(masm, eax, ebx, ecx, edx); | 2487 PrepareForTailCall(masm, eax, ebx, ecx, edx); |
2526 } | 2488 } |
2527 | 2489 |
2528 // Patch the receiver to [[BoundThis]]. | 2490 // Patch the receiver to [[BoundThis]]. |
2529 __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset)); | 2491 __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset)); |
2530 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx); | 2492 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx); |
2531 | 2493 |
2532 // Push the [[BoundArguments]] onto the stack. | 2494 // Push the [[BoundArguments]] onto the stack. |
2533 Generate_PushBoundArguments(masm); | 2495 Generate_PushBoundArguments(masm); |
2534 | 2496 |
2535 // Call the [[BoundTargetFunction]] via the Call builtin. | 2497 // Call the [[BoundTargetFunction]] via the Call builtin. |
2536 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2498 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
2537 __ mov(ecx, Operand::StaticVariable(ExternalReference( | 2499 __ mov(ecx, Operand::StaticVariable(ExternalReference( |
2538 Builtins::kCall_ReceiverIsAny, masm->isolate()))); | 2500 Builtins::kCall_ReceiverIsAny, masm->isolate()))); |
2539 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2501 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
2540 __ jmp(ecx); | 2502 __ jmp(ecx); |
2541 } | 2503 } |
2542 | 2504 |
2543 | |
2544 // static | 2505 // static |
2545 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, | 2506 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, |
2546 TailCallMode tail_call_mode) { | 2507 TailCallMode tail_call_mode) { |
2547 // ----------- S t a t e ------------- | 2508 // ----------- S t a t e ------------- |
2548 // -- eax : the number of arguments (not including the receiver) | 2509 // -- eax : the number of arguments (not including the receiver) |
2549 // -- edi : the target to call (can be any Object). | 2510 // -- edi : the target to call (can be any Object). |
2550 // ----------------------------------- | 2511 // ----------------------------------- |
2551 | 2512 |
2552 Label non_callable, non_function, non_smi; | 2513 Label non_callable, non_function, non_smi; |
2553 __ JumpIfSmi(edi, &non_callable); | 2514 __ JumpIfSmi(edi, &non_callable); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2596 | 2557 |
2597 // 3. Call to something that is not callable. | 2558 // 3. Call to something that is not callable. |
2598 __ bind(&non_callable); | 2559 __ bind(&non_callable); |
2599 { | 2560 { |
2600 FrameScope scope(masm, StackFrame::INTERNAL); | 2561 FrameScope scope(masm, StackFrame::INTERNAL); |
2601 __ Push(edi); | 2562 __ Push(edi); |
2602 __ CallRuntime(Runtime::kThrowCalledNonCallable); | 2563 __ CallRuntime(Runtime::kThrowCalledNonCallable); |
2603 } | 2564 } |
2604 } | 2565 } |
2605 | 2566 |
2606 | |
2607 // static | 2567 // static |
2608 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2568 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
2609 // ----------- S t a t e ------------- | 2569 // ----------- S t a t e ------------- |
2610 // -- eax : the number of arguments (not including the receiver) | 2570 // -- eax : the number of arguments (not including the receiver) |
2611 // -- edx : the new target (checked to be a constructor) | 2571 // -- edx : the new target (checked to be a constructor) |
2612 // -- edi : the constructor to call (checked to be a JSFunction) | 2572 // -- edi : the constructor to call (checked to be a JSFunction) |
2613 // ----------------------------------- | 2573 // ----------------------------------- |
2614 __ AssertFunction(edi); | 2574 __ AssertFunction(edi); |
2615 | 2575 |
2616 // Calling convention for function specific ConstructStubs require | 2576 // Calling convention for function specific ConstructStubs require |
2617 // ebx to contain either an AllocationSite or undefined. | 2577 // ebx to contain either an AllocationSite or undefined. |
2618 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); | 2578 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); |
2619 | 2579 |
2620 // Tail call to the function-specific construct stub (still in the caller | 2580 // Tail call to the function-specific construct stub (still in the caller |
2621 // context at this point). | 2581 // context at this point). |
2622 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2582 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
2623 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); | 2583 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); |
2624 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2584 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
2625 __ jmp(ecx); | 2585 __ jmp(ecx); |
2626 } | 2586 } |
2627 | 2587 |
2628 | |
2629 // static | 2588 // static |
2630 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { | 2589 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
2631 // ----------- S t a t e ------------- | 2590 // ----------- S t a t e ------------- |
2632 // -- eax : the number of arguments (not including the receiver) | 2591 // -- eax : the number of arguments (not including the receiver) |
2633 // -- edx : the new target (checked to be a constructor) | 2592 // -- edx : the new target (checked to be a constructor) |
2634 // -- edi : the constructor to call (checked to be a JSBoundFunction) | 2593 // -- edi : the constructor to call (checked to be a JSBoundFunction) |
2635 // ----------------------------------- | 2594 // ----------------------------------- |
2636 __ AssertBoundFunction(edi); | 2595 __ AssertBoundFunction(edi); |
2637 | 2596 |
2638 // Push the [[BoundArguments]] onto the stack. | 2597 // Push the [[BoundArguments]] onto the stack. |
2639 Generate_PushBoundArguments(masm); | 2598 Generate_PushBoundArguments(masm); |
2640 | 2599 |
2641 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. | 2600 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
2642 { | 2601 { |
2643 Label done; | 2602 Label done; |
2644 __ cmp(edi, edx); | 2603 __ cmp(edi, edx); |
2645 __ j(not_equal, &done, Label::kNear); | 2604 __ j(not_equal, &done, Label::kNear); |
2646 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2605 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
2647 __ bind(&done); | 2606 __ bind(&done); |
2648 } | 2607 } |
2649 | 2608 |
2650 // Construct the [[BoundTargetFunction]] via the Construct builtin. | 2609 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
2651 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2610 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
2652 __ mov(ecx, Operand::StaticVariable( | 2611 __ mov(ecx, Operand::StaticVariable( |
2653 ExternalReference(Builtins::kConstruct, masm->isolate()))); | 2612 ExternalReference(Builtins::kConstruct, masm->isolate()))); |
2654 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2613 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
2655 __ jmp(ecx); | 2614 __ jmp(ecx); |
2656 } | 2615 } |
2657 | 2616 |
2658 | |
2659 // static | 2617 // static |
2660 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2618 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
2661 // ----------- S t a t e ------------- | 2619 // ----------- S t a t e ------------- |
2662 // -- eax : the number of arguments (not including the receiver) | 2620 // -- eax : the number of arguments (not including the receiver) |
2663 // -- edi : the constructor to call (checked to be a JSProxy) | 2621 // -- edi : the constructor to call (checked to be a JSProxy) |
2664 // -- edx : the new target (either the same as the constructor or | 2622 // -- edx : the new target (either the same as the constructor or |
2665 // the JSFunction on which new was invoked initially) | 2623 // the JSFunction on which new was invoked initially) |
2666 // ----------------------------------- | 2624 // ----------------------------------- |
2667 | 2625 |
2668 // Call into the Runtime for Proxy [[Construct]]. | 2626 // Call into the Runtime for Proxy [[Construct]]. |
2669 __ PopReturnAddressTo(ecx); | 2627 __ PopReturnAddressTo(ecx); |
2670 __ Push(edi); | 2628 __ Push(edi); |
2671 __ Push(edx); | 2629 __ Push(edx); |
2672 __ PushReturnAddressFrom(ecx); | 2630 __ PushReturnAddressFrom(ecx); |
2673 // Include the pushed new_target, constructor and the receiver. | 2631 // Include the pushed new_target, constructor and the receiver. |
2674 __ add(eax, Immediate(3)); | 2632 __ add(eax, Immediate(3)); |
2675 // Tail-call to the runtime. | 2633 // Tail-call to the runtime. |
2676 __ JumpToExternalReference( | 2634 __ JumpToExternalReference( |
2677 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); | 2635 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); |
2678 } | 2636 } |
2679 | 2637 |
2680 | |
2681 // static | 2638 // static |
2682 void Builtins::Generate_Construct(MacroAssembler* masm) { | 2639 void Builtins::Generate_Construct(MacroAssembler* masm) { |
2683 // ----------- S t a t e ------------- | 2640 // ----------- S t a t e ------------- |
2684 // -- eax : the number of arguments (not including the receiver) | 2641 // -- eax : the number of arguments (not including the receiver) |
2685 // -- edx : the new target (either the same as the constructor or | 2642 // -- edx : the new target (either the same as the constructor or |
2686 // the JSFunction on which new was invoked initially) | 2643 // the JSFunction on which new was invoked initially) |
2687 // -- edi : the constructor to call (can be any Object) | 2644 // -- edi : the constructor to call (can be any Object) |
2688 // ----------------------------------- | 2645 // ----------------------------------- |
2689 | 2646 |
2690 // Check if target is a Smi. | 2647 // Check if target is a Smi. |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2933 __ jmp(ecx); | 2890 __ jmp(ecx); |
2934 | 2891 |
2935 __ bind(&stack_overflow); | 2892 __ bind(&stack_overflow); |
2936 { | 2893 { |
2937 FrameScope frame(masm, StackFrame::MANUAL); | 2894 FrameScope frame(masm, StackFrame::MANUAL); |
2938 __ CallRuntime(Runtime::kThrowStackOverflow); | 2895 __ CallRuntime(Runtime::kThrowStackOverflow); |
2939 __ int3(); | 2896 __ int3(); |
2940 } | 2897 } |
2941 } | 2898 } |
2942 | 2899 |
2943 | |
2944 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, | 2900 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
2945 Register function_template_info, | 2901 Register function_template_info, |
2946 Register scratch0, Register scratch1, | 2902 Register scratch0, Register scratch1, |
2947 Label* receiver_check_failed) { | 2903 Label* receiver_check_failed) { |
2948 // If there is no signature, return the holder. | 2904 // If there is no signature, return the holder. |
2949 __ CompareRoot(FieldOperand(function_template_info, | 2905 __ CompareRoot(FieldOperand(function_template_info, |
2950 FunctionTemplateInfo::kSignatureOffset), | 2906 FunctionTemplateInfo::kSignatureOffset), |
2951 Heap::kUndefinedValueRootIndex); | 2907 Heap::kUndefinedValueRootIndex); |
2952 Label receiver_check_passed; | 2908 Label receiver_check_passed; |
2953 __ j(equal, &receiver_check_passed, Label::kNear); | 2909 __ j(equal, &receiver_check_passed, Label::kNear); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2997 __ j(zero, receiver_check_failed); | 2953 __ j(zero, receiver_check_failed); |
2998 | 2954 |
2999 __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset)); | 2955 __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset)); |
3000 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 2956 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); |
3001 // Iterate. | 2957 // Iterate. |
3002 __ jmp(&prototype_loop_start, Label::kNear); | 2958 __ jmp(&prototype_loop_start, Label::kNear); |
3003 | 2959 |
3004 __ bind(&receiver_check_passed); | 2960 __ bind(&receiver_check_passed); |
3005 } | 2961 } |
3006 | 2962 |
3007 | |
3008 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { | 2963 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { |
3009 // ----------- S t a t e ------------- | 2964 // ----------- S t a t e ------------- |
3010 // -- eax : number of arguments (not including the receiver) | 2965 // -- eax : number of arguments (not including the receiver) |
3011 // -- edi : callee | 2966 // -- edi : callee |
3012 // -- esi : context | 2967 // -- esi : context |
3013 // -- esp[0] : return address | 2968 // -- esp[0] : return address |
3014 // -- esp[4] : last argument | 2969 // -- esp[4] : last argument |
3015 // -- ... | 2970 // -- ... |
3016 // -- esp[eax * 4] : first argument | 2971 // -- esp[eax * 4] : first argument |
3017 // -- esp[(eax + 1) * 4] : receiver | 2972 // -- esp[(eax + 1) * 4] : receiver |
(...skipping 23 matching lines...) Expand all Loading... |
3041 __ PopReturnAddressTo(ebx); | 2996 __ PopReturnAddressTo(ebx); |
3042 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); | 2997 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); |
3043 __ add(esp, eax); | 2998 __ add(esp, eax); |
3044 __ PushReturnAddressFrom(ebx); | 2999 __ PushReturnAddressFrom(ebx); |
3045 { | 3000 { |
3046 FrameScope scope(masm, StackFrame::INTERNAL); | 3001 FrameScope scope(masm, StackFrame::INTERNAL); |
3047 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); | 3002 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
3048 } | 3003 } |
3049 } | 3004 } |
3050 | 3005 |
3051 | |
3052 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 3006 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
3053 // Lookup the function in the JavaScript frame. | 3007 // Lookup the function in the JavaScript frame. |
3054 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3008 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
3055 { | 3009 { |
3056 FrameScope scope(masm, StackFrame::INTERNAL); | 3010 FrameScope scope(masm, StackFrame::INTERNAL); |
3057 // Pass function as argument. | 3011 // Pass function as argument. |
3058 __ push(eax); | 3012 __ push(eax); |
3059 __ CallRuntime(Runtime::kCompileForOnStackReplacement); | 3013 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
3060 } | 3014 } |
3061 | 3015 |
3062 Label skip; | 3016 Label skip; |
3063 // If the code object is null, just return to the unoptimized code. | 3017 // If the code object is null, just return to the unoptimized code. |
3064 __ cmp(eax, Immediate(0)); | 3018 __ cmp(eax, Immediate(0)); |
3065 __ j(not_equal, &skip, Label::kNear); | 3019 __ j(not_equal, &skip, Label::kNear); |
3066 __ ret(0); | 3020 __ ret(0); |
3067 | 3021 |
3068 __ bind(&skip); | 3022 __ bind(&skip); |
3069 | 3023 |
3070 // Load deoptimization data from the code object. | 3024 // Load deoptimization data from the code object. |
3071 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 3025 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); |
3072 | 3026 |
3073 // Load the OSR entrypoint offset from the deoptimization data. | 3027 // Load the OSR entrypoint offset from the deoptimization data. |
3074 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( | 3028 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( |
3075 DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag)); | 3029 DeoptimizationInputData::kOsrPcOffsetIndex) - |
| 3030 kHeapObjectTag)); |
3076 __ SmiUntag(ebx); | 3031 __ SmiUntag(ebx); |
3077 | 3032 |
3078 // Compute the target address = code_obj + header_size + osr_offset | 3033 // Compute the target address = code_obj + header_size + osr_offset |
3079 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); | 3034 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); |
3080 | 3035 |
3081 // Overwrite the return address on the stack. | 3036 // Overwrite the return address on the stack. |
3082 __ mov(Operand(esp, 0), eax); | 3037 __ mov(Operand(esp, 0), eax); |
3083 | 3038 |
3084 // And "return" to the OSR entry point of the function. | 3039 // And "return" to the OSR entry point of the function. |
3085 __ ret(0); | 3040 __ ret(0); |
3086 } | 3041 } |
3087 | 3042 |
3088 | |
3089 #undef __ | 3043 #undef __ |
3090 } // namespace internal | 3044 } // namespace internal |
3091 } // namespace v8 | 3045 } // namespace v8 |
3092 | 3046 |
3093 #endif // V8_TARGET_ARCH_IA32 | 3047 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |