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

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

Issue 593073002: Stores and compound assignments for named super properties. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased for landing 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 1846 matching lines...) Expand 10 before | Expand all | Expand 10 after
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) 1865 // Left-hand side can only be a property, a global or a (parameter or local)
1866 // slot. 1866 // slot.
1867 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1867 enum LhsKind {
1868 VARIABLE,
1869 NAMED_PROPERTY,
1870 KEYED_PROPERTY,
1871 NAMED_SUPER_PROPERTY
1872 };
1868 LhsKind assign_type = VARIABLE; 1873 LhsKind assign_type = VARIABLE;
1869 Property* property = expr->target()->AsProperty(); 1874 Property* property = expr->target()->AsProperty();
1870 if (property != NULL) { 1875 if (property != NULL) {
1871 assign_type = (property->key()->IsPropertyName()) 1876 assign_type = (property->key()->IsPropertyName())
1872 ? NAMED_PROPERTY 1877 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
1873 : KEYED_PROPERTY; 1878 : NAMED_PROPERTY)
1879 : KEYED_PROPERTY;
1874 } 1880 }
1875 1881
1876 // Evaluate LHS expression. 1882 // Evaluate LHS expression.
1877 switch (assign_type) { 1883 switch (assign_type) {
1878 case VARIABLE: 1884 case VARIABLE:
1879 // Nothing to do here. 1885 // Nothing to do here.
1880 break; 1886 break;
1881 case NAMED_PROPERTY: 1887 case NAMED_PROPERTY:
1882 if (expr->is_compound()) { 1888 if (expr->is_compound()) {
1883 // We need the receiver both on the stack and in the register. 1889 // We need the receiver both on the stack and in the register.
1884 VisitForStackValue(property->obj()); 1890 VisitForStackValue(property->obj());
1885 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 1891 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
1886 } else { 1892 } else {
1887 VisitForStackValue(property->obj()); 1893 VisitForStackValue(property->obj());
1888 } 1894 }
1889 break; 1895 break;
1896 case NAMED_SUPER_PROPERTY:
1897 VisitForStackValue(property->obj()->AsSuperReference()->this_var());
1898 EmitLoadHomeObject(property->obj()->AsSuperReference());
1899 __ Push(result_register());
1900 if (expr->is_compound()) {
1901 const Register scratch = x10;
1902 __ Peek(scratch, kPointerSize);
1903 __ Push(scratch, result_register());
1904 }
1905 break;
1890 case KEYED_PROPERTY: 1906 case KEYED_PROPERTY:
1891 if (expr->is_compound()) { 1907 if (expr->is_compound()) {
1892 VisitForStackValue(property->obj()); 1908 VisitForStackValue(property->obj());
1893 VisitForStackValue(property->key()); 1909 VisitForStackValue(property->key());
1894 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); 1910 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
1895 __ Peek(LoadDescriptor::NameRegister(), 0); 1911 __ Peek(LoadDescriptor::NameRegister(), 0);
1896 } else { 1912 } else {
1897 VisitForStackValue(property->obj()); 1913 VisitForStackValue(property->obj());
1898 VisitForStackValue(property->key()); 1914 VisitForStackValue(property->key());
1899 } 1915 }
1900 break; 1916 break;
1901 } 1917 }
1902 1918
1903 // For compound assignments we need another deoptimization point after the 1919 // For compound assignments we need another deoptimization point after the
1904 // variable/property load. 1920 // variable/property load.
1905 if (expr->is_compound()) { 1921 if (expr->is_compound()) {
1906 { AccumulatorValueContext context(this); 1922 { AccumulatorValueContext context(this);
1907 switch (assign_type) { 1923 switch (assign_type) {
1908 case VARIABLE: 1924 case VARIABLE:
1909 EmitVariableLoad(expr->target()->AsVariableProxy()); 1925 EmitVariableLoad(expr->target()->AsVariableProxy());
1910 PrepareForBailout(expr->target(), TOS_REG); 1926 PrepareForBailout(expr->target(), TOS_REG);
1911 break; 1927 break;
1912 case NAMED_PROPERTY: 1928 case NAMED_PROPERTY:
1913 EmitNamedPropertyLoad(property); 1929 EmitNamedPropertyLoad(property);
1914 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1930 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1915 break; 1931 break;
1932 case NAMED_SUPER_PROPERTY:
1933 EmitNamedSuperPropertyLoad(property);
1934 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1935 break;
1916 case KEYED_PROPERTY: 1936 case KEYED_PROPERTY:
1917 EmitKeyedPropertyLoad(property); 1937 EmitKeyedPropertyLoad(property);
1918 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1938 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1919 break; 1939 break;
1920 } 1940 }
1921 } 1941 }
1922 1942
1923 Token::Value op = expr->binary_op(); 1943 Token::Value op = expr->binary_op();
1924 __ Push(x0); // Left operand goes on the stack. 1944 __ Push(x0); // Left operand goes on the stack.
1925 VisitForAccumulatorValue(expr->value()); 1945 VisitForAccumulatorValue(expr->value());
(...skipping 26 matching lines...) Expand all
1952 switch (assign_type) { 1972 switch (assign_type) {
1953 case VARIABLE: 1973 case VARIABLE:
1954 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1974 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1955 expr->op()); 1975 expr->op());
1956 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1976 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1957 context()->Plug(x0); 1977 context()->Plug(x0);
1958 break; 1978 break;
1959 case NAMED_PROPERTY: 1979 case NAMED_PROPERTY:
1960 EmitNamedPropertyAssignment(expr); 1980 EmitNamedPropertyAssignment(expr);
1961 break; 1981 break;
1982 case NAMED_SUPER_PROPERTY:
1983 EmitNamedSuperPropertyAssignment(expr);
1984 break;
1962 case KEYED_PROPERTY: 1985 case KEYED_PROPERTY:
1963 EmitKeyedPropertyAssignment(expr); 1986 EmitKeyedPropertyAssignment(expr);
1964 break; 1987 break;
1965 } 1988 }
1966 } 1989 }
1967 1990
1968 1991
1969 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1992 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1970 SetSourcePosition(prop->position()); 1993 SetSourcePosition(prop->position());
1971 Literal* key = prop->key()->AsLiteral(); 1994 Literal* key = prop->key()->AsLiteral();
1972 DCHECK(!prop->IsSuperAccess()); 1995 DCHECK(!prop->IsSuperAccess());
1973 1996
1974 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); 1997 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
1975 if (FLAG_vector_ics) { 1998 if (FLAG_vector_ics) {
1976 __ Mov(VectorLoadICDescriptor::SlotRegister(), 1999 __ Mov(VectorLoadICDescriptor::SlotRegister(),
1977 Smi::FromInt(prop->PropertyFeedbackSlot())); 2000 Smi::FromInt(prop->PropertyFeedbackSlot()));
1978 CallLoadIC(NOT_CONTEXTUAL); 2001 CallLoadIC(NOT_CONTEXTUAL);
1979 } else { 2002 } else {
1980 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2003 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
1981 } 2004 }
1982 } 2005 }
1983 2006
1984 2007
1985 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2008 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2009 // Stack: receiver, home_object.
1986 SetSourcePosition(prop->position()); 2010 SetSourcePosition(prop->position());
1987 Literal* key = prop->key()->AsLiteral(); 2011 Literal* key = prop->key()->AsLiteral();
1988 DCHECK(!key->value()->IsSmi()); 2012 DCHECK(!key->value()->IsSmi());
1989 DCHECK(prop->IsSuperAccess()); 2013 DCHECK(prop->IsSuperAccess());
1990 2014
1991 SuperReference* super_ref = prop->obj()->AsSuperReference();
1992 EmitLoadHomeObject(super_ref);
1993 __ Push(x0);
1994 VisitForStackValue(super_ref->this_var());
1995 __ Push(key->value()); 2015 __ Push(key->value());
1996 __ CallRuntime(Runtime::kLoadFromSuper, 3); 2016 __ CallRuntime(Runtime::kLoadFromSuper, 3);
1997 } 2017 }
1998 2018
1999 2019
2000 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2020 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2001 SetSourcePosition(prop->position()); 2021 SetSourcePosition(prop->position());
2002 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 2022 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
2003 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 2023 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2004 if (FLAG_vector_ics) { 2024 if (FLAG_vector_ics) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 __ Mov(StoreDescriptor::NameRegister(), 2290 __ Mov(StoreDescriptor::NameRegister(),
2271 Operand(prop->key()->AsLiteral()->value())); 2291 Operand(prop->key()->AsLiteral()->value()));
2272 __ Pop(StoreDescriptor::ReceiverRegister()); 2292 __ Pop(StoreDescriptor::ReceiverRegister());
2273 CallStoreIC(expr->AssignmentFeedbackId()); 2293 CallStoreIC(expr->AssignmentFeedbackId());
2274 2294
2275 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2295 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2276 context()->Plug(x0); 2296 context()->Plug(x0);
2277 } 2297 }
2278 2298
2279 2299
2300 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) {
2301 // Assignment to named property of super.
2302 // x0 : value
2303 // stack : receiver ('this'), home_object
2304 Property* prop = expr->target()->AsProperty();
2305 DCHECK(prop != NULL);
2306 Literal* key = prop->key()->AsLiteral();
2307 DCHECK(key != NULL);
2308
2309 __ Push(x0);
2310 __ Push(key->value());
2311 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
2312 : Runtime::kStoreToSuper_Sloppy),
2313 4);
2314 context()->Plug(x0);
2315 }
2316
2317
2280 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2318 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2281 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); 2319 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
2282 // Assignment to a property, using a keyed store IC. 2320 // Assignment to a property, using a keyed store IC.
2283 2321
2284 // Record source code position before IC call. 2322 // Record source code position before IC call.
2285 SetSourcePosition(expr->position()); 2323 SetSourcePosition(expr->position());
2286 // TODO(all): Could we pass this in registers rather than on the stack? 2324 // TODO(all): Could we pass this in registers rather than on the stack?
2287 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); 2325 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister());
2288 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 2326 DCHECK(StoreDescriptor::ValueRegister().is(x0));
2289 2327
2290 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 2328 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
2291 CallIC(ic, expr->AssignmentFeedbackId()); 2329 CallIC(ic, expr->AssignmentFeedbackId());
2292 2330
2293 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2331 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2294 context()->Plug(x0); 2332 context()->Plug(x0);
2295 } 2333 }
2296 2334
2297 2335
2298 void FullCodeGenerator::VisitProperty(Property* expr) { 2336 void FullCodeGenerator::VisitProperty(Property* expr) {
2299 Comment cmnt(masm_, "[ Property"); 2337 Comment cmnt(masm_, "[ Property");
2300 Expression* key = expr->key(); 2338 Expression* key = expr->key();
2301 2339
2302 if (key->IsPropertyName()) { 2340 if (key->IsPropertyName()) {
2303 if (!expr->IsSuperAccess()) { 2341 if (!expr->IsSuperAccess()) {
2304 VisitForAccumulatorValue(expr->obj()); 2342 VisitForAccumulatorValue(expr->obj());
2305 __ Move(LoadDescriptor::ReceiverRegister(), x0); 2343 __ Move(LoadDescriptor::ReceiverRegister(), x0);
2306 EmitNamedPropertyLoad(expr); 2344 EmitNamedPropertyLoad(expr);
2307 } else { 2345 } else {
2346 VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
2347 EmitLoadHomeObject(expr->obj()->AsSuperReference());
2348 __ Push(result_register());
2308 EmitNamedSuperPropertyLoad(expr); 2349 EmitNamedSuperPropertyLoad(expr);
2309 } 2350 }
2310 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2351 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2311 context()->Plug(x0); 2352 context()->Plug(x0);
2312 } else { 2353 } else {
2313 VisitForStackValue(expr->obj()); 2354 VisitForStackValue(expr->obj());
2314 VisitForAccumulatorValue(expr->key()); 2355 VisitForAccumulatorValue(expr->key());
2315 __ Move(LoadDescriptor::NameRegister(), x0); 2356 __ Move(LoadDescriptor::NameRegister(), x0);
2316 __ Pop(LoadDescriptor::ReceiverRegister()); 2357 __ Pop(LoadDescriptor::ReceiverRegister());
2317 EmitKeyedPropertyLoad(expr); 2358 EmitKeyedPropertyLoad(expr);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2372 DCHECK(!key->value()->IsSmi()); 2413 DCHECK(!key->value()->IsSmi());
2373 2414
2374 // Load the function from the receiver. 2415 // Load the function from the receiver.
2375 const Register scratch = x10; 2416 const Register scratch = x10;
2376 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); 2417 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
2377 EmitLoadHomeObject(super_ref); 2418 EmitLoadHomeObject(super_ref);
2378 __ Push(x0); 2419 __ Push(x0);
2379 VisitForAccumulatorValue(super_ref->this_var()); 2420 VisitForAccumulatorValue(super_ref->this_var());
2380 __ Push(x0); 2421 __ Push(x0);
2381 __ Peek(scratch, kPointerSize); 2422 __ Peek(scratch, kPointerSize);
2382 __ Push(scratch, x0); 2423 __ Push(x0, scratch);
2383 __ Push(key->value()); 2424 __ Push(key->value());
2384 2425
2385 // Stack here: 2426 // Stack here:
2386 // - home_object 2427 // - home_object
2387 // - this (receiver) 2428 // - this (receiver)
2388 // - home_object <-- LoadFromSuper will pop here and below. 2429 // - this (receiver) <-- LoadFromSuper will pop here and below.
2389 // - this (receiver) 2430 // - home_object
2390 // - key 2431 // - key
2391 __ CallRuntime(Runtime::kLoadFromSuper, 3); 2432 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2392 2433
2393 // Replace home_object with target function. 2434 // Replace home_object with target function.
2394 __ Poke(x0, kPointerSize); 2435 __ Poke(x0, kPointerSize);
2395 2436
2396 // Stack here: 2437 // Stack here:
2397 // - target function 2438 // - target function
2398 // - this (receiver) 2439 // - this (receiver)
2399 EmitCall(expr, CallICState::METHOD); 2440 EmitCall(expr, CallICState::METHOD);
(...skipping 1599 matching lines...) Expand 10 before | Expand all | Expand 10 after
3999 // Expression can only be a property, a global or a (parameter or local) 4040 // Expression can only be a property, a global or a (parameter or local)
4000 // slot. 4041 // slot.
4001 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 4042 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
4002 LhsKind assign_type = VARIABLE; 4043 LhsKind assign_type = VARIABLE;
4003 Property* prop = expr->expression()->AsProperty(); 4044 Property* prop = expr->expression()->AsProperty();
4004 // In case of a property we use the uninitialized expression context 4045 // In case of a property we use the uninitialized expression context
4005 // of the key to detect a named property. 4046 // of the key to detect a named property.
4006 if (prop != NULL) { 4047 if (prop != NULL) {
4007 assign_type = 4048 assign_type =
4008 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 4049 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
4050 if (prop->IsSuperAccess()) {
4051 // throw exception.
4052 VisitSuperReference(prop->obj()->AsSuperReference());
4053 return;
4054 }
4009 } 4055 }
4010 4056
4011 // Evaluate expression and get value. 4057 // Evaluate expression and get value.
4012 if (assign_type == VARIABLE) { 4058 if (assign_type == VARIABLE) {
4013 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4059 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4014 AccumulatorValueContext context(this); 4060 AccumulatorValueContext context(this);
4015 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4061 EmitVariableLoad(expr->expression()->AsVariableProxy());
4016 } else { 4062 } else {
4017 // Reserve space for result of postfix operation. 4063 // Reserve space for result of postfix operation.
4018 if (expr->is_postfix() && !context()->IsEffect()) { 4064 if (expr->is_postfix() && !context()->IsEffect()) {
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
4996 return previous_; 5042 return previous_;
4997 } 5043 }
4998 5044
4999 5045
5000 #undef __ 5046 #undef __
5001 5047
5002 5048
5003 } } // namespace v8::internal 5049 } } // namespace v8::internal
5004 5050
5005 #endif // V8_TARGET_ARCH_ARM64 5051 #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