Chromium Code Reviews| 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 |