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

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

Issue 1889083002: X87: [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
« no previous file with comments | « no previous file | src/x87/builtins-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_X87 5 #if V8_TARGET_ARCH_X87
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 1731 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 1742
1743 1743
1744 void FullCodeGenerator::VisitYield(Yield* expr) { 1744 void FullCodeGenerator::VisitYield(Yield* expr) {
1745 Comment cmnt(masm_, "[ Yield"); 1745 Comment cmnt(masm_, "[ Yield");
1746 SetExpressionPosition(expr); 1746 SetExpressionPosition(expr);
1747 1747
1748 // Evaluate yielded value first; the initial iterator definition depends on 1748 // Evaluate yielded value first; the initial iterator definition depends on
1749 // this. It stays on the stack while we update the iterator. 1749 // this. It stays on the stack while we update the iterator.
1750 VisitForStackValue(expr->expression()); 1750 VisitForStackValue(expr->expression());
1751 1751
1752 Label suspend, continuation, post_runtime, resume; 1752 Label suspend, continuation, post_runtime, resume, exception;
1753 1753
1754 __ jmp(&suspend); 1754 __ jmp(&suspend);
1755 __ bind(&continuation); 1755 __ bind(&continuation);
1756 // When we arrive here, the stack top is the resume mode and 1756 // When we arrive here, the stack top is the resume mode and
1757 // result_register() holds the input value (the argument given to the 1757 // result_register() holds the input value (the argument given to the
1758 // respective resume operation). 1758 // respective resume operation).
1759 __ RecordGeneratorContinuation(); 1759 __ RecordGeneratorContinuation();
1760 __ pop(ebx); 1760 __ pop(ebx);
1761 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::RETURN))); 1761 STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
1762 __ j(not_equal, &resume); 1762 STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
1763 __ push(result_register()); 1763 __ cmp(ebx, Immediate(Smi::FromInt(JSGeneratorObject::kReturn)));
1764 __ j(less, &resume);
1765 __ Push(result_register());
1766 __ j(greater, &exception);
1764 EmitCreateIteratorResult(true); 1767 EmitCreateIteratorResult(true);
1765 EmitUnwindAndReturn(); 1768 EmitUnwindAndReturn();
1766 1769
1770 __ bind(&exception);
1771 __ CallRuntime(Runtime::kThrow);
1772
1767 __ bind(&suspend); 1773 __ bind(&suspend);
1768 OperandStackDepthIncrement(1); // Not popped on this path. 1774 OperandStackDepthIncrement(1); // Not popped on this path.
1769 VisitForAccumulatorValue(expr->generator_object()); 1775 VisitForAccumulatorValue(expr->generator_object());
1770 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1776 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1771 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), 1777 __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset),
1772 Immediate(Smi::FromInt(continuation.pos()))); 1778 Immediate(Smi::FromInt(continuation.pos())));
1773 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); 1779 __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi);
1774 __ mov(ecx, esi); 1780 __ mov(ecx, esi);
1775 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 1781 __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx,
1776 kDontSaveFPRegs); 1782 kDontSaveFPRegs);
1777 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1783 __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset));
1778 __ cmp(esp, ebx); 1784 __ cmp(esp, ebx);
1779 __ j(equal, &post_runtime); 1785 __ j(equal, &post_runtime);
1780 __ push(eax); // generator object 1786 __ push(eax); // generator object
1781 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1787 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1782 __ mov(context_register(), 1788 __ mov(context_register(),
1783 Operand(ebp, StandardFrameConstants::kContextOffset)); 1789 Operand(ebp, StandardFrameConstants::kContextOffset));
1784 __ bind(&post_runtime); 1790 __ bind(&post_runtime);
1785 PopOperand(result_register()); 1791 PopOperand(result_register());
1786 EmitReturnSequence(); 1792 EmitReturnSequence();
1787 1793
1788 __ bind(&resume); 1794 __ bind(&resume);
1789 context()->Plug(result_register()); 1795 context()->Plug(result_register());
1790 } 1796 }
1791 1797
1792
1793 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1794 Expression *value,
1795 JSGeneratorObject::ResumeMode resume_mode) {
1796 // The value stays in eax, and is ultimately read by the resumed generator, as
1797 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1798 // is read to throw the value when the resumed generator is already closed.
1799 // ebx will hold the generator object until the activation has been resumed.
1800 VisitForStackValue(generator);
1801 VisitForAccumulatorValue(value);
1802 PopOperand(ebx);
1803
1804 // Store input value into generator object.
1805 __ mov(FieldOperand(ebx, JSGeneratorObject::kInputOffset), result_register());
1806 __ mov(ecx, result_register());
1807 __ RecordWriteField(ebx, JSGeneratorObject::kInputOffset, ecx, edx,
1808 kDontSaveFPRegs);
1809
1810 // Load suspended function and context.
1811 __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
1812 __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
1813
1814 // Push receiver.
1815 __ push(FieldOperand(ebx, JSGeneratorObject::kReceiverOffset));
1816
1817 // Push holes for arguments to generator function. Since the parser forced
1818 // context allocation for any variables in generators, the actual argument
1819 // values have already been copied into the context and these dummy values
1820 // will never be used.
1821 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1822 __ mov(edx,
1823 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
1824 __ mov(ecx, isolate()->factory()->the_hole_value());
1825 Label push_argument_holes, push_frame;
1826 __ bind(&push_argument_holes);
1827 __ sub(edx, Immediate(Smi::FromInt(1)));
1828 __ j(carry, &push_frame);
1829 __ push(ecx);
1830 __ jmp(&push_argument_holes);
1831
1832 // Enter a new JavaScript frame, and initialize its slots as they were when
1833 // the generator was suspended.
1834 Label resume_frame, done;
1835 __ bind(&push_frame);
1836 __ call(&resume_frame);
1837 __ jmp(&done);
1838 __ bind(&resume_frame);
1839 __ push(ebp); // Caller's frame pointer.
1840 __ mov(ebp, esp);
1841 __ push(esi); // Callee's context.
1842 __ push(edi); // Callee's JS Function.
1843
1844 // Load the operand stack size.
1845 __ mov(edx, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset));
1846 __ mov(edx, FieldOperand(edx, FixedArray::kLengthOffset));
1847 __ SmiUntag(edx);
1848
1849 // If we are sending a value and there is no operand stack, we can jump back
1850 // in directly.
1851 if (resume_mode == JSGeneratorObject::NEXT) {
1852 Label slow_resume;
1853 __ cmp(edx, Immediate(0));
1854 __ j(not_zero, &slow_resume);
1855 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
1856 __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset));
1857 __ SmiUntag(ecx);
1858 __ add(edx, ecx);
1859 __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset),
1860 Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
1861 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1862 __ jmp(edx);
1863 __ bind(&slow_resume);
1864 }
1865
1866 // Otherwise, we push holes for the operand stack and call the runtime to fix
1867 // up the stack and the handlers.
1868 Label push_operand_holes, call_resume;
1869 __ bind(&push_operand_holes);
1870 __ sub(edx, Immediate(1));
1871 __ j(carry, &call_resume);
1872 __ push(ecx);
1873 __ jmp(&push_operand_holes);
1874 __ bind(&call_resume);
1875 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1876 __ push(ebx);
1877 __ push(result_register());
1878 __ Push(Smi::FromInt(resume_mode));
1879 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1880 // Not reached: the runtime call returns elsewhere.
1881 __ Abort(kGeneratorFailedToResume);
1882
1883 __ bind(&done);
1884 context()->Plug(result_register());
1885 }
1886
1887 void FullCodeGenerator::PushOperand(MemOperand operand) { 1798 void FullCodeGenerator::PushOperand(MemOperand operand) {
1888 OperandStackDepthIncrement(1); 1799 OperandStackDepthIncrement(1);
1889 __ Push(operand); 1800 __ Push(operand);
1890 } 1801 }
1891 1802
1892 void FullCodeGenerator::EmitOperandStackDepthCheck() { 1803 void FullCodeGenerator::EmitOperandStackDepthCheck() {
1893 if (FLAG_debug_code) { 1804 if (FLAG_debug_code) {
1894 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp + 1805 int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
1895 operand_stack_depth_ * kPointerSize; 1806 operand_stack_depth_ * kPointerSize;
1896 __ mov(eax, ebp); 1807 __ mov(eax, ebp);
(...skipping 2081 matching lines...) Expand 10 before | Expand all | Expand 10 after
3978 isolate->builtins()->OnStackReplacement()->entry(), 3889 isolate->builtins()->OnStackReplacement()->entry(),
3979 Assembler::target_address_at(call_target_address, unoptimized_code)); 3890 Assembler::target_address_at(call_target_address, unoptimized_code));
3980 return ON_STACK_REPLACEMENT; 3891 return ON_STACK_REPLACEMENT;
3981 } 3892 }
3982 3893
3983 3894
3984 } // namespace internal 3895 } // namespace internal
3985 } // namespace v8 3896 } // namespace v8
3986 3897
3987 #endif // V8_TARGET_ARCH_X87 3898 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | src/x87/builtins-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698