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 1350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 __ B(done); | 1361 __ B(done); |
1362 } | 1362 } |
1363 } | 1363 } |
1364 | 1364 |
1365 | 1365 |
1366 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 1366 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
1367 TypeofMode typeof_mode) { | 1367 TypeofMode typeof_mode) { |
1368 Variable* var = proxy->var(); | 1368 Variable* var = proxy->var(); |
1369 DCHECK(var->IsUnallocatedOrGlobalSlot() || | 1369 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
1370 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); | 1370 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); |
1371 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); | 1371 __ LoadGlobalObject(LoadDescriptor::ReceiverRegister()); |
1372 __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); | 1372 __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); |
1373 __ Mov(LoadDescriptor::SlotRegister(), | 1373 __ Mov(LoadDescriptor::SlotRegister(), |
1374 SmiFromSlot(proxy->VariableFeedbackSlot())); | 1374 SmiFromSlot(proxy->VariableFeedbackSlot())); |
1375 CallLoadIC(typeof_mode); | 1375 CallLoadIC(typeof_mode); |
1376 } | 1376 } |
1377 | 1377 |
1378 | 1378 |
1379 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, | 1379 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, |
1380 TypeofMode typeof_mode) { | 1380 TypeofMode typeof_mode) { |
1381 // Record position before possible IC call. | 1381 // Record position before possible IC call. |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2221 } | 2221 } |
2222 } | 2222 } |
2223 | 2223 |
2224 | 2224 |
2225 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2225 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
2226 FeedbackVectorSlot slot) { | 2226 FeedbackVectorSlot slot) { |
2227 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2227 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
2228 if (var->IsUnallocated()) { | 2228 if (var->IsUnallocated()) { |
2229 // Global var, const, or let. | 2229 // Global var, const, or let. |
2230 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); | 2230 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
2231 __ Ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); | 2231 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); |
2232 EmitLoadStoreICSlot(slot); | 2232 EmitLoadStoreICSlot(slot); |
2233 CallStoreIC(); | 2233 CallStoreIC(); |
2234 | 2234 |
2235 } else if (var->mode() == LET && op != Token::INIT) { | 2235 } else if (var->mode() == LET && op != Token::INIT) { |
2236 // Non-initializing assignment to let variable needs a write barrier. | 2236 // Non-initializing assignment to let variable needs a write barrier. |
2237 DCHECK(!var->IsLookupSlot()); | 2237 DCHECK(!var->IsLookupSlot()); |
2238 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2238 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2239 Label assign; | 2239 Label assign; |
2240 MemOperand location = VarOperand(var, x1); | 2240 MemOperand location = VarOperand(var, x1); |
2241 __ Ldr(x10, location); | 2241 __ Ldr(x10, location); |
(...skipping 1571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3813 | 3813 |
3814 Label runtime, done; | 3814 Label runtime, done; |
3815 | 3815 |
3816 Register result = x0; | 3816 Register result = x0; |
3817 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &runtime, TAG_OBJECT); | 3817 __ Allocate(JSIteratorResult::kSize, result, x10, x11, &runtime, TAG_OBJECT); |
3818 Register map_reg = x1; | 3818 Register map_reg = x1; |
3819 Register result_value = x2; | 3819 Register result_value = x2; |
3820 Register boolean_done = x3; | 3820 Register boolean_done = x3; |
3821 Register empty_fixed_array = x4; | 3821 Register empty_fixed_array = x4; |
3822 Register untagged_result = x5; | 3822 Register untagged_result = x5; |
3823 __ Ldr(map_reg, GlobalObjectMemOperand()); | 3823 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg); |
3824 __ Ldr(map_reg, | |
3825 FieldMemOperand(map_reg, JSGlobalObject::kNativeContextOffset)); | |
3826 __ Ldr(map_reg, | |
3827 ContextMemOperand(map_reg, Context::ITERATOR_RESULT_MAP_INDEX)); | |
3828 __ Pop(boolean_done); | 3824 __ Pop(boolean_done); |
3829 __ Pop(result_value); | 3825 __ Pop(result_value); |
3830 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); | 3826 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); |
3831 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == | 3827 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == |
3832 JSObject::kElementsOffset); | 3828 JSObject::kElementsOffset); |
3833 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == | 3829 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == |
3834 JSIteratorResult::kDoneOffset); | 3830 JSIteratorResult::kDoneOffset); |
3835 __ ObjectUntag(untagged_result, result); | 3831 __ ObjectUntag(untagged_result, result); |
3836 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); | 3832 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); |
3837 __ Stp(empty_fixed_array, empty_fixed_array, | 3833 __ Stp(empty_fixed_array, empty_fixed_array, |
3838 MemOperand(untagged_result, JSObject::kPropertiesOffset)); | 3834 MemOperand(untagged_result, JSObject::kPropertiesOffset)); |
3839 __ Stp(result_value, boolean_done, | 3835 __ Stp(result_value, boolean_done, |
3840 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); | 3836 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); |
3841 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 3837 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
3842 __ B(&done); | 3838 __ B(&done); |
3843 | 3839 |
3844 __ Bind(&runtime); | 3840 __ Bind(&runtime); |
3845 __ CallRuntime(Runtime::kCreateIterResultObject, 2); | 3841 __ CallRuntime(Runtime::kCreateIterResultObject, 2); |
3846 | 3842 |
3847 __ Bind(&done); | 3843 __ Bind(&done); |
3848 context()->Plug(x0); | 3844 context()->Plug(x0); |
3849 } | 3845 } |
3850 | 3846 |
3851 | 3847 |
3852 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 3848 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
3853 // Push undefined as the receiver. | 3849 // Push undefined as the receiver. |
3854 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 3850 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
3855 __ Push(x0); | 3851 __ Push(x0); |
3856 | 3852 |
3857 __ Ldr(x0, GlobalObjectMemOperand()); | 3853 __ LoadNativeContextSlot(expr->context_index(), x0); |
3858 __ Ldr(x0, FieldMemOperand(x0, JSGlobalObject::kNativeContextOffset)); | |
3859 __ Ldr(x0, ContextMemOperand(x0, expr->context_index())); | |
3860 } | 3854 } |
3861 | 3855 |
3862 | 3856 |
3863 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3857 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3864 ZoneList<Expression*>* args = expr->arguments(); | 3858 ZoneList<Expression*>* args = expr->arguments(); |
3865 int arg_count = args->length(); | 3859 int arg_count = args->length(); |
3866 | 3860 |
3867 SetCallPosition(expr, arg_count); | 3861 SetCallPosition(expr, arg_count); |
3868 __ Peek(x1, (arg_count + 1) * kPointerSize); | 3862 __ Peek(x1, (arg_count + 1) * kPointerSize); |
3869 __ Mov(x0, arg_count); | 3863 __ Mov(x0, arg_count); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3938 : Runtime::kDeleteProperty_Sloppy, | 3932 : Runtime::kDeleteProperty_Sloppy, |
3939 2); | 3933 2); |
3940 context()->Plug(x0); | 3934 context()->Plug(x0); |
3941 } else if (proxy != NULL) { | 3935 } else if (proxy != NULL) { |
3942 Variable* var = proxy->var(); | 3936 Variable* var = proxy->var(); |
3943 // Delete of an unqualified identifier is disallowed in strict mode but | 3937 // Delete of an unqualified identifier is disallowed in strict mode but |
3944 // "delete this" is allowed. | 3938 // "delete this" is allowed. |
3945 bool is_this = var->HasThisName(isolate()); | 3939 bool is_this = var->HasThisName(isolate()); |
3946 DCHECK(is_sloppy(language_mode()) || is_this); | 3940 DCHECK(is_sloppy(language_mode()) || is_this); |
3947 if (var->IsUnallocatedOrGlobalSlot()) { | 3941 if (var->IsUnallocatedOrGlobalSlot()) { |
3948 __ Ldr(x12, GlobalObjectMemOperand()); | 3942 __ LoadGlobalObject(x12); |
3949 __ Mov(x11, Operand(var->name())); | 3943 __ Mov(x11, Operand(var->name())); |
3950 __ Push(x12, x11); | 3944 __ Push(x12, x11); |
3951 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); | 3945 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); |
3952 context()->Plug(x0); | 3946 context()->Plug(x0); |
3953 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 3947 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
3954 // Result of deleting non-global, non-dynamic variables is false. | 3948 // Result of deleting non-global, non-dynamic variables is false. |
3955 // The subexpression does not have side effects. | 3949 // The subexpression does not have side effects. |
3956 context()->Plug(is_this); | 3950 context()->Plug(is_this); |
3957 } else { | 3951 } else { |
3958 // Non-global variable. Call the runtime to try to delete from the | 3952 // Non-global variable. Call the runtime to try to delete from the |
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4765 __ Bind(&allocate); | 4759 __ Bind(&allocate); |
4766 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 4760 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
4767 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 4761 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
4768 | 4762 |
4769 __ Bind(&done_allocate); | 4763 __ Bind(&done_allocate); |
4770 Register map_reg = x1; | 4764 Register map_reg = x1; |
4771 Register result_value = x2; | 4765 Register result_value = x2; |
4772 Register boolean_done = x3; | 4766 Register boolean_done = x3; |
4773 Register empty_fixed_array = x4; | 4767 Register empty_fixed_array = x4; |
4774 Register untagged_result = x5; | 4768 Register untagged_result = x5; |
4775 __ Ldr(map_reg, GlobalObjectMemOperand()); | 4769 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg); |
4776 __ Ldr(map_reg, | |
4777 FieldMemOperand(map_reg, JSGlobalObject::kNativeContextOffset)); | |
4778 __ Ldr(map_reg, | |
4779 ContextMemOperand(map_reg, Context::ITERATOR_RESULT_MAP_INDEX)); | |
4780 __ Pop(result_value); | 4770 __ Pop(result_value); |
4781 __ LoadRoot(boolean_done, | 4771 __ LoadRoot(boolean_done, |
4782 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 4772 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
4783 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); | 4773 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); |
4784 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == | 4774 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == |
4785 JSObject::kElementsOffset); | 4775 JSObject::kElementsOffset); |
4786 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == | 4776 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == |
4787 JSIteratorResult::kDoneOffset); | 4777 JSIteratorResult::kDoneOffset); |
4788 __ ObjectUntag(untagged_result, result); | 4778 __ ObjectUntag(untagged_result, result); |
4789 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); | 4779 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4826 | 4816 |
4827 | 4817 |
4828 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 4818 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { |
4829 Scope* closure_scope = scope()->ClosureScope(); | 4819 Scope* closure_scope = scope()->ClosureScope(); |
4830 if (closure_scope->is_script_scope() || | 4820 if (closure_scope->is_script_scope() || |
4831 closure_scope->is_module_scope()) { | 4821 closure_scope->is_module_scope()) { |
4832 // Contexts nested in the native context have a canonical empty function | 4822 // Contexts nested in the native context have a canonical empty function |
4833 // as their closure, not the anonymous closure containing the global | 4823 // as their closure, not the anonymous closure containing the global |
4834 // code. | 4824 // code. |
4835 DCHECK(kSmiTag == 0); | 4825 DCHECK(kSmiTag == 0); |
4836 __ Ldr(x10, GlobalObjectMemOperand()); | 4826 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10); |
4837 __ Ldr(x10, FieldMemOperand(x10, JSGlobalObject::kNativeContextOffset)); | |
4838 __ Ldr(x10, ContextMemOperand(x10, Context::CLOSURE_INDEX)); | |
4839 } else if (closure_scope->is_eval_scope()) { | 4827 } else if (closure_scope->is_eval_scope()) { |
4840 // Contexts created by a call to eval have the same closure as the | 4828 // Contexts created by a call to eval have the same closure as the |
4841 // context calling eval, not the anonymous closure containing the eval | 4829 // context calling eval, not the anonymous closure containing the eval |
4842 // code. Fetch it from the context. | 4830 // code. Fetch it from the context. |
4843 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); | 4831 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); |
4844 } else { | 4832 } else { |
4845 DCHECK(closure_scope->is_function_scope()); | 4833 DCHECK(closure_scope->is_function_scope()); |
4846 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4834 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
4847 } | 4835 } |
4848 __ Push(x10); | 4836 __ Push(x10); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5001 } | 4989 } |
5002 | 4990 |
5003 return INTERRUPT; | 4991 return INTERRUPT; |
5004 } | 4992 } |
5005 | 4993 |
5006 | 4994 |
5007 } // namespace internal | 4995 } // namespace internal |
5008 } // namespace v8 | 4996 } // namespace v8 |
5009 | 4997 |
5010 #endif // V8_TARGET_ARCH_ARM64 | 4998 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |