OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/full-codegen/full-codegen.h" | 7 #include "src/full-codegen/full-codegen.h" |
8 #include "src/ast/compile-time-value.h" | 8 #include "src/ast/compile-time-value.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); | 1161 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); |
1162 __ bind(&exit); | 1162 __ bind(&exit); |
1163 decrement_loop_depth(); | 1163 decrement_loop_depth(); |
1164 } | 1164 } |
1165 | 1165 |
1166 | 1166 |
1167 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, | 1167 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
1168 FeedbackVectorSlot slot) { | 1168 FeedbackVectorSlot slot) { |
1169 DCHECK(NeedsHomeObject(initializer)); | 1169 DCHECK(NeedsHomeObject(initializer)); |
1170 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1170 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1171 __ mov(StoreDescriptor::NameRegister(), |
| 1172 Operand(isolate()->factory()->home_object_symbol())); |
1171 __ ldr(StoreDescriptor::ValueRegister(), | 1173 __ ldr(StoreDescriptor::ValueRegister(), |
1172 MemOperand(sp, offset * kPointerSize)); | 1174 MemOperand(sp, offset * kPointerSize)); |
1173 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); | 1175 EmitLoadStoreICSlot(slot); |
| 1176 CallStoreIC(); |
1174 } | 1177 } |
1175 | 1178 |
1176 | 1179 |
1177 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, | 1180 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, |
1178 int offset, | 1181 int offset, |
1179 FeedbackVectorSlot slot) { | 1182 FeedbackVectorSlot slot) { |
1180 DCHECK(NeedsHomeObject(initializer)); | 1183 DCHECK(NeedsHomeObject(initializer)); |
1181 __ Move(StoreDescriptor::ReceiverRegister(), r0); | 1184 __ Move(StoreDescriptor::ReceiverRegister(), r0); |
| 1185 __ mov(StoreDescriptor::NameRegister(), |
| 1186 Operand(isolate()->factory()->home_object_symbol())); |
1182 __ ldr(StoreDescriptor::ValueRegister(), | 1187 __ ldr(StoreDescriptor::ValueRegister(), |
1183 MemOperand(sp, offset * kPointerSize)); | 1188 MemOperand(sp, offset * kPointerSize)); |
1184 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); | 1189 EmitLoadStoreICSlot(slot); |
| 1190 CallStoreIC(); |
1185 } | 1191 } |
1186 | 1192 |
1187 | 1193 |
1188 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1194 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1189 TypeofMode typeof_mode, | 1195 TypeofMode typeof_mode, |
1190 Label* slow) { | 1196 Label* slow) { |
1191 Register current = cp; | 1197 Register current = cp; |
1192 Register next = r1; | 1198 Register next = r1; |
1193 Register temp = r2; | 1199 Register temp = r2; |
1194 | 1200 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1415 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1410 // Fall through. | 1416 // Fall through. |
1411 case ObjectLiteral::Property::COMPUTED: | 1417 case ObjectLiteral::Property::COMPUTED: |
1412 // It is safe to use [[Put]] here because the boilerplate already | 1418 // It is safe to use [[Put]] here because the boilerplate already |
1413 // contains computed properties with an uninitialized value. | 1419 // contains computed properties with an uninitialized value. |
1414 if (key->IsStringLiteral()) { | 1420 if (key->IsStringLiteral()) { |
1415 DCHECK(key->IsPropertyName()); | 1421 DCHECK(key->IsPropertyName()); |
1416 if (property->emit_store()) { | 1422 if (property->emit_store()) { |
1417 VisitForAccumulatorValue(value); | 1423 VisitForAccumulatorValue(value); |
1418 DCHECK(StoreDescriptor::ValueRegister().is(r0)); | 1424 DCHECK(StoreDescriptor::ValueRegister().is(r0)); |
| 1425 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
1419 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1426 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1420 CallStoreIC(property->GetSlot(0), key->value()); | 1427 EmitLoadStoreICSlot(property->GetSlot(0)); |
| 1428 CallStoreIC(); |
1421 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); | 1429 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); |
1422 | 1430 |
1423 if (NeedsHomeObject(value)) { | 1431 if (NeedsHomeObject(value)) { |
1424 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1432 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
1425 } | 1433 } |
1426 } else { | 1434 } else { |
1427 VisitForEffect(value); | 1435 VisitForEffect(value); |
1428 } | 1436 } |
1429 break; | 1437 break; |
1430 } | 1438 } |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1616 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1609 | 1617 |
1610 if (!result_saved) { | 1618 if (!result_saved) { |
1611 PushOperand(r0); | 1619 PushOperand(r0); |
1612 result_saved = true; | 1620 result_saved = true; |
1613 } | 1621 } |
1614 VisitForAccumulatorValue(subexpr); | 1622 VisitForAccumulatorValue(subexpr); |
1615 | 1623 |
1616 __ mov(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); | 1624 __ mov(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); |
1617 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1625 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
1618 CallKeyedStoreIC(expr->LiteralFeedbackSlot()); | 1626 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
| 1627 CallKeyedStoreIC(); |
1619 | 1628 |
1620 PrepareForBailoutForId(expr->GetIdForElement(array_index), | 1629 PrepareForBailoutForId(expr->GetIdForElement(array_index), |
1621 BailoutState::NO_REGISTERS); | 1630 BailoutState::NO_REGISTERS); |
1622 } | 1631 } |
1623 | 1632 |
1624 if (result_saved) { | 1633 if (result_saved) { |
1625 context()->PlugTOS(); | 1634 context()->PlugTOS(); |
1626 } else { | 1635 } else { |
1627 context()->Plug(r0); | 1636 context()->Plug(r0); |
1628 } | 1637 } |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2040 Variable* var = expr->AsVariableProxy()->var(); | 2049 Variable* var = expr->AsVariableProxy()->var(); |
2041 EffectContext context(this); | 2050 EffectContext context(this); |
2042 EmitVariableAssignment(var, Token::ASSIGN, slot); | 2051 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2043 break; | 2052 break; |
2044 } | 2053 } |
2045 case NAMED_PROPERTY: { | 2054 case NAMED_PROPERTY: { |
2046 PushOperand(r0); // Preserve value. | 2055 PushOperand(r0); // Preserve value. |
2047 VisitForAccumulatorValue(prop->obj()); | 2056 VisitForAccumulatorValue(prop->obj()); |
2048 __ Move(StoreDescriptor::ReceiverRegister(), r0); | 2057 __ Move(StoreDescriptor::ReceiverRegister(), r0); |
2049 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 2058 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
2050 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 2059 __ mov(StoreDescriptor::NameRegister(), |
| 2060 Operand(prop->key()->AsLiteral()->value())); |
| 2061 EmitLoadStoreICSlot(slot); |
| 2062 CallStoreIC(); |
2051 break; | 2063 break; |
2052 } | 2064 } |
2053 case NAMED_SUPER_PROPERTY: { | 2065 case NAMED_SUPER_PROPERTY: { |
2054 PushOperand(r0); | 2066 PushOperand(r0); |
2055 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 2067 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
2056 VisitForAccumulatorValue( | 2068 VisitForAccumulatorValue( |
2057 prop->obj()->AsSuperPropertyReference()->home_object()); | 2069 prop->obj()->AsSuperPropertyReference()->home_object()); |
2058 // stack: value, this; r0: home_object | 2070 // stack: value, this; r0: home_object |
2059 Register scratch = r2; | 2071 Register scratch = r2; |
2060 Register scratch2 = r3; | 2072 Register scratch2 = r3; |
(...skipping 26 matching lines...) Expand all Loading... |
2087 EmitKeyedSuperPropertyStore(prop); | 2099 EmitKeyedSuperPropertyStore(prop); |
2088 break; | 2100 break; |
2089 } | 2101 } |
2090 case KEYED_PROPERTY: { | 2102 case KEYED_PROPERTY: { |
2091 PushOperand(r0); // Preserve value. | 2103 PushOperand(r0); // Preserve value. |
2092 VisitForStackValue(prop->obj()); | 2104 VisitForStackValue(prop->obj()); |
2093 VisitForAccumulatorValue(prop->key()); | 2105 VisitForAccumulatorValue(prop->key()); |
2094 __ Move(StoreDescriptor::NameRegister(), r0); | 2106 __ Move(StoreDescriptor::NameRegister(), r0); |
2095 PopOperands(StoreDescriptor::ValueRegister(), | 2107 PopOperands(StoreDescriptor::ValueRegister(), |
2096 StoreDescriptor::ReceiverRegister()); | 2108 StoreDescriptor::ReceiverRegister()); |
2097 CallKeyedStoreIC(slot); | 2109 EmitLoadStoreICSlot(slot); |
| 2110 CallKeyedStoreIC(); |
2098 break; | 2111 break; |
2099 } | 2112 } |
2100 } | 2113 } |
2101 context()->Plug(r0); | 2114 context()->Plug(r0); |
2102 } | 2115 } |
2103 | 2116 |
2104 | 2117 |
2105 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2118 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2106 Variable* var, MemOperand location) { | 2119 Variable* var, MemOperand location) { |
2107 __ str(result_register(), location); | 2120 __ str(result_register(), location); |
2108 if (var->IsContextSlot()) { | 2121 if (var->IsContextSlot()) { |
2109 // RecordWrite may destroy all its register arguments. | 2122 // RecordWrite may destroy all its register arguments. |
2110 __ mov(r3, result_register()); | 2123 __ mov(r3, result_register()); |
2111 int offset = Context::SlotOffset(var->index()); | 2124 int offset = Context::SlotOffset(var->index()); |
2112 __ RecordWriteContextSlot( | 2125 __ RecordWriteContextSlot( |
2113 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); | 2126 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); |
2114 } | 2127 } |
2115 } | 2128 } |
2116 | 2129 |
2117 | 2130 |
2118 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2131 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
2119 FeedbackVectorSlot slot) { | 2132 FeedbackVectorSlot slot) { |
2120 if (var->IsUnallocated()) { | 2133 if (var->IsUnallocated()) { |
2121 // Global var, const, or let. | 2134 // Global var, const, or let. |
| 2135 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
2122 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); | 2136 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); |
2123 CallStoreIC(slot, var->name()); | 2137 EmitLoadStoreICSlot(slot); |
| 2138 CallStoreIC(); |
2124 | 2139 |
2125 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { | 2140 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { |
2126 DCHECK(!var->IsLookupSlot()); | 2141 DCHECK(!var->IsLookupSlot()); |
2127 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2142 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2128 MemOperand location = VarOperand(var, r1); | 2143 MemOperand location = VarOperand(var, r1); |
2129 // Perform an initialization check for lexically declared variables. | 2144 // Perform an initialization check for lexically declared variables. |
2130 if (var->binding_needs_init()) { | 2145 if (var->binding_needs_init()) { |
2131 Label assign; | 2146 Label assign; |
2132 __ ldr(r3, location); | 2147 __ ldr(r3, location); |
2133 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 2148 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2181 } | 2196 } |
2182 } | 2197 } |
2183 | 2198 |
2184 | 2199 |
2185 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2200 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2186 // Assignment to a property, using a named store IC. | 2201 // Assignment to a property, using a named store IC. |
2187 Property* prop = expr->target()->AsProperty(); | 2202 Property* prop = expr->target()->AsProperty(); |
2188 DCHECK(prop != NULL); | 2203 DCHECK(prop != NULL); |
2189 DCHECK(prop->key()->IsLiteral()); | 2204 DCHECK(prop->key()->IsLiteral()); |
2190 | 2205 |
| 2206 __ mov(StoreDescriptor::NameRegister(), |
| 2207 Operand(prop->key()->AsLiteral()->value())); |
2191 PopOperand(StoreDescriptor::ReceiverRegister()); | 2208 PopOperand(StoreDescriptor::ReceiverRegister()); |
2192 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 2209 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2210 CallStoreIC(); |
2193 | 2211 |
2194 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2212 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2195 context()->Plug(r0); | 2213 context()->Plug(r0); |
2196 } | 2214 } |
2197 | 2215 |
2198 | 2216 |
2199 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2217 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2200 // Assignment to named property of super. | 2218 // Assignment to named property of super. |
2201 // r0 : value | 2219 // r0 : value |
2202 // stack : receiver ('this'), home_object | 2220 // stack : receiver ('this'), home_object |
(...skipping 21 matching lines...) Expand all Loading... |
2224 : Runtime::kStoreKeyedToSuper_Sloppy); | 2242 : Runtime::kStoreKeyedToSuper_Sloppy); |
2225 } | 2243 } |
2226 | 2244 |
2227 | 2245 |
2228 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2246 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2229 // Assignment to a property, using a keyed store IC. | 2247 // Assignment to a property, using a keyed store IC. |
2230 PopOperands(StoreDescriptor::ReceiverRegister(), | 2248 PopOperands(StoreDescriptor::ReceiverRegister(), |
2231 StoreDescriptor::NameRegister()); | 2249 StoreDescriptor::NameRegister()); |
2232 DCHECK(StoreDescriptor::ValueRegister().is(r0)); | 2250 DCHECK(StoreDescriptor::ValueRegister().is(r0)); |
2233 | 2251 |
2234 CallKeyedStoreIC(expr->AssignmentSlot()); | 2252 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2253 CallKeyedStoreIC(); |
2235 | 2254 |
2236 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2255 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2237 context()->Plug(r0); | 2256 context()->Plug(r0); |
2238 } | 2257 } |
2239 | 2258 |
2240 | 2259 |
2241 void FullCodeGenerator::CallIC(Handle<Code> code, | 2260 void FullCodeGenerator::CallIC(Handle<Code> code, |
2242 TypeFeedbackId ast_id) { | 2261 TypeFeedbackId ast_id) { |
2243 ic_total_count_++; | 2262 ic_total_count_++; |
2244 // All calls must have a predictable size in full-codegen code to ensure that | 2263 // All calls must have a predictable size in full-codegen code to ensure that |
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3278 } | 3297 } |
3279 } else { | 3298 } else { |
3280 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3299 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3281 Token::ASSIGN, expr->CountSlot()); | 3300 Token::ASSIGN, expr->CountSlot()); |
3282 PrepareForBailoutForId(expr->AssignmentId(), | 3301 PrepareForBailoutForId(expr->AssignmentId(), |
3283 BailoutState::TOS_REGISTER); | 3302 BailoutState::TOS_REGISTER); |
3284 context()->Plug(r0); | 3303 context()->Plug(r0); |
3285 } | 3304 } |
3286 break; | 3305 break; |
3287 case NAMED_PROPERTY: { | 3306 case NAMED_PROPERTY: { |
| 3307 __ mov(StoreDescriptor::NameRegister(), |
| 3308 Operand(prop->key()->AsLiteral()->value())); |
3288 PopOperand(StoreDescriptor::ReceiverRegister()); | 3309 PopOperand(StoreDescriptor::ReceiverRegister()); |
3289 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); | 3310 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3311 CallStoreIC(); |
3290 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 3312 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
3291 if (expr->is_postfix()) { | 3313 if (expr->is_postfix()) { |
3292 if (!context()->IsEffect()) { | 3314 if (!context()->IsEffect()) { |
3293 context()->PlugTOS(); | 3315 context()->PlugTOS(); |
3294 } | 3316 } |
3295 } else { | 3317 } else { |
3296 context()->Plug(r0); | 3318 context()->Plug(r0); |
3297 } | 3319 } |
3298 break; | 3320 break; |
3299 } | 3321 } |
(...skipping 17 matching lines...) Expand all Loading... |
3317 context()->PlugTOS(); | 3339 context()->PlugTOS(); |
3318 } | 3340 } |
3319 } else { | 3341 } else { |
3320 context()->Plug(r0); | 3342 context()->Plug(r0); |
3321 } | 3343 } |
3322 break; | 3344 break; |
3323 } | 3345 } |
3324 case KEYED_PROPERTY: { | 3346 case KEYED_PROPERTY: { |
3325 PopOperands(StoreDescriptor::ReceiverRegister(), | 3347 PopOperands(StoreDescriptor::ReceiverRegister(), |
3326 StoreDescriptor::NameRegister()); | 3348 StoreDescriptor::NameRegister()); |
3327 CallKeyedStoreIC(expr->CountSlot()); | 3349 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3350 CallKeyedStoreIC(); |
3328 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 3351 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
3329 if (expr->is_postfix()) { | 3352 if (expr->is_postfix()) { |
3330 if (!context()->IsEffect()) { | 3353 if (!context()->IsEffect()) { |
3331 context()->PlugTOS(); | 3354 context()->PlugTOS(); |
3332 } | 3355 } |
3333 } else { | 3356 } else { |
3334 context()->Plug(r0); | 3357 context()->Plug(r0); |
3335 } | 3358 } |
3336 break; | 3359 break; |
3337 } | 3360 } |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3768 DCHECK(interrupt_address == | 3791 DCHECK(interrupt_address == |
3769 isolate->builtins()->OnStackReplacement()->entry()); | 3792 isolate->builtins()->OnStackReplacement()->entry()); |
3770 return ON_STACK_REPLACEMENT; | 3793 return ON_STACK_REPLACEMENT; |
3771 } | 3794 } |
3772 | 3795 |
3773 | 3796 |
3774 } // namespace internal | 3797 } // namespace internal |
3775 } // namespace v8 | 3798 } // namespace v8 |
3776 | 3799 |
3777 #endif // V8_TARGET_ARCH_ARM | 3800 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |