| 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_X87 | 5 #if V8_TARGET_ARCH_X87 |
| 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/x87/frames-x87.h" | 11 #include "src/x87/frames-x87.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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 238 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 240 __ pop(ecx); | 239 __ pop(ecx); |
| 241 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 240 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
| 242 __ push(ecx); | 241 __ push(ecx); |
| 243 if (create_implicit_receiver) { | 242 if (create_implicit_receiver) { |
| 244 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); | 243 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); |
| 245 } | 244 } |
| 246 __ ret(0); | 245 __ ret(0); |
| 247 } | 246 } |
| 248 | 247 |
| 249 | |
| 250 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 248 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| 251 Generate_JSConstructStubHelper(masm, false, true, false); | 249 Generate_JSConstructStubHelper(masm, false, true, false); |
| 252 } | 250 } |
| 253 | 251 |
| 254 | |
| 255 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 252 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 256 Generate_JSConstructStubHelper(masm, true, false, false); | 253 Generate_JSConstructStubHelper(masm, true, false, false); |
| 257 } | 254 } |
| 258 | 255 |
| 259 | |
| 260 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { | 256 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
| 261 Generate_JSConstructStubHelper(masm, false, false, false); | 257 Generate_JSConstructStubHelper(masm, false, false, false); |
| 262 } | 258 } |
| 263 | 259 |
| 264 | |
| 265 void Builtins::Generate_JSBuiltinsConstructStubForDerived( | 260 void Builtins::Generate_JSBuiltinsConstructStubForDerived( |
| 266 MacroAssembler* masm) { | 261 MacroAssembler* masm) { |
| 267 Generate_JSConstructStubHelper(masm, false, false, true); | 262 Generate_JSConstructStubHelper(masm, false, false, true); |
| 268 } | 263 } |
| 269 | 264 |
| 270 | |
| 271 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { | 265 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { |
| 272 FrameScope scope(masm, StackFrame::INTERNAL); | 266 FrameScope scope(masm, StackFrame::INTERNAL); |
| 273 __ push(edi); | 267 __ push(edi); |
| 274 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); | 268 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); |
| 275 } | 269 } |
| 276 | 270 |
| 277 | |
| 278 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; | 271 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; |
| 279 | 272 |
| 280 | |
| 281 // Clobbers ecx, edx, edi; preserves all other registers. | 273 // Clobbers ecx, edx, edi; preserves all other registers. |
| 282 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 274 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
| 283 IsTagged eax_is_tagged) { | 275 IsTagged eax_is_tagged) { |
| 284 // eax : the number of items to be pushed to the stack | 276 // eax : the number of items to be pushed to the stack |
| 285 // | 277 // |
| 286 // Check the stack for overflow. We are not trying to catch | 278 // Check the stack for overflow. We are not trying to catch |
| 287 // interruptions (e.g. debug break and preemption) here, so the "real stack | 279 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 288 // limit" is checked. | 280 // limit" is checked. |
| 289 Label okay; | 281 Label okay; |
| 290 ExternalReference real_stack_limit = | 282 ExternalReference real_stack_limit = |
| (...skipping 11 matching lines...) Expand all Loading... |
| 302 // Check if the arguments will overflow the stack. | 294 // Check if the arguments will overflow the stack. |
| 303 __ cmp(ecx, edx); | 295 __ cmp(ecx, edx); |
| 304 __ j(greater, &okay); // Signed comparison. | 296 __ j(greater, &okay); // Signed comparison. |
| 305 | 297 |
| 306 // Out of stack space. | 298 // Out of stack space. |
| 307 __ CallRuntime(Runtime::kThrowStackOverflow); | 299 __ CallRuntime(Runtime::kThrowStackOverflow); |
| 308 | 300 |
| 309 __ bind(&okay); | 301 __ bind(&okay); |
| 310 } | 302 } |
| 311 | 303 |
| 312 | |
| 313 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 304 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
| 314 bool is_construct) { | 305 bool is_construct) { |
| 315 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 306 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 316 | 307 |
| 317 { | 308 { |
| 318 FrameScope scope(masm, StackFrame::INTERNAL); | 309 FrameScope scope(masm, StackFrame::INTERNAL); |
| 319 | 310 |
| 320 // Setup the context (we need to use the caller context from the isolate). | 311 // Setup the context (we need to use the caller context from the isolate). |
| 321 ExternalReference context_address(Isolate::kContextAddress, | 312 ExternalReference context_address(Isolate::kContextAddress, |
| 322 masm->isolate()); | 313 masm->isolate()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 336 // Check if we have enough stack space to push all arguments. | 327 // Check if we have enough stack space to push all arguments. |
| 337 // Expects argument count in eax. Clobbers ecx, edx, edi. | 328 // Expects argument count in eax. Clobbers ecx, edx, edi. |
| 338 Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt); | 329 Generate_CheckStackOverflow(masm, kEaxIsUntaggedInt); |
| 339 | 330 |
| 340 // Copy arguments to the stack in a loop. | 331 // Copy arguments to the stack in a loop. |
| 341 Label loop, entry; | 332 Label loop, entry; |
| 342 __ Move(ecx, Immediate(0)); | 333 __ Move(ecx, Immediate(0)); |
| 343 __ jmp(&entry, Label::kNear); | 334 __ jmp(&entry, Label::kNear); |
| 344 __ bind(&loop); | 335 __ bind(&loop); |
| 345 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv | 336 __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv |
| 346 __ push(Operand(edx, 0)); // dereference handle | 337 __ push(Operand(edx, 0)); // dereference handle |
| 347 __ inc(ecx); | 338 __ inc(ecx); |
| 348 __ bind(&entry); | 339 __ bind(&entry); |
| 349 __ cmp(ecx, eax); | 340 __ cmp(ecx, eax); |
| 350 __ j(not_equal, &loop); | 341 __ j(not_equal, &loop); |
| 351 | 342 |
| 352 // Load the previous frame pointer (ebx) to access C arguments | 343 // Load the previous frame pointer (ebx) to access C arguments |
| 353 __ mov(ebx, Operand(ebp, 0)); | 344 __ mov(ebx, Operand(ebp, 0)); |
| 354 | 345 |
| 355 // Get the new.target and function from the frame. | 346 // Get the new.target and function from the frame. |
| 356 __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset)); | 347 __ mov(edx, Operand(ebx, EntryFrameConstants::kNewTargetArgOffset)); |
| 357 __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); | 348 __ mov(edi, Operand(ebx, EntryFrameConstants::kFunctionArgOffset)); |
| 358 | 349 |
| 359 // Invoke the code. | 350 // Invoke the code. |
| 360 Handle<Code> builtin = is_construct | 351 Handle<Code> builtin = is_construct |
| 361 ? masm->isolate()->builtins()->Construct() | 352 ? masm->isolate()->builtins()->Construct() |
| 362 : masm->isolate()->builtins()->Call(); | 353 : masm->isolate()->builtins()->Call(); |
| 363 __ Call(builtin, RelocInfo::CODE_TARGET); | 354 __ Call(builtin, RelocInfo::CODE_TARGET); |
| 364 | 355 |
| 365 // Exit the internal frame. Notice that this also removes the empty. | 356 // Exit the internal frame. Notice that this also removes the empty. |
| 366 // context and the function left on the stack by the code | 357 // context and the function left on the stack by the code |
| 367 // invocation. | 358 // invocation. |
| 368 } | 359 } |
| 369 __ ret(kPointerSize); // Remove receiver. | 360 __ ret(kPointerSize); // Remove receiver. |
| 370 } | 361 } |
| 371 | 362 |
| 372 | |
| 373 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 363 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
| 374 Generate_JSEntryTrampolineHelper(masm, false); | 364 Generate_JSEntryTrampolineHelper(masm, false); |
| 375 } | 365 } |
| 376 | 366 |
| 377 | |
| 378 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 367 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
| 379 Generate_JSEntryTrampolineHelper(masm, true); | 368 Generate_JSEntryTrampolineHelper(masm, true); |
| 380 } | 369 } |
| 381 | 370 |
| 382 // static | 371 // static |
| 383 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { | 372 void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { |
| 384 // ----------- S t a t e ------------- | 373 // ----------- S t a t e ------------- |
| 385 // -- eax : the value to pass to the generator | 374 // -- eax : the value to pass to the generator |
| 386 // -- ebx : the JSGeneratorObject to resume | 375 // -- ebx : the JSGeneratorObject to resume |
| 387 // -- edx : the resume mode (tagged) | 376 // -- edx : the resume mode (tagged) |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 tail_call_mode), | 751 tail_call_mode), |
| 763 RelocInfo::CODE_TARGET); | 752 RelocInfo::CODE_TARGET); |
| 764 } else { | 753 } else { |
| 765 DCHECK_EQ(function_type, CallableType::kAny); | 754 DCHECK_EQ(function_type, CallableType::kAny); |
| 766 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 755 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
| 767 tail_call_mode), | 756 tail_call_mode), |
| 768 RelocInfo::CODE_TARGET); | 757 RelocInfo::CODE_TARGET); |
| 769 } | 758 } |
| 770 } | 759 } |
| 771 | 760 |
| 772 | |
| 773 // static | 761 // static |
| 774 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 762 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
| 775 // ----------- S t a t e ------------- | 763 // ----------- S t a t e ------------- |
| 776 // -- eax : the number of arguments (not including the receiver) | 764 // -- eax : the number of arguments (not including the receiver) |
| 777 // -- edx : the new target | 765 // -- edx : the new target |
| 778 // -- edi : the constructor | 766 // -- edi : the constructor |
| 779 // -- ebx : the address of the first argument to be pushed. Subsequent | 767 // -- ebx : the address of the first argument to be pushed. Subsequent |
| 780 // arguments should be consecutive above this, in the same order as | 768 // arguments should be consecutive above this, in the same order as |
| 781 // they are to be pushed onto the stack. | 769 // they are to be pushed onto the stack. |
| 782 // ----------------------------------- | 770 // ----------------------------------- |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 | 1008 |
| 1021 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { | 1009 void Builtins::Generate_CompileBaseline(MacroAssembler* masm) { |
| 1022 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); | 1010 GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline); |
| 1023 } | 1011 } |
| 1024 | 1012 |
| 1025 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 1013 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
| 1026 GenerateTailCallToReturnedCode(masm, | 1014 GenerateTailCallToReturnedCode(masm, |
| 1027 Runtime::kCompileOptimized_NotConcurrent); | 1015 Runtime::kCompileOptimized_NotConcurrent); |
| 1028 } | 1016 } |
| 1029 | 1017 |
| 1030 | |
| 1031 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { | 1018 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { |
| 1032 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); | 1019 GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent); |
| 1033 } | 1020 } |
| 1034 | 1021 |
| 1035 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { | 1022 void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { |
| 1036 // ----------- S t a t e ------------- | 1023 // ----------- S t a t e ------------- |
| 1037 // -- eax : argument count (preserved for callee) | 1024 // -- eax : argument count (preserved for callee) |
| 1038 // -- edx : new target (preserved for callee) | 1025 // -- edx : new target (preserved for callee) |
| 1039 // -- edi : target function (preserved for callee) | 1026 // -- edi : target function (preserved for callee) |
| 1040 // ----------------------------------- | 1027 // ----------------------------------- |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 __ mov(Operand(esp, 1 * kPointerSize), | 1078 __ mov(Operand(esp, 1 * kPointerSize), |
| 1092 Immediate(ExternalReference::isolate_address(masm->isolate()))); | 1079 Immediate(ExternalReference::isolate_address(masm->isolate()))); |
| 1093 __ mov(Operand(esp, 0), eax); | 1080 __ mov(Operand(esp, 0), eax); |
| 1094 __ CallCFunction( | 1081 __ CallCFunction( |
| 1095 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 1082 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
| 1096 } | 1083 } |
| 1097 __ popad(); | 1084 __ popad(); |
| 1098 __ ret(0); | 1085 __ ret(0); |
| 1099 } | 1086 } |
| 1100 | 1087 |
| 1101 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ | 1088 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ |
| 1102 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ | 1089 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ |
| 1103 MacroAssembler* masm) { \ | 1090 MacroAssembler* masm) { \ |
| 1104 GenerateMakeCodeYoungAgainCommon(masm); \ | 1091 GenerateMakeCodeYoungAgainCommon(masm); \ |
| 1105 } \ | 1092 } \ |
| 1106 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ | 1093 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ |
| 1107 MacroAssembler* masm) { \ | 1094 MacroAssembler* masm) { \ |
| 1108 GenerateMakeCodeYoungAgainCommon(masm); \ | 1095 GenerateMakeCodeYoungAgainCommon(masm); \ |
| 1109 } | 1096 } |
| 1110 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) | 1097 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) |
| 1111 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR | 1098 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR |
| 1112 | 1099 |
| 1113 | |
| 1114 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 1100 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { |
| 1115 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 1101 // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact |
| 1116 // that make_code_young doesn't do any garbage collection which allows us to | 1102 // that make_code_young doesn't do any garbage collection which allows us to |
| 1117 // save/restore the registers without worrying about which of them contain | 1103 // save/restore the registers without worrying about which of them contain |
| 1118 // pointers. | 1104 // pointers. |
| 1119 __ pushad(); | 1105 __ pushad(); |
| 1120 __ mov(eax, Operand(esp, 8 * kPointerSize)); | 1106 __ mov(eax, Operand(esp, 8 * kPointerSize)); |
| 1121 __ sub(eax, Immediate(Assembler::kCallInstructionLength)); | 1107 __ sub(eax, Immediate(Assembler::kCallInstructionLength)); |
| 1122 { // NOLINT | 1108 { // NOLINT |
| 1123 FrameScope scope(masm, StackFrame::MANUAL); | 1109 FrameScope scope(masm, StackFrame::MANUAL); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1136 __ push(ebp); // Caller's frame pointer. | 1122 __ push(ebp); // Caller's frame pointer. |
| 1137 __ mov(ebp, esp); | 1123 __ mov(ebp, esp); |
| 1138 __ push(esi); // Callee's context. | 1124 __ push(esi); // Callee's context. |
| 1139 __ push(edi); // Callee's JS Function. | 1125 __ push(edi); // Callee's JS Function. |
| 1140 __ push(eax); // Push return address after frame prologue. | 1126 __ push(eax); // Push return address after frame prologue. |
| 1141 | 1127 |
| 1142 // Jump to point after the code-age stub. | 1128 // Jump to point after the code-age stub. |
| 1143 __ ret(0); | 1129 __ ret(0); |
| 1144 } | 1130 } |
| 1145 | 1131 |
| 1146 | |
| 1147 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 1132 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { |
| 1148 GenerateMakeCodeYoungAgainCommon(masm); | 1133 GenerateMakeCodeYoungAgainCommon(masm); |
| 1149 } | 1134 } |
| 1150 | 1135 |
| 1151 | |
| 1152 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { | 1136 void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) { |
| 1153 Generate_MarkCodeAsExecutedOnce(masm); | 1137 Generate_MarkCodeAsExecutedOnce(masm); |
| 1154 } | 1138 } |
| 1155 | 1139 |
| 1156 | |
| 1157 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 1140 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, |
| 1158 SaveFPRegsMode save_doubles) { | 1141 SaveFPRegsMode save_doubles) { |
| 1159 // Enter an internal frame. | 1142 // Enter an internal frame. |
| 1160 { | 1143 { |
| 1161 FrameScope scope(masm, StackFrame::INTERNAL); | 1144 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1162 | 1145 |
| 1163 // Preserve registers across notification, this is important for compiled | 1146 // Preserve registers across notification, this is important for compiled |
| 1164 // stubs that tail call the runtime on deopts passing their parameters in | 1147 // stubs that tail call the runtime on deopts passing their parameters in |
| 1165 // registers. | 1148 // registers. |
| 1166 __ pushad(); | 1149 __ pushad(); |
| 1167 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); | 1150 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); |
| 1168 __ popad(); | 1151 __ popad(); |
| 1169 // Tear down internal frame. | 1152 // Tear down internal frame. |
| 1170 } | 1153 } |
| 1171 | 1154 |
| 1172 __ pop(MemOperand(esp, 0)); // Ignore state offset | 1155 __ pop(MemOperand(esp, 0)); // Ignore state offset |
| 1173 __ ret(0); // Return to IC Miss stub, continuation still on stack. | 1156 __ ret(0); // Return to IC Miss stub, continuation still on stack. |
| 1174 } | 1157 } |
| 1175 | 1158 |
| 1176 | |
| 1177 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 1159 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { |
| 1178 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 1160 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); |
| 1179 } | 1161 } |
| 1180 | 1162 |
| 1181 | |
| 1182 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 1163 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { |
| 1183 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 1164 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); |
| 1184 } | 1165 } |
| 1185 | 1166 |
| 1186 | |
| 1187 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 1167 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
| 1188 Deoptimizer::BailoutType type) { | 1168 Deoptimizer::BailoutType type) { |
| 1189 { | 1169 { |
| 1190 FrameScope scope(masm, StackFrame::INTERNAL); | 1170 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1191 | 1171 |
| 1192 // Pass deoptimization type to the runtime system. | 1172 // Pass deoptimization type to the runtime system. |
| 1193 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); | 1173 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); |
| 1194 __ CallRuntime(Runtime::kNotifyDeoptimized); | 1174 __ CallRuntime(Runtime::kNotifyDeoptimized); |
| 1195 | 1175 |
| 1196 // Tear down internal frame. | 1176 // Tear down internal frame. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1210 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code()); | 1190 DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code()); |
| 1211 __ mov(eax, Operand(esp, 2 * kPointerSize)); | 1191 __ mov(eax, Operand(esp, 2 * kPointerSize)); |
| 1212 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)); | 1192 __ cmp(ecx, static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)); |
| 1213 __ j(not_equal, ¬_tos_eax, Label::kNear); | 1193 __ j(not_equal, ¬_tos_eax, Label::kNear); |
| 1214 __ ret(2 * kPointerSize); // Remove state, eax. | 1194 __ ret(2 * kPointerSize); // Remove state, eax. |
| 1215 | 1195 |
| 1216 __ bind(¬_tos_eax); | 1196 __ bind(¬_tos_eax); |
| 1217 __ Abort(kNoCasesLeft); | 1197 __ Abort(kNoCasesLeft); |
| 1218 } | 1198 } |
| 1219 | 1199 |
| 1220 | |
| 1221 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 1200 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { |
| 1222 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); | 1201 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); |
| 1223 } | 1202 } |
| 1224 | 1203 |
| 1225 | |
| 1226 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 1204 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { |
| 1227 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 1205 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); |
| 1228 } | 1206 } |
| 1229 | 1207 |
| 1230 | |
| 1231 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 1208 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { |
| 1232 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 1209 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); |
| 1233 } | 1210 } |
| 1234 | 1211 |
| 1235 | |
| 1236 // static | 1212 // static |
| 1237 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, | 1213 void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm, |
| 1238 int field_index) { | 1214 int field_index) { |
| 1239 // ----------- S t a t e ------------- | 1215 // ----------- S t a t e ------------- |
| 1240 // -- eax : number of arguments | 1216 // -- eax : number of arguments |
| 1241 // -- edi : function | 1217 // -- edi : function |
| 1242 // -- esi : context | 1218 // -- esi : context |
| 1243 // -- esp[0] : return address | 1219 // -- esp[0] : return address |
| 1244 // -- esp[4] : receiver | 1220 // -- esp[4] : receiver |
| 1245 // ----------------------------------- | 1221 // ----------------------------------- |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1358 } | 1334 } |
| 1359 | 1335 |
| 1360 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1336 // 4c. The receiver is not callable, throw an appropriate TypeError. |
| 1361 __ bind(&receiver_not_callable); | 1337 __ bind(&receiver_not_callable); |
| 1362 { | 1338 { |
| 1363 __ mov(Operand(esp, kPointerSize), edi); | 1339 __ mov(Operand(esp, kPointerSize), edi); |
| 1364 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); | 1340 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
| 1365 } | 1341 } |
| 1366 } | 1342 } |
| 1367 | 1343 |
| 1368 | |
| 1369 // static | 1344 // static |
| 1370 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { | 1345 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { |
| 1371 // Stack Layout: | 1346 // Stack Layout: |
| 1372 // esp[0] : Return address | 1347 // esp[0] : Return address |
| 1373 // esp[8] : Argument n | 1348 // esp[8] : Argument n |
| 1374 // esp[16] : Argument n-1 | 1349 // esp[16] : Argument n-1 |
| 1375 // ... | 1350 // ... |
| 1376 // esp[8 * n] : Argument 1 | 1351 // esp[8 * n] : Argument 1 |
| 1377 // esp[8 * (n + 1)] : Receiver (callable to call) | 1352 // esp[8 * (n + 1)] : Receiver (callable to call) |
| 1378 // | 1353 // |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1405 __ dec(ecx); | 1380 __ dec(ecx); |
| 1406 __ j(not_sign, &loop); // While non-negative (to copy return address). | 1381 __ j(not_sign, &loop); // While non-negative (to copy return address). |
| 1407 __ pop(ebx); // Discard copy of return address. | 1382 __ pop(ebx); // Discard copy of return address. |
| 1408 __ dec(eax); // One fewer argument (first argument is new receiver). | 1383 __ dec(eax); // One fewer argument (first argument is new receiver). |
| 1409 } | 1384 } |
| 1410 | 1385 |
| 1411 // 4. Call the callable. | 1386 // 4. Call the callable. |
| 1412 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1387 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1413 } | 1388 } |
| 1414 | 1389 |
| 1415 | |
| 1416 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { | 1390 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { |
| 1417 // ----------- S t a t e ------------- | 1391 // ----------- S t a t e ------------- |
| 1418 // -- eax : argc | 1392 // -- eax : argc |
| 1419 // -- esp[0] : return address | 1393 // -- esp[0] : return address |
| 1420 // -- esp[4] : argumentsList | 1394 // -- esp[4] : argumentsList |
| 1421 // -- esp[8] : thisArgument | 1395 // -- esp[8] : thisArgument |
| 1422 // -- esp[12] : target | 1396 // -- esp[12] : target |
| 1423 // -- esp[16] : receiver | 1397 // -- esp[16] : receiver |
| 1424 // ----------------------------------- | 1398 // ----------------------------------- |
| 1425 | 1399 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 } | 1520 } |
| 1547 | 1521 |
| 1548 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1522 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
| 1549 __ bind(&new_target_not_constructor); | 1523 __ bind(&new_target_not_constructor); |
| 1550 { | 1524 { |
| 1551 __ mov(Operand(esp, kPointerSize), edx); | 1525 __ mov(Operand(esp, kPointerSize), edx); |
| 1552 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); | 1526 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
| 1553 } | 1527 } |
| 1554 } | 1528 } |
| 1555 | 1529 |
| 1556 | |
| 1557 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1530 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
| 1558 // ----------- S t a t e ------------- | 1531 // ----------- S t a t e ------------- |
| 1559 // -- eax : argc | 1532 // -- eax : argc |
| 1560 // -- esp[0] : return address | 1533 // -- esp[0] : return address |
| 1561 // -- esp[4] : last argument | 1534 // -- esp[4] : last argument |
| 1562 // ----------------------------------- | 1535 // ----------------------------------- |
| 1563 Label generic_array_code; | 1536 Label generic_array_code; |
| 1564 | 1537 |
| 1565 // Get the InternalArray function. | 1538 // Get the InternalArray function. |
| 1566 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); | 1539 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); |
| 1567 | 1540 |
| 1568 if (FLAG_debug_code) { | 1541 if (FLAG_debug_code) { |
| 1569 // Initial map for the builtin InternalArray function should be a map. | 1542 // Initial map for the builtin InternalArray function should be a map. |
| 1570 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 1543 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 1571 // Will both indicate a NULL and a Smi. | 1544 // Will both indicate a NULL and a Smi. |
| 1572 __ test(ebx, Immediate(kSmiTagMask)); | 1545 __ test(ebx, Immediate(kSmiTagMask)); |
| 1573 __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction); | 1546 __ Assert(not_zero, kUnexpectedInitialMapForInternalArrayFunction); |
| 1574 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1547 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
| 1575 __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction); | 1548 __ Assert(equal, kUnexpectedInitialMapForInternalArrayFunction); |
| 1576 } | 1549 } |
| 1577 | 1550 |
| 1578 // Run the native code for the InternalArray function called as a normal | 1551 // Run the native code for the InternalArray function called as a normal |
| 1579 // function. | 1552 // function. |
| 1580 // tail call a stub | 1553 // tail call a stub |
| 1581 InternalArrayConstructorStub stub(masm->isolate()); | 1554 InternalArrayConstructorStub stub(masm->isolate()); |
| 1582 __ TailCallStub(&stub); | 1555 __ TailCallStub(&stub); |
| 1583 } | 1556 } |
| 1584 | 1557 |
| 1585 | |
| 1586 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 1558 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |
| 1587 // ----------- S t a t e ------------- | 1559 // ----------- S t a t e ------------- |
| 1588 // -- eax : argc | 1560 // -- eax : argc |
| 1589 // -- esp[0] : return address | 1561 // -- esp[0] : return address |
| 1590 // -- esp[4] : last argument | 1562 // -- esp[4] : last argument |
| 1591 // ----------------------------------- | 1563 // ----------------------------------- |
| 1592 Label generic_array_code; | 1564 Label generic_array_code; |
| 1593 | 1565 |
| 1594 // Get the Array function. | 1566 // Get the Array function. |
| 1595 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); | 1567 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); |
| 1596 __ mov(edx, edi); | 1568 __ mov(edx, edi); |
| 1597 | 1569 |
| 1598 if (FLAG_debug_code) { | 1570 if (FLAG_debug_code) { |
| 1599 // Initial map for the builtin Array function should be a map. | 1571 // Initial map for the builtin Array function should be a map. |
| 1600 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 1572 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
| 1601 // Will both indicate a NULL and a Smi. | 1573 // Will both indicate a NULL and a Smi. |
| 1602 __ test(ebx, Immediate(kSmiTagMask)); | 1574 __ test(ebx, Immediate(kSmiTagMask)); |
| 1603 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); | 1575 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); |
| 1604 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1576 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
| 1605 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); | 1577 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); |
| 1606 } | 1578 } |
| 1607 | 1579 |
| 1608 // Run the native code for the Array function called as a normal function. | 1580 // Run the native code for the Array function called as a normal function. |
| 1609 // tail call a stub | 1581 // tail call a stub |
| 1610 __ mov(ebx, masm->isolate()->factory()->undefined_value()); | 1582 __ mov(ebx, masm->isolate()->factory()->undefined_value()); |
| 1611 ArrayConstructorStub stub(masm->isolate()); | 1583 ArrayConstructorStub stub(masm->isolate()); |
| 1612 __ TailCallStub(&stub); | 1584 __ TailCallStub(&stub); |
| 1613 } | 1585 } |
| 1614 | 1586 |
| 1615 | |
| 1616 // static | 1587 // static |
| 1617 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { | 1588 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { |
| 1618 // ----------- S t a t e ------------- | 1589 // ----------- S t a t e ------------- |
| 1619 // -- eax : number of arguments | 1590 // -- eax : number of arguments |
| 1620 // -- edi : function | 1591 // -- edi : function |
| 1621 // -- esi : context | 1592 // -- esi : context |
| 1622 // -- esp[0] : return address | 1593 // -- esp[0] : return address |
| 1623 // -- esp[(argc - n) * 8] : arg[n] (zero-based) | 1594 // -- esp[(argc - n) * 8] : arg[n] (zero-based) |
| 1624 // -- esp[(argc + 1) * 8] : receiver | 1595 // -- esp[(argc + 1) * 8] : receiver |
| 1625 // ----------------------------------- | 1596 // ----------------------------------- |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1755 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
| 1785 __ PushReturnAddressFrom(ecx); | 1756 __ PushReturnAddressFrom(ecx); |
| 1786 __ Ret(); | 1757 __ Ret(); |
| 1787 } | 1758 } |
| 1788 | 1759 |
| 1789 // 2b. No arguments, return +0 (already in eax). | 1760 // 2b. No arguments, return +0 (already in eax). |
| 1790 __ bind(&no_arguments); | 1761 __ bind(&no_arguments); |
| 1791 __ ret(1 * kPointerSize); | 1762 __ ret(1 * kPointerSize); |
| 1792 } | 1763 } |
| 1793 | 1764 |
| 1794 | |
| 1795 // static | 1765 // static |
| 1796 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { | 1766 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
| 1797 // ----------- S t a t e ------------- | 1767 // ----------- S t a t e ------------- |
| 1798 // -- eax : number of arguments | 1768 // -- eax : number of arguments |
| 1799 // -- edi : constructor function | 1769 // -- edi : constructor function |
| 1800 // -- edx : new target | 1770 // -- edx : new target |
| 1801 // -- esi : context | 1771 // -- esi : context |
| 1802 // -- esp[0] : return address | 1772 // -- esp[0] : return address |
| 1803 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1773 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1804 // -- esp[(argc + 1) * 4] : receiver | 1774 // -- esp[(argc + 1) * 4] : receiver |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1871 { | 1841 { |
| 1872 // Drop all arguments including the receiver. | 1842 // Drop all arguments including the receiver. |
| 1873 __ PopReturnAddressTo(esi); | 1843 __ PopReturnAddressTo(esi); |
| 1874 __ SmiUntag(ecx); | 1844 __ SmiUntag(ecx); |
| 1875 __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize)); | 1845 __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize)); |
| 1876 __ PushReturnAddressFrom(esi); | 1846 __ PushReturnAddressFrom(esi); |
| 1877 __ Ret(); | 1847 __ Ret(); |
| 1878 } | 1848 } |
| 1879 } | 1849 } |
| 1880 | 1850 |
| 1881 | |
| 1882 // static | 1851 // static |
| 1883 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1852 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 1884 // ----------- S t a t e ------------- | 1853 // ----------- S t a t e ------------- |
| 1885 // -- eax : number of arguments | 1854 // -- eax : number of arguments |
| 1886 // -- edi : constructor function | 1855 // -- edi : constructor function |
| 1887 // -- esi : context | 1856 // -- esi : context |
| 1888 // -- esp[0] : return address | 1857 // -- esp[0] : return address |
| 1889 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1858 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1890 // -- esp[(argc + 1) * 4] : receiver | 1859 // -- esp[(argc + 1) * 4] : receiver |
| 1891 // ----------------------------------- | 1860 // ----------------------------------- |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 __ bind(&drop_frame_and_ret); | 1913 __ bind(&drop_frame_and_ret); |
| 1945 { | 1914 { |
| 1946 // Drop all arguments including the receiver. | 1915 // Drop all arguments including the receiver. |
| 1947 __ PopReturnAddressTo(ecx); | 1916 __ PopReturnAddressTo(ecx); |
| 1948 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 1917 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
| 1949 __ PushReturnAddressFrom(ecx); | 1918 __ PushReturnAddressFrom(ecx); |
| 1950 __ Ret(); | 1919 __ Ret(); |
| 1951 } | 1920 } |
| 1952 } | 1921 } |
| 1953 | 1922 |
| 1954 | |
| 1955 // static | 1923 // static |
| 1956 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1924 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
| 1957 // ----------- S t a t e ------------- | 1925 // ----------- S t a t e ------------- |
| 1958 // -- eax : number of arguments | 1926 // -- eax : number of arguments |
| 1959 // -- edi : constructor function | 1927 // -- edi : constructor function |
| 1960 // -- edx : new target | 1928 // -- edx : new target |
| 1961 // -- esi : context | 1929 // -- esi : context |
| 1962 // -- esp[0] : return address | 1930 // -- esp[0] : return address |
| 1963 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1931 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1964 // -- esp[(argc + 1) * 4] : receiver | 1932 // -- esp[(argc + 1) * 4] : receiver |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2038 __ bind(&drop_frame_and_ret); | 2006 __ bind(&drop_frame_and_ret); |
| 2039 { | 2007 { |
| 2040 // Drop all arguments including the receiver. | 2008 // Drop all arguments including the receiver. |
| 2041 __ PopReturnAddressTo(ecx); | 2009 __ PopReturnAddressTo(ecx); |
| 2042 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); | 2010 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize)); |
| 2043 __ PushReturnAddressFrom(ecx); | 2011 __ PushReturnAddressFrom(ecx); |
| 2044 __ Ret(); | 2012 __ Ret(); |
| 2045 } | 2013 } |
| 2046 } | 2014 } |
| 2047 | 2015 |
| 2048 | |
| 2049 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 2016 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
| 2050 Label* stack_overflow) { | 2017 Label* stack_overflow) { |
| 2051 // ----------- S t a t e ------------- | 2018 // ----------- S t a t e ------------- |
| 2052 // -- eax : actual number of arguments | 2019 // -- eax : actual number of arguments |
| 2053 // -- ebx : expected number of arguments | 2020 // -- ebx : expected number of arguments |
| 2054 // -- edx : new target (passed through to callee) | 2021 // -- edx : new target (passed through to callee) |
| 2055 // ----------------------------------- | 2022 // ----------------------------------- |
| 2056 // Check the stack for overflow. We are not trying to catch | 2023 // Check the stack for overflow. We are not trying to catch |
| 2057 // interruptions (e.g. debug break and preemption) here, so the "real stack | 2024 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 2058 // limit" is checked. | 2025 // limit" is checked. |
| 2059 ExternalReference real_stack_limit = | 2026 ExternalReference real_stack_limit = |
| 2060 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 2027 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
| 2061 __ mov(edi, Operand::StaticVariable(real_stack_limit)); | 2028 __ mov(edi, Operand::StaticVariable(real_stack_limit)); |
| 2062 // Make ecx the space we have left. The stack might already be overflowed | 2029 // Make ecx the space we have left. The stack might already be overflowed |
| 2063 // here which will cause ecx to become negative. | 2030 // here which will cause ecx to become negative. |
| 2064 __ mov(ecx, esp); | 2031 __ mov(ecx, esp); |
| 2065 __ sub(ecx, edi); | 2032 __ sub(ecx, edi); |
| 2066 // Make edi the space we need for the array when it is unrolled onto the | 2033 // Make edi the space we need for the array when it is unrolled onto the |
| 2067 // stack. | 2034 // stack. |
| 2068 __ mov(edi, ebx); | 2035 __ mov(edi, ebx); |
| 2069 __ shl(edi, kPointerSizeLog2); | 2036 __ shl(edi, kPointerSizeLog2); |
| 2070 // Check if the arguments will overflow the stack. | 2037 // Check if the arguments will overflow the stack. |
| 2071 __ cmp(ecx, edi); | 2038 __ cmp(ecx, edi); |
| 2072 __ j(less_equal, stack_overflow); // Signed comparison. | 2039 __ j(less_equal, stack_overflow); // Signed comparison. |
| 2073 } | 2040 } |
| 2074 | 2041 |
| 2075 | |
| 2076 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 2042 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
| 2077 __ push(ebp); | 2043 __ push(ebp); |
| 2078 __ mov(ebp, esp); | 2044 __ mov(ebp, esp); |
| 2079 | 2045 |
| 2080 // Store the arguments adaptor context sentinel. | 2046 // Store the arguments adaptor context sentinel. |
| 2081 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2047 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2082 | 2048 |
| 2083 // Push the function on the stack. | 2049 // Push the function on the stack. |
| 2084 __ push(edi); | 2050 __ push(edi); |
| 2085 | 2051 |
| 2086 // Preserve the number of arguments on the stack. Must preserve eax, | 2052 // Preserve the number of arguments on the stack. Must preserve eax, |
| 2087 // ebx and ecx because these registers are used when copying the | 2053 // ebx and ecx because these registers are used when copying the |
| 2088 // arguments and the receiver. | 2054 // arguments and the receiver. |
| 2089 STATIC_ASSERT(kSmiTagSize == 1); | 2055 STATIC_ASSERT(kSmiTagSize == 1); |
| 2090 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); | 2056 __ lea(edi, Operand(eax, eax, times_1, kSmiTag)); |
| 2091 __ push(edi); | 2057 __ push(edi); |
| 2092 } | 2058 } |
| 2093 | 2059 |
| 2094 | |
| 2095 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 2060 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { |
| 2096 // Retrieve the number of arguments from the stack. | 2061 // Retrieve the number of arguments from the stack. |
| 2097 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2062 __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2098 | 2063 |
| 2099 // Leave the frame. | 2064 // Leave the frame. |
| 2100 __ leave(); | 2065 __ leave(); |
| 2101 | 2066 |
| 2102 // Remove caller arguments from the stack. | 2067 // Remove caller arguments from the stack. |
| 2103 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 2068 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
| 2104 __ pop(ecx); | 2069 __ pop(ecx); |
| 2105 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver | 2070 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver |
| 2106 __ push(ecx); | 2071 __ push(ecx); |
| 2107 } | 2072 } |
| 2108 | 2073 |
| 2109 | |
| 2110 // static | 2074 // static |
| 2111 void Builtins::Generate_Apply(MacroAssembler* masm) { | 2075 void Builtins::Generate_Apply(MacroAssembler* masm) { |
| 2112 // ----------- S t a t e ------------- | 2076 // ----------- S t a t e ------------- |
| 2113 // -- eax : argumentsList | 2077 // -- eax : argumentsList |
| 2114 // -- edi : target | 2078 // -- edi : target |
| 2115 // -- edx : new.target (checked to be constructor or undefined) | 2079 // -- edx : new.target (checked to be constructor or undefined) |
| 2116 // -- esp[0] : return address. | 2080 // -- esp[0] : return address. |
| 2117 // -- esp[4] : thisArgument | 2081 // -- esp[4] : thisArgument |
| 2118 // ----------------------------------- | 2082 // ----------------------------------- |
| 2119 | 2083 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2441 CheckDebugStepCallWrapper()); | 2405 CheckDebugStepCallWrapper()); |
| 2442 // The function is a "classConstructor", need to raise an exception. | 2406 // The function is a "classConstructor", need to raise an exception. |
| 2443 __ bind(&class_constructor); | 2407 __ bind(&class_constructor); |
| 2444 { | 2408 { |
| 2445 FrameScope frame(masm, StackFrame::INTERNAL); | 2409 FrameScope frame(masm, StackFrame::INTERNAL); |
| 2446 __ push(edi); | 2410 __ push(edi); |
| 2447 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); | 2411 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); |
| 2448 } | 2412 } |
| 2449 } | 2413 } |
| 2450 | 2414 |
| 2451 | |
| 2452 namespace { | 2415 namespace { |
| 2453 | 2416 |
| 2454 void Generate_PushBoundArguments(MacroAssembler* masm) { | 2417 void Generate_PushBoundArguments(MacroAssembler* masm) { |
| 2455 // ----------- S t a t e ------------- | 2418 // ----------- S t a t e ------------- |
| 2456 // -- eax : the number of arguments (not including the receiver) | 2419 // -- eax : the number of arguments (not including the receiver) |
| 2457 // -- edx : new.target (only in case of [[Construct]]) | 2420 // -- edx : new.target (only in case of [[Construct]]) |
| 2458 // -- edi : target (checked to be a JSBoundFunction) | 2421 // -- edi : target (checked to be a JSBoundFunction) |
| 2459 // ----------------------------------- | 2422 // ----------------------------------- |
| 2460 | 2423 |
| 2461 // Load [[BoundArguments]] into ecx and length of that into ebx. | 2424 // Load [[BoundArguments]] into ecx and length of that into ebx. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2528 // Adjust effective number of arguments (eax contains the number of | 2491 // Adjust effective number of arguments (eax contains the number of |
| 2529 // arguments from the call plus return address plus the number of | 2492 // arguments from the call plus return address plus the number of |
| 2530 // [[BoundArguments]]), so we need to subtract one for the return address. | 2493 // [[BoundArguments]]), so we need to subtract one for the return address. |
| 2531 __ dec(eax); | 2494 __ dec(eax); |
| 2532 } | 2495 } |
| 2533 __ bind(&no_bound_arguments); | 2496 __ bind(&no_bound_arguments); |
| 2534 } | 2497 } |
| 2535 | 2498 |
| 2536 } // namespace | 2499 } // namespace |
| 2537 | 2500 |
| 2538 | |
| 2539 // static | 2501 // static |
| 2540 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, | 2502 void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm, |
| 2541 TailCallMode tail_call_mode) { | 2503 TailCallMode tail_call_mode) { |
| 2542 // ----------- S t a t e ------------- | 2504 // ----------- S t a t e ------------- |
| 2543 // -- eax : the number of arguments (not including the receiver) | 2505 // -- eax : the number of arguments (not including the receiver) |
| 2544 // -- edi : the function to call (checked to be a JSBoundFunction) | 2506 // -- edi : the function to call (checked to be a JSBoundFunction) |
| 2545 // ----------------------------------- | 2507 // ----------------------------------- |
| 2546 __ AssertBoundFunction(edi); | 2508 __ AssertBoundFunction(edi); |
| 2547 | 2509 |
| 2548 if (tail_call_mode == TailCallMode::kAllow) { | 2510 if (tail_call_mode == TailCallMode::kAllow) { |
| 2549 PrepareForTailCall(masm, eax, ebx, ecx, edx); | 2511 PrepareForTailCall(masm, eax, ebx, ecx, edx); |
| 2550 } | 2512 } |
| 2551 | 2513 |
| 2552 // Patch the receiver to [[BoundThis]]. | 2514 // Patch the receiver to [[BoundThis]]. |
| 2553 __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset)); | 2515 __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset)); |
| 2554 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx); | 2516 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx); |
| 2555 | 2517 |
| 2556 // Push the [[BoundArguments]] onto the stack. | 2518 // Push the [[BoundArguments]] onto the stack. |
| 2557 Generate_PushBoundArguments(masm); | 2519 Generate_PushBoundArguments(masm); |
| 2558 | 2520 |
| 2559 // Call the [[BoundTargetFunction]] via the Call builtin. | 2521 // Call the [[BoundTargetFunction]] via the Call builtin. |
| 2560 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2522 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2561 __ mov(ecx, Operand::StaticVariable(ExternalReference( | 2523 __ mov(ecx, Operand::StaticVariable(ExternalReference( |
| 2562 Builtins::kCall_ReceiverIsAny, masm->isolate()))); | 2524 Builtins::kCall_ReceiverIsAny, masm->isolate()))); |
| 2563 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2525 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
| 2564 __ jmp(ecx); | 2526 __ jmp(ecx); |
| 2565 } | 2527 } |
| 2566 | 2528 |
| 2567 | |
| 2568 // static | 2529 // static |
| 2569 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, | 2530 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode, |
| 2570 TailCallMode tail_call_mode) { | 2531 TailCallMode tail_call_mode) { |
| 2571 // ----------- S t a t e ------------- | 2532 // ----------- S t a t e ------------- |
| 2572 // -- eax : the number of arguments (not including the receiver) | 2533 // -- eax : the number of arguments (not including the receiver) |
| 2573 // -- edi : the target to call (can be any Object). | 2534 // -- edi : the target to call (can be any Object). |
| 2574 // ----------------------------------- | 2535 // ----------------------------------- |
| 2575 | 2536 |
| 2576 Label non_callable, non_function, non_smi; | 2537 Label non_callable, non_function, non_smi; |
| 2577 __ JumpIfSmi(edi, &non_callable); | 2538 __ JumpIfSmi(edi, &non_callable); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2620 | 2581 |
| 2621 // 3. Call to something that is not callable. | 2582 // 3. Call to something that is not callable. |
| 2622 __ bind(&non_callable); | 2583 __ bind(&non_callable); |
| 2623 { | 2584 { |
| 2624 FrameScope scope(masm, StackFrame::INTERNAL); | 2585 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2625 __ Push(edi); | 2586 __ Push(edi); |
| 2626 __ CallRuntime(Runtime::kThrowCalledNonCallable); | 2587 __ CallRuntime(Runtime::kThrowCalledNonCallable); |
| 2627 } | 2588 } |
| 2628 } | 2589 } |
| 2629 | 2590 |
| 2630 | |
| 2631 // static | 2591 // static |
| 2632 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2592 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
| 2633 // ----------- S t a t e ------------- | 2593 // ----------- S t a t e ------------- |
| 2634 // -- eax : the number of arguments (not including the receiver) | 2594 // -- eax : the number of arguments (not including the receiver) |
| 2635 // -- edx : the new target (checked to be a constructor) | 2595 // -- edx : the new target (checked to be a constructor) |
| 2636 // -- edi : the constructor to call (checked to be a JSFunction) | 2596 // -- edi : the constructor to call (checked to be a JSFunction) |
| 2637 // ----------------------------------- | 2597 // ----------------------------------- |
| 2638 __ AssertFunction(edi); | 2598 __ AssertFunction(edi); |
| 2639 | 2599 |
| 2640 // Calling convention for function specific ConstructStubs require | 2600 // Calling convention for function specific ConstructStubs require |
| 2641 // ebx to contain either an AllocationSite or undefined. | 2601 // ebx to contain either an AllocationSite or undefined. |
| 2642 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); | 2602 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); |
| 2643 | 2603 |
| 2644 // Tail call to the function-specific construct stub (still in the caller | 2604 // Tail call to the function-specific construct stub (still in the caller |
| 2645 // context at this point). | 2605 // context at this point). |
| 2646 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2606 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 2647 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); | 2607 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); |
| 2648 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2608 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
| 2649 __ jmp(ecx); | 2609 __ jmp(ecx); |
| 2650 } | 2610 } |
| 2651 | 2611 |
| 2652 | |
| 2653 // static | 2612 // static |
| 2654 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { | 2613 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { |
| 2655 // ----------- S t a t e ------------- | 2614 // ----------- S t a t e ------------- |
| 2656 // -- eax : the number of arguments (not including the receiver) | 2615 // -- eax : the number of arguments (not including the receiver) |
| 2657 // -- edx : the new target (checked to be a constructor) | 2616 // -- edx : the new target (checked to be a constructor) |
| 2658 // -- edi : the constructor to call (checked to be a JSBoundFunction) | 2617 // -- edi : the constructor to call (checked to be a JSBoundFunction) |
| 2659 // ----------------------------------- | 2618 // ----------------------------------- |
| 2660 __ AssertBoundFunction(edi); | 2619 __ AssertBoundFunction(edi); |
| 2661 | 2620 |
| 2662 // Push the [[BoundArguments]] onto the stack. | 2621 // Push the [[BoundArguments]] onto the stack. |
| 2663 Generate_PushBoundArguments(masm); | 2622 Generate_PushBoundArguments(masm); |
| 2664 | 2623 |
| 2665 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. | 2624 // Patch new.target to [[BoundTargetFunction]] if new.target equals target. |
| 2666 { | 2625 { |
| 2667 Label done; | 2626 Label done; |
| 2668 __ cmp(edi, edx); | 2627 __ cmp(edi, edx); |
| 2669 __ j(not_equal, &done, Label::kNear); | 2628 __ j(not_equal, &done, Label::kNear); |
| 2670 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2629 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2671 __ bind(&done); | 2630 __ bind(&done); |
| 2672 } | 2631 } |
| 2673 | 2632 |
| 2674 // Construct the [[BoundTargetFunction]] via the Construct builtin. | 2633 // Construct the [[BoundTargetFunction]] via the Construct builtin. |
| 2675 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); | 2634 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); |
| 2676 __ mov(ecx, Operand::StaticVariable( | 2635 __ mov(ecx, Operand::StaticVariable( |
| 2677 ExternalReference(Builtins::kConstruct, masm->isolate()))); | 2636 ExternalReference(Builtins::kConstruct, masm->isolate()))); |
| 2678 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); | 2637 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); |
| 2679 __ jmp(ecx); | 2638 __ jmp(ecx); |
| 2680 } | 2639 } |
| 2681 | 2640 |
| 2682 | |
| 2683 // static | 2641 // static |
| 2684 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { | 2642 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { |
| 2685 // ----------- S t a t e ------------- | 2643 // ----------- S t a t e ------------- |
| 2686 // -- eax : the number of arguments (not including the receiver) | 2644 // -- eax : the number of arguments (not including the receiver) |
| 2687 // -- edi : the constructor to call (checked to be a JSProxy) | 2645 // -- edi : the constructor to call (checked to be a JSProxy) |
| 2688 // -- edx : the new target (either the same as the constructor or | 2646 // -- edx : the new target (either the same as the constructor or |
| 2689 // the JSFunction on which new was invoked initially) | 2647 // the JSFunction on which new was invoked initially) |
| 2690 // ----------------------------------- | 2648 // ----------------------------------- |
| 2691 | 2649 |
| 2692 // Call into the Runtime for Proxy [[Construct]]. | 2650 // Call into the Runtime for Proxy [[Construct]]. |
| 2693 __ PopReturnAddressTo(ecx); | 2651 __ PopReturnAddressTo(ecx); |
| 2694 __ Push(edi); | 2652 __ Push(edi); |
| 2695 __ Push(edx); | 2653 __ Push(edx); |
| 2696 __ PushReturnAddressFrom(ecx); | 2654 __ PushReturnAddressFrom(ecx); |
| 2697 // Include the pushed new_target, constructor and the receiver. | 2655 // Include the pushed new_target, constructor and the receiver. |
| 2698 __ add(eax, Immediate(3)); | 2656 __ add(eax, Immediate(3)); |
| 2699 // Tail-call to the runtime. | 2657 // Tail-call to the runtime. |
| 2700 __ JumpToExternalReference( | 2658 __ JumpToExternalReference( |
| 2701 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); | 2659 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate())); |
| 2702 } | 2660 } |
| 2703 | 2661 |
| 2704 | |
| 2705 // static | 2662 // static |
| 2706 void Builtins::Generate_Construct(MacroAssembler* masm) { | 2663 void Builtins::Generate_Construct(MacroAssembler* masm) { |
| 2707 // ----------- S t a t e ------------- | 2664 // ----------- S t a t e ------------- |
| 2708 // -- eax : the number of arguments (not including the receiver) | 2665 // -- eax : the number of arguments (not including the receiver) |
| 2709 // -- edx : the new target (either the same as the constructor or | 2666 // -- edx : the new target (either the same as the constructor or |
| 2710 // the JSFunction on which new was invoked initially) | 2667 // the JSFunction on which new was invoked initially) |
| 2711 // -- edi : the constructor to call (can be any Object) | 2668 // -- edi : the constructor to call (can be any Object) |
| 2712 // ----------------------------------- | 2669 // ----------------------------------- |
| 2713 | 2670 |
| 2714 // Check if target is a Smi. | 2671 // Check if target is a Smi. |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2958 __ jmp(ecx); | 2915 __ jmp(ecx); |
| 2959 | 2916 |
| 2960 __ bind(&stack_overflow); | 2917 __ bind(&stack_overflow); |
| 2961 { | 2918 { |
| 2962 FrameScope frame(masm, StackFrame::MANUAL); | 2919 FrameScope frame(masm, StackFrame::MANUAL); |
| 2963 __ CallRuntime(Runtime::kThrowStackOverflow); | 2920 __ CallRuntime(Runtime::kThrowStackOverflow); |
| 2964 __ int3(); | 2921 __ int3(); |
| 2965 } | 2922 } |
| 2966 } | 2923 } |
| 2967 | 2924 |
| 2968 | |
| 2969 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, | 2925 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
| 2970 Register function_template_info, | 2926 Register function_template_info, |
| 2971 Register scratch0, Register scratch1, | 2927 Register scratch0, Register scratch1, |
| 2972 Label* receiver_check_failed) { | 2928 Label* receiver_check_failed) { |
| 2973 // If there is no signature, return the holder. | 2929 // If there is no signature, return the holder. |
| 2974 __ CompareRoot(FieldOperand(function_template_info, | 2930 __ CompareRoot(FieldOperand(function_template_info, |
| 2975 FunctionTemplateInfo::kSignatureOffset), | 2931 FunctionTemplateInfo::kSignatureOffset), |
| 2976 Heap::kUndefinedValueRootIndex); | 2932 Heap::kUndefinedValueRootIndex); |
| 2977 Label receiver_check_passed; | 2933 Label receiver_check_passed; |
| 2978 __ j(equal, &receiver_check_passed, Label::kNear); | 2934 __ j(equal, &receiver_check_passed, Label::kNear); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3022 __ j(zero, receiver_check_failed); | 2978 __ j(zero, receiver_check_failed); |
| 3023 | 2979 |
| 3024 __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset)); | 2980 __ mov(receiver, FieldOperand(receiver, Map::kPrototypeOffset)); |
| 3025 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 2981 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 3026 // Iterate. | 2982 // Iterate. |
| 3027 __ jmp(&prototype_loop_start, Label::kNear); | 2983 __ jmp(&prototype_loop_start, Label::kNear); |
| 3028 | 2984 |
| 3029 __ bind(&receiver_check_passed); | 2985 __ bind(&receiver_check_passed); |
| 3030 } | 2986 } |
| 3031 | 2987 |
| 3032 | |
| 3033 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { | 2988 void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) { |
| 3034 // ----------- S t a t e ------------- | 2989 // ----------- S t a t e ------------- |
| 3035 // -- eax : number of arguments (not including the receiver) | 2990 // -- eax : number of arguments (not including the receiver) |
| 3036 // -- edi : callee | 2991 // -- edi : callee |
| 3037 // -- esi : context | 2992 // -- esi : context |
| 3038 // -- esp[0] : return address | 2993 // -- esp[0] : return address |
| 3039 // -- esp[4] : last argument | 2994 // -- esp[4] : last argument |
| 3040 // -- ... | 2995 // -- ... |
| 3041 // -- esp[eax * 4] : first argument | 2996 // -- esp[eax * 4] : first argument |
| 3042 // -- esp[(eax + 1) * 4] : receiver | 2997 // -- esp[(eax + 1) * 4] : receiver |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3066 __ PopReturnAddressTo(ebx); | 3021 __ PopReturnAddressTo(ebx); |
| 3067 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); | 3022 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); |
| 3068 __ add(esp, eax); | 3023 __ add(esp, eax); |
| 3069 __ PushReturnAddressFrom(ebx); | 3024 __ PushReturnAddressFrom(ebx); |
| 3070 { | 3025 { |
| 3071 FrameScope scope(masm, StackFrame::INTERNAL); | 3026 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3072 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); | 3027 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
| 3073 } | 3028 } |
| 3074 } | 3029 } |
| 3075 | 3030 |
| 3076 | |
| 3077 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 3031 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| 3078 // Lookup the function in the JavaScript frame. | 3032 // Lookup the function in the JavaScript frame. |
| 3079 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3033 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3080 { | 3034 { |
| 3081 FrameScope scope(masm, StackFrame::INTERNAL); | 3035 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3082 // Pass function as argument. | 3036 // Pass function as argument. |
| 3083 __ push(eax); | 3037 __ push(eax); |
| 3084 __ CallRuntime(Runtime::kCompileForOnStackReplacement); | 3038 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
| 3085 } | 3039 } |
| 3086 | 3040 |
| 3087 Label skip; | 3041 Label skip; |
| 3088 // If the code object is null, just return to the unoptimized code. | 3042 // If the code object is null, just return to the unoptimized code. |
| 3089 __ cmp(eax, Immediate(0)); | 3043 __ cmp(eax, Immediate(0)); |
| 3090 __ j(not_equal, &skip, Label::kNear); | 3044 __ j(not_equal, &skip, Label::kNear); |
| 3091 __ ret(0); | 3045 __ ret(0); |
| 3092 | 3046 |
| 3093 __ bind(&skip); | 3047 __ bind(&skip); |
| 3094 | 3048 |
| 3095 // Load deoptimization data from the code object. | 3049 // Load deoptimization data from the code object. |
| 3096 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 3050 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); |
| 3097 | 3051 |
| 3098 // Load the OSR entrypoint offset from the deoptimization data. | 3052 // Load the OSR entrypoint offset from the deoptimization data. |
| 3099 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( | 3053 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( |
| 3100 DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag)); | 3054 DeoptimizationInputData::kOsrPcOffsetIndex) - |
| 3055 kHeapObjectTag)); |
| 3101 __ SmiUntag(ebx); | 3056 __ SmiUntag(ebx); |
| 3102 | 3057 |
| 3103 // Compute the target address = code_obj + header_size + osr_offset | 3058 // Compute the target address = code_obj + header_size + osr_offset |
| 3104 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); | 3059 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); |
| 3105 | 3060 |
| 3106 // Overwrite the return address on the stack. | 3061 // Overwrite the return address on the stack. |
| 3107 __ mov(Operand(esp, 0), eax); | 3062 __ mov(Operand(esp, 0), eax); |
| 3108 | 3063 |
| 3109 // And "return" to the OSR entry point of the function. | 3064 // And "return" to the OSR entry point of the function. |
| 3110 __ ret(0); | 3065 __ ret(0); |
| 3111 } | 3066 } |
| 3112 | 3067 |
| 3113 | |
| 3114 #undef __ | 3068 #undef __ |
| 3115 } // namespace internal | 3069 } // namespace internal |
| 3116 } // namespace v8 | 3070 } // namespace v8 |
| 3117 | 3071 |
| 3118 #endif // V8_TARGET_ARCH_X87 | 3072 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |