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

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

Powered by Google App Engine
This is Rietveld 408576698