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 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 { | 530 { |
531 Label done_loop, loop; | 531 Label done_loop, loop; |
532 __ bind(&loop); | 532 __ bind(&loop); |
533 __ subl(rcx, Immediate(1)); | 533 __ subl(rcx, Immediate(1)); |
534 __ j(carry, &done_loop, Label::kNear); | 534 __ j(carry, &done_loop, Label::kNear); |
535 __ PushRoot(Heap::kTheHoleValueRootIndex); | 535 __ PushRoot(Heap::kTheHoleValueRootIndex); |
536 __ jmp(&loop); | 536 __ jmp(&loop); |
537 __ bind(&done_loop); | 537 __ bind(&done_loop); |
538 } | 538 } |
539 | 539 |
540 // Enter a new JavaScript frame, and initialize its slots as they were when | 540 // Dispatch on the kind of generator object. |
541 // the generator was suspended. | 541 Label old_generator; |
542 FrameScope scope(masm, StackFrame::MANUAL); | 542 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
543 __ PushReturnAddressFrom(rax); // Return address. | 543 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kFunctionDataOffset)); |
544 __ Push(rbp); // Caller's frame pointer. | 544 __ CmpObjectType(rcx, BYTECODE_ARRAY_TYPE, rcx); |
545 __ Move(rbp, rsp); | 545 __ j(not_equal, &old_generator); |
546 __ Push(rsi); // Callee's context. | |
547 __ Push(rdi); // Callee's JS Function. | |
548 | 546 |
549 // Restore the operand stack. | 547 // New-style (ignition/turbofan) generator object. |
550 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset)); | |
551 __ SmiToInteger32(rax, FieldOperand(rsi, FixedArray::kLengthOffset)); | |
552 { | 548 { |
553 Label done_loop, loop; | 549 __ PushReturnAddressFrom(rax); |
554 __ Set(rcx, 0); | 550 __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
555 __ bind(&loop); | 551 __ LoadSharedFunctionInfoSpecialField( |
556 __ cmpl(rcx, rax); | 552 rax, rax, SharedFunctionInfo::kFormalParameterCountOffset); |
557 __ j(equal, &done_loop, Label::kNear); | 553 // We abuse new.target both to indicate that this is a resume call and to |
558 __ Push( | 554 // pass in the generator object. In ordinary calls, new.target is always |
559 FieldOperand(rsi, rcx, times_pointer_size, FixedArray::kHeaderSize)); | 555 // undefined because generator functions are non-constructable. |
560 __ addl(rcx, Immediate(1)); | 556 __ movp(rdx, rbx); |
561 __ jmp(&loop); | 557 __ jmp(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
562 __ bind(&done_loop); | |
563 } | 558 } |
564 | 559 |
565 // Reset operand stack so we don't leak. | 560 // Old-style (full-codegen) generator object. |
566 __ LoadRoot(FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset), | 561 __ bind(&old_generator); |
567 Heap::kEmptyFixedArrayRootIndex); | 562 { |
| 563 // Enter a new JavaScript frame, and initialize its slots as they were when |
| 564 // the generator was suspended. |
| 565 FrameScope scope(masm, StackFrame::MANUAL); |
| 566 __ PushReturnAddressFrom(rax); // Return address. |
| 567 __ Push(rbp); // Caller's frame pointer. |
| 568 __ Move(rbp, rsp); |
| 569 __ Push(rsi); // Callee's context. |
| 570 __ Push(rdi); // Callee's JS Function. |
568 | 571 |
569 // Restore context. | 572 // Restore the operand stack. |
570 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); | 573 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset)); |
| 574 __ SmiToInteger32(rax, FieldOperand(rsi, FixedArray::kLengthOffset)); |
| 575 { |
| 576 Label done_loop, loop; |
| 577 __ Set(rcx, 0); |
| 578 __ bind(&loop); |
| 579 __ cmpl(rcx, rax); |
| 580 __ j(equal, &done_loop, Label::kNear); |
| 581 __ Push( |
| 582 FieldOperand(rsi, rcx, times_pointer_size, FixedArray::kHeaderSize)); |
| 583 __ addl(rcx, Immediate(1)); |
| 584 __ jmp(&loop); |
| 585 __ bind(&done_loop); |
| 586 } |
571 | 587 |
572 // Resume the generator function at the continuation. | 588 // Reset operand stack so we don't leak. |
573 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 589 __ LoadRoot(FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset), |
574 __ movp(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); | 590 Heap::kEmptyFixedArrayRootIndex); |
575 __ SmiToInteger64(rcx, | 591 |
576 FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); | 592 // Restore context. |
577 __ leap(rdx, FieldOperand(rdx, rcx, times_1, Code::kHeaderSize)); | 593 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset)); |
578 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), | 594 |
579 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); | 595 // Resume the generator function at the continuation. |
580 __ movp(rax, rbx); // Continuation expects generator object in rax. | 596 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
581 __ jmp(rdx); | 597 __ movp(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); |
| 598 __ SmiToInteger64( |
| 599 rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); |
| 600 __ leap(rdx, FieldOperand(rdx, rcx, times_1, Code::kHeaderSize)); |
| 601 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), |
| 602 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); |
| 603 __ movp(rax, rbx); // Continuation expects generator object in rax. |
| 604 __ jmp(rdx); |
| 605 } |
582 } | 606 } |
583 | 607 |
584 // Generate code for entering a JS function with the interpreter. | 608 // Generate code for entering a JS function with the interpreter. |
585 // On entry to the function the receiver and arguments have been pushed on the | 609 // On entry to the function the receiver and arguments have been pushed on the |
586 // stack left to right. The actual argument count matches the formal parameter | 610 // stack left to right. The actual argument count matches the formal parameter |
587 // count expected by the function. | 611 // count expected by the function. |
588 // | 612 // |
589 // The live registers are: | 613 // The live registers are: |
590 // o rdi: the JS function object being called | 614 // o rdi: the JS function object being called |
591 // o rdx: the new target | 615 // o rdx: the new target |
(...skipping 2315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2907 __ ret(0); | 2931 __ ret(0); |
2908 } | 2932 } |
2909 | 2933 |
2910 | 2934 |
2911 #undef __ | 2935 #undef __ |
2912 | 2936 |
2913 } // namespace internal | 2937 } // namespace internal |
2914 } // namespace v8 | 2938 } // namespace v8 |
2915 | 2939 |
2916 #endif // V8_TARGET_ARCH_X64 | 2940 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |