OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 | 990 |
991 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 991 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
992 ASM_LOCATION("FullCodeGenerator::VisitForInStatement"); | 992 ASM_LOCATION("FullCodeGenerator::VisitForInStatement"); |
993 Comment cmnt(masm_, "[ ForInStatement"); | 993 Comment cmnt(masm_, "[ ForInStatement"); |
994 SetStatementPosition(stmt, SKIP_BREAK); | 994 SetStatementPosition(stmt, SKIP_BREAK); |
995 | 995 |
996 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 996 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
997 | 997 |
998 // TODO(all): This visitor probably needs better comments and a revisit. | 998 // TODO(all): This visitor probably needs better comments and a revisit. |
999 | 999 |
1000 Label loop, exit; | |
1001 ForIn loop_statement(this, stmt); | |
1002 increment_loop_depth(); | |
1003 | |
1004 // Get the object to enumerate over. | 1000 // Get the object to enumerate over. |
1005 SetExpressionAsStatementPosition(stmt->enumerable()); | 1001 SetExpressionAsStatementPosition(stmt->enumerable()); |
1006 VisitForAccumulatorValue(stmt->enumerable()); | 1002 VisitForAccumulatorValue(stmt->enumerable()); |
1007 OperandStackDepthIncrement(ForIn::kElementCount); | 1003 OperandStackDepthIncrement(5); |
| 1004 |
| 1005 Label loop, exit; |
| 1006 Iteration loop_statement(this, stmt); |
| 1007 increment_loop_depth(); |
1008 | 1008 |
1009 // If the object is null or undefined, skip over the loop, otherwise convert | 1009 // If the object is null or undefined, skip over the loop, otherwise convert |
1010 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 1010 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
1011 Label convert, done_convert; | 1011 Label convert, done_convert; |
1012 __ JumpIfSmi(x0, &convert); | 1012 __ JumpIfSmi(x0, &convert); |
1013 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); | 1013 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); |
1014 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); | 1014 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); |
1015 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); | 1015 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); |
1016 __ Bind(&convert); | 1016 __ Bind(&convert); |
1017 ToObjectStub stub(isolate()); | 1017 ToObjectStub stub(isolate()); |
(...skipping 2849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3867 VisitForStackValue(expr->expression()); | 3867 VisitForStackValue(expr->expression()); |
3868 | 3868 |
3869 // TODO(jbramley): Tidy this up once the merge is done, using named registers | 3869 // TODO(jbramley): Tidy this up once the merge is done, using named registers |
3870 // and suchlike. The implementation changes a little by bleeding_edge so I | 3870 // and suchlike. The implementation changes a little by bleeding_edge so I |
3871 // don't want to spend too much time on it now. | 3871 // don't want to spend too much time on it now. |
3872 | 3872 |
3873 switch (expr->yield_kind()) { | 3873 switch (expr->yield_kind()) { |
3874 case Yield::kSuspend: | 3874 case Yield::kSuspend: |
3875 // Pop value from top-of-stack slot; box result into result register. | 3875 // Pop value from top-of-stack slot; box result into result register. |
3876 EmitCreateIteratorResult(false); | 3876 EmitCreateIteratorResult(false); |
3877 __ Push(result_register()); | 3877 PushOperand(result_register()); |
3878 // Fall through. | 3878 // Fall through. |
3879 case Yield::kInitial: { | 3879 case Yield::kInitial: { |
3880 Label suspend, continuation, post_runtime, resume; | 3880 Label suspend, continuation, post_runtime, resume; |
3881 | 3881 |
3882 __ B(&suspend); | 3882 __ B(&suspend); |
3883 // TODO(jbramley): This label is bound here because the following code | 3883 // TODO(jbramley): This label is bound here because the following code |
3884 // looks at its pos(). Is it possible to do something more efficient here, | 3884 // looks at its pos(). Is it possible to do something more efficient here, |
3885 // perhaps using Adr? | 3885 // perhaps using Adr? |
3886 __ Bind(&continuation); | 3886 __ Bind(&continuation); |
3887 // When we arrive here, the stack top is the resume mode and | 3887 // When we arrive here, the stack top is the resume mode and |
3888 // result_register() holds the input value (the argument given to the | 3888 // result_register() holds the input value (the argument given to the |
3889 // respective resume operation). | 3889 // respective resume operation). |
3890 __ RecordGeneratorContinuation(); | 3890 __ RecordGeneratorContinuation(); |
3891 __ Pop(x1); | 3891 __ Pop(x1); |
3892 __ Cmp(x1, Smi::FromInt(JSGeneratorObject::RETURN)); | 3892 __ Cmp(x1, Smi::FromInt(JSGeneratorObject::RETURN)); |
3893 __ B(ne, &resume); | 3893 __ B(ne, &resume); |
3894 __ Push(result_register()); | 3894 __ Push(result_register()); |
3895 EmitCreateIteratorResult(true); | 3895 EmitCreateIteratorResult(true); |
3896 EmitUnwindAndReturn(); | 3896 EmitUnwindAndReturn(); |
3897 | 3897 |
3898 __ Bind(&suspend); | 3898 __ Bind(&suspend); |
| 3899 OperandStackDepthIncrement(1); // Not popped on this path. |
3899 VisitForAccumulatorValue(expr->generator_object()); | 3900 VisitForAccumulatorValue(expr->generator_object()); |
3900 DCHECK((continuation.pos() > 0) && Smi::IsValid(continuation.pos())); | 3901 DCHECK((continuation.pos() > 0) && Smi::IsValid(continuation.pos())); |
3901 __ Mov(x1, Smi::FromInt(continuation.pos())); | 3902 __ Mov(x1, Smi::FromInt(continuation.pos())); |
3902 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); | 3903 __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); |
3903 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); | 3904 __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); |
3904 __ Mov(x1, cp); | 3905 __ Mov(x1, cp); |
3905 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, | 3906 __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, |
3906 kLRHasBeenSaved, kDontSaveFPRegs); | 3907 kLRHasBeenSaved, kDontSaveFPRegs); |
3907 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); | 3908 __ Add(x1, fp, StandardFrameConstants::kExpressionsOffset); |
3908 __ Cmp(__ StackPointer(), x1); | 3909 __ Cmp(__ StackPointer(), x1); |
3909 __ B(eq, &post_runtime); | 3910 __ B(eq, &post_runtime); |
3910 __ Push(x0); // generator object | 3911 __ Push(x0); // generator object |
3911 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 3912 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
3912 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3913 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3913 __ Bind(&post_runtime); | 3914 __ Bind(&post_runtime); |
3914 PopOperand(result_register()); | 3915 PopOperand(result_register()); |
3915 EmitReturnSequence(); | 3916 EmitReturnSequence(); |
3916 | 3917 |
3917 __ Bind(&resume); | 3918 __ Bind(&resume); |
3918 context()->Plug(result_register()); | 3919 context()->Plug(result_register()); |
3919 break; | 3920 break; |
3920 } | 3921 } |
3921 | 3922 |
3922 case Yield::kFinal: { | 3923 case Yield::kFinal: { |
3923 // Pop value from top-of-stack slot, box result into result register. | 3924 // Pop value from top-of-stack slot, box result into result register. |
3924 OperandStackDepthDecrement(1); | |
3925 EmitCreateIteratorResult(true); | 3925 EmitCreateIteratorResult(true); |
3926 EmitUnwindAndReturn(); | 3926 EmitUnwindAndReturn(); |
3927 break; | 3927 break; |
3928 } | 3928 } |
3929 | 3929 |
3930 case Yield::kDelegating: | 3930 case Yield::kDelegating: |
3931 UNREACHABLE(); | 3931 UNREACHABLE(); |
3932 } | 3932 } |
3933 } | 3933 } |
3934 | 3934 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4072 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 4072 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
4073 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4073 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4074 | 4074 |
4075 __ Bind(&done_allocate); | 4075 __ Bind(&done_allocate); |
4076 Register map_reg = x1; | 4076 Register map_reg = x1; |
4077 Register result_value = x2; | 4077 Register result_value = x2; |
4078 Register boolean_done = x3; | 4078 Register boolean_done = x3; |
4079 Register empty_fixed_array = x4; | 4079 Register empty_fixed_array = x4; |
4080 Register untagged_result = x5; | 4080 Register untagged_result = x5; |
4081 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg); | 4081 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg); |
4082 __ Pop(result_value); | 4082 PopOperand(result_value); |
4083 __ LoadRoot(boolean_done, | 4083 __ LoadRoot(boolean_done, |
4084 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 4084 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
4085 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); | 4085 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); |
4086 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == | 4086 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == |
4087 JSObject::kElementsOffset); | 4087 JSObject::kElementsOffset); |
4088 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == | 4088 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == |
4089 JSIteratorResult::kDoneOffset); | 4089 JSIteratorResult::kDoneOffset); |
4090 __ ObjectUntag(untagged_result, result); | 4090 __ ObjectUntag(untagged_result, result); |
4091 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); | 4091 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); |
4092 __ Stp(empty_fixed_array, empty_fixed_array, | 4092 __ Stp(empty_fixed_array, empty_fixed_array, |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4304 } | 4304 } |
4305 | 4305 |
4306 return INTERRUPT; | 4306 return INTERRUPT; |
4307 } | 4307 } |
4308 | 4308 |
4309 | 4309 |
4310 } // namespace internal | 4310 } // namespace internal |
4311 } // namespace v8 | 4311 } // namespace v8 |
4312 | 4312 |
4313 #endif // V8_TARGET_ARCH_ARM64 | 4313 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |