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 |