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

Side by Side Diff: src/full-codegen/mips/full-codegen-mips.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_MIPS 5 #if V8_TARGET_ARCH_MIPS
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
(...skipping 1820 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 1831
1832 1832
1833 void FullCodeGenerator::VisitYield(Yield* expr) { 1833 void FullCodeGenerator::VisitYield(Yield* expr) {
1834 Comment cmnt(masm_, "[ Yield"); 1834 Comment cmnt(masm_, "[ Yield");
1835 SetExpressionPosition(expr); 1835 SetExpressionPosition(expr);
1836 1836
1837 // Evaluate yielded value first; the initial iterator definition depends on 1837 // Evaluate yielded value first; the initial iterator definition depends on
1838 // this. It stays on the stack while we update the iterator. 1838 // this. It stays on the stack while we update the iterator.
1839 VisitForStackValue(expr->expression()); 1839 VisitForStackValue(expr->expression());
1840 1840
1841 Label suspend, continuation, post_runtime, resume; 1841 Label suspend, continuation, post_runtime, resume, exception;
1842 1842
1843 __ jmp(&suspend); 1843 __ jmp(&suspend);
1844 __ bind(&continuation); 1844 __ bind(&continuation);
1845 // When we arrive here, the stack top is the resume mode and 1845 // When we arrive here, the stack top is the resume mode and
1846 // result_register() holds the input value (the argument given to the 1846 // result_register() holds the input value (the argument given to the
1847 // respective resume operation). 1847 // respective resume operation).
1848 __ RecordGeneratorContinuation(); 1848 __ RecordGeneratorContinuation();
1849 __ pop(a1); 1849 __ pop(a1);
1850 __ Branch(&resume, ne, a1, Operand(Smi::FromInt(JSGeneratorObject::RETURN))); 1850 __ Branch(&resume, eq, a1, Operand(Smi::FromInt(JSGeneratorObject::kNext)));
1851 __ push(result_register()); 1851 __ Push(result_register());
1852 __ Branch(&exception, eq, a1,
1853 Operand(Smi::FromInt(JSGeneratorObject::kThrow)));
1852 EmitCreateIteratorResult(true); 1854 EmitCreateIteratorResult(true);
1853 EmitUnwindAndReturn(); 1855 EmitUnwindAndReturn();
1854 1856
1857 __ bind(&exception);
1858 __ CallRuntime(Runtime::kThrow);
1859
1855 __ bind(&suspend); 1860 __ bind(&suspend);
1856 OperandStackDepthIncrement(1); // Not popped on this path. 1861 OperandStackDepthIncrement(1); // Not popped on this path.
1857 VisitForAccumulatorValue(expr->generator_object()); 1862 VisitForAccumulatorValue(expr->generator_object());
1858 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1863 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1859 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); 1864 __ li(a1, Operand(Smi::FromInt(continuation.pos())));
1860 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); 1865 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset));
1861 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); 1866 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
1862 __ mov(a1, cp); 1867 __ mov(a1, cp);
1863 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, 1868 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
1864 kRAHasBeenSaved, kDontSaveFPRegs); 1869 kRAHasBeenSaved, kDontSaveFPRegs);
1865 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1870 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1866 __ Branch(&post_runtime, eq, sp, Operand(a1)); 1871 __ Branch(&post_runtime, eq, sp, Operand(a1));
1867 __ push(v0); // generator object 1872 __ push(v0); // generator object
1868 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1873 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1869 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1874 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1870 __ bind(&post_runtime); 1875 __ bind(&post_runtime);
1871 PopOperand(result_register()); 1876 PopOperand(result_register());
1872 EmitReturnSequence(); 1877 EmitReturnSequence();
1873 1878
1874 __ bind(&resume); 1879 __ bind(&resume);
1875 context()->Plug(result_register()); 1880 context()->Plug(result_register());
1876 } 1881 }
1877 1882
1878
1879 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1880 Expression *value,
1881 JSGeneratorObject::ResumeMode resume_mode) {
1882 // The value stays in a0, and is ultimately read by the resumed generator, as
1883 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1884 // is read to throw the value when the resumed generator is already closed.
1885 // a1 will hold the generator object until the activation has been resumed.
1886 VisitForStackValue(generator);
1887 VisitForAccumulatorValue(value);
1888 PopOperand(a1);
1889
1890 // Store input value into generator object.
1891 __ sw(result_register(),
1892 FieldMemOperand(a1, JSGeneratorObject::kInputOffset));
1893 __ mov(a2, result_register());
1894 __ RecordWriteField(a1, JSGeneratorObject::kInputOffset, a2, a3,
1895 kRAHasBeenSaved, kDontSaveFPRegs);
1896
1897 // Load suspended function and context.
1898 __ lw(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset));
1899 __ lw(t0, FieldMemOperand(a1, JSGeneratorObject::kFunctionOffset));
1900
1901 // Load receiver and store as the first argument.
1902 __ lw(a2, FieldMemOperand(a1, JSGeneratorObject::kReceiverOffset));
1903 __ push(a2);
1904
1905 // Push holes for arguments to generator function. Since the parser forced
1906 // context allocation for any variables in generators, the actual argument
1907 // values have already been copied into the context and these dummy values
1908 // will never be used.
1909 __ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
1910 __ lw(a3,
1911 FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset));
1912 __ LoadRoot(a2, Heap::kTheHoleValueRootIndex);
1913 Label push_argument_holes, push_frame;
1914 __ bind(&push_argument_holes);
1915 __ Subu(a3, a3, Operand(Smi::FromInt(1)));
1916 __ Branch(&push_frame, lt, a3, Operand(zero_reg));
1917 __ push(a2);
1918 __ jmp(&push_argument_holes);
1919
1920 // Enter a new JavaScript frame, and initialize its slots as they were when
1921 // the generator was suspended.
1922 Label resume_frame, done;
1923 __ bind(&push_frame);
1924 __ Call(&resume_frame);
1925 __ jmp(&done);
1926 __ bind(&resume_frame);
1927 // ra = return address.
1928 // fp = caller's frame pointer.
1929 // cp = callee's context,
1930 // t0 = callee's JS function.
1931 __ PushStandardFrame(t0);
1932
1933 // Load the operand stack size.
1934 __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kOperandStackOffset));
1935 __ lw(a3, FieldMemOperand(a3, FixedArray::kLengthOffset));
1936 __ SmiUntag(a3);
1937
1938 // If we are sending a value and there is no operand stack, we can jump back
1939 // in directly.
1940 if (resume_mode == JSGeneratorObject::NEXT) {
1941 Label slow_resume;
1942 __ Branch(&slow_resume, ne, a3, Operand(zero_reg));
1943 __ lw(a3, FieldMemOperand(t0, JSFunction::kCodeEntryOffset));
1944 __ lw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset));
1945 __ SmiUntag(a2);
1946 __ Addu(a3, a3, Operand(a2));
1947 __ li(a2, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
1948 __ sw(a2, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset));
1949 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1950 __ Jump(a3);
1951 __ bind(&slow_resume);
1952 }
1953
1954 // Otherwise, we push holes for the operand stack and call the runtime to fix
1955 // up the stack and the handlers.
1956 Label push_operand_holes, call_resume;
1957 __ bind(&push_operand_holes);
1958 __ Subu(a3, a3, Operand(1));
1959 __ Branch(&call_resume, lt, a3, Operand(zero_reg));
1960 __ push(a2);
1961 __ Branch(&push_operand_holes);
1962 __ bind(&call_resume);
1963 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1964 DCHECK(!result_register().is(a1));
1965 __ Push(a1, result_register());
1966 __ Push(Smi::FromInt(resume_mode));
1967 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1968 // Not reached: the runtime call returns elsewhere.
1969 __ stop("not-reached");
1970
1971 __ bind(&done);
1972 context()->Plug(result_register());
1973 }
1974
1975 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { 1883 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
1976 OperandStackDepthIncrement(2); 1884 OperandStackDepthIncrement(2);
1977 __ Push(reg1, reg2); 1885 __ Push(reg1, reg2);
1978 } 1886 }
1979 1887
1980 void FullCodeGenerator::PushOperands(Register reg1, Register reg2, 1888 void FullCodeGenerator::PushOperands(Register reg1, Register reg2,
1981 Register reg3) { 1889 Register reg3) {
1982 OperandStackDepthIncrement(3); 1890 OperandStackDepthIncrement(3);
1983 __ Push(reg1, reg2, reg3); 1891 __ Push(reg1, reg2, reg3);
1984 } 1892 }
(...skipping 2117 matching lines...) Expand 10 before | Expand all | Expand 10 after
4102 reinterpret_cast<uint32_t>( 4010 reinterpret_cast<uint32_t>(
4103 isolate->builtins()->OnStackReplacement()->entry())); 4011 isolate->builtins()->OnStackReplacement()->entry()));
4104 return ON_STACK_REPLACEMENT; 4012 return ON_STACK_REPLACEMENT;
4105 } 4013 }
4106 4014
4107 4015
4108 } // namespace internal 4016 } // namespace internal
4109 } // namespace v8 4017 } // namespace v8
4110 4018
4111 #endif // V8_TARGET_ARCH_MIPS 4019 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698