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