| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 2137 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2148           ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2148           ? isolate()->builtins()->KeyedStoreIC_Initialize() | 
| 2149           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2149           : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 
| 2150       CallIC(ic); | 2150       CallIC(ic); | 
| 2151       break; | 2151       break; | 
| 2152     } | 2152     } | 
| 2153   } | 2153   } | 
| 2154   context()->Plug(x0); | 2154   context()->Plug(x0); | 
| 2155 } | 2155 } | 
| 2156 | 2156 | 
| 2157 | 2157 | 
|  | 2158 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 
|  | 2159     Variable* var, MemOperand location) { | 
|  | 2160   __ Str(result_register(), location); | 
|  | 2161   if (var->IsContextSlot()) { | 
|  | 2162     // RecordWrite may destroy all its register arguments. | 
|  | 2163     __ Mov(x10, result_register()); | 
|  | 2164     int offset = Context::SlotOffset(var->index()); | 
|  | 2165     __ RecordWriteContextSlot( | 
|  | 2166         x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 
|  | 2167   } | 
|  | 2168 } | 
|  | 2169 | 
|  | 2170 | 
|  | 2171 void FullCodeGenerator::EmitCallStoreContextSlot( | 
|  | 2172     Handle<String> name, LanguageMode mode) { | 
|  | 2173   __ Mov(x11, Operand(name)); | 
|  | 2174   __ Mov(x10, Operand(Smi::FromInt(mode))); | 
|  | 2175   // jssp[0]  : mode. | 
|  | 2176   // jssp[8]  : name. | 
|  | 2177   // jssp[16] : context. | 
|  | 2178   // jssp[24] : value. | 
|  | 2179   __ Push(x0, cp, x11, x10); | 
|  | 2180   __ CallRuntime(Runtime::kStoreContextSlot, 4); | 
|  | 2181 } | 
|  | 2182 | 
|  | 2183 | 
| 2158 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2184 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 
| 2159                                                Token::Value op) { | 2185                                                Token::Value op) { | 
| 2160   ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2186   ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 
| 2161   if (var->IsUnallocated()) { | 2187   if (var->IsUnallocated()) { | 
| 2162     // Global var, const, or let. | 2188     // Global var, const, or let. | 
| 2163     __ Mov(x2, Operand(var->name())); | 2189     __ Mov(x2, Operand(var->name())); | 
| 2164     __ Ldr(x1, GlobalObjectMemOperand()); | 2190     __ Ldr(x1, GlobalObjectMemOperand()); | 
| 2165     CallStoreIC(); | 2191     CallStoreIC(); | 
| 2166 | 2192 | 
| 2167   } else if (op == Token::INIT_CONST) { | 2193   } else if (op == Token::INIT_CONST) { | 
| 2168     // Const initializers need a write barrier. | 2194     // Const initializers need a write barrier. | 
| 2169     ASSERT(!var->IsParameter());  // No const parameters. | 2195     ASSERT(!var->IsParameter());  // No const parameters. | 
| 2170     if (var->IsStackLocal()) { | 2196     if (var->IsLookupSlot()) { | 
| 2171       Label skip; |  | 
| 2172       __ Ldr(x1, StackOperand(var)); |  | 
| 2173       __ JumpIfNotRoot(x1, Heap::kTheHoleValueRootIndex, &skip); |  | 
| 2174       __ Str(result_register(), StackOperand(var)); |  | 
| 2175       __ Bind(&skip); |  | 
| 2176     } else { |  | 
| 2177       ASSERT(var->IsContextSlot() || var->IsLookupSlot()); |  | 
| 2178       // Like var declarations, const declarations are hoisted to function |  | 
| 2179       // scope.  However, unlike var initializers, const initializers are |  | 
| 2180       // able to drill a hole to that function context, even from inside a |  | 
| 2181       // 'with' context.  We thus bypass the normal static scope lookup for |  | 
| 2182       // var->IsContextSlot(). |  | 
| 2183       __ Push(x0); | 2197       __ Push(x0); | 
| 2184       __ Mov(x0, Operand(var->name())); | 2198       __ Mov(x0, Operand(var->name())); | 
| 2185       __ Push(cp, x0);  // Context and name. | 2199       __ Push(cp, x0);  // Context and name. | 
| 2186       __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 2200       __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); | 
|  | 2201     } else { | 
|  | 2202       ASSERT(var->IsStackLocal() || var->IsContextSlot()); | 
|  | 2203       Label skip; | 
|  | 2204       MemOperand location = VarOperand(var, x1); | 
|  | 2205       __ Ldr(x10, location); | 
|  | 2206       __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &skip); | 
|  | 2207       EmitStoreToStackLocalOrContextSlot(var, location); | 
|  | 2208       __ Bind(&skip); | 
| 2187     } | 2209     } | 
| 2188 | 2210 | 
| 2189   } else if (var->mode() == LET && op != Token::INIT_LET) { | 2211   } else if (var->mode() == LET && op != Token::INIT_LET) { | 
| 2190     // Non-initializing assignment to let variable needs a write barrier. | 2212     // Non-initializing assignment to let variable needs a write barrier. | 
| 2191     if (var->IsLookupSlot()) { | 2213     if (var->IsLookupSlot()) { | 
| 2192       __ Push(x0, cp);  // Context, value. | 2214       EmitCallStoreContextSlot(var->name(), language_mode()); | 
| 2193       __ Mov(x11, Operand(var->name())); |  | 
| 2194       __ Mov(x10, Operand(Smi::FromInt(language_mode()))); |  | 
| 2195       __ Push(x11, x10);  // Strict mode, name. |  | 
| 2196       __ CallRuntime(Runtime::kStoreContextSlot, 4); |  | 
| 2197     } else { | 2215     } else { | 
| 2198       ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 2216       ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 
| 2199       Label assign; | 2217       Label assign; | 
| 2200       MemOperand location = VarOperand(var, x1); | 2218       MemOperand location = VarOperand(var, x1); | 
| 2201       __ Ldr(x10, location); | 2219       __ Ldr(x10, location); | 
| 2202       __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); | 2220       __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); | 
| 2203       __ Mov(x10, Operand(var->name())); | 2221       __ Mov(x10, Operand(var->name())); | 
| 2204       __ Push(x10); | 2222       __ Push(x10); | 
| 2205       __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2223       __ CallRuntime(Runtime::kThrowReferenceError, 1); | 
| 2206       // Perform the assignment. | 2224       // Perform the assignment. | 
| 2207       __ Bind(&assign); | 2225       __ Bind(&assign); | 
| 2208       __ Str(result_register(), location); | 2226       EmitStoreToStackLocalOrContextSlot(var, location); | 
| 2209       if (var->IsContextSlot()) { |  | 
| 2210         // RecordWrite may destroy all its register arguments. |  | 
| 2211         __ Mov(x10, result_register()); |  | 
| 2212         int offset = Context::SlotOffset(var->index()); |  | 
| 2213         __ RecordWriteContextSlot( |  | 
| 2214             x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |  | 
| 2215       } |  | 
| 2216     } | 2227     } | 
| 2217 | 2228 | 
| 2218   } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { | 2229   } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { | 
| 2219     // Assignment to var or initializing assignment to let/const | 2230     // Assignment to var or initializing assignment to let/const | 
| 2220     // in harmony mode. | 2231     // in harmony mode. | 
| 2221     if (var->IsStackAllocated() || var->IsContextSlot()) { | 2232     if (var->IsLookupSlot()) { | 
|  | 2233       EmitCallStoreContextSlot(var->name(), language_mode()); | 
|  | 2234     } else { | 
|  | 2235       ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 
| 2222       MemOperand location = VarOperand(var, x1); | 2236       MemOperand location = VarOperand(var, x1); | 
| 2223       if (FLAG_debug_code && op == Token::INIT_LET) { | 2237       if (FLAG_debug_code && op == Token::INIT_LET) { | 
| 2224         __ Ldr(x10, location); | 2238         __ Ldr(x10, location); | 
| 2225         __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); | 2239         __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); | 
| 2226         __ Check(eq, kLetBindingReInitialization); | 2240         __ Check(eq, kLetBindingReInitialization); | 
| 2227       } | 2241       } | 
| 2228       // Perform the assignment. | 2242       EmitStoreToStackLocalOrContextSlot(var, location); | 
| 2229       __ Str(x0, location); |  | 
| 2230       if (var->IsContextSlot()) { |  | 
| 2231         __ Mov(x10, x0); |  | 
| 2232         int offset = Context::SlotOffset(var->index()); |  | 
| 2233         __ RecordWriteContextSlot( |  | 
| 2234             x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |  | 
| 2235       } |  | 
| 2236     } else { |  | 
| 2237       ASSERT(var->IsLookupSlot()); |  | 
| 2238       __ Mov(x11, Operand(var->name())); |  | 
| 2239       __ Mov(x10, Operand(Smi::FromInt(language_mode()))); |  | 
| 2240       // jssp[0]  : mode. |  | 
| 2241       // jssp[8]  : name. |  | 
| 2242       // jssp[16] : context. |  | 
| 2243       // jssp[24] : value. |  | 
| 2244       __ Push(x0, cp, x11, x10); |  | 
| 2245       __ CallRuntime(Runtime::kStoreContextSlot, 4); |  | 
| 2246     } | 2243     } | 
| 2247   } | 2244   } | 
| 2248   // Non-initializing assignments to consts are ignored. | 2245   // Non-initializing assignments to consts are ignored. | 
| 2249 } | 2246 } | 
| 2250 | 2247 | 
| 2251 | 2248 | 
| 2252 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2249 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 
| 2253   ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2250   ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 
| 2254   // Assignment to a property, using a named store IC. | 2251   // Assignment to a property, using a named store IC. | 
| 2255   Property* prop = expr->target()->AsProperty(); | 2252   Property* prop = expr->target()->AsProperty(); | 
| (...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5007   return previous_; | 5004   return previous_; | 
| 5008 } | 5005 } | 
| 5009 | 5006 | 
| 5010 | 5007 | 
| 5011 #undef __ | 5008 #undef __ | 
| 5012 | 5009 | 
| 5013 | 5010 | 
| 5014 } }  // namespace v8::internal | 5011 } }  // namespace v8::internal | 
| 5015 | 5012 | 
| 5016 #endif  // V8_TARGET_ARCH_A64 | 5013 #endif  // V8_TARGET_ARCH_A64 | 
| OLD | NEW | 
|---|