| 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 1257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 break; | 1268 break; |
| 1269 } | 1269 } |
| 1270 | 1270 |
| 1271 case VariableLocation::PARAMETER: | 1271 case VariableLocation::PARAMETER: |
| 1272 case VariableLocation::LOCAL: | 1272 case VariableLocation::LOCAL: |
| 1273 case VariableLocation::CONTEXT: { | 1273 case VariableLocation::CONTEXT: { |
| 1274 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); | 1274 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); |
| 1275 Comment cmnt(masm_, var->IsContextSlot() | 1275 Comment cmnt(masm_, var->IsContextSlot() |
| 1276 ? "Context variable" | 1276 ? "Context variable" |
| 1277 : "Stack variable"); | 1277 : "Stack variable"); |
| 1278 if (proxy->needs_hole_check()) { | 1278 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) { |
| 1279 // Throw a reference error when using an uninitialized let/const | 1279 // Throw a reference error when using an uninitialized let/const |
| 1280 // binding in harmony mode. | 1280 // binding in harmony mode. |
| 1281 Label done; | 1281 Label done; |
| 1282 GetVar(x0, var); | 1282 GetVar(x0, var); |
| 1283 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done); | 1283 __ JumpIfNotRoot(x0, Heap::kTheHoleValueRootIndex, &done); |
| 1284 __ Mov(x0, Operand(var->name())); | 1284 __ Mov(x0, Operand(var->name())); |
| 1285 __ Push(x0); | 1285 __ Push(x0); |
| 1286 __ CallRuntime(Runtime::kThrowReferenceError); | 1286 __ CallRuntime(Runtime::kThrowReferenceError); |
| 1287 __ Bind(&done); | 1287 __ Bind(&done); |
| 1288 context()->Plug(x0); | 1288 context()->Plug(x0); |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 // Deoptimization point in case the binary operation may have side effects. | 1703 // Deoptimization point in case the binary operation may have side effects. |
| 1704 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); | 1704 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); |
| 1705 } else { | 1705 } else { |
| 1706 VisitForAccumulatorValue(expr->value()); | 1706 VisitForAccumulatorValue(expr->value()); |
| 1707 } | 1707 } |
| 1708 | 1708 |
| 1709 SetExpressionPosition(expr); | 1709 SetExpressionPosition(expr); |
| 1710 | 1710 |
| 1711 // Store the value. | 1711 // Store the value. |
| 1712 switch (assign_type) { | 1712 switch (assign_type) { |
| 1713 case VARIABLE: | 1713 case VARIABLE: { |
| 1714 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1714 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1715 expr->op(), expr->AssignmentSlot()); | 1715 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
| 1716 proxy->hole_check_mode()); |
| 1716 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1717 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1717 context()->Plug(x0); | 1718 context()->Plug(x0); |
| 1718 break; | 1719 break; |
| 1720 } |
| 1719 case NAMED_PROPERTY: | 1721 case NAMED_PROPERTY: |
| 1720 EmitNamedPropertyAssignment(expr); | 1722 EmitNamedPropertyAssignment(expr); |
| 1721 break; | 1723 break; |
| 1722 case NAMED_SUPER_PROPERTY: | 1724 case NAMED_SUPER_PROPERTY: |
| 1723 EmitNamedSuperPropertyStore(property); | 1725 EmitNamedSuperPropertyStore(property); |
| 1724 context()->Plug(x0); | 1726 context()->Plug(x0); |
| 1725 break; | 1727 break; |
| 1726 case KEYED_SUPER_PROPERTY: | 1728 case KEYED_SUPER_PROPERTY: |
| 1727 EmitKeyedSuperPropertyStore(property); | 1729 EmitKeyedSuperPropertyStore(property); |
| 1728 context()->Plug(x0); | 1730 context()->Plug(x0); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 | 1903 |
| 1902 void FullCodeGenerator::EmitAssignment(Expression* expr, | 1904 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 1903 FeedbackVectorSlot slot) { | 1905 FeedbackVectorSlot slot) { |
| 1904 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 1906 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
| 1905 | 1907 |
| 1906 Property* prop = expr->AsProperty(); | 1908 Property* prop = expr->AsProperty(); |
| 1907 LhsKind assign_type = Property::GetAssignType(prop); | 1909 LhsKind assign_type = Property::GetAssignType(prop); |
| 1908 | 1910 |
| 1909 switch (assign_type) { | 1911 switch (assign_type) { |
| 1910 case VARIABLE: { | 1912 case VARIABLE: { |
| 1911 Variable* var = expr->AsVariableProxy()->var(); | 1913 VariableProxy* proxy = expr->AsVariableProxy(); |
| 1912 EffectContext context(this); | 1914 EffectContext context(this); |
| 1913 EmitVariableAssignment(var, Token::ASSIGN, slot); | 1915 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot, |
| 1916 proxy->hole_check_mode()); |
| 1914 break; | 1917 break; |
| 1915 } | 1918 } |
| 1916 case NAMED_PROPERTY: { | 1919 case NAMED_PROPERTY: { |
| 1917 PushOperand(x0); // Preserve value. | 1920 PushOperand(x0); // Preserve value. |
| 1918 VisitForAccumulatorValue(prop->obj()); | 1921 VisitForAccumulatorValue(prop->obj()); |
| 1919 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid | 1922 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid |
| 1920 // this copy. | 1923 // this copy. |
| 1921 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 1924 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
| 1922 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1925 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1923 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1926 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1980 __ Str(result_register(), location); | 1983 __ Str(result_register(), location); |
| 1981 if (var->IsContextSlot()) { | 1984 if (var->IsContextSlot()) { |
| 1982 // RecordWrite may destroy all its register arguments. | 1985 // RecordWrite may destroy all its register arguments. |
| 1983 __ Mov(x10, result_register()); | 1986 __ Mov(x10, result_register()); |
| 1984 int offset = Context::SlotOffset(var->index()); | 1987 int offset = Context::SlotOffset(var->index()); |
| 1985 __ RecordWriteContextSlot( | 1988 __ RecordWriteContextSlot( |
| 1986 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 1989 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |
| 1987 } | 1990 } |
| 1988 } | 1991 } |
| 1989 | 1992 |
| 1990 | |
| 1991 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 1993 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 1992 FeedbackVectorSlot slot) { | 1994 FeedbackVectorSlot slot, |
| 1995 HoleCheckMode hole_check_mode) { |
| 1993 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 1996 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
| 1994 if (var->IsUnallocated()) { | 1997 if (var->IsUnallocated()) { |
| 1995 // Global var, const, or let. | 1998 // Global var, const, or let. |
| 1996 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); | 1999 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); |
| 1997 CallStoreIC(slot, var->name()); | 2000 CallStoreIC(slot, var->name()); |
| 1998 | 2001 |
| 1999 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { | 2002 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { |
| 2000 DCHECK(!var->IsLookupSlot()); | 2003 DCHECK(!var->IsLookupSlot()); |
| 2001 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2004 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2002 MemOperand location = VarOperand(var, x1); | 2005 MemOperand location = VarOperand(var, x1); |
| (...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3099 { | 3102 { |
| 3100 Assembler::BlockPoolsScope scope(masm_); | 3103 Assembler::BlockPoolsScope scope(masm_); |
| 3101 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code(); | 3104 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code(); |
| 3102 CallIC(code, expr->CountBinOpFeedbackId()); | 3105 CallIC(code, expr->CountBinOpFeedbackId()); |
| 3103 patch_site.EmitPatchInfo(); | 3106 patch_site.EmitPatchInfo(); |
| 3104 } | 3107 } |
| 3105 __ Bind(&done); | 3108 __ Bind(&done); |
| 3106 | 3109 |
| 3107 // Store the value returned in x0. | 3110 // Store the value returned in x0. |
| 3108 switch (assign_type) { | 3111 switch (assign_type) { |
| 3109 case VARIABLE: | 3112 case VARIABLE: { |
| 3113 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 3110 if (expr->is_postfix()) { | 3114 if (expr->is_postfix()) { |
| 3111 { EffectContext context(this); | 3115 { EffectContext context(this); |
| 3112 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3116 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), |
| 3113 Token::ASSIGN, expr->CountSlot()); | 3117 proxy->hole_check_mode()); |
| 3114 PrepareForBailoutForId(expr->AssignmentId(), | 3118 PrepareForBailoutForId(expr->AssignmentId(), |
| 3115 BailoutState::TOS_REGISTER); | 3119 BailoutState::TOS_REGISTER); |
| 3116 context.Plug(x0); | 3120 context.Plug(x0); |
| 3117 } | 3121 } |
| 3118 // For all contexts except EffectConstant We have the result on | 3122 // For all contexts except EffectConstant We have the result on |
| 3119 // top of the stack. | 3123 // top of the stack. |
| 3120 if (!context()->IsEffect()) { | 3124 if (!context()->IsEffect()) { |
| 3121 context()->PlugTOS(); | 3125 context()->PlugTOS(); |
| 3122 } | 3126 } |
| 3123 } else { | 3127 } else { |
| 3124 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3128 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), |
| 3125 Token::ASSIGN, expr->CountSlot()); | 3129 proxy->hole_check_mode()); |
| 3126 PrepareForBailoutForId(expr->AssignmentId(), | 3130 PrepareForBailoutForId(expr->AssignmentId(), |
| 3127 BailoutState::TOS_REGISTER); | 3131 BailoutState::TOS_REGISTER); |
| 3128 context()->Plug(x0); | 3132 context()->Plug(x0); |
| 3129 } | 3133 } |
| 3130 break; | 3134 break; |
| 3135 } |
| 3131 case NAMED_PROPERTY: { | 3136 case NAMED_PROPERTY: { |
| 3132 PopOperand(StoreDescriptor::ReceiverRegister()); | 3137 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 3133 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); | 3138 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); |
| 3134 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 3139 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 3135 if (expr->is_postfix()) { | 3140 if (expr->is_postfix()) { |
| 3136 if (!context()->IsEffect()) { | 3141 if (!context()->IsEffect()) { |
| 3137 context()->PlugTOS(); | 3142 context()->PlugTOS(); |
| 3138 } | 3143 } |
| 3139 } else { | 3144 } else { |
| 3140 context()->Plug(x0); | 3145 context()->Plug(x0); |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3699 } | 3704 } |
| 3700 | 3705 |
| 3701 return INTERRUPT; | 3706 return INTERRUPT; |
| 3702 } | 3707 } |
| 3703 | 3708 |
| 3704 | 3709 |
| 3705 } // namespace internal | 3710 } // namespace internal |
| 3706 } // namespace v8 | 3711 } // namespace v8 |
| 3707 | 3712 |
| 3708 #endif // V8_TARGET_ARCH_ARM64 | 3713 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |