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 |