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); |
rmcilroy
2016/04/15 13:17:47
I don't think we need the formal parameter count i
neis
2016/04/18 08:04:17
Benedikt suggested to keep it this way for consist
| |
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 2323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2915 __ ret(0); | 2939 __ ret(0); |
2916 } | 2940 } |
2917 | 2941 |
2918 | 2942 |
2919 #undef __ | 2943 #undef __ |
2920 | 2944 |
2921 } // namespace internal | 2945 } // namespace internal |
2922 } // namespace v8 | 2946 } // namespace v8 |
2923 | 2947 |
2924 #endif // V8_TARGET_ARCH_X64 | 2948 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |