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 |