| 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 |