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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 // Note: For variables we must not push an initial value (such as | 852 // Note: For variables we must not push an initial value (such as |
853 // 'undefined') because we may have a (legal) redeclaration and we | 853 // 'undefined') because we may have a (legal) redeclaration and we |
854 // must not destroy the current value. | 854 // must not destroy the current value. |
855 if (hole_init) { | 855 if (hole_init) { |
856 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); | 856 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); |
857 __ Push(cp, x2, x1, x0); | 857 __ Push(cp, x2, x1, x0); |
858 } else { | 858 } else { |
859 // Pushing 0 (xzr) indicates no initial value. | 859 // Pushing 0 (xzr) indicates no initial value. |
860 __ Push(cp, x2, x1, xzr); | 860 __ Push(cp, x2, x1, xzr); |
861 } | 861 } |
862 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 862 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
863 break; | 863 break; |
864 } | 864 } |
865 } | 865 } |
866 } | 866 } |
867 | 867 |
868 | 868 |
869 void FullCodeGenerator::VisitFunctionDeclaration( | 869 void FullCodeGenerator::VisitFunctionDeclaration( |
870 FunctionDeclaration* declaration) { | 870 FunctionDeclaration* declaration) { |
871 VariableProxy* proxy = declaration->proxy(); | 871 VariableProxy* proxy = declaration->proxy(); |
872 Variable* variable = proxy->var(); | 872 Variable* variable = proxy->var(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 break; | 908 break; |
909 } | 909 } |
910 | 910 |
911 case Variable::LOOKUP: { | 911 case Variable::LOOKUP: { |
912 Comment cmnt(masm_, "[ Function Declaration"); | 912 Comment cmnt(masm_, "[ Function Declaration"); |
913 __ Mov(x2, Operand(variable->name())); | 913 __ Mov(x2, Operand(variable->name())); |
914 __ Mov(x1, Smi::FromInt(NONE)); | 914 __ Mov(x1, Smi::FromInt(NONE)); |
915 __ Push(cp, x2, x1); | 915 __ Push(cp, x2, x1); |
916 // Push initial value for function declaration. | 916 // Push initial value for function declaration. |
917 VisitForStackValue(declaration->fun()); | 917 VisitForStackValue(declaration->fun()); |
918 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 918 __ CallRuntime(Runtime::kDeclareLookupSlot, 4); |
919 break; | 919 break; |
920 } | 920 } |
921 } | 921 } |
922 } | 922 } |
923 | 923 |
924 | 924 |
925 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { | 925 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { |
926 Variable* variable = declaration->proxy()->var(); | 926 Variable* variable = declaration->proxy()->var(); |
927 ASSERT(variable->location() == Variable::CONTEXT); | 927 ASSERT(variable->location() == Variable::CONTEXT); |
928 ASSERT(variable->interface()->IsFrozen()); | 928 ASSERT(variable->interface()->IsFrozen()); |
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2133 if (var->IsContextSlot()) { | 2133 if (var->IsContextSlot()) { |
2134 // RecordWrite may destroy all its register arguments. | 2134 // RecordWrite may destroy all its register arguments. |
2135 __ Mov(x10, result_register()); | 2135 __ Mov(x10, result_register()); |
2136 int offset = Context::SlotOffset(var->index()); | 2136 int offset = Context::SlotOffset(var->index()); |
2137 __ RecordWriteContextSlot( | 2137 __ RecordWriteContextSlot( |
2138 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 2138 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |
2139 } | 2139 } |
2140 } | 2140 } |
2141 | 2141 |
2142 | 2142 |
2143 void FullCodeGenerator::EmitCallStoreContextSlot( | |
2144 Handle<String> name, StrictMode strict_mode) { | |
2145 __ Mov(x11, Operand(name)); | |
2146 __ Mov(x10, Smi::FromInt(strict_mode)); | |
2147 // jssp[0] : mode. | |
2148 // jssp[8] : name. | |
2149 // jssp[16] : context. | |
2150 // jssp[24] : value. | |
2151 __ Push(x0, cp, x11, x10); | |
2152 __ CallRuntime(Runtime::kStoreContextSlot, 4); | |
2153 } | |
2154 | |
2155 | |
2156 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2143 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2157 Token::Value op) { | 2144 Token::Value op) { |
2158 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2145 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
2159 if (var->IsUnallocated()) { | 2146 if (var->IsUnallocated()) { |
2160 // Global var, const, or let. | 2147 // Global var, const, or let. |
2161 __ Mov(x2, Operand(var->name())); | 2148 __ Mov(x2, Operand(var->name())); |
2162 __ Ldr(x1, GlobalObjectMemOperand()); | 2149 __ Ldr(x1, GlobalObjectMemOperand()); |
2163 CallStoreIC(); | 2150 CallStoreIC(); |
2164 | 2151 |
2165 } else if (op == Token::INIT_CONST_LEGACY) { | 2152 } else if (op == Token::INIT_CONST_LEGACY) { |
2166 // Const initializers need a write barrier. | 2153 // Const initializers need a write barrier. |
2167 ASSERT(!var->IsParameter()); // No const parameters. | 2154 ASSERT(!var->IsParameter()); // No const parameters. |
2168 if (var->IsLookupSlot()) { | 2155 if (var->IsLookupSlot()) { |
2169 __ Mov(x1, Operand(var->name())); | 2156 __ Mov(x1, Operand(var->name())); |
2170 __ Push(x0, cp, x1); | 2157 __ Push(x0, cp, x1); |
2171 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2158 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
2172 } else { | 2159 } else { |
2173 ASSERT(var->IsStackLocal() || var->IsContextSlot()); | 2160 ASSERT(var->IsStackLocal() || var->IsContextSlot()); |
2174 Label skip; | 2161 Label skip; |
2175 MemOperand location = VarOperand(var, x1); | 2162 MemOperand location = VarOperand(var, x1); |
2176 __ Ldr(x10, location); | 2163 __ Ldr(x10, location); |
2177 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); | 2164 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); |
2178 EmitStoreToStackLocalOrContextSlot(var, location); | 2165 EmitStoreToStackLocalOrContextSlot(var, location); |
2179 __ Bind(&skip); | 2166 __ Bind(&skip); |
2180 } | 2167 } |
2181 | 2168 |
2182 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2169 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2183 // Non-initializing assignment to let variable needs a write barrier. | 2170 // Non-initializing assignment to let variable needs a write barrier. |
2184 if (var->IsLookupSlot()) { | 2171 ASSERT(!var->IsLookupSlot()); |
2185 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2172 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2186 } else { | 2173 Label assign; |
2187 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2174 MemOperand location = VarOperand(var, x1); |
2188 Label assign; | 2175 __ Ldr(x10, location); |
2189 MemOperand location = VarOperand(var, x1); | 2176 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); |
2190 __ Ldr(x10, location); | 2177 __ Mov(x10, Operand(var->name())); |
2191 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); | 2178 __ Push(x10); |
2192 __ Mov(x10, Operand(var->name())); | 2179 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
2193 __ Push(x10); | 2180 // Perform the assignment. |
2194 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2181 __ Bind(&assign); |
2195 // Perform the assignment. | 2182 EmitStoreToStackLocalOrContextSlot(var, location); |
2196 __ Bind(&assign); | |
2197 EmitStoreToStackLocalOrContextSlot(var, location); | |
2198 } | |
2199 | 2183 |
2200 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2184 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
2201 // Assignment to var or initializing assignment to let/const | |
2202 // in harmony mode. | |
2203 if (var->IsLookupSlot()) { | 2185 if (var->IsLookupSlot()) { |
2204 EmitCallStoreContextSlot(var->name(), strict_mode()); | 2186 ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR || |
| 2187 op == Token::ASSIGN_ADD); |
| 2188 // Assignment to var. |
| 2189 __ Mov(x11, Operand(var->name())); |
| 2190 __ Mov(x10, Smi::FromInt(strict_mode())); |
| 2191 // jssp[0] : mode. |
| 2192 // jssp[8] : name. |
| 2193 // jssp[16] : context. |
| 2194 // jssp[24] : value. |
| 2195 __ Push(x0, cp, x11, x10); |
| 2196 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
2205 } else { | 2197 } else { |
| 2198 // Assignment to var or initializing assignment to let/const in harmony |
| 2199 // mode. |
2206 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2200 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
2207 MemOperand location = VarOperand(var, x1); | 2201 MemOperand location = VarOperand(var, x1); |
2208 if (FLAG_debug_code && op == Token::INIT_LET) { | 2202 if (FLAG_debug_code && op == Token::INIT_LET) { |
2209 __ Ldr(x10, location); | 2203 __ Ldr(x10, location); |
2210 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); | 2204 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); |
2211 __ Check(eq, kLetBindingReInitialization); | 2205 __ Check(eq, kLetBindingReInitialization); |
2212 } | 2206 } |
2213 EmitStoreToStackLocalOrContextSlot(var, location); | 2207 EmitStoreToStackLocalOrContextSlot(var, location); |
2214 } | 2208 } |
2215 } | 2209 } |
(...skipping 2675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4891 return previous_; | 4885 return previous_; |
4892 } | 4886 } |
4893 | 4887 |
4894 | 4888 |
4895 #undef __ | 4889 #undef __ |
4896 | 4890 |
4897 | 4891 |
4898 } } // namespace v8::internal | 4892 } } // namespace v8::internal |
4899 | 4893 |
4900 #endif // V8_TARGET_ARCH_ARM64 | 4894 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |