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