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 __ LoadGlobalObject(LoadDescriptor::ReceiverRegister()); | 1371 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
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 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); | 2231 __ Ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
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 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg); | 3823 __ Ldr(map_reg, GlobalObjectMemOperand()); |
| 3824 __ Ldr(map_reg, |
| 3825 FieldMemOperand(map_reg, JSGlobalObject::kNativeContextOffset)); |
| 3826 __ Ldr(map_reg, |
| 3827 ContextMemOperand(map_reg, Context::ITERATOR_RESULT_MAP_INDEX)); |
3824 __ Pop(boolean_done); | 3828 __ Pop(boolean_done); |
3825 __ Pop(result_value); | 3829 __ Pop(result_value); |
3826 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); | 3830 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); |
3827 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == | 3831 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == |
3828 JSObject::kElementsOffset); | 3832 JSObject::kElementsOffset); |
3829 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == | 3833 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == |
3830 JSIteratorResult::kDoneOffset); | 3834 JSIteratorResult::kDoneOffset); |
3831 __ ObjectUntag(untagged_result, result); | 3835 __ ObjectUntag(untagged_result, result); |
3832 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); | 3836 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); |
3833 __ Stp(empty_fixed_array, empty_fixed_array, | 3837 __ Stp(empty_fixed_array, empty_fixed_array, |
3834 MemOperand(untagged_result, JSObject::kPropertiesOffset)); | 3838 MemOperand(untagged_result, JSObject::kPropertiesOffset)); |
3835 __ Stp(result_value, boolean_done, | 3839 __ Stp(result_value, boolean_done, |
3836 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); | 3840 MemOperand(untagged_result, JSIteratorResult::kValueOffset)); |
3837 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 3841 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
3838 __ B(&done); | 3842 __ B(&done); |
3839 | 3843 |
3840 __ Bind(&runtime); | 3844 __ Bind(&runtime); |
3841 __ CallRuntime(Runtime::kCreateIterResultObject, 2); | 3845 __ CallRuntime(Runtime::kCreateIterResultObject, 2); |
3842 | 3846 |
3843 __ Bind(&done); | 3847 __ Bind(&done); |
3844 context()->Plug(x0); | 3848 context()->Plug(x0); |
3845 } | 3849 } |
3846 | 3850 |
3847 | 3851 |
3848 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 3852 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
3849 // Push undefined as the receiver. | 3853 // Push undefined as the receiver. |
3850 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); | 3854 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |
3851 __ Push(x0); | 3855 __ Push(x0); |
3852 | 3856 |
3853 __ LoadNativeContextSlot(expr->context_index(), x0); | 3857 __ Ldr(x0, GlobalObjectMemOperand()); |
| 3858 __ Ldr(x0, FieldMemOperand(x0, JSGlobalObject::kNativeContextOffset)); |
| 3859 __ Ldr(x0, ContextMemOperand(x0, expr->context_index())); |
3854 } | 3860 } |
3855 | 3861 |
3856 | 3862 |
3857 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 3863 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
3858 ZoneList<Expression*>* args = expr->arguments(); | 3864 ZoneList<Expression*>* args = expr->arguments(); |
3859 int arg_count = args->length(); | 3865 int arg_count = args->length(); |
3860 | 3866 |
3861 SetCallPosition(expr, arg_count); | 3867 SetCallPosition(expr, arg_count); |
3862 __ Peek(x1, (arg_count + 1) * kPointerSize); | 3868 __ Peek(x1, (arg_count + 1) * kPointerSize); |
3863 __ Mov(x0, arg_count); | 3869 __ Mov(x0, arg_count); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3932 : Runtime::kDeleteProperty_Sloppy, | 3938 : Runtime::kDeleteProperty_Sloppy, |
3933 2); | 3939 2); |
3934 context()->Plug(x0); | 3940 context()->Plug(x0); |
3935 } else if (proxy != NULL) { | 3941 } else if (proxy != NULL) { |
3936 Variable* var = proxy->var(); | 3942 Variable* var = proxy->var(); |
3937 // Delete of an unqualified identifier is disallowed in strict mode but | 3943 // Delete of an unqualified identifier is disallowed in strict mode but |
3938 // "delete this" is allowed. | 3944 // "delete this" is allowed. |
3939 bool is_this = var->HasThisName(isolate()); | 3945 bool is_this = var->HasThisName(isolate()); |
3940 DCHECK(is_sloppy(language_mode()) || is_this); | 3946 DCHECK(is_sloppy(language_mode()) || is_this); |
3941 if (var->IsUnallocatedOrGlobalSlot()) { | 3947 if (var->IsUnallocatedOrGlobalSlot()) { |
3942 __ LoadGlobalObject(x12); | 3948 __ Ldr(x12, GlobalObjectMemOperand()); |
3943 __ Mov(x11, Operand(var->name())); | 3949 __ Mov(x11, Operand(var->name())); |
3944 __ Push(x12, x11); | 3950 __ Push(x12, x11); |
3945 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); | 3951 __ CallRuntime(Runtime::kDeleteProperty_Sloppy, 2); |
3946 context()->Plug(x0); | 3952 context()->Plug(x0); |
3947 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 3953 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
3948 // Result of deleting non-global, non-dynamic variables is false. | 3954 // Result of deleting non-global, non-dynamic variables is false. |
3949 // The subexpression does not have side effects. | 3955 // The subexpression does not have side effects. |
3950 context()->Plug(is_this); | 3956 context()->Plug(is_this); |
3951 } else { | 3957 } else { |
3952 // Non-global variable. Call the runtime to try to delete from the | 3958 // 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... |
4759 __ Bind(&allocate); | 4765 __ Bind(&allocate); |
4760 __ Push(Smi::FromInt(JSIteratorResult::kSize)); | 4766 __ Push(Smi::FromInt(JSIteratorResult::kSize)); |
4761 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 4767 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
4762 | 4768 |
4763 __ Bind(&done_allocate); | 4769 __ Bind(&done_allocate); |
4764 Register map_reg = x1; | 4770 Register map_reg = x1; |
4765 Register result_value = x2; | 4771 Register result_value = x2; |
4766 Register boolean_done = x3; | 4772 Register boolean_done = x3; |
4767 Register empty_fixed_array = x4; | 4773 Register empty_fixed_array = x4; |
4768 Register untagged_result = x5; | 4774 Register untagged_result = x5; |
4769 __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, map_reg); | 4775 __ Ldr(map_reg, GlobalObjectMemOperand()); |
| 4776 __ Ldr(map_reg, |
| 4777 FieldMemOperand(map_reg, JSGlobalObject::kNativeContextOffset)); |
| 4778 __ Ldr(map_reg, |
| 4779 ContextMemOperand(map_reg, Context::ITERATOR_RESULT_MAP_INDEX)); |
4770 __ Pop(result_value); | 4780 __ Pop(result_value); |
4771 __ LoadRoot(boolean_done, | 4781 __ LoadRoot(boolean_done, |
4772 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); | 4782 done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); |
4773 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); | 4783 __ LoadRoot(empty_fixed_array, Heap::kEmptyFixedArrayRootIndex); |
4774 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == | 4784 STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize == |
4775 JSObject::kElementsOffset); | 4785 JSObject::kElementsOffset); |
4776 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == | 4786 STATIC_ASSERT(JSIteratorResult::kValueOffset + kPointerSize == |
4777 JSIteratorResult::kDoneOffset); | 4787 JSIteratorResult::kDoneOffset); |
4778 __ ObjectUntag(untagged_result, result); | 4788 __ ObjectUntag(untagged_result, result); |
4779 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); | 4789 __ Str(map_reg, MemOperand(untagged_result, HeapObject::kMapOffset)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4816 | 4826 |
4817 | 4827 |
4818 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { | 4828 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { |
4819 Scope* closure_scope = scope()->ClosureScope(); | 4829 Scope* closure_scope = scope()->ClosureScope(); |
4820 if (closure_scope->is_script_scope() || | 4830 if (closure_scope->is_script_scope() || |
4821 closure_scope->is_module_scope()) { | 4831 closure_scope->is_module_scope()) { |
4822 // Contexts nested in the native context have a canonical empty function | 4832 // Contexts nested in the native context have a canonical empty function |
4823 // as their closure, not the anonymous closure containing the global | 4833 // as their closure, not the anonymous closure containing the global |
4824 // code. | 4834 // code. |
4825 DCHECK(kSmiTag == 0); | 4835 DCHECK(kSmiTag == 0); |
4826 __ LoadNativeContextSlot(Context::CLOSURE_INDEX, x10); | 4836 __ Ldr(x10, GlobalObjectMemOperand()); |
| 4837 __ Ldr(x10, FieldMemOperand(x10, JSGlobalObject::kNativeContextOffset)); |
| 4838 __ Ldr(x10, ContextMemOperand(x10, Context::CLOSURE_INDEX)); |
4827 } else if (closure_scope->is_eval_scope()) { | 4839 } else if (closure_scope->is_eval_scope()) { |
4828 // Contexts created by a call to eval have the same closure as the | 4840 // Contexts created by a call to eval have the same closure as the |
4829 // context calling eval, not the anonymous closure containing the eval | 4841 // context calling eval, not the anonymous closure containing the eval |
4830 // code. Fetch it from the context. | 4842 // code. Fetch it from the context. |
4831 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); | 4843 __ Ldr(x10, ContextMemOperand(cp, Context::CLOSURE_INDEX)); |
4832 } else { | 4844 } else { |
4833 DCHECK(closure_scope->is_function_scope()); | 4845 DCHECK(closure_scope->is_function_scope()); |
4834 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4846 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
4835 } | 4847 } |
4836 __ Push(x10); | 4848 __ Push(x10); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4989 } | 5001 } |
4990 | 5002 |
4991 return INTERRUPT; | 5003 return INTERRUPT; |
4992 } | 5004 } |
4993 | 5005 |
4994 | 5006 |
4995 } // namespace internal | 5007 } // namespace internal |
4996 } // namespace v8 | 5008 } // namespace v8 |
4997 | 5009 |
4998 #endif // V8_TARGET_ARCH_ARM64 | 5010 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |