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

Side by Side Diff: src/full-codegen/arm/full-codegen-arm.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_ARM 5 #if V8_TARGET_ARCH_ARM
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 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 1833
1834 1834
1835 void FullCodeGenerator::VisitYield(Yield* expr) { 1835 void FullCodeGenerator::VisitYield(Yield* expr) {
1836 Comment cmnt(masm_, "[ Yield"); 1836 Comment cmnt(masm_, "[ Yield");
1837 SetExpressionPosition(expr); 1837 SetExpressionPosition(expr);
1838 1838
1839 // Evaluate yielded value first; the initial iterator definition depends on 1839 // Evaluate yielded value first; the initial iterator definition depends on
1840 // this. It stays on the stack while we update the iterator. 1840 // this. It stays on the stack while we update the iterator.
1841 VisitForStackValue(expr->expression()); 1841 VisitForStackValue(expr->expression());
1842 1842
1843 Label suspend, continuation, post_runtime, resume; 1843 Label suspend, continuation, post_runtime, resume, exception;
1844 1844
1845 __ jmp(&suspend); 1845 __ jmp(&suspend);
1846 __ bind(&continuation); 1846 __ bind(&continuation);
1847 // When we arrive here, the stack top is the resume mode and 1847 // When we arrive here, the stack top is the resume mode and
1848 // result_register() holds the input value (the argument given to the 1848 // result_register() holds the input value (the argument given to the
1849 // respective resume operation). 1849 // respective resume operation).
1850 __ RecordGeneratorContinuation(); 1850 __ RecordGeneratorContinuation();
1851 __ pop(r1); 1851 __ pop(r1);
1852 __ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::RETURN))); 1852 STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
1853 __ b(ne, &resume); 1853 STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
1854 __ push(result_register()); 1854 __ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
1855 __ b(lt, &resume);
1856 __ Push(result_register());
1857 __ b(gt, &exception);
1855 EmitCreateIteratorResult(true); 1858 EmitCreateIteratorResult(true);
1856 EmitUnwindAndReturn(); 1859 EmitUnwindAndReturn();
1857 1860
1861 __ bind(&exception);
1862 __ CallRuntime(Runtime::kThrow);
1863
1858 __ bind(&suspend); 1864 __ bind(&suspend);
1859 OperandStackDepthIncrement(1); // Not popped on this path. 1865 OperandStackDepthIncrement(1); // Not popped on this path.
1860 VisitForAccumulatorValue(expr->generator_object()); 1866 VisitForAccumulatorValue(expr->generator_object());
1861 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1867 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1862 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); 1868 __ mov(r1, Operand(Smi::FromInt(continuation.pos())));
1863 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); 1869 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset));
1864 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); 1870 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset));
1865 __ mov(r1, cp); 1871 __ mov(r1, cp);
1866 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, 1872 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2,
1867 kLRHasBeenSaved, kDontSaveFPRegs); 1873 kLRHasBeenSaved, kDontSaveFPRegs);
1868 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1874 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1869 __ cmp(sp, r1); 1875 __ cmp(sp, r1);
1870 __ b(eq, &post_runtime); 1876 __ b(eq, &post_runtime);
1871 __ push(r0); // generator object 1877 __ push(r0); // generator object
1872 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1878 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1873 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1879 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1874 __ bind(&post_runtime); 1880 __ bind(&post_runtime);
1875 PopOperand(result_register()); 1881 PopOperand(result_register());
1876 EmitReturnSequence(); 1882 EmitReturnSequence();
1877 1883
1878 __ bind(&resume); 1884 __ bind(&resume);
1879 context()->Plug(result_register()); 1885 context()->Plug(result_register());
1880 } 1886 }
1881 1887
1882
1883 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
1884 Expression *value,
1885 JSGeneratorObject::ResumeMode resume_mode) {
1886 // The value stays in r0, and is ultimately read by the resumed generator, as
1887 // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
1888 // is read to throw the value when the resumed generator is already closed.
1889 // r1 will hold the generator object until the activation has been resumed.
1890 VisitForStackValue(generator);
1891 VisitForAccumulatorValue(value);
1892 PopOperand(r1);
1893
1894 // Store input value into generator object.
1895 __ str(result_register(),
1896 FieldMemOperand(r1, JSGeneratorObject::kInputOffset));
1897 __ mov(r2, result_register());
1898 __ RecordWriteField(r1, JSGeneratorObject::kInputOffset, r2, r3,
1899 kLRHasBeenSaved, kDontSaveFPRegs);
1900
1901 // Load suspended function and context.
1902 __ ldr(cp, FieldMemOperand(r1, JSGeneratorObject::kContextOffset));
1903 __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
1904
1905 // Load receiver and store as the first argument.
1906 __ ldr(r2, FieldMemOperand(r1, JSGeneratorObject::kReceiverOffset));
1907 __ push(r2);
1908
1909 // Push holes for arguments to generator function. Since the parser forced
1910 // context allocation for any variables in generators, the actual argument
1911 // values have already been copied into the context and these dummy values
1912 // will never be used.
1913 __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
1914 __ ldr(r3,
1915 FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset));
1916 __ LoadRoot(r2, Heap::kTheHoleValueRootIndex);
1917 Label push_argument_holes, push_frame;
1918 __ bind(&push_argument_holes);
1919 __ sub(r3, r3, Operand(Smi::FromInt(1)), SetCC);
1920 __ b(mi, &push_frame);
1921 __ push(r2);
1922 __ jmp(&push_argument_holes);
1923
1924 // Enter a new JavaScript frame, and initialize its slots as they were when
1925 // the generator was suspended.
1926 Label resume_frame, done;
1927 __ bind(&push_frame);
1928 __ bl(&resume_frame);
1929 __ jmp(&done);
1930 __ bind(&resume_frame);
1931 // lr = return address.
1932 // fp = caller's frame pointer.
1933 // pp = caller's constant pool (if FLAG_enable_embedded_constant_pool),
1934 // cp = callee's context,
1935 // r4 = callee's JS function.
1936 __ PushStandardFrame(r4);
1937
1938 // Load the operand stack size.
1939 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset));
1940 __ ldr(r3, FieldMemOperand(r3, FixedArray::kLengthOffset));
1941 __ SmiUntag(r3);
1942
1943 // If we are sending a value and there is no operand stack, we can jump back
1944 // in directly.
1945 if (resume_mode == JSGeneratorObject::NEXT) {
1946 Label slow_resume;
1947 __ cmp(r3, Operand(0));
1948 __ b(ne, &slow_resume);
1949 __ ldr(r3, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
1950
1951 { ConstantPoolUnavailableScope constant_pool_unavailable(masm_);
1952 if (FLAG_enable_embedded_constant_pool) {
1953 // Load the new code object's constant pool pointer.
1954 __ LoadConstantPoolPointerRegisterFromCodeTargetAddress(r3);
1955 }
1956
1957 __ ldr(r2, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset));
1958 __ SmiUntag(r2);
1959 __ add(r3, r3, r2);
1960 __ mov(r2, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
1961 __ str(r2, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset));
1962 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1963 __ Jump(r3);
1964 }
1965 __ bind(&slow_resume);
1966 }
1967
1968 // Otherwise, we push holes for the operand stack and call the runtime to fix
1969 // up the stack and the handlers.
1970 Label push_operand_holes, call_resume;
1971 __ bind(&push_operand_holes);
1972 __ sub(r3, r3, Operand(1), SetCC);
1973 __ b(mi, &call_resume);
1974 __ push(r2);
1975 __ b(&push_operand_holes);
1976 __ bind(&call_resume);
1977 __ Push(Smi::FromInt(resume_mode)); // Consumed in continuation.
1978 DCHECK(!result_register().is(r1));
1979 __ Push(r1, result_register());
1980 __ Push(Smi::FromInt(resume_mode));
1981 __ CallRuntime(Runtime::kResumeJSGeneratorObject);
1982 // Not reached: the runtime call returns elsewhere.
1983 __ stop("not-reached");
1984
1985 __ bind(&done);
1986 context()->Plug(result_register());
1987 }
1988
1989 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { 1888 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
1990 OperandStackDepthIncrement(2); 1889 OperandStackDepthIncrement(2);
1991 __ Push(reg1, reg2); 1890 __ Push(reg1, reg2);
1992 } 1891 }
1993 1892
1994 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) { 1893 void FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
1995 OperandStackDepthDecrement(2); 1894 OperandStackDepthDecrement(2);
1996 __ Pop(reg1, reg2); 1895 __ Pop(reg1, reg2);
1997 } 1896 }
1998 1897
(...skipping 2157 matching lines...) Expand 10 before | Expand all | Expand 10 after
4156 DCHECK(interrupt_address == 4055 DCHECK(interrupt_address ==
4157 isolate->builtins()->OnStackReplacement()->entry()); 4056 isolate->builtins()->OnStackReplacement()->entry());
4158 return ON_STACK_REPLACEMENT; 4057 return ON_STACK_REPLACEMENT;
4159 } 4058 }
4160 4059
4161 4060
4162 } // namespace internal 4061 } // namespace internal
4163 } // namespace v8 4062 } // namespace v8
4164 4063
4165 #endif // V8_TARGET_ARCH_ARM 4064 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698