| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 1962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1973 case VARIABLE: | 1973 case VARIABLE: |
| 1974 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1974 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 1975 expr->op()); | 1975 expr->op()); |
| 1976 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1976 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 1977 context()->Plug(x0); | 1977 context()->Plug(x0); |
| 1978 break; | 1978 break; |
| 1979 case NAMED_PROPERTY: | 1979 case NAMED_PROPERTY: |
| 1980 EmitNamedPropertyAssignment(expr); | 1980 EmitNamedPropertyAssignment(expr); |
| 1981 break; | 1981 break; |
| 1982 case NAMED_SUPER_PROPERTY: | 1982 case NAMED_SUPER_PROPERTY: |
| 1983 EmitNamedSuperPropertyAssignment(expr); | 1983 EmitNamedSuperPropertyStore(property); |
| 1984 context()->Plug(x0); |
| 1984 break; | 1985 break; |
| 1985 case KEYED_PROPERTY: | 1986 case KEYED_PROPERTY: |
| 1986 EmitKeyedPropertyAssignment(expr); | 1987 EmitKeyedPropertyAssignment(expr); |
| 1987 break; | 1988 break; |
| 1988 } | 1989 } |
| 1989 } | 1990 } |
| 1990 | 1991 |
| 1991 | 1992 |
| 1992 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1993 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1993 SetSourcePosition(prop->position()); | 1994 SetSourcePosition(prop->position()); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2290 __ Mov(StoreDescriptor::NameRegister(), | 2291 __ Mov(StoreDescriptor::NameRegister(), |
| 2291 Operand(prop->key()->AsLiteral()->value())); | 2292 Operand(prop->key()->AsLiteral()->value())); |
| 2292 __ Pop(StoreDescriptor::ReceiverRegister()); | 2293 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2293 CallStoreIC(expr->AssignmentFeedbackId()); | 2294 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2294 | 2295 |
| 2295 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2296 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2296 context()->Plug(x0); | 2297 context()->Plug(x0); |
| 2297 } | 2298 } |
| 2298 | 2299 |
| 2299 | 2300 |
| 2300 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { | 2301 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2301 // Assignment to named property of super. | 2302 // Assignment to named property of super. |
| 2302 // x0 : value | 2303 // x0 : value |
| 2303 // stack : receiver ('this'), home_object | 2304 // stack : receiver ('this'), home_object |
| 2304 Property* prop = expr->target()->AsProperty(); | |
| 2305 DCHECK(prop != NULL); | 2305 DCHECK(prop != NULL); |
| 2306 Literal* key = prop->key()->AsLiteral(); | 2306 Literal* key = prop->key()->AsLiteral(); |
| 2307 DCHECK(key != NULL); | 2307 DCHECK(key != NULL); |
| 2308 | 2308 |
| 2309 __ Push(x0); | 2309 __ Push(x0); |
| 2310 __ Push(key->value()); | 2310 __ Push(key->value()); |
| 2311 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict | 2311 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
| 2312 : Runtime::kStoreToSuper_Sloppy), | 2312 : Runtime::kStoreToSuper_Sloppy), |
| 2313 4); | 2313 4); |
| 2314 context()->Plug(x0); | |
| 2315 } | 2314 } |
| 2316 | 2315 |
| 2317 | 2316 |
| 2318 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2317 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2319 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2318 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
| 2320 // Assignment to a property, using a keyed store IC. | 2319 // Assignment to a property, using a keyed store IC. |
| 2321 | 2320 |
| 2322 // Record source code position before IC call. | 2321 // Record source code position before IC call. |
| 2323 SetSourcePosition(expr->position()); | 2322 SetSourcePosition(expr->position()); |
| 2324 // TODO(all): Could we pass this in registers rather than on the stack? | 2323 // TODO(all): Could we pass this in registers rather than on the stack? |
| (...skipping 1707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4032 | 4031 |
| 4033 | 4032 |
| 4034 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4033 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4035 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4034 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4036 | 4035 |
| 4037 Comment cmnt(masm_, "[ CountOperation"); | 4036 Comment cmnt(masm_, "[ CountOperation"); |
| 4038 SetSourcePosition(expr->position()); | 4037 SetSourcePosition(expr->position()); |
| 4039 | 4038 |
| 4040 // Expression can only be a property, a global or a (parameter or local) | 4039 // Expression can only be a property, a global or a (parameter or local) |
| 4041 // slot. | 4040 // slot. |
| 4042 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4041 enum LhsKind { |
| 4042 VARIABLE, |
| 4043 NAMED_PROPERTY, |
| 4044 KEYED_PROPERTY, |
| 4045 NAMED_SUPER_PROPERTY |
| 4046 }; |
| 4043 LhsKind assign_type = VARIABLE; | 4047 LhsKind assign_type = VARIABLE; |
| 4044 Property* prop = expr->expression()->AsProperty(); | 4048 Property* prop = expr->expression()->AsProperty(); |
| 4045 // In case of a property we use the uninitialized expression context | 4049 // In case of a property we use the uninitialized expression context |
| 4046 // of the key to detect a named property. | 4050 // of the key to detect a named property. |
| 4047 if (prop != NULL) { | 4051 if (prop != NULL) { |
| 4048 assign_type = | 4052 assign_type = |
| 4049 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4053 (prop->key()->IsPropertyName()) |
| 4050 if (prop->IsSuperAccess()) { | 4054 ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) |
| 4051 // throw exception. | 4055 : KEYED_PROPERTY; |
| 4052 VisitSuperReference(prop->obj()->AsSuperReference()); | |
| 4053 return; | |
| 4054 } | |
| 4055 } | 4056 } |
| 4056 | 4057 |
| 4057 // Evaluate expression and get value. | 4058 // Evaluate expression and get value. |
| 4058 if (assign_type == VARIABLE) { | 4059 if (assign_type == VARIABLE) { |
| 4059 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4060 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4060 AccumulatorValueContext context(this); | 4061 AccumulatorValueContext context(this); |
| 4061 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4062 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4062 } else { | 4063 } else { |
| 4063 // Reserve space for result of postfix operation. | 4064 // Reserve space for result of postfix operation. |
| 4064 if (expr->is_postfix() && !context()->IsEffect()) { | 4065 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4065 __ Push(xzr); | 4066 __ Push(xzr); |
| 4066 } | 4067 } |
| 4067 if (assign_type == NAMED_PROPERTY) { | 4068 if (assign_type == NAMED_PROPERTY) { |
| 4068 // Put the object both on the stack and in the register. | 4069 // Put the object both on the stack and in the register. |
| 4069 VisitForStackValue(prop->obj()); | 4070 VisitForStackValue(prop->obj()); |
| 4070 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 4071 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
| 4071 EmitNamedPropertyLoad(prop); | 4072 EmitNamedPropertyLoad(prop); |
| 4073 } else if (assign_type == NAMED_SUPER_PROPERTY) { |
| 4074 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 4075 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 4076 __ Push(result_register()); |
| 4077 const Register scratch = x10; |
| 4078 __ Peek(scratch, kPointerSize); |
| 4079 __ Push(scratch, result_register()); |
| 4080 EmitNamedSuperPropertyLoad(prop); |
| 4072 } else { | 4081 } else { |
| 4073 // KEYED_PROPERTY | 4082 // KEYED_PROPERTY |
| 4074 VisitForStackValue(prop->obj()); | 4083 VisitForStackValue(prop->obj()); |
| 4075 VisitForStackValue(prop->key()); | 4084 VisitForStackValue(prop->key()); |
| 4076 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); | 4085 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
| 4077 __ Peek(LoadDescriptor::NameRegister(), 0); | 4086 __ Peek(LoadDescriptor::NameRegister(), 0); |
| 4078 EmitKeyedPropertyLoad(prop); | 4087 EmitKeyedPropertyLoad(prop); |
| 4079 } | 4088 } |
| 4080 } | 4089 } |
| 4081 | 4090 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4102 // Save the result on the stack. If we have a named or keyed property we | 4111 // Save the result on the stack. If we have a named or keyed property we |
| 4103 // store the result under the receiver that is currently on top of the | 4112 // store the result under the receiver that is currently on top of the |
| 4104 // stack. | 4113 // stack. |
| 4105 switch (assign_type) { | 4114 switch (assign_type) { |
| 4106 case VARIABLE: | 4115 case VARIABLE: |
| 4107 __ Push(x0); | 4116 __ Push(x0); |
| 4108 break; | 4117 break; |
| 4109 case NAMED_PROPERTY: | 4118 case NAMED_PROPERTY: |
| 4110 __ Poke(x0, kPointerSize); | 4119 __ Poke(x0, kPointerSize); |
| 4111 break; | 4120 break; |
| 4121 case NAMED_SUPER_PROPERTY: |
| 4122 __ Poke(x0, kPointerSize * 2); |
| 4123 break; |
| 4112 case KEYED_PROPERTY: | 4124 case KEYED_PROPERTY: |
| 4113 __ Poke(x0, kPointerSize * 2); | 4125 __ Poke(x0, kPointerSize * 2); |
| 4114 break; | 4126 break; |
| 4115 } | 4127 } |
| 4116 } | 4128 } |
| 4117 } | 4129 } |
| 4118 | 4130 |
| 4119 __ Adds(x0, x0, Smi::FromInt(count_value)); | 4131 __ Adds(x0, x0, Smi::FromInt(count_value)); |
| 4120 __ B(vc, &done); | 4132 __ B(vc, &done); |
| 4121 // Call stub. Undo operation first. | 4133 // Call stub. Undo operation first. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4132 // Save the result on the stack. If we have a named or keyed property | 4144 // Save the result on the stack. If we have a named or keyed property |
| 4133 // we store the result under the receiver that is currently on top | 4145 // we store the result under the receiver that is currently on top |
| 4134 // of the stack. | 4146 // of the stack. |
| 4135 switch (assign_type) { | 4147 switch (assign_type) { |
| 4136 case VARIABLE: | 4148 case VARIABLE: |
| 4137 __ Push(x0); | 4149 __ Push(x0); |
| 4138 break; | 4150 break; |
| 4139 case NAMED_PROPERTY: | 4151 case NAMED_PROPERTY: |
| 4140 __ Poke(x0, kXRegSize); | 4152 __ Poke(x0, kXRegSize); |
| 4141 break; | 4153 break; |
| 4154 case NAMED_SUPER_PROPERTY: |
| 4155 __ Poke(x0, 2 * kXRegSize); |
| 4156 break; |
| 4142 case KEYED_PROPERTY: | 4157 case KEYED_PROPERTY: |
| 4143 __ Poke(x0, 2 * kXRegSize); | 4158 __ Poke(x0, 2 * kXRegSize); |
| 4144 break; | 4159 break; |
| 4145 } | 4160 } |
| 4146 } | 4161 } |
| 4147 } | 4162 } |
| 4148 | 4163 |
| 4149 __ Bind(&stub_call); | 4164 __ Bind(&stub_call); |
| 4150 __ Mov(x1, x0); | 4165 __ Mov(x1, x0); |
| 4151 __ Mov(x0, Smi::FromInt(count_value)); | 4166 __ Mov(x0, Smi::FromInt(count_value)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4192 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4207 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4193 if (expr->is_postfix()) { | 4208 if (expr->is_postfix()) { |
| 4194 if (!context()->IsEffect()) { | 4209 if (!context()->IsEffect()) { |
| 4195 context()->PlugTOS(); | 4210 context()->PlugTOS(); |
| 4196 } | 4211 } |
| 4197 } else { | 4212 } else { |
| 4198 context()->Plug(x0); | 4213 context()->Plug(x0); |
| 4199 } | 4214 } |
| 4200 break; | 4215 break; |
| 4201 } | 4216 } |
| 4217 case NAMED_SUPER_PROPERTY: { |
| 4218 EmitNamedSuperPropertyStore(prop); |
| 4219 if (expr->is_postfix()) { |
| 4220 if (!context()->IsEffect()) { |
| 4221 context()->PlugTOS(); |
| 4222 } |
| 4223 } else { |
| 4224 context()->Plug(x0); |
| 4225 } |
| 4226 break; |
| 4227 } |
| 4202 case KEYED_PROPERTY: { | 4228 case KEYED_PROPERTY: { |
| 4203 __ Pop(StoreDescriptor::NameRegister()); | 4229 __ Pop(StoreDescriptor::NameRegister()); |
| 4204 __ Pop(StoreDescriptor::ReceiverRegister()); | 4230 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4205 Handle<Code> ic = | 4231 Handle<Code> ic = |
| 4206 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 4232 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
| 4207 CallIC(ic, expr->CountStoreFeedbackId()); | 4233 CallIC(ic, expr->CountStoreFeedbackId()); |
| 4208 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4234 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4209 if (expr->is_postfix()) { | 4235 if (expr->is_postfix()) { |
| 4210 if (!context()->IsEffect()) { | 4236 if (!context()->IsEffect()) { |
| 4211 context()->PlugTOS(); | 4237 context()->PlugTOS(); |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5042 return previous_; | 5068 return previous_; |
| 5043 } | 5069 } |
| 5044 | 5070 |
| 5045 | 5071 |
| 5046 #undef __ | 5072 #undef __ |
| 5047 | 5073 |
| 5048 | 5074 |
| 5049 } } // namespace v8::internal | 5075 } } // namespace v8::internal |
| 5050 | 5076 |
| 5051 #endif // V8_TARGET_ARCH_ARM64 | 5077 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |