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 1846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |