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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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" |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd)); | 223 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd)); |
224 __ j(not_equal, &allocated); | 224 __ j(not_equal, &allocated); |
225 | 225 |
226 // Push the constructor, new_target and the object to the stack, | 226 // Push the constructor, new_target and the object to the stack, |
227 // and then the initial map as an argument to the runtime call. | 227 // and then the initial map as an argument to the runtime call. |
228 __ Push(rdi); | 228 __ Push(rdi); |
229 __ Push(rdx); | 229 __ Push(rdx); |
230 __ Push(rbx); | 230 __ Push(rbx); |
231 | 231 |
232 __ Push(rax); // initial map | 232 __ Push(rax); // initial map |
233 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); | 233 __ CallRuntime(Runtime::kFinalizeInstanceSize); |
234 | 234 |
235 __ Pop(rbx); | 235 __ Pop(rbx); |
236 __ Pop(rdx); | 236 __ Pop(rdx); |
237 __ Pop(rdi); | 237 __ Pop(rdi); |
238 | 238 |
239 // Continue with JSObject being successfully allocated. | 239 // Continue with JSObject being successfully allocated. |
240 // rdi: constructor | 240 // rdi: constructor |
241 // rdx: new target | 241 // rdx: new target |
242 // rbx: JSObject (tagged) | 242 // rbx: JSObject (tagged) |
243 __ jmp(&allocated); | 243 __ jmp(&allocated); |
(...skipping 17 matching lines...) Expand all Loading... |
261 | 261 |
262 // Must restore rsi (context) before calling runtime. | 262 // Must restore rsi (context) before calling runtime. |
263 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 263 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
264 | 264 |
265 // Push the constructor and new_target twice, second pair as arguments | 265 // Push the constructor and new_target twice, second pair as arguments |
266 // to the runtime call. | 266 // to the runtime call. |
267 __ Push(rdi); | 267 __ Push(rdi); |
268 __ Push(rdx); | 268 __ Push(rdx); |
269 __ Push(rdi); // constructor function | 269 __ Push(rdi); // constructor function |
270 __ Push(rdx); // new target | 270 __ Push(rdx); // new target |
271 __ CallRuntime(Runtime::kNewObject, 2); | 271 __ CallRuntime(Runtime::kNewObject); |
272 __ movp(rbx, rax); // store result in rbx | 272 __ movp(rbx, rax); // store result in rbx |
273 __ Pop(rdx); | 273 __ Pop(rdx); |
274 __ Pop(rdi); | 274 __ Pop(rdi); |
275 | 275 |
276 // Receiver for constructor call allocated. | 276 // Receiver for constructor call allocated. |
277 // rdi: constructor | 277 // rdi: constructor |
278 // rdx: new target | 278 // rdx: new target |
279 // rbx: newly allocated object | 279 // rbx: newly allocated object |
280 __ bind(&allocated); | 280 __ bind(&allocated); |
281 | 281 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 | 381 |
382 | 382 |
383 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { | 383 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
384 Generate_JSConstructStubHelper(masm, false, false); | 384 Generate_JSConstructStubHelper(masm, false, false); |
385 } | 385 } |
386 | 386 |
387 | 387 |
388 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { | 388 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { |
389 FrameScope scope(masm, StackFrame::INTERNAL); | 389 FrameScope scope(masm, StackFrame::INTERNAL); |
390 __ Push(rdi); | 390 __ Push(rdi); |
391 __ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1); | 391 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); |
392 } | 392 } |
393 | 393 |
394 | 394 |
395 enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt }; | 395 enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt }; |
396 | 396 |
397 | 397 |
398 // Clobbers rcx, r11, kScratchRegister; preserves all other registers. | 398 // Clobbers rcx, r11, kScratchRegister; preserves all other registers. |
399 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 399 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
400 IsTagged rax_is_tagged) { | 400 IsTagged rax_is_tagged) { |
401 // rax : the number of items to be pushed to the stack | 401 // rax : the number of items to be pushed to the stack |
(...skipping 14 matching lines...) Expand all Loading... |
416 } else { | 416 } else { |
417 DCHECK(rax_is_tagged == kRaxIsUntaggedInt); | 417 DCHECK(rax_is_tagged == kRaxIsUntaggedInt); |
418 __ movp(r11, rax); | 418 __ movp(r11, rax); |
419 __ shlq(r11, Immediate(kPointerSizeLog2)); | 419 __ shlq(r11, Immediate(kPointerSizeLog2)); |
420 } | 420 } |
421 // Check if the arguments will overflow the stack. | 421 // Check if the arguments will overflow the stack. |
422 __ cmpp(rcx, r11); | 422 __ cmpp(rcx, r11); |
423 __ j(greater, &okay); // Signed comparison. | 423 __ j(greater, &okay); // Signed comparison. |
424 | 424 |
425 // Out of stack space. | 425 // Out of stack space. |
426 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 426 __ CallRuntime(Runtime::kThrowStackOverflow); |
427 | 427 |
428 __ bind(&okay); | 428 __ bind(&okay); |
429 } | 429 } |
430 | 430 |
431 | 431 |
432 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 432 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
433 bool is_construct) { | 433 bool is_construct) { |
434 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 434 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
435 | 435 |
436 // Expects five C++ function parameters. | 436 // Expects five C++ function parameters. |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 // Load frame size from the BytecodeArray object. | 621 // Load frame size from the BytecodeArray object. |
622 __ movl(rcx, FieldOperand(kInterpreterBytecodeArrayRegister, | 622 __ movl(rcx, FieldOperand(kInterpreterBytecodeArrayRegister, |
623 BytecodeArray::kFrameSizeOffset)); | 623 BytecodeArray::kFrameSizeOffset)); |
624 | 624 |
625 // Do a stack check to ensure we don't go over the limit. | 625 // Do a stack check to ensure we don't go over the limit. |
626 Label ok; | 626 Label ok; |
627 __ movp(rdx, rsp); | 627 __ movp(rdx, rsp); |
628 __ subp(rdx, rcx); | 628 __ subp(rdx, rcx); |
629 __ CompareRoot(rdx, Heap::kRealStackLimitRootIndex); | 629 __ CompareRoot(rdx, Heap::kRealStackLimitRootIndex); |
630 __ j(above_equal, &ok, Label::kNear); | 630 __ j(above_equal, &ok, Label::kNear); |
631 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 631 __ CallRuntime(Runtime::kThrowStackOverflow); |
632 __ bind(&ok); | 632 __ bind(&ok); |
633 | 633 |
634 // If ok, push undefined as the initial value for all register file entries. | 634 // If ok, push undefined as the initial value for all register file entries. |
635 Label loop_header; | 635 Label loop_header; |
636 Label loop_check; | 636 Label loop_check; |
637 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 637 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
638 __ j(always, &loop_check); | 638 __ j(always, &loop_check); |
639 __ bind(&loop_header); | 639 __ bind(&loop_header); |
640 // TODO(rmcilroy): Consider doing more than one push per loop iteration. | 640 // TODO(rmcilroy): Consider doing more than one push per loop iteration. |
641 __ Push(rdx); | 641 __ Push(rdx); |
642 // Continue loop if not done. | 642 // Continue loop if not done. |
643 __ bind(&loop_check); | 643 __ bind(&loop_check); |
644 __ subp(rcx, Immediate(kPointerSize)); | 644 __ subp(rcx, Immediate(kPointerSize)); |
645 __ j(greater_equal, &loop_header, Label::kNear); | 645 __ j(greater_equal, &loop_header, Label::kNear); |
646 } | 646 } |
647 | 647 |
648 // TODO(rmcilroy): List of things not currently dealt with here but done in | 648 // TODO(rmcilroy): List of things not currently dealt with here but done in |
649 // fullcodegen's prologue: | 649 // fullcodegen's prologue: |
650 // - Support profiler (specifically profiling_counter). | 650 // - Support profiler (specifically profiling_counter). |
651 // - Call ProfileEntryHookStub when isolate has a function_entry_hook. | 651 // - Call ProfileEntryHookStub when isolate has a function_entry_hook. |
652 // - Allow simulator stop operations if FLAG_stop_at is set. | 652 // - Allow simulator stop operations if FLAG_stop_at is set. |
653 // - Code aging of the BytecodeArray object. | 653 // - Code aging of the BytecodeArray object. |
654 | 654 |
655 // Perform stack guard check. | 655 // Perform stack guard check. |
656 { | 656 { |
657 Label ok; | 657 Label ok; |
658 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 658 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
659 __ j(above_equal, &ok, Label::kNear); | 659 __ j(above_equal, &ok, Label::kNear); |
660 __ Push(kInterpreterBytecodeArrayRegister); | 660 __ Push(kInterpreterBytecodeArrayRegister); |
661 __ CallRuntime(Runtime::kStackGuard, 0); | 661 __ CallRuntime(Runtime::kStackGuard); |
662 __ Pop(kInterpreterBytecodeArrayRegister); | 662 __ Pop(kInterpreterBytecodeArrayRegister); |
663 __ bind(&ok); | 663 __ bind(&ok); |
664 } | 664 } |
665 | 665 |
666 // Load accumulator, register file, bytecode offset, dispatch table into | 666 // Load accumulator, register file, bytecode offset, dispatch table into |
667 // registers. | 667 // registers. |
668 __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); | 668 __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); |
669 __ movp(kInterpreterRegisterFileRegister, rbp); | 669 __ movp(kInterpreterRegisterFileRegister, rbp); |
670 __ addp(kInterpreterRegisterFileRegister, | 670 __ addp(kInterpreterRegisterFileRegister, |
671 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); | 671 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 static void Generate_InterpreterNotifyDeoptimizedHelper( | 793 static void Generate_InterpreterNotifyDeoptimizedHelper( |
794 MacroAssembler* masm, Deoptimizer::BailoutType type) { | 794 MacroAssembler* masm, Deoptimizer::BailoutType type) { |
795 // Enter an internal frame. | 795 // Enter an internal frame. |
796 { | 796 { |
797 FrameScope scope(masm, StackFrame::INTERNAL); | 797 FrameScope scope(masm, StackFrame::INTERNAL); |
798 __ Push(kInterpreterAccumulatorRegister); // Save accumulator register. | 798 __ Push(kInterpreterAccumulatorRegister); // Save accumulator register. |
799 | 799 |
800 // Pass the deoptimization type to the runtime system. | 800 // Pass the deoptimization type to the runtime system. |
801 __ Push(Smi::FromInt(static_cast<int>(type))); | 801 __ Push(Smi::FromInt(static_cast<int>(type))); |
802 | 802 |
803 __ CallRuntime(Runtime::kNotifyDeoptimized, 1); | 803 __ CallRuntime(Runtime::kNotifyDeoptimized); |
804 | 804 |
805 __ Pop(kInterpreterAccumulatorRegister); // Restore accumulator register. | 805 __ Pop(kInterpreterAccumulatorRegister); // Restore accumulator register. |
806 // Tear down internal frame. | 806 // Tear down internal frame. |
807 } | 807 } |
808 | 808 |
809 // Drop state (we don't use these for interpreter deopts) and push PC at top | 809 // Drop state (we don't use these for interpreter deopts) and push PC at top |
810 // of stack (to simulate initial call to bytecode handler in interpreter entry | 810 // of stack (to simulate initial call to bytecode handler in interpreter entry |
811 // trampoline). | 811 // trampoline). |
812 __ Pop(rbx); | 812 __ Pop(rbx); |
813 __ Drop(1); | 813 __ Drop(1); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 977 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, |
978 SaveFPRegsMode save_doubles) { | 978 SaveFPRegsMode save_doubles) { |
979 // Enter an internal frame. | 979 // Enter an internal frame. |
980 { | 980 { |
981 FrameScope scope(masm, StackFrame::INTERNAL); | 981 FrameScope scope(masm, StackFrame::INTERNAL); |
982 | 982 |
983 // Preserve registers across notification, this is important for compiled | 983 // Preserve registers across notification, this is important for compiled |
984 // stubs that tail call the runtime on deopts passing their parameters in | 984 // stubs that tail call the runtime on deopts passing their parameters in |
985 // registers. | 985 // registers. |
986 __ Pushad(); | 986 __ Pushad(); |
987 __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles); | 987 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); |
988 __ Popad(); | 988 __ Popad(); |
989 // Tear down internal frame. | 989 // Tear down internal frame. |
990 } | 990 } |
991 | 991 |
992 __ DropUnderReturnAddress(1); // Ignore state offset | 992 __ DropUnderReturnAddress(1); // Ignore state offset |
993 __ ret(0); // Return to IC Miss stub, continuation still on stack. | 993 __ ret(0); // Return to IC Miss stub, continuation still on stack. |
994 } | 994 } |
995 | 995 |
996 | 996 |
997 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 997 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { |
998 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 998 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); |
999 } | 999 } |
1000 | 1000 |
1001 | 1001 |
1002 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 1002 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { |
1003 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 1003 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); |
1004 } | 1004 } |
1005 | 1005 |
1006 | 1006 |
1007 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 1007 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
1008 Deoptimizer::BailoutType type) { | 1008 Deoptimizer::BailoutType type) { |
1009 // Enter an internal frame. | 1009 // Enter an internal frame. |
1010 { | 1010 { |
1011 FrameScope scope(masm, StackFrame::INTERNAL); | 1011 FrameScope scope(masm, StackFrame::INTERNAL); |
1012 | 1012 |
1013 // Pass the deoptimization type to the runtime system. | 1013 // Pass the deoptimization type to the runtime system. |
1014 __ Push(Smi::FromInt(static_cast<int>(type))); | 1014 __ Push(Smi::FromInt(static_cast<int>(type))); |
1015 | 1015 |
1016 __ CallRuntime(Runtime::kNotifyDeoptimized, 1); | 1016 __ CallRuntime(Runtime::kNotifyDeoptimized); |
1017 // Tear down internal frame. | 1017 // Tear down internal frame. |
1018 } | 1018 } |
1019 | 1019 |
1020 // Get the full codegen state from the stack and untag it. | 1020 // Get the full codegen state from the stack and untag it. |
1021 __ SmiToInteger32(kScratchRegister, Operand(rsp, kPCOnStackSize)); | 1021 __ SmiToInteger32(kScratchRegister, Operand(rsp, kPCOnStackSize)); |
1022 | 1022 |
1023 // Switch on the state. | 1023 // Switch on the state. |
1024 Label not_no_registers, not_tos_rax; | 1024 Label not_no_registers, not_tos_rax; |
1025 __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::NO_REGISTERS)); | 1025 __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::NO_REGISTERS)); |
1026 __ j(not_equal, ¬_no_registers, Label::kNear); | 1026 __ j(not_equal, ¬_no_registers, Label::kNear); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 { | 1119 { |
1120 __ Set(rax, 0); | 1120 __ Set(rax, 0); |
1121 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1121 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1122 } | 1122 } |
1123 | 1123 |
1124 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1124 // 4c. The receiver is not callable, throw an appropriate TypeError. |
1125 __ bind(&receiver_not_callable); | 1125 __ bind(&receiver_not_callable); |
1126 { | 1126 { |
1127 StackArgumentsAccessor args(rsp, 0); | 1127 StackArgumentsAccessor args(rsp, 0); |
1128 __ movp(args.GetReceiverOperand(), rdi); | 1128 __ movp(args.GetReceiverOperand(), rdi); |
1129 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1); | 1129 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1130 } | 1130 } |
1131 } | 1131 } |
1132 | 1132 |
1133 | 1133 |
1134 // static | 1134 // static |
1135 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { | 1135 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { |
1136 // Stack Layout: | 1136 // Stack Layout: |
1137 // rsp[0] : Return address | 1137 // rsp[0] : Return address |
1138 // rsp[8] : Argument n | 1138 // rsp[8] : Argument n |
1139 // rsp[16] : Argument n-1 | 1139 // rsp[16] : Argument n-1 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1235 // 3a. Apply the target to the given argumentsList (passing undefined for | 1235 // 3a. Apply the target to the given argumentsList (passing undefined for |
1236 // new.target). | 1236 // new.target). |
1237 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 1237 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
1238 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1238 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |
1239 | 1239 |
1240 // 3b. The target is not callable, throw an appropriate TypeError. | 1240 // 3b. The target is not callable, throw an appropriate TypeError. |
1241 __ bind(&target_not_callable); | 1241 __ bind(&target_not_callable); |
1242 { | 1242 { |
1243 StackArgumentsAccessor args(rsp, 0); | 1243 StackArgumentsAccessor args(rsp, 0); |
1244 __ movp(args.GetReceiverOperand(), rdi); | 1244 __ movp(args.GetReceiverOperand(), rdi); |
1245 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1); | 1245 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1246 } | 1246 } |
1247 } | 1247 } |
1248 | 1248 |
1249 | 1249 |
1250 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { | 1250 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { |
1251 // ----------- S t a t e ------------- | 1251 // ----------- S t a t e ------------- |
1252 // -- rax : argc | 1252 // -- rax : argc |
1253 // -- rsp[0] : return address | 1253 // -- rsp[0] : return address |
1254 // -- rsp[8] : new.target (optional) | 1254 // -- rsp[8] : new.target (optional) |
1255 // -- rsp[16] : argumentsList | 1255 // -- rsp[16] : argumentsList |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 __ j(zero, &new_target_not_constructor, Label::kNear); | 1309 __ j(zero, &new_target_not_constructor, Label::kNear); |
1310 | 1310 |
1311 // 4a. Construct the target with the given new.target and argumentsList. | 1311 // 4a. Construct the target with the given new.target and argumentsList. |
1312 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1312 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |
1313 | 1313 |
1314 // 4b. The target is not a constructor, throw an appropriate TypeError. | 1314 // 4b. The target is not a constructor, throw an appropriate TypeError. |
1315 __ bind(&target_not_constructor); | 1315 __ bind(&target_not_constructor); |
1316 { | 1316 { |
1317 StackArgumentsAccessor args(rsp, 0); | 1317 StackArgumentsAccessor args(rsp, 0); |
1318 __ movp(args.GetReceiverOperand(), rdi); | 1318 __ movp(args.GetReceiverOperand(), rdi); |
1319 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1319 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
1320 } | 1320 } |
1321 | 1321 |
1322 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1322 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
1323 __ bind(&new_target_not_constructor); | 1323 __ bind(&new_target_not_constructor); |
1324 { | 1324 { |
1325 StackArgumentsAccessor args(rsp, 0); | 1325 StackArgumentsAccessor args(rsp, 0); |
1326 __ movp(args.GetReceiverOperand(), rdx); | 1326 __ movp(args.GetReceiverOperand(), rdx); |
1327 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1327 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
1328 } | 1328 } |
1329 } | 1329 } |
1330 | 1330 |
1331 | 1331 |
1332 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1332 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
1333 // ----------- S t a t e ------------- | 1333 // ----------- S t a t e ------------- |
1334 // -- rax : argc | 1334 // -- rax : argc |
1335 // -- rsp[0] : return address | 1335 // -- rsp[0] : return address |
1336 // -- rsp[8] : last argument | 1336 // -- rsp[8] : last argument |
1337 // ----------------------------------- | 1337 // ----------------------------------- |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1439 ToStringStub stub(masm->isolate()); | 1439 ToStringStub stub(masm->isolate()); |
1440 __ TailCallStub(&stub); | 1440 __ TailCallStub(&stub); |
1441 } | 1441 } |
1442 | 1442 |
1443 // 3b. Convert symbol in rax to a string. | 1443 // 3b. Convert symbol in rax to a string. |
1444 __ bind(&symbol_descriptive_string); | 1444 __ bind(&symbol_descriptive_string); |
1445 { | 1445 { |
1446 __ PopReturnAddressTo(rcx); | 1446 __ PopReturnAddressTo(rcx); |
1447 __ Push(rax); | 1447 __ Push(rax); |
1448 __ PushReturnAddressFrom(rcx); | 1448 __ PushReturnAddressFrom(rcx); |
1449 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1); | 1449 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); |
1450 } | 1450 } |
1451 } | 1451 } |
1452 | 1452 |
1453 | 1453 |
1454 // static | 1454 // static |
1455 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1455 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1456 // ----------- S t a t e ------------- | 1456 // ----------- S t a t e ------------- |
1457 // -- rax : number of arguments | 1457 // -- rax : number of arguments |
1458 // -- rdi : constructor function | 1458 // -- rdi : constructor function |
1459 // -- rdx : new target | 1459 // -- rdx : new target |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1525 __ Ret(); | 1525 __ Ret(); |
1526 } | 1526 } |
1527 | 1527 |
1528 // 5. Fallback to the runtime to create new object. | 1528 // 5. Fallback to the runtime to create new object. |
1529 __ bind(&new_object); | 1529 __ bind(&new_object); |
1530 { | 1530 { |
1531 FrameScope scope(masm, StackFrame::INTERNAL); | 1531 FrameScope scope(masm, StackFrame::INTERNAL); |
1532 __ Push(rbx); // the first argument | 1532 __ Push(rbx); // the first argument |
1533 __ Push(rdi); // constructor function | 1533 __ Push(rdi); // constructor function |
1534 __ Push(rdx); // new target | 1534 __ Push(rdx); // new target |
1535 __ CallRuntime(Runtime::kNewObject, 2); | 1535 __ CallRuntime(Runtime::kNewObject); |
1536 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); | 1536 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); |
1537 } | 1537 } |
1538 __ Ret(); | 1538 __ Ret(); |
1539 } | 1539 } |
1540 | 1540 |
1541 | 1541 |
1542 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1542 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
1543 Label* stack_overflow) { | 1543 Label* stack_overflow) { |
1544 // ----------- S t a t e ------------- | 1544 // ----------- S t a t e ------------- |
1545 // -- rax : actual number of arguments | 1545 // -- rax : actual number of arguments |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 FieldOperand(kScratchRegister, SharedFunctionInfo::kLengthOffset)); | 1664 FieldOperand(kScratchRegister, SharedFunctionInfo::kLengthOffset)); |
1665 __ shrq(kScratchRegister, Immediate(1)); | 1665 __ shrq(kScratchRegister, Immediate(1)); |
1666 } | 1666 } |
1667 | 1667 |
1668 __ cmpp(rax, kScratchRegister); | 1668 __ cmpp(rax, kScratchRegister); |
1669 __ j(greater_equal, &no_strong_error, Label::kNear); | 1669 __ j(greater_equal, &no_strong_error, Label::kNear); |
1670 | 1670 |
1671 { | 1671 { |
1672 FrameScope frame(masm, StackFrame::MANUAL); | 1672 FrameScope frame(masm, StackFrame::MANUAL); |
1673 EnterArgumentsAdaptorFrame(masm); | 1673 EnterArgumentsAdaptorFrame(masm); |
1674 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); | 1674 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments); |
1675 } | 1675 } |
1676 | 1676 |
1677 __ bind(&no_strong_error); | 1677 __ bind(&no_strong_error); |
1678 EnterArgumentsAdaptorFrame(masm); | 1678 EnterArgumentsAdaptorFrame(masm); |
1679 ArgumentsAdaptorStackCheck(masm, &stack_overflow); | 1679 ArgumentsAdaptorStackCheck(masm, &stack_overflow); |
1680 | 1680 |
1681 // Copy receiver and all actual arguments. | 1681 // Copy receiver and all actual arguments. |
1682 const int offset = StandardFrameConstants::kCallerSPOffset; | 1682 const int offset = StandardFrameConstants::kCallerSPOffset; |
1683 __ leap(rdi, Operand(rbp, rax, times_pointer_size, offset)); | 1683 __ leap(rdi, Operand(rbp, rax, times_pointer_size, offset)); |
1684 __ Set(r8, -1); // account for receiver | 1684 __ Set(r8, -1); // account for receiver |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 // ------------------------------------------- | 1723 // ------------------------------------------- |
1724 // Dont adapt arguments. | 1724 // Dont adapt arguments. |
1725 // ------------------------------------------- | 1725 // ------------------------------------------- |
1726 __ bind(&dont_adapt_arguments); | 1726 __ bind(&dont_adapt_arguments); |
1727 __ movp(rcx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 1727 __ movp(rcx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
1728 __ jmp(rcx); | 1728 __ jmp(rcx); |
1729 | 1729 |
1730 __ bind(&stack_overflow); | 1730 __ bind(&stack_overflow); |
1731 { | 1731 { |
1732 FrameScope frame(masm, StackFrame::MANUAL); | 1732 FrameScope frame(masm, StackFrame::MANUAL); |
1733 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 1733 __ CallRuntime(Runtime::kThrowStackOverflow); |
1734 __ int3(); | 1734 __ int3(); |
1735 } | 1735 } |
1736 } | 1736 } |
1737 | 1737 |
1738 | 1738 |
1739 // static | 1739 // static |
1740 void Builtins::Generate_Apply(MacroAssembler* masm) { | 1740 void Builtins::Generate_Apply(MacroAssembler* masm) { |
1741 // ----------- S t a t e ------------- | 1741 // ----------- S t a t e ------------- |
1742 // -- rax : argumentsList | 1742 // -- rax : argumentsList |
1743 // -- rdi : target | 1743 // -- rdi : target |
(...skipping 23 matching lines...) Expand all Loading... |
1767 __ CmpInstanceType(rcx, JS_ARRAY_TYPE); | 1767 __ CmpInstanceType(rcx, JS_ARRAY_TYPE); |
1768 __ j(equal, &create_array); | 1768 __ j(equal, &create_array); |
1769 | 1769 |
1770 // Ask the runtime to create the list (actually a FixedArray). | 1770 // Ask the runtime to create the list (actually a FixedArray). |
1771 __ bind(&create_runtime); | 1771 __ bind(&create_runtime); |
1772 { | 1772 { |
1773 FrameScope scope(masm, StackFrame::INTERNAL); | 1773 FrameScope scope(masm, StackFrame::INTERNAL); |
1774 __ Push(rdi); | 1774 __ Push(rdi); |
1775 __ Push(rdx); | 1775 __ Push(rdx); |
1776 __ Push(rax); | 1776 __ Push(rax); |
1777 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1); | 1777 __ CallRuntime(Runtime::kCreateListFromArrayLike); |
1778 __ Pop(rdx); | 1778 __ Pop(rdx); |
1779 __ Pop(rdi); | 1779 __ Pop(rdi); |
1780 __ SmiToInteger32(rbx, FieldOperand(rax, FixedArray::kLengthOffset)); | 1780 __ SmiToInteger32(rbx, FieldOperand(rax, FixedArray::kLengthOffset)); |
1781 } | 1781 } |
1782 __ jmp(&done_create); | 1782 __ jmp(&done_create); |
1783 | 1783 |
1784 // Try to create the list from an arguments object. | 1784 // Try to create the list from an arguments object. |
1785 __ bind(&create_arguments); | 1785 __ bind(&create_arguments); |
1786 __ movp(rbx, | 1786 __ movp(rbx, |
1787 FieldOperand(rax, JSObject::kHeaderSize + | 1787 FieldOperand(rax, JSObject::kHeaderSize + |
(...skipping 29 matching lines...) Expand all Loading... |
1817 Label done; | 1817 Label done; |
1818 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); | 1818 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); |
1819 __ movp(rcx, rsp); | 1819 __ movp(rcx, rsp); |
1820 // Make rcx the space we have left. The stack might already be overflowed | 1820 // Make rcx the space we have left. The stack might already be overflowed |
1821 // here which will cause rcx to become negative. | 1821 // here which will cause rcx to become negative. |
1822 __ subp(rcx, kScratchRegister); | 1822 __ subp(rcx, kScratchRegister); |
1823 __ sarp(rcx, Immediate(kPointerSizeLog2)); | 1823 __ sarp(rcx, Immediate(kPointerSizeLog2)); |
1824 // Check if the arguments will overflow the stack. | 1824 // Check if the arguments will overflow the stack. |
1825 __ cmpp(rcx, rbx); | 1825 __ cmpp(rcx, rbx); |
1826 __ j(greater, &done, Label::kNear); // Signed comparison. | 1826 __ j(greater, &done, Label::kNear); // Signed comparison. |
1827 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1); | 1827 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
1828 __ bind(&done); | 1828 __ bind(&done); |
1829 } | 1829 } |
1830 | 1830 |
1831 // ----------- S t a t e ------------- | 1831 // ----------- S t a t e ------------- |
1832 // -- rdi : target | 1832 // -- rdi : target |
1833 // -- rax : args (a FixedArray built from argumentsList) | 1833 // -- rax : args (a FixedArray built from argumentsList) |
1834 // -- rbx : len (number of elements to push from args) | 1834 // -- rbx : len (number of elements to push from args) |
1835 // -- rdx : new.target (checked to be constructor or undefined) | 1835 // -- rdx : new.target (checked to be constructor or undefined) |
1836 // -- rsp[0] : return address. | 1836 // -- rsp[0] : return address. |
1837 // -- rsp[8] : thisArgument | 1837 // -- rsp[8] : thisArgument |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 ParameterCount expected(rbx); | 1967 ParameterCount expected(rbx); |
1968 | 1968 |
1969 __ InvokeFunctionCode(rdi, no_reg, expected, actual, JUMP_FUNCTION, | 1969 __ InvokeFunctionCode(rdi, no_reg, expected, actual, JUMP_FUNCTION, |
1970 CheckDebugStepCallWrapper()); | 1970 CheckDebugStepCallWrapper()); |
1971 | 1971 |
1972 // The function is a "classConstructor", need to raise an exception. | 1972 // The function is a "classConstructor", need to raise an exception. |
1973 __ bind(&class_constructor); | 1973 __ bind(&class_constructor); |
1974 { | 1974 { |
1975 FrameScope frame(masm, StackFrame::INTERNAL); | 1975 FrameScope frame(masm, StackFrame::INTERNAL); |
1976 __ Push(rdi); | 1976 __ Push(rdi); |
1977 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); | 1977 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); |
1978 } | 1978 } |
1979 } | 1979 } |
1980 | 1980 |
1981 | 1981 |
1982 namespace { | 1982 namespace { |
1983 | 1983 |
1984 void Generate_PushBoundArguments(MacroAssembler* masm) { | 1984 void Generate_PushBoundArguments(MacroAssembler* masm) { |
1985 // ----------- S t a t e ------------- | 1985 // ----------- S t a t e ------------- |
1986 // -- rax : the number of arguments (not including the receiver) | 1986 // -- rax : the number of arguments (not including the receiver) |
1987 // -- rdx : new.target (only in case of [[Construct]]) | 1987 // -- rdx : new.target (only in case of [[Construct]]) |
(...skipping 23 matching lines...) Expand all Loading... |
2011 // Check the stack for overflow. We are not trying to catch interruptions | 2011 // Check the stack for overflow. We are not trying to catch interruptions |
2012 // (i.e. debug break and preemption) here, so check the "real stack | 2012 // (i.e. debug break and preemption) here, so check the "real stack |
2013 // limit". | 2013 // limit". |
2014 __ CompareRoot(rsp, Heap::kRealStackLimitRootIndex); | 2014 __ CompareRoot(rsp, Heap::kRealStackLimitRootIndex); |
2015 __ j(greater, &done, Label::kNear); // Signed comparison. | 2015 __ j(greater, &done, Label::kNear); // Signed comparison. |
2016 // Restore the stack pointer. | 2016 // Restore the stack pointer. |
2017 __ leap(rsp, Operand(rsp, rbx, times_pointer_size, 0)); | 2017 __ leap(rsp, Operand(rsp, rbx, times_pointer_size, 0)); |
2018 { | 2018 { |
2019 FrameScope scope(masm, StackFrame::MANUAL); | 2019 FrameScope scope(masm, StackFrame::MANUAL); |
2020 __ EnterFrame(StackFrame::INTERNAL); | 2020 __ EnterFrame(StackFrame::INTERNAL); |
2021 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 2021 __ CallRuntime(Runtime::kThrowStackOverflow); |
2022 } | 2022 } |
2023 __ bind(&done); | 2023 __ bind(&done); |
2024 } | 2024 } |
2025 | 2025 |
2026 // Adjust effective number of arguments to include return address. | 2026 // Adjust effective number of arguments to include return address. |
2027 __ incl(rax); | 2027 __ incl(rax); |
2028 | 2028 |
2029 // Relocate arguments and return address down the stack. | 2029 // Relocate arguments and return address down the stack. |
2030 { | 2030 { |
2031 Label loop; | 2031 Label loop; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2133 __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, rdi); | 2133 __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, rdi); |
2134 __ Jump(masm->isolate()->builtins()->CallFunction( | 2134 __ Jump(masm->isolate()->builtins()->CallFunction( |
2135 ConvertReceiverMode::kNotNullOrUndefined), | 2135 ConvertReceiverMode::kNotNullOrUndefined), |
2136 RelocInfo::CODE_TARGET); | 2136 RelocInfo::CODE_TARGET); |
2137 | 2137 |
2138 // 3. Call to something that is not callable. | 2138 // 3. Call to something that is not callable. |
2139 __ bind(&non_callable); | 2139 __ bind(&non_callable); |
2140 { | 2140 { |
2141 FrameScope scope(masm, StackFrame::INTERNAL); | 2141 FrameScope scope(masm, StackFrame::INTERNAL); |
2142 __ Push(rdi); | 2142 __ Push(rdi); |
2143 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 2143 __ CallRuntime(Runtime::kThrowCalledNonCallable); |
2144 } | 2144 } |
2145 } | 2145 } |
2146 | 2146 |
2147 | 2147 |
2148 // static | 2148 // static |
2149 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2149 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
2150 // ----------- S t a t e ------------- | 2150 // ----------- S t a t e ------------- |
2151 // -- rax : the number of arguments (not including the receiver) | 2151 // -- rax : the number of arguments (not including the receiver) |
2152 // -- rdx : the new target (checked to be a constructor) | 2152 // -- rdx : the new target (checked to be a constructor) |
2153 // -- rdi : the constructor to call (checked to be a JSFunction) | 2153 // -- rdi : the constructor to call (checked to be a JSFunction) |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2387 | 2387 |
2388 // Compatible receiver check failed: pop return address, arguments and | 2388 // Compatible receiver check failed: pop return address, arguments and |
2389 // receiver and throw an Illegal Invocation exception. | 2389 // receiver and throw an Illegal Invocation exception. |
2390 __ bind(&receiver_check_failed); | 2390 __ bind(&receiver_check_failed); |
2391 __ PopReturnAddressTo(rbx); | 2391 __ PopReturnAddressTo(rbx); |
2392 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize)); | 2392 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize)); |
2393 __ addp(rsp, rax); | 2393 __ addp(rsp, rax); |
2394 __ PushReturnAddressFrom(rbx); | 2394 __ PushReturnAddressFrom(rbx); |
2395 { | 2395 { |
2396 FrameScope scope(masm, StackFrame::INTERNAL); | 2396 FrameScope scope(masm, StackFrame::INTERNAL); |
2397 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 0); | 2397 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
2398 } | 2398 } |
2399 } | 2399 } |
2400 | 2400 |
2401 | 2401 |
2402 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 2402 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
2403 // Lookup the function in the JavaScript frame. | 2403 // Lookup the function in the JavaScript frame. |
2404 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 2404 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
2405 { | 2405 { |
2406 FrameScope scope(masm, StackFrame::INTERNAL); | 2406 FrameScope scope(masm, StackFrame::INTERNAL); |
2407 // Pass function as argument. | 2407 // Pass function as argument. |
2408 __ Push(rax); | 2408 __ Push(rax); |
2409 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 2409 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
2410 } | 2410 } |
2411 | 2411 |
2412 Label skip; | 2412 Label skip; |
2413 // If the code object is null, just return to the unoptimized code. | 2413 // If the code object is null, just return to the unoptimized code. |
2414 __ cmpp(rax, Immediate(0)); | 2414 __ cmpp(rax, Immediate(0)); |
2415 __ j(not_equal, &skip, Label::kNear); | 2415 __ j(not_equal, &skip, Label::kNear); |
2416 __ ret(0); | 2416 __ ret(0); |
2417 | 2417 |
2418 __ bind(&skip); | 2418 __ bind(&skip); |
2419 | 2419 |
(...skipping 15 matching lines...) Expand all Loading... |
2435 } | 2435 } |
2436 | 2436 |
2437 | 2437 |
2438 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { | 2438 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { |
2439 // We check the stack limit as indicator that recompilation might be done. | 2439 // We check the stack limit as indicator that recompilation might be done. |
2440 Label ok; | 2440 Label ok; |
2441 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 2441 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
2442 __ j(above_equal, &ok); | 2442 __ j(above_equal, &ok); |
2443 { | 2443 { |
2444 FrameScope scope(masm, StackFrame::INTERNAL); | 2444 FrameScope scope(masm, StackFrame::INTERNAL); |
2445 __ CallRuntime(Runtime::kStackGuard, 0); | 2445 __ CallRuntime(Runtime::kStackGuard); |
2446 } | 2446 } |
2447 __ jmp(masm->isolate()->builtins()->OnStackReplacement(), | 2447 __ jmp(masm->isolate()->builtins()->OnStackReplacement(), |
2448 RelocInfo::CODE_TARGET); | 2448 RelocInfo::CODE_TARGET); |
2449 | 2449 |
2450 __ bind(&ok); | 2450 __ bind(&ok); |
2451 __ ret(0); | 2451 __ ret(0); |
2452 } | 2452 } |
2453 | 2453 |
2454 | 2454 |
2455 #undef __ | 2455 #undef __ |
2456 | 2456 |
2457 } // namespace internal | 2457 } // namespace internal |
2458 } // namespace v8 | 2458 } // namespace v8 |
2459 | 2459 |
2460 #endif // V8_TARGET_ARCH_X64 | 2460 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |