Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: src/arm64/full-codegen-arm64.cc

Issue 638623002: Keyed stores to super where key is a name. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: All platforms + CR feedback Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1844 matching lines...) Expand 10 before | Expand all | Expand 10 after
1855 context()->Plug(x0); 1855 context()->Plug(x0);
1856 } 1856 }
1857 } 1857 }
1858 1858
1859 1859
1860 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1860 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1861 DCHECK(expr->target()->IsValidReferenceExpression()); 1861 DCHECK(expr->target()->IsValidReferenceExpression());
1862 1862
1863 Comment cmnt(masm_, "[ Assignment"); 1863 Comment cmnt(masm_, "[ Assignment");
1864 1864
1865 // Left-hand side can only be a property, a global or a (parameter or local)
1866 // slot.
1867 enum LhsKind {
1868 VARIABLE,
1869 NAMED_PROPERTY,
1870 KEYED_PROPERTY,
1871 NAMED_SUPER_PROPERTY
1872 };
1873 LhsKind assign_type = VARIABLE;
1874 Property* property = expr->target()->AsProperty(); 1865 Property* property = expr->target()->AsProperty();
1875 if (property != NULL) { 1866 LhsKind assign_type = GetAssignType(property);
1876 assign_type = (property->key()->IsPropertyName())
1877 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
1878 : NAMED_PROPERTY)
1879 : KEYED_PROPERTY;
1880 }
1881 1867
1882 // Evaluate LHS expression. 1868 // Evaluate LHS expression.
1883 switch (assign_type) { 1869 switch (assign_type) {
1884 case VARIABLE: 1870 case VARIABLE:
1885 // Nothing to do here. 1871 // Nothing to do here.
1886 break; 1872 break;
1887 case NAMED_PROPERTY: 1873 case NAMED_PROPERTY:
1888 if (expr->is_compound()) { 1874 if (expr->is_compound()) {
1889 // We need the receiver both on the stack and in the register. 1875 // We need the receiver both on the stack and in the register.
1890 VisitForStackValue(property->obj()); 1876 VisitForStackValue(property->obj());
1891 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 1877 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
1892 } else { 1878 } else {
1893 VisitForStackValue(property->obj()); 1879 VisitForStackValue(property->obj());
1894 } 1880 }
1895 break; 1881 break;
1896 case NAMED_SUPER_PROPERTY: 1882 case NAMED_SUPER_PROPERTY:
1897 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); 1883 VisitForStackValue(property->obj()->AsSuperReference()->this_var());
1898 EmitLoadHomeObject(property->obj()->AsSuperReference()); 1884 EmitLoadHomeObject(property->obj()->AsSuperReference());
1899 __ Push(result_register()); 1885 __ Push(result_register());
1900 if (expr->is_compound()) { 1886 if (expr->is_compound()) {
1901 const Register scratch = x10; 1887 const Register scratch = x10;
1902 __ Peek(scratch, kPointerSize); 1888 __ Peek(scratch, kPointerSize);
1903 __ Push(scratch, result_register()); 1889 __ Push(scratch, result_register());
1904 } 1890 }
1905 break; 1891 break;
1892 case KEYED_SUPER_PROPERTY:
1893 VisitForStackValue(property->obj()->AsSuperReference()->this_var());
1894 EmitLoadHomeObject(property->obj()->AsSuperReference());
1895 __ Push(result_register());
1896 VisitForAccumulatorValue(property->key());
1897 __ Push(result_register());
1898 if (expr->is_compound()) {
1899 const Register scratch1 = x10;
1900 const Register scratch2 = x11;
1901 __ Peek(scratch1, 2 * kPointerSize);
1902 __ Peek(scratch2, kPointerSize);
1903 __ Push(scratch1, scratch2, result_register());
1904 }
1905 break;
1906 case KEYED_PROPERTY: 1906 case KEYED_PROPERTY:
1907 if (expr->is_compound()) { 1907 if (expr->is_compound()) {
1908 VisitForStackValue(property->obj()); 1908 VisitForStackValue(property->obj());
1909 VisitForStackValue(property->key()); 1909 VisitForStackValue(property->key());
1910 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); 1910 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
1911 __ Peek(LoadDescriptor::NameRegister(), 0); 1911 __ Peek(LoadDescriptor::NameRegister(), 0);
1912 } else { 1912 } else {
1913 VisitForStackValue(property->obj()); 1913 VisitForStackValue(property->obj());
1914 VisitForStackValue(property->key()); 1914 VisitForStackValue(property->key());
1915 } 1915 }
(...skipping 10 matching lines...) Expand all
1926 PrepareForBailout(expr->target(), TOS_REG); 1926 PrepareForBailout(expr->target(), TOS_REG);
1927 break; 1927 break;
1928 case NAMED_PROPERTY: 1928 case NAMED_PROPERTY:
1929 EmitNamedPropertyLoad(property); 1929 EmitNamedPropertyLoad(property);
1930 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1930 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1931 break; 1931 break;
1932 case NAMED_SUPER_PROPERTY: 1932 case NAMED_SUPER_PROPERTY:
1933 EmitNamedSuperPropertyLoad(property); 1933 EmitNamedSuperPropertyLoad(property);
1934 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1934 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1935 break; 1935 break;
1936 case KEYED_SUPER_PROPERTY:
1937 EmitKeyedSuperPropertyLoad(property);
1938 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1939 break;
1936 case KEYED_PROPERTY: 1940 case KEYED_PROPERTY:
1937 EmitKeyedPropertyLoad(property); 1941 EmitKeyedPropertyLoad(property);
1938 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1942 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1939 break; 1943 break;
1940 } 1944 }
1941 } 1945 }
1942 1946
1943 Token::Value op = expr->binary_op(); 1947 Token::Value op = expr->binary_op();
1944 __ Push(x0); // Left operand goes on the stack. 1948 __ Push(x0); // Left operand goes on the stack.
1945 VisitForAccumulatorValue(expr->value()); 1949 VisitForAccumulatorValue(expr->value());
(...skipping 30 matching lines...) Expand all
1976 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1980 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1977 context()->Plug(x0); 1981 context()->Plug(x0);
1978 break; 1982 break;
1979 case NAMED_PROPERTY: 1983 case NAMED_PROPERTY:
1980 EmitNamedPropertyAssignment(expr); 1984 EmitNamedPropertyAssignment(expr);
1981 break; 1985 break;
1982 case NAMED_SUPER_PROPERTY: 1986 case NAMED_SUPER_PROPERTY:
1983 EmitNamedSuperPropertyStore(property); 1987 EmitNamedSuperPropertyStore(property);
1984 context()->Plug(x0); 1988 context()->Plug(x0);
1985 break; 1989 break;
1990 case KEYED_SUPER_PROPERTY:
1991 EmitKeyedSuperPropertyStore(property);
1992 context()->Plug(x0);
1993 break;
1986 case KEYED_PROPERTY: 1994 case KEYED_PROPERTY:
1987 EmitKeyedPropertyAssignment(expr); 1995 EmitKeyedPropertyAssignment(expr);
1988 break; 1996 break;
1989 } 1997 }
1990 } 1998 }
1991 1999
1992 2000
1993 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2001 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1994 SetSourcePosition(prop->position()); 2002 SetSourcePosition(prop->position());
1995 Literal* key = prop->key()->AsLiteral(); 2003 Literal* key = prop->key()->AsLiteral();
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
2307 2315
2308 2316
2309 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2317 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2310 // Assignment to named property of super. 2318 // Assignment to named property of super.
2311 // x0 : value 2319 // x0 : value
2312 // stack : receiver ('this'), home_object 2320 // stack : receiver ('this'), home_object
2313 DCHECK(prop != NULL); 2321 DCHECK(prop != NULL);
2314 Literal* key = prop->key()->AsLiteral(); 2322 Literal* key = prop->key()->AsLiteral();
2315 DCHECK(key != NULL); 2323 DCHECK(key != NULL);
2316 2324
2325 __ Push(key->value());
2317 __ Push(x0); 2326 __ Push(x0);
2318 __ Push(key->value());
2319 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict 2327 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
2320 : Runtime::kStoreToSuper_Sloppy), 2328 : Runtime::kStoreToSuper_Sloppy),
2321 4); 2329 4);
2322 } 2330 }
2323 2331
2324 2332
2333 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2334 // Assignment to named property of super.
2335 // x0 : value
2336 // stack : receiver ('this'), home_object, key
2337 DCHECK(prop != NULL);
2338
2339 __ Push(x0);
2340 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
2341 : Runtime::kStoreKeyedToSuper_Sloppy),
2342 4);
2343 }
2344
2345
2325 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2346 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2326 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); 2347 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
2327 // Assignment to a property, using a keyed store IC. 2348 // Assignment to a property, using a keyed store IC.
2328 2349
2329 // Record source code position before IC call. 2350 // Record source code position before IC call.
2330 SetSourcePosition(expr->position()); 2351 SetSourcePosition(expr->position());
2331 // TODO(all): Could we pass this in registers rather than on the stack? 2352 // TODO(all): Could we pass this in registers rather than on the stack?
2332 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); 2353 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister());
2333 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 2354 DCHECK(StoreDescriptor::ValueRegister().is(x0));
2334 2355
(...skipping 1753 matching lines...) Expand 10 before | Expand all | Expand 10 after
4088 } 4109 }
4089 } 4110 }
4090 4111
4091 4112
4092 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4113 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4093 DCHECK(expr->expression()->IsValidReferenceExpression()); 4114 DCHECK(expr->expression()->IsValidReferenceExpression());
4094 4115
4095 Comment cmnt(masm_, "[ CountOperation"); 4116 Comment cmnt(masm_, "[ CountOperation");
4096 SetSourcePosition(expr->position()); 4117 SetSourcePosition(expr->position());
4097 4118
4098 // Expression can only be a property, a global or a (parameter or local)
4099 // slot.
4100 enum LhsKind {
4101 VARIABLE,
4102 NAMED_PROPERTY,
4103 KEYED_PROPERTY,
4104 NAMED_SUPER_PROPERTY
4105 };
4106 LhsKind assign_type = VARIABLE;
4107 Property* prop = expr->expression()->AsProperty(); 4119 Property* prop = expr->expression()->AsProperty();
4108 // In case of a property we use the uninitialized expression context 4120 LhsKind assign_type = GetAssignType(prop);
4109 // of the key to detect a named property.
4110 if (prop != NULL) {
4111 assign_type =
4112 (prop->key()->IsPropertyName())
4113 ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
4114 : KEYED_PROPERTY;
4115 }
4116 4121
4117 // Evaluate expression and get value. 4122 // Evaluate expression and get value.
4118 if (assign_type == VARIABLE) { 4123 if (assign_type == VARIABLE) {
4119 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4124 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4120 AccumulatorValueContext context(this); 4125 AccumulatorValueContext context(this);
4121 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4126 EmitVariableLoad(expr->expression()->AsVariableProxy());
4122 } else { 4127 } else {
4123 // Reserve space for result of postfix operation. 4128 // Reserve space for result of postfix operation.
4124 if (expr->is_postfix() && !context()->IsEffect()) { 4129 if (expr->is_postfix() && !context()->IsEffect()) {
4125 __ Push(xzr); 4130 __ Push(xzr);
4126 } 4131 }
4127 if (assign_type == NAMED_PROPERTY) { 4132 switch (assign_type) {
4128 // Put the object both on the stack and in the register. 4133 case NAMED_PROPERTY: {
4129 VisitForStackValue(prop->obj()); 4134 // Put the object both on the stack and in the register.
4130 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 4135 VisitForStackValue(prop->obj());
4131 EmitNamedPropertyLoad(prop); 4136 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
4132 } else if (assign_type == NAMED_SUPER_PROPERTY) { 4137 EmitNamedPropertyLoad(prop);
4133 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); 4138 break;
4134 EmitLoadHomeObject(prop->obj()->AsSuperReference()); 4139 }
4135 __ Push(result_register()); 4140
4136 const Register scratch = x10; 4141 case NAMED_SUPER_PROPERTY: {
4137 __ Peek(scratch, kPointerSize); 4142 VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
4138 __ Push(scratch, result_register()); 4143 EmitLoadHomeObject(prop->obj()->AsSuperReference());
4139 EmitNamedSuperPropertyLoad(prop); 4144 __ Push(result_register());
4140 } else { 4145 const Register scratch = x10;
4141 // KEYED_PROPERTY 4146 __ Peek(scratch, kPointerSize);
4142 VisitForStackValue(prop->obj()); 4147 __ Push(scratch, result_register());
4143 VisitForStackValue(prop->key()); 4148 EmitNamedSuperPropertyLoad(prop);
4144 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); 4149 break;
4145 __ Peek(LoadDescriptor::NameRegister(), 0); 4150 }
4146 EmitKeyedPropertyLoad(prop); 4151
4152 case KEYED_SUPER_PROPERTY: {
4153 VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
4154 EmitLoadHomeObject(prop->obj()->AsSuperReference());
4155 __ Push(result_register());
4156 VisitForAccumulatorValue(prop->key());
4157 __ Push(result_register());
4158 const Register scratch1 = x10;
4159 const Register scratch2 = x11;
4160 __ Peek(scratch1, 2 * kPointerSize);
4161 __ Peek(scratch2, kPointerSize);
4162 __ Push(scratch1, scratch2, result_register());
4163 EmitKeyedSuperPropertyLoad(prop);
4164 break;
4165 }
4166
4167 case KEYED_PROPERTY: {
4168 VisitForStackValue(prop->obj());
4169 VisitForStackValue(prop->key());
4170 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
4171 __ Peek(LoadDescriptor::NameRegister(), 0);
4172 EmitKeyedPropertyLoad(prop);
4173 break;
4174 }
4175
4176 case VARIABLE:
4177 UNREACHABLE();
4147 } 4178 }
4148 } 4179 }
4149 4180
4150 // We need a second deoptimization point after loading the value 4181 // We need a second deoptimization point after loading the value
4151 // in case evaluating the property load my have a side effect. 4182 // in case evaluating the property load my have a side effect.
4152 if (assign_type == VARIABLE) { 4183 if (assign_type == VARIABLE) {
4153 PrepareForBailout(expr->expression(), TOS_REG); 4184 PrepareForBailout(expr->expression(), TOS_REG);
4154 } else { 4185 } else {
4155 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4186 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
4156 } 4187 }
(...skipping 19 matching lines...) Expand all
4176 break; 4207 break;
4177 case NAMED_PROPERTY: 4208 case NAMED_PROPERTY:
4178 __ Poke(x0, kPointerSize); 4209 __ Poke(x0, kPointerSize);
4179 break; 4210 break;
4180 case NAMED_SUPER_PROPERTY: 4211 case NAMED_SUPER_PROPERTY:
4181 __ Poke(x0, kPointerSize * 2); 4212 __ Poke(x0, kPointerSize * 2);
4182 break; 4213 break;
4183 case KEYED_PROPERTY: 4214 case KEYED_PROPERTY:
4184 __ Poke(x0, kPointerSize * 2); 4215 __ Poke(x0, kPointerSize * 2);
4185 break; 4216 break;
4217 case KEYED_SUPER_PROPERTY:
4218 __ Poke(x0, kPointerSize * 3);
4219 break;
4186 } 4220 }
4187 } 4221 }
4188 } 4222 }
4189 4223
4190 __ Adds(x0, x0, Smi::FromInt(count_value)); 4224 __ Adds(x0, x0, Smi::FromInt(count_value));
4191 __ B(vc, &done); 4225 __ B(vc, &done);
4192 // Call stub. Undo operation first. 4226 // Call stub. Undo operation first.
4193 __ Sub(x0, x0, Smi::FromInt(count_value)); 4227 __ Sub(x0, x0, Smi::FromInt(count_value));
4194 __ B(&stub_call); 4228 __ B(&stub_call);
4195 __ Bind(&slow); 4229 __ Bind(&slow);
(...skipping 13 matching lines...) Expand all
4209 break; 4243 break;
4210 case NAMED_PROPERTY: 4244 case NAMED_PROPERTY:
4211 __ Poke(x0, kXRegSize); 4245 __ Poke(x0, kXRegSize);
4212 break; 4246 break;
4213 case NAMED_SUPER_PROPERTY: 4247 case NAMED_SUPER_PROPERTY:
4214 __ Poke(x0, 2 * kXRegSize); 4248 __ Poke(x0, 2 * kXRegSize);
4215 break; 4249 break;
4216 case KEYED_PROPERTY: 4250 case KEYED_PROPERTY:
4217 __ Poke(x0, 2 * kXRegSize); 4251 __ Poke(x0, 2 * kXRegSize);
4218 break; 4252 break;
4253 case KEYED_SUPER_PROPERTY:
4254 __ Poke(x0, 3 * kXRegSize);
4255 break;
4219 } 4256 }
4220 } 4257 }
4221 } 4258 }
4222 4259
4223 __ Bind(&stub_call); 4260 __ Bind(&stub_call);
4224 __ Mov(x1, x0); 4261 __ Mov(x1, x0);
4225 __ Mov(x0, Smi::FromInt(count_value)); 4262 __ Mov(x0, Smi::FromInt(count_value));
4226 4263
4227 // Record position before stub call. 4264 // Record position before stub call.
4228 SetSourcePosition(expr->position()); 4265 SetSourcePosition(expr->position());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4277 EmitNamedSuperPropertyStore(prop); 4314 EmitNamedSuperPropertyStore(prop);
4278 if (expr->is_postfix()) { 4315 if (expr->is_postfix()) {
4279 if (!context()->IsEffect()) { 4316 if (!context()->IsEffect()) {
4280 context()->PlugTOS(); 4317 context()->PlugTOS();
4281 } 4318 }
4282 } else { 4319 } else {
4283 context()->Plug(x0); 4320 context()->Plug(x0);
4284 } 4321 }
4285 break; 4322 break;
4286 } 4323 }
4324 case KEYED_SUPER_PROPERTY: {
4325 EmitKeyedSuperPropertyStore(prop);
4326 if (expr->is_postfix()) {
4327 if (!context()->IsEffect()) {
4328 context()->PlugTOS();
4329 }
4330 } else {
4331 context()->Plug(x0);
4332 }
4333 break;
4334 }
4287 case KEYED_PROPERTY: { 4335 case KEYED_PROPERTY: {
4288 __ Pop(StoreDescriptor::NameRegister()); 4336 __ Pop(StoreDescriptor::NameRegister());
4289 __ Pop(StoreDescriptor::ReceiverRegister()); 4337 __ Pop(StoreDescriptor::ReceiverRegister());
4290 Handle<Code> ic = 4338 Handle<Code> ic =
4291 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 4339 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
4292 CallIC(ic, expr->CountStoreFeedbackId()); 4340 CallIC(ic, expr->CountStoreFeedbackId());
4293 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4341 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4294 if (expr->is_postfix()) { 4342 if (expr->is_postfix()) {
4295 if (!context()->IsEffect()) { 4343 if (!context()->IsEffect()) {
4296 context()->PlugTOS(); 4344 context()->PlugTOS();
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after
5127 return previous_; 5175 return previous_;
5128 } 5176 }
5129 5177
5130 5178
5131 #undef __ 5179 #undef __
5132 5180
5133 5181
5134 } } // namespace v8::internal 5182 } } // namespace v8::internal
5135 5183
5136 #endif // V8_TARGET_ARCH_ARM64 5184 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/full-codegen-arm.cc ('k') | src/full-codegen.h » ('j') | src/full-codegen.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698