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