Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: src/full-codegen/x64/full-codegen-x64.cc

Issue 1865833002: [generators] Decouple generator resume from fullcodegen. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 1762 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 1773
1774 1774
1775 void FullCodeGenerator::VisitYield(Yield* expr) { 1775 void FullCodeGenerator::VisitYield(Yield* expr) {
1776 Comment cmnt(masm_, "[ Yield"); 1776 Comment cmnt(masm_, "[ Yield");
1777 SetExpressionPosition(expr); 1777 SetExpressionPosition(expr);
1778 1778
1779 // Evaluate yielded value first; the initial iterator definition depends on 1779 // Evaluate yielded value first; the initial iterator definition depends on
1780 // this. It stays on the stack while we update the iterator. 1780 // this. It stays on the stack while we update the iterator.
1781 VisitForStackValue(expr->expression()); 1781 VisitForStackValue(expr->expression());
1782 1782
1783 Label suspend, continuation, post_runtime, resume; 1783 Label suspend, continuation, post_runtime, resume, exception;
1784 1784
1785 __ jmp(&suspend); 1785 __ jmp(&suspend);
1786 __ bind(&continuation); 1786 __ bind(&continuation);
1787 // When we arrive here, the stack top is the resume mode and 1787 // When we arrive here, the stack top is the resume mode and
1788 // result_register() holds the input value (the argument given to the 1788 // result_register() holds the input value (the argument given to the
1789 // respective resume operation). 1789 // respective resume operation).
1790 __ RecordGeneratorContinuation(); 1790 __ RecordGeneratorContinuation();
1791 __ Pop(rbx); 1791 __ Pop(rbx);
1792 __ SmiCompare(rbx, Smi::FromInt(JSGeneratorObject::RETURN)); 1792 STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
1793 __ j(not_equal, &resume); 1793 STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
1794 __ SmiCompare(rbx, Smi::FromInt(JSGeneratorObject::kReturn));
1795 __ j(less, &resume);
1794 __ Push(result_register()); 1796 __ Push(result_register());
1797 __ j(greater, &exception);
1795 EmitCreateIteratorResult(true); 1798 EmitCreateIteratorResult(true);
1796 EmitUnwindAndReturn(); 1799 EmitUnwindAndReturn();
1797 1800
1801 __ bind(&exception);
1802 __ CallRuntime(Runtime::kThrow);
1803
1798 __ bind(&suspend); 1804 __ bind(&suspend);
1799 OperandStackDepthIncrement(1); // Not popped on this path. 1805 OperandStackDepthIncrement(1); // Not popped on this path.
1800 VisitForAccumulatorValue(expr->generator_object()); 1806 VisitForAccumulatorValue(expr->generator_object());
1801 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1807 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1802 __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset), 1808 __ Move(FieldOperand(rax, JSGeneratorObject::kContinuationOffset),
1803 Smi::FromInt(continuation.pos())); 1809 Smi::FromInt(continuation.pos()));
1804 __ movp(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi); 1810 __ movp(FieldOperand(rax, JSGeneratorObject::kContextOffset), rsi);
1805 __ movp(rcx, rsi); 1811 __ movp(rcx, rsi);
1806 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx, 1812 __ RecordWriteField(rax, JSGeneratorObject::kContextOffset, rcx, rdx,
1807 kDontSaveFPRegs); 1813 kDontSaveFPRegs);
1808 __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset)); 1814 __ leap(rbx, Operand(rbp, StandardFrameConstants::kExpressionsOffset));
1809 __ cmpp(rsp, rbx); 1815 __ cmpp(rsp, rbx);
1810 __ j(equal, &post_runtime); 1816 __ j(equal, &post_runtime);
1811 __ Push(rax); // generator object 1817 __ Push(rax); // generator object
1812 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1818 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1813 __ movp(context_register(), 1819 __ movp(context_register(),
1814 Operand(rbp, StandardFrameConstants::kContextOffset)); 1820 Operand(rbp, StandardFrameConstants::kContextOffset));
1815 __ bind(&post_runtime); 1821 __ bind(&post_runtime);
1816 1822
1817 PopOperand(result_register()); 1823 PopOperand(result_register());
1818 EmitReturnSequence(); 1824 EmitReturnSequence();
1819 1825
1820 __ bind(&resume); 1826 __ bind(&resume);
1821 context()->Plug(result_register()); 1827 context()->Plug(result_register());
1822 } 1828 }
1823 1829
1824
1825 void FullCodeGenerator::EmitGeneratorResume(
1826 Expression* generator, Expression* value,
1827 JSGeneratorObject::ResumeMode resume_mode) {
1828 // The value stays in rax, and is ultimately read by the resumed generator, as
1829 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1830 // is read to throw the value when the resumed generator is already closed.
1831 // rbx will hold the generator object until the activation has been resumed.
1832 VisitForStackValue(generator);
1833 VisitForAccumulatorValue(value);
1834 PopOperand(rbx);
1835
1836 // Store input value into generator object.
1837 __ movp(FieldOperand(rbx, JSGeneratorObject::kInputOffset),
1838 result_register());
1839 __ movp(rcx, result_register());
1840 __ RecordWriteField(rbx, JSGeneratorObject::kInputOffset, rcx, rdx,
1841 kDontSaveFPRegs);
1842
1843 // Load suspended function and context.
1844 __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset));
1845 __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
1846
1847 // Push receiver.
1848 __ Push(FieldOperand(rbx, JSGeneratorObject::kReceiverOffset));
1849
1850 // Push holes for arguments to generator function. Since the parser forced
1851 // context allocation for any variables in generators, the actual argument
1852 // values have already been copied into the context and these dummy values
1853 // will never be used.
1854 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
1855 __ LoadSharedFunctionInfoSpecialField(rdx, rdx,
1856 SharedFunctionInfo::kFormalParameterCountOffset);
1857 __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex);
1858 Label push_argument_holes, push_frame;
1859 __ bind(&push_argument_holes);
1860 __ subp(rdx, Immediate(1));
1861 __ j(carry, &push_frame);
1862 __ Push(rcx);
1863 __ jmp(&push_argument_holes);
1864
1865 // Enter a new JavaScript frame, and initialize its slots as they were when
1866 // the generator was suspended.
1867 Label resume_frame, done;
1868 __ bind(&push_frame);
1869 __ call(&resume_frame);
1870 __ jmp(&done);
1871 __ bind(&resume_frame);
1872 __ pushq(rbp); // Caller's frame pointer.
1873 __ movp(rbp, rsp);
1874 __ Push(rsi); // Callee's context.
1875 __ Push(rdi); // Callee's JS Function.
1876
1877 // Load the operand stack size.
1878 __ movp(rdx, FieldOperand(rbx, JSGeneratorObject::kOperandStackOffset));
1879 __ movp(rdx, FieldOperand(rdx, FixedArray::kLengthOffset));
1880 __ SmiToInteger32(rdx, rdx);
1881
1882 // If we are sending a value and there is no operand stack, we can jump back
1883 // in directly.
1884 if (resume_mode == JSGeneratorObject::NEXT) {
1885 Label slow_resume;
1886 __ cmpp(rdx, Immediate(0));
1887 __ j(not_zero, &slow_resume);
1888 __ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
1889 __ SmiToInteger64(rcx,
1890 FieldOperand(rbx, JSGeneratorObject::kContinuationOffset));
1891 __ addp(rdx, rcx);
1892 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset),
1893 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
1894 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1895 __ jmp(rdx);
1896 __ bind(&slow_resume);
1897 }
1898
1899 // Otherwise, we push holes for the operand stack and call the runtime to fix
1900 // up the stack and the handlers.
1901 Label push_operand_holes, call_resume;
1902 __ bind(&push_operand_holes);
1903 __ subp(rdx, Immediate(1));
1904 __ j(carry, &call_resume);
1905 __ Push(rcx);
1906 __ jmp(&push_operand_holes);
1907 __ bind(&call_resume);
1908 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1909 __ Push(rbx);
1910 __ Push(result_register());
1911 __ Push(Smi::FromInt(resume_mode));
1912 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1913 // Not reached: the runtime call returns elsewhere.
1914 __ Abort(kGeneratorFailedToResume);
1915
1916 __ bind(&done);
1917 context()->Plug(result_register());
1918 }
1919
1920 void FullCodeGenerator::PushOperand(MemOperand operand) { 1830 void FullCodeGenerator::PushOperand(MemOperand operand) {
1921 OperandStackDepthIncrement(1); 1831 OperandStackDepthIncrement(1);
1922 __ Push(operand); 1832 __ Push(operand);
1923 } 1833 }
1924 1834
1925 void FullCodeGenerator::EmitOperandStackDepthCheck() { 1835 void FullCodeGenerator::EmitOperandStackDepthCheck() {
1926 if (FLAG_debug_code) { 1836 if (FLAG_debug_code) {
1927 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + 1837 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
1928 operand_stack_depth_ * kPointerSize; 1838 operand_stack_depth_ * kPointerSize;
1929 __ movp(rax, rbp); 1839 __ movp(rax, rbp);
(...skipping 2040 matching lines...) Expand 10 before | Expand all | Expand 10 after
3970 DCHECK_EQ( 3880 DCHECK_EQ(
3971 isolate->builtins()->OnStackReplacement()->entry(), 3881 isolate->builtins()->OnStackReplacement()->entry(),
3972 Assembler::target_address_at(call_target_address, unoptimized_code)); 3882 Assembler::target_address_at(call_target_address, unoptimized_code));
3973 return ON_STACK_REPLACEMENT; 3883 return ON_STACK_REPLACEMENT;
3974 } 3884 }
3975 3885
3976 } // namespace internal 3886 } // namespace internal
3977 } // namespace v8 3887 } // namespace v8
3978 3888
3979 #endif // V8_TARGET_ARCH_X64 3889 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698