OLD | NEW |
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 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 983 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
984 } | 984 } |
985 | 985 |
986 | 986 |
987 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 987 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
988 Comment cmnt(masm_, "[ ForInStatement"); | 988 Comment cmnt(masm_, "[ ForInStatement"); |
989 SetStatementPosition(stmt, SKIP_BREAK); | 989 SetStatementPosition(stmt, SKIP_BREAK); |
990 | 990 |
991 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 991 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
992 | 992 |
993 Label loop, exit; | |
994 ForIn loop_statement(this, stmt); | |
995 increment_loop_depth(); | |
996 | |
997 // Get the object to enumerate over. If the object is null or undefined, skip | 993 // Get the object to enumerate over. If the object is null or undefined, skip |
998 // over the loop. See ECMA-262 version 5, section 12.6.4. | 994 // over the loop. See ECMA-262 version 5, section 12.6.4. |
999 SetExpressionAsStatementPosition(stmt->enumerable()); | 995 SetExpressionAsStatementPosition(stmt->enumerable()); |
1000 VisitForAccumulatorValue(stmt->enumerable()); | 996 VisitForAccumulatorValue(stmt->enumerable()); |
1001 __ mov(a0, result_register()); | 997 __ mov(a0, result_register()); |
1002 OperandStackDepthIncrement(ForIn::kElementCount); | 998 OperandStackDepthIncrement(5); |
| 999 |
| 1000 Label loop, exit; |
| 1001 Iteration loop_statement(this, stmt); |
| 1002 increment_loop_depth(); |
1003 | 1003 |
1004 // If the object is null or undefined, skip over the loop, otherwise convert | 1004 // If the object is null or undefined, skip over the loop, otherwise convert |
1005 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 1005 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
1006 Label convert, done_convert; | 1006 Label convert, done_convert; |
1007 __ JumpIfSmi(a0, &convert); | 1007 __ JumpIfSmi(a0, &convert); |
1008 __ GetObjectType(a0, a1, a1); | 1008 __ GetObjectType(a0, a1, a1); |
1009 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, | 1009 __ Branch(USE_DELAY_SLOT, &done_convert, ge, a1, |
1010 Operand(FIRST_JS_RECEIVER_TYPE)); | 1010 Operand(FIRST_JS_RECEIVER_TYPE)); |
1011 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. | 1011 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. |
1012 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); | 1012 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); |
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1881 SetExpressionPosition(expr); | 1881 SetExpressionPosition(expr); |
1882 | 1882 |
1883 // Evaluate yielded value first; the initial iterator definition depends on | 1883 // Evaluate yielded value first; the initial iterator definition depends on |
1884 // this. It stays on the stack while we update the iterator. | 1884 // this. It stays on the stack while we update the iterator. |
1885 VisitForStackValue(expr->expression()); | 1885 VisitForStackValue(expr->expression()); |
1886 | 1886 |
1887 switch (expr->yield_kind()) { | 1887 switch (expr->yield_kind()) { |
1888 case Yield::kSuspend: | 1888 case Yield::kSuspend: |
1889 // Pop value from top-of-stack slot; box result into result register. | 1889 // Pop value from top-of-stack slot; box result into result register. |
1890 EmitCreateIteratorResult(false); | 1890 EmitCreateIteratorResult(false); |
1891 __ push(result_register()); | 1891 PushOperand(result_register()); |
1892 // Fall through. | 1892 // Fall through. |
1893 case Yield::kInitial: { | 1893 case Yield::kInitial: { |
1894 Label suspend, continuation, post_runtime, resume; | 1894 Label suspend, continuation, post_runtime, resume; |
1895 | 1895 |
1896 __ jmp(&suspend); | 1896 __ jmp(&suspend); |
1897 __ bind(&continuation); | 1897 __ bind(&continuation); |
1898 // When we arrive here, the stack top is the resume mode and | 1898 // When we arrive here, the stack top is the resume mode and |
1899 // result_register() holds the input value (the argument given to the | 1899 // result_register() holds the input value (the argument given to the |
1900 // respective resume operation). | 1900 // respective resume operation). |
1901 __ RecordGeneratorContinuation(); | 1901 __ RecordGeneratorContinuation(); |
1902 __ pop(a1); | 1902 __ pop(a1); |
1903 __ Branch(&resume, ne, a1, | 1903 __ Branch(&resume, ne, a1, |
1904 Operand(Smi::FromInt(JSGeneratorObject::RETURN))); | 1904 Operand(Smi::FromInt(JSGeneratorObject::RETURN))); |
1905 __ push(result_register()); | 1905 __ push(result_register()); |
1906 EmitCreateIteratorResult(true); | 1906 EmitCreateIteratorResult(true); |
1907 EmitUnwindAndReturn(); | 1907 EmitUnwindAndReturn(); |
1908 | 1908 |
1909 __ bind(&suspend); | 1909 __ bind(&suspend); |
| 1910 OperandStackDepthIncrement(1); // Not popped on this path. |
1910 VisitForAccumulatorValue(expr->generator_object()); | 1911 VisitForAccumulatorValue(expr->generator_object()); |
1911 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); | 1912 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); |
1912 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); | 1913 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); |
1913 __ sd(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); | 1914 __ sd(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); |
1914 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); | 1915 __ sd(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); |
1915 __ mov(a1, cp); | 1916 __ mov(a1, cp); |
1916 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, | 1917 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, |
1917 kRAHasBeenSaved, kDontSaveFPRegs); | 1918 kRAHasBeenSaved, kDontSaveFPRegs); |
1918 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); | 1919 __ Daddu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); |
1919 __ Branch(&post_runtime, eq, sp, Operand(a1)); | 1920 __ Branch(&post_runtime, eq, sp, Operand(a1)); |
1920 __ push(v0); // generator object | 1921 __ push(v0); // generator object |
1921 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1922 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1922 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1923 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1923 __ bind(&post_runtime); | 1924 __ bind(&post_runtime); |
1924 PopOperand(result_register()); | 1925 PopOperand(result_register()); |
1925 EmitReturnSequence(); | 1926 EmitReturnSequence(); |
1926 | 1927 |
1927 __ bind(&resume); | 1928 __ bind(&resume); |
1928 context()->Plug(result_register()); | 1929 context()->Plug(result_register()); |
1929 break; | 1930 break; |
1930 } | 1931 } |
1931 | 1932 |
1932 case Yield::kFinal: { | 1933 case Yield::kFinal: { |
1933 // Pop value from top-of-stack slot, box result into result register. | 1934 // Pop value from top-of-stack slot, box result into result register. |
1934 OperandStackDepthDecrement(1); | |
1935 EmitCreateIteratorResult(true); | 1935 EmitCreateIteratorResult(true); |
1936 EmitUnwindAndReturn(); | 1936 EmitUnwindAndReturn(); |
1937 break; | 1937 break; |
1938 } | 1938 } |
1939 | 1939 |
1940 case Yield::kDelegating: | 1940 case Yield::kDelegating: |
1941 UNREACHABLE(); | 1941 UNREACHABLE(); |
1942 } | 1942 } |
1943 } | 1943 } |
1944 | 1944 |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2076 | 2076 |
2077 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); | 2077 __ Allocate(JSIteratorResult::kSize, v0, a2, a3, &allocate, TAG_OBJECT); |
2078 __ jmp(&done_allocate); | 2078 __ jmp(&done_allocate); |
2079 | 2079 |
2080 __ bind(&allocate); | 2080 __ bind(&allocate); |
2081 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 2081 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
2082 __ CallRuntime(Runtime::kAllocateInNewSpace); | 2082 __ CallRuntime(Runtime::kAllocateInNewSpace); |
2083 | 2083 |
2084 __ bind(&done_allocate); | 2084 __ bind(&done_allocate); |
2085 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, a1); | 2085 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, a1); |
2086 __ pop(a2); | 2086 PopOperand(a2); |
2087 __ LoadRoot(a3, | 2087 __ LoadRoot(a3, |
2088 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 2088 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
2089 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex); | 2089 __ LoadRoot(a4, Heap::kEmptyFixedArrayRootIndex); |
2090 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 2090 __ sd(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
2091 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset)); | 2091 __ sd(a4, FieldMemOperand(v0, JSObject::kPropertiesOffset)); |
2092 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); | 2092 __ sd(a4, FieldMemOperand(v0, JSObject::kElementsOffset)); |
2093 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); | 2093 __ sd(a2, FieldMemOperand(v0, JSIteratorResult::kValueOffset)); |
2094 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); | 2094 __ sd(a3, FieldMemOperand(v0, JSIteratorResult::kDoneOffset)); |
2095 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 2095 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
2096 } | 2096 } |
(...skipping 2171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4268 reinterpret_cast<uint64_t>( | 4268 reinterpret_cast<uint64_t>( |
4269 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4269 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4270 return OSR_AFTER_STACK_CHECK; | 4270 return OSR_AFTER_STACK_CHECK; |
4271 } | 4271 } |
4272 | 4272 |
4273 | 4273 |
4274 } // namespace internal | 4274 } // namespace internal |
4275 } // namespace v8 | 4275 } // namespace v8 |
4276 | 4276 |
4277 #endif // V8_TARGET_ARCH_MIPS64 | 4277 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |