| 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 2122 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::kInitializeConstContextSlot, 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(opt == 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 |