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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); | 1151 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); |
1152 __ Bind(&exit); | 1152 __ Bind(&exit); |
1153 decrement_loop_depth(); | 1153 decrement_loop_depth(); |
1154 } | 1154 } |
1155 | 1155 |
1156 | 1156 |
1157 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, | 1157 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
1158 FeedbackVectorSlot slot) { | 1158 FeedbackVectorSlot slot) { |
1159 DCHECK(NeedsHomeObject(initializer)); | 1159 DCHECK(NeedsHomeObject(initializer)); |
1160 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1160 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1161 __ Mov(StoreDescriptor::NameRegister(), |
| 1162 Operand(isolate()->factory()->home_object_symbol())); |
1161 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); | 1163 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); |
1162 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); | 1164 EmitLoadStoreICSlot(slot); |
| 1165 CallStoreIC(); |
1163 } | 1166 } |
1164 | 1167 |
1165 | 1168 |
1166 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, | 1169 void FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer, |
1167 int offset, | 1170 int offset, |
1168 FeedbackVectorSlot slot) { | 1171 FeedbackVectorSlot slot) { |
1169 DCHECK(NeedsHomeObject(initializer)); | 1172 DCHECK(NeedsHomeObject(initializer)); |
1170 __ Move(StoreDescriptor::ReceiverRegister(), x0); | 1173 __ Move(StoreDescriptor::ReceiverRegister(), x0); |
| 1174 __ Mov(StoreDescriptor::NameRegister(), |
| 1175 Operand(isolate()->factory()->home_object_symbol())); |
1171 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); | 1176 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); |
1172 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); | 1177 EmitLoadStoreICSlot(slot); |
| 1178 CallStoreIC(); |
1173 } | 1179 } |
1174 | 1180 |
1175 | 1181 |
1176 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1182 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1177 TypeofMode typeof_mode, | 1183 TypeofMode typeof_mode, |
1178 Label* slow) { | 1184 Label* slow) { |
1179 Register current = cp; | 1185 Register current = cp; |
1180 Register next = x10; | 1186 Register next = x10; |
1181 Register temp = x11; | 1187 Register temp = x11; |
1182 | 1188 |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1402 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1397 // Fall through. | 1403 // Fall through. |
1398 case ObjectLiteral::Property::COMPUTED: | 1404 case ObjectLiteral::Property::COMPUTED: |
1399 // It is safe to use [[Put]] here because the boilerplate already | 1405 // It is safe to use [[Put]] here because the boilerplate already |
1400 // contains computed properties with an uninitialized value. | 1406 // contains computed properties with an uninitialized value. |
1401 if (key->IsStringLiteral()) { | 1407 if (key->IsStringLiteral()) { |
1402 DCHECK(key->IsPropertyName()); | 1408 DCHECK(key->IsPropertyName()); |
1403 if (property->emit_store()) { | 1409 if (property->emit_store()) { |
1404 VisitForAccumulatorValue(value); | 1410 VisitForAccumulatorValue(value); |
1405 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 1411 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 1412 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
1406 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1413 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
1407 CallStoreIC(property->GetSlot(0), key->value()); | 1414 EmitLoadStoreICSlot(property->GetSlot(0)); |
| 1415 CallStoreIC(); |
1408 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); | 1416 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); |
1409 | 1417 |
1410 if (NeedsHomeObject(value)) { | 1418 if (NeedsHomeObject(value)) { |
1411 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); | 1419 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
1412 } | 1420 } |
1413 } else { | 1421 } else { |
1414 VisitForEffect(value); | 1422 VisitForEffect(value); |
1415 } | 1423 } |
1416 break; | 1424 break; |
1417 } | 1425 } |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1591 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1599 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1592 | 1600 |
1593 if (!result_saved) { | 1601 if (!result_saved) { |
1594 PushOperand(x0); | 1602 PushOperand(x0); |
1595 result_saved = true; | 1603 result_saved = true; |
1596 } | 1604 } |
1597 VisitForAccumulatorValue(subexpr); | 1605 VisitForAccumulatorValue(subexpr); |
1598 | 1606 |
1599 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); | 1607 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); |
1600 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1608 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
1601 CallKeyedStoreIC(expr->LiteralFeedbackSlot()); | 1609 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); |
| 1610 CallKeyedStoreIC(); |
1602 | 1611 |
1603 PrepareForBailoutForId(expr->GetIdForElement(array_index), | 1612 PrepareForBailoutForId(expr->GetIdForElement(array_index), |
1604 BailoutState::NO_REGISTERS); | 1613 BailoutState::NO_REGISTERS); |
1605 } | 1614 } |
1606 | 1615 |
1607 if (result_saved) { | 1616 if (result_saved) { |
1608 context()->PlugTOS(); | 1617 context()->PlugTOS(); |
1609 } else { | 1618 } else { |
1610 context()->Plug(x0); | 1619 context()->Plug(x0); |
1611 } | 1620 } |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1933 EmitVariableAssignment(var, Token::ASSIGN, slot); | 1942 EmitVariableAssignment(var, Token::ASSIGN, slot); |
1934 break; | 1943 break; |
1935 } | 1944 } |
1936 case NAMED_PROPERTY: { | 1945 case NAMED_PROPERTY: { |
1937 PushOperand(x0); // Preserve value. | 1946 PushOperand(x0); // Preserve value. |
1938 VisitForAccumulatorValue(prop->obj()); | 1947 VisitForAccumulatorValue(prop->obj()); |
1939 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid | 1948 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid |
1940 // this copy. | 1949 // this copy. |
1941 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 1950 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
1942 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1951 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
1943 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1952 __ Mov(StoreDescriptor::NameRegister(), |
| 1953 Operand(prop->key()->AsLiteral()->value())); |
| 1954 EmitLoadStoreICSlot(slot); |
| 1955 CallStoreIC(); |
1944 break; | 1956 break; |
1945 } | 1957 } |
1946 case NAMED_SUPER_PROPERTY: { | 1958 case NAMED_SUPER_PROPERTY: { |
1947 PushOperand(x0); | 1959 PushOperand(x0); |
1948 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | 1960 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); |
1949 VisitForAccumulatorValue( | 1961 VisitForAccumulatorValue( |
1950 prop->obj()->AsSuperPropertyReference()->home_object()); | 1962 prop->obj()->AsSuperPropertyReference()->home_object()); |
1951 // stack: value, this; x0: home_object | 1963 // stack: value, this; x0: home_object |
1952 Register scratch = x10; | 1964 Register scratch = x10; |
1953 Register scratch2 = x11; | 1965 Register scratch2 = x11; |
(...skipping 26 matching lines...) Expand all Loading... |
1980 EmitKeyedSuperPropertyStore(prop); | 1992 EmitKeyedSuperPropertyStore(prop); |
1981 break; | 1993 break; |
1982 } | 1994 } |
1983 case KEYED_PROPERTY: { | 1995 case KEYED_PROPERTY: { |
1984 PushOperand(x0); // Preserve value. | 1996 PushOperand(x0); // Preserve value. |
1985 VisitForStackValue(prop->obj()); | 1997 VisitForStackValue(prop->obj()); |
1986 VisitForAccumulatorValue(prop->key()); | 1998 VisitForAccumulatorValue(prop->key()); |
1987 __ Mov(StoreDescriptor::NameRegister(), x0); | 1999 __ Mov(StoreDescriptor::NameRegister(), x0); |
1988 PopOperands(StoreDescriptor::ReceiverRegister(), | 2000 PopOperands(StoreDescriptor::ReceiverRegister(), |
1989 StoreDescriptor::ValueRegister()); | 2001 StoreDescriptor::ValueRegister()); |
1990 CallKeyedStoreIC(slot); | 2002 EmitLoadStoreICSlot(slot); |
| 2003 CallKeyedStoreIC(); |
1991 break; | 2004 break; |
1992 } | 2005 } |
1993 } | 2006 } |
1994 context()->Plug(x0); | 2007 context()->Plug(x0); |
1995 } | 2008 } |
1996 | 2009 |
1997 | 2010 |
1998 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2011 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
1999 Variable* var, MemOperand location) { | 2012 Variable* var, MemOperand location) { |
2000 __ Str(result_register(), location); | 2013 __ Str(result_register(), location); |
2001 if (var->IsContextSlot()) { | 2014 if (var->IsContextSlot()) { |
2002 // RecordWrite may destroy all its register arguments. | 2015 // RecordWrite may destroy all its register arguments. |
2003 __ Mov(x10, result_register()); | 2016 __ Mov(x10, result_register()); |
2004 int offset = Context::SlotOffset(var->index()); | 2017 int offset = Context::SlotOffset(var->index()); |
2005 __ RecordWriteContextSlot( | 2018 __ RecordWriteContextSlot( |
2006 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 2019 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |
2007 } | 2020 } |
2008 } | 2021 } |
2009 | 2022 |
2010 | 2023 |
2011 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2024 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
2012 FeedbackVectorSlot slot) { | 2025 FeedbackVectorSlot slot) { |
2013 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2026 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
2014 if (var->IsUnallocated()) { | 2027 if (var->IsUnallocated()) { |
2015 // Global var, const, or let. | 2028 // Global var, const, or let. |
| 2029 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
2016 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); | 2030 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); |
2017 CallStoreIC(slot, var->name()); | 2031 EmitLoadStoreICSlot(slot); |
| 2032 CallStoreIC(); |
2018 | 2033 |
2019 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { | 2034 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { |
2020 DCHECK(!var->IsLookupSlot()); | 2035 DCHECK(!var->IsLookupSlot()); |
2021 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2036 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2022 MemOperand location = VarOperand(var, x1); | 2037 MemOperand location = VarOperand(var, x1); |
2023 // Perform an initialization check for lexically declared variables. | 2038 // Perform an initialization check for lexically declared variables. |
2024 if (var->binding_needs_init()) { | 2039 if (var->binding_needs_init()) { |
2025 Label assign; | 2040 Label assign; |
2026 __ Ldr(x10, location); | 2041 __ Ldr(x10, location); |
2027 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); | 2042 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2073 } | 2088 } |
2074 | 2089 |
2075 | 2090 |
2076 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2091 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2077 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2092 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); |
2078 // Assignment to a property, using a named store IC. | 2093 // Assignment to a property, using a named store IC. |
2079 Property* prop = expr->target()->AsProperty(); | 2094 Property* prop = expr->target()->AsProperty(); |
2080 DCHECK(prop != NULL); | 2095 DCHECK(prop != NULL); |
2081 DCHECK(prop->key()->IsLiteral()); | 2096 DCHECK(prop->key()->IsLiteral()); |
2082 | 2097 |
| 2098 __ Mov(StoreDescriptor::NameRegister(), |
| 2099 Operand(prop->key()->AsLiteral()->value())); |
2083 PopOperand(StoreDescriptor::ReceiverRegister()); | 2100 PopOperand(StoreDescriptor::ReceiverRegister()); |
2084 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 2101 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2102 CallStoreIC(); |
2085 | 2103 |
2086 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2104 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2087 context()->Plug(x0); | 2105 context()->Plug(x0); |
2088 } | 2106 } |
2089 | 2107 |
2090 | 2108 |
2091 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2109 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2092 // Assignment to named property of super. | 2110 // Assignment to named property of super. |
2093 // x0 : value | 2111 // x0 : value |
2094 // stack : receiver ('this'), home_object | 2112 // stack : receiver ('this'), home_object |
(...skipping 24 matching lines...) Expand all Loading... |
2119 | 2137 |
2120 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2138 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2121 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2139 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
2122 // Assignment to a property, using a keyed store IC. | 2140 // Assignment to a property, using a keyed store IC. |
2123 | 2141 |
2124 // TODO(all): Could we pass this in registers rather than on the stack? | 2142 // TODO(all): Could we pass this in registers rather than on the stack? |
2125 PopOperands(StoreDescriptor::NameRegister(), | 2143 PopOperands(StoreDescriptor::NameRegister(), |
2126 StoreDescriptor::ReceiverRegister()); | 2144 StoreDescriptor::ReceiverRegister()); |
2127 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 2145 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
2128 | 2146 |
2129 CallKeyedStoreIC(expr->AssignmentSlot()); | 2147 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2148 CallKeyedStoreIC(); |
2130 | 2149 |
2131 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2150 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2132 context()->Plug(x0); | 2151 context()->Plug(x0); |
2133 } | 2152 } |
2134 | 2153 |
2135 | 2154 |
2136 void FullCodeGenerator::CallIC(Handle<Code> code, | 2155 void FullCodeGenerator::CallIC(Handle<Code> code, |
2137 TypeFeedbackId ast_id) { | 2156 TypeFeedbackId ast_id) { |
2138 ic_total_count_++; | 2157 ic_total_count_++; |
2139 // All calls must have a predictable size in full-codegen code to ensure that | 2158 // All calls must have a predictable size in full-codegen code to ensure that |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3200 } | 3219 } |
3201 } else { | 3220 } else { |
3202 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3221 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3203 Token::ASSIGN, expr->CountSlot()); | 3222 Token::ASSIGN, expr->CountSlot()); |
3204 PrepareForBailoutForId(expr->AssignmentId(), | 3223 PrepareForBailoutForId(expr->AssignmentId(), |
3205 BailoutState::TOS_REGISTER); | 3224 BailoutState::TOS_REGISTER); |
3206 context()->Plug(x0); | 3225 context()->Plug(x0); |
3207 } | 3226 } |
3208 break; | 3227 break; |
3209 case NAMED_PROPERTY: { | 3228 case NAMED_PROPERTY: { |
| 3229 __ Mov(StoreDescriptor::NameRegister(), |
| 3230 Operand(prop->key()->AsLiteral()->value())); |
3210 PopOperand(StoreDescriptor::ReceiverRegister()); | 3231 PopOperand(StoreDescriptor::ReceiverRegister()); |
3211 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); | 3232 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3233 CallStoreIC(); |
3212 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 3234 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
3213 if (expr->is_postfix()) { | 3235 if (expr->is_postfix()) { |
3214 if (!context()->IsEffect()) { | 3236 if (!context()->IsEffect()) { |
3215 context()->PlugTOS(); | 3237 context()->PlugTOS(); |
3216 } | 3238 } |
3217 } else { | 3239 } else { |
3218 context()->Plug(x0); | 3240 context()->Plug(x0); |
3219 } | 3241 } |
3220 break; | 3242 break; |
3221 } | 3243 } |
(...skipping 17 matching lines...) Expand all Loading... |
3239 context()->PlugTOS(); | 3261 context()->PlugTOS(); |
3240 } | 3262 } |
3241 } else { | 3263 } else { |
3242 context()->Plug(x0); | 3264 context()->Plug(x0); |
3243 } | 3265 } |
3244 break; | 3266 break; |
3245 } | 3267 } |
3246 case KEYED_PROPERTY: { | 3268 case KEYED_PROPERTY: { |
3247 PopOperand(StoreDescriptor::NameRegister()); | 3269 PopOperand(StoreDescriptor::NameRegister()); |
3248 PopOperand(StoreDescriptor::ReceiverRegister()); | 3270 PopOperand(StoreDescriptor::ReceiverRegister()); |
3249 CallKeyedStoreIC(expr->CountSlot()); | 3271 EmitLoadStoreICSlot(expr->CountSlot()); |
| 3272 CallKeyedStoreIC(); |
3250 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 3273 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
3251 if (expr->is_postfix()) { | 3274 if (expr->is_postfix()) { |
3252 if (!context()->IsEffect()) { | 3275 if (!context()->IsEffect()) { |
3253 context()->PlugTOS(); | 3276 context()->PlugTOS(); |
3254 } | 3277 } |
3255 } else { | 3278 } else { |
3256 context()->Plug(x0); | 3279 context()->Plug(x0); |
3257 } | 3280 } |
3258 break; | 3281 break; |
3259 } | 3282 } |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3778 } | 3801 } |
3779 | 3802 |
3780 return INTERRUPT; | 3803 return INTERRUPT; |
3781 } | 3804 } |
3782 | 3805 |
3783 | 3806 |
3784 } // namespace internal | 3807 } // namespace internal |
3785 } // namespace v8 | 3808 } // namespace v8 |
3786 | 3809 |
3787 #endif // V8_TARGET_ARCH_ARM64 | 3810 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |