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

Side by Side Diff: src/x64/full-codegen-x64.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_X64 7 #if V8_TARGET_ARCH_X64
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 1831 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 } 1842 }
1843 1843
1844 1844
1845 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1845 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1846 DCHECK(expr->target()->IsValidReferenceExpression()); 1846 DCHECK(expr->target()->IsValidReferenceExpression());
1847 1847
1848 Comment cmnt(masm_, "[ Assignment"); 1848 Comment cmnt(masm_, "[ Assignment");
1849 1849
1850 // Left-hand side can only be a property, a global or a (parameter or local) 1850 // Left-hand side can only be a property, a global or a (parameter or local)
1851 // slot. 1851 // slot.
1852 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1852 enum LhsKind {
1853 VARIABLE,
1854 NAMED_PROPERTY,
1855 KEYED_PROPERTY,
1856 NAMED_SUPER_PROPERTY
1857 };
1853 LhsKind assign_type = VARIABLE; 1858 LhsKind assign_type = VARIABLE;
1854 Property* property = expr->target()->AsProperty(); 1859 Property* property = expr->target()->AsProperty();
1855 if (property != NULL) { 1860 if (property != NULL) {
1856 assign_type = (property->key()->IsPropertyName()) 1861 assign_type = (property->key()->IsPropertyName())
1857 ? NAMED_PROPERTY 1862 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
1858 : KEYED_PROPERTY; 1863 : NAMED_PROPERTY)
1864 : KEYED_PROPERTY;
1859 } 1865 }
1860 1866
1861 // Evaluate LHS expression. 1867 // Evaluate LHS expression.
1862 switch (assign_type) { 1868 switch (assign_type) {
1863 case VARIABLE: 1869 case VARIABLE:
1864 // Nothing to do here. 1870 // Nothing to do here.
1865 break; 1871 break;
1866 case NAMED_PROPERTY: 1872 case NAMED_PROPERTY:
1867 if (expr->is_compound()) { 1873 if (expr->is_compound()) {
1868 // We need the receiver both on the stack and in the register. 1874 // We need the receiver both on the stack and in the register.
1869 VisitForStackValue(property->obj()); 1875 VisitForStackValue(property->obj());
1870 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); 1876 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
1871 } else { 1877 } else {
1872 VisitForStackValue(property->obj()); 1878 VisitForStackValue(property->obj());
1873 } 1879 }
1874 break; 1880 break;
1881 case NAMED_SUPER_PROPERTY:
1882 VisitForStackValue(property->obj()->AsSuperReference()->this_var());
1883 EmitLoadHomeObject(property->obj()->AsSuperReference());
1884 __ Push(result_register());
1885 if (expr->is_compound()) {
1886 __ Push(MemOperand(rsp, kPointerSize));
1887 __ Push(result_register());
1888 }
1889 break;
1875 case KEYED_PROPERTY: { 1890 case KEYED_PROPERTY: {
1876 if (expr->is_compound()) { 1891 if (expr->is_compound()) {
1877 VisitForStackValue(property->obj()); 1892 VisitForStackValue(property->obj());
1878 VisitForStackValue(property->key()); 1893 VisitForStackValue(property->key());
1879 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); 1894 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize));
1880 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); 1895 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0));
1881 } else { 1896 } else {
1882 VisitForStackValue(property->obj()); 1897 VisitForStackValue(property->obj());
1883 VisitForStackValue(property->key()); 1898 VisitForStackValue(property->key());
1884 } 1899 }
1885 break; 1900 break;
1886 } 1901 }
1887 } 1902 }
1888 1903
1889 // For compound assignments we need another deoptimization point after the 1904 // For compound assignments we need another deoptimization point after the
1890 // variable/property load. 1905 // variable/property load.
1891 if (expr->is_compound()) { 1906 if (expr->is_compound()) {
1892 { AccumulatorValueContext context(this); 1907 { AccumulatorValueContext context(this);
1893 switch (assign_type) { 1908 switch (assign_type) {
1894 case VARIABLE: 1909 case VARIABLE:
1895 EmitVariableLoad(expr->target()->AsVariableProxy()); 1910 EmitVariableLoad(expr->target()->AsVariableProxy());
1896 PrepareForBailout(expr->target(), TOS_REG); 1911 PrepareForBailout(expr->target(), TOS_REG);
1897 break; 1912 break;
1898 case NAMED_PROPERTY: 1913 case NAMED_PROPERTY:
1899 EmitNamedPropertyLoad(property); 1914 EmitNamedPropertyLoad(property);
1900 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1915 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1901 break; 1916 break;
1917 case NAMED_SUPER_PROPERTY:
1918 EmitNamedSuperPropertyLoad(property);
1919 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1920 break;
1902 case KEYED_PROPERTY: 1921 case KEYED_PROPERTY:
1903 EmitKeyedPropertyLoad(property); 1922 EmitKeyedPropertyLoad(property);
1904 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1923 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1905 break; 1924 break;
1906 } 1925 }
1907 } 1926 }
1908 1927
1909 Token::Value op = expr->binary_op(); 1928 Token::Value op = expr->binary_op();
1910 __ Push(rax); // Left operand goes on the stack. 1929 __ Push(rax); // Left operand goes on the stack.
1911 VisitForAccumulatorValue(expr->value()); 1930 VisitForAccumulatorValue(expr->value());
(...skipping 25 matching lines...) Expand all
1937 switch (assign_type) { 1956 switch (assign_type) {
1938 case VARIABLE: 1957 case VARIABLE:
1939 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1958 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1940 expr->op()); 1959 expr->op());
1941 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1960 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1942 context()->Plug(rax); 1961 context()->Plug(rax);
1943 break; 1962 break;
1944 case NAMED_PROPERTY: 1963 case NAMED_PROPERTY:
1945 EmitNamedPropertyAssignment(expr); 1964 EmitNamedPropertyAssignment(expr);
1946 break; 1965 break;
1966 case NAMED_SUPER_PROPERTY:
1967 EmitNamedSuperPropertyAssignment(expr);
1968 break;
1947 case KEYED_PROPERTY: 1969 case KEYED_PROPERTY:
1948 EmitKeyedPropertyAssignment(expr); 1970 EmitKeyedPropertyAssignment(expr);
1949 break; 1971 break;
1950 } 1972 }
1951 } 1973 }
1952 1974
1953 1975
1954 void FullCodeGenerator::VisitYield(Yield* expr) { 1976 void FullCodeGenerator::VisitYield(Yield* expr) {
1955 Comment cmnt(masm_, "[ Yield"); 1977 Comment cmnt(masm_, "[ Yield");
1956 // Evaluate yielded value first; the initial iterator definition depends on 1978 // Evaluate yielded value first; the initial iterator definition depends on
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 // Only the value field needs a write barrier, as the other values are in the 2286 // Only the value field needs a write barrier, as the other values are in the
2265 // root set. 2287 // root set.
2266 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, 2288 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset,
2267 rcx, rdx, kDontSaveFPRegs); 2289 rcx, rdx, kDontSaveFPRegs);
2268 } 2290 }
2269 2291
2270 2292
2271 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2293 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2272 SetSourcePosition(prop->position()); 2294 SetSourcePosition(prop->position());
2273 Literal* key = prop->key()->AsLiteral(); 2295 Literal* key = prop->key()->AsLiteral();
2296 DCHECK(!prop->IsSuperAccess());
2297
2274 __ Move(LoadDescriptor::NameRegister(), key->value()); 2298 __ Move(LoadDescriptor::NameRegister(), key->value());
2275 if (FLAG_vector_ics) { 2299 if (FLAG_vector_ics) {
2276 __ Move(VectorLoadICDescriptor::SlotRegister(), 2300 __ Move(VectorLoadICDescriptor::SlotRegister(),
2277 Smi::FromInt(prop->PropertyFeedbackSlot())); 2301 Smi::FromInt(prop->PropertyFeedbackSlot()));
2278 CallLoadIC(NOT_CONTEXTUAL); 2302 CallLoadIC(NOT_CONTEXTUAL);
2279 } else { 2303 } else {
2280 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2304 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2281 } 2305 }
2282 } 2306 }
2283 2307
2284 2308
2285 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2309 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2310 // Stack: receiver, home_object
2286 SetSourcePosition(prop->position()); 2311 SetSourcePosition(prop->position());
2287 Literal* key = prop->key()->AsLiteral(); 2312 Literal* key = prop->key()->AsLiteral();
2288 DCHECK(!key->value()->IsSmi()); 2313 DCHECK(!key->value()->IsSmi());
2289 DCHECK(prop->IsSuperAccess()); 2314 DCHECK(prop->IsSuperAccess());
2290 2315
2291 SuperReference* super_ref = prop->obj()->AsSuperReference();
2292 EmitLoadHomeObject(super_ref);
2293 __ Push(rax);
2294 VisitForStackValue(super_ref->this_var());
2295 __ Push(key->value()); 2316 __ Push(key->value());
2296 __ CallRuntime(Runtime::kLoadFromSuper, 3); 2317 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2297 } 2318 }
2298 2319
2299 2320
2300 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2321 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2301 SetSourcePosition(prop->position()); 2322 SetSourcePosition(prop->position());
2302 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 2323 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2303 if (FLAG_vector_ics) { 2324 if (FLAG_vector_ics) {
2304 __ Move(VectorLoadICDescriptor::SlotRegister(), 2325 __ Move(VectorLoadICDescriptor::SlotRegister(),
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 SetSourcePosition(expr->position()); 2540 SetSourcePosition(expr->position());
2520 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 2541 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2521 __ Pop(StoreDescriptor::ReceiverRegister()); 2542 __ Pop(StoreDescriptor::ReceiverRegister());
2522 CallStoreIC(expr->AssignmentFeedbackId()); 2543 CallStoreIC(expr->AssignmentFeedbackId());
2523 2544
2524 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2545 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2525 context()->Plug(rax); 2546 context()->Plug(rax);
2526 } 2547 }
2527 2548
2528 2549
2550 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) {
2551 // Assignment to named property of super.
2552 // rax : value
2553 // stack : receiver ('this'), home_object
2554 Property* prop = expr->target()->AsProperty();
2555 DCHECK(prop != NULL);
2556 Literal* key = prop->key()->AsLiteral();
2557 DCHECK(key != NULL);
2558
2559 __ Push(rax);
2560 __ Push(key->value());
2561 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
2562 : Runtime::kStoreToSuper_Sloppy),
2563 4);
2564 context()->Plug(rax);
2565 }
2566
2567
2529 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2568 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2530 // Assignment to a property, using a keyed store IC. 2569 // Assignment to a property, using a keyed store IC.
2531 2570
2532 __ Pop(StoreDescriptor::NameRegister()); // Key. 2571 __ Pop(StoreDescriptor::NameRegister()); // Key.
2533 __ Pop(StoreDescriptor::ReceiverRegister()); 2572 __ Pop(StoreDescriptor::ReceiverRegister());
2534 DCHECK(StoreDescriptor::ValueRegister().is(rax)); 2573 DCHECK(StoreDescriptor::ValueRegister().is(rax));
2535 // Record source code position before IC call. 2574 // Record source code position before IC call.
2536 SetSourcePosition(expr->position()); 2575 SetSourcePosition(expr->position());
2537 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 2576 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
2538 CallIC(ic, expr->AssignmentFeedbackId()); 2577 CallIC(ic, expr->AssignmentFeedbackId());
2539 2578
2540 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2579 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2541 context()->Plug(rax); 2580 context()->Plug(rax);
2542 } 2581 }
2543 2582
2544 2583
2545 void FullCodeGenerator::VisitProperty(Property* expr) { 2584 void FullCodeGenerator::VisitProperty(Property* expr) {
2546 Comment cmnt(masm_, "[ Property"); 2585 Comment cmnt(masm_, "[ Property");
2547 Expression* key = expr->key(); 2586 Expression* key = expr->key();
2548 2587
2549 if (key->IsPropertyName()) { 2588 if (key->IsPropertyName()) {
2550 if (!expr->IsSuperAccess()) { 2589 if (!expr->IsSuperAccess()) {
2551 VisitForAccumulatorValue(expr->obj()); 2590 VisitForAccumulatorValue(expr->obj());
2552 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister())); 2591 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister()));
2553 __ movp(LoadDescriptor::ReceiverRegister(), rax); 2592 __ movp(LoadDescriptor::ReceiverRegister(), rax);
2554 EmitNamedPropertyLoad(expr); 2593 EmitNamedPropertyLoad(expr);
2555 } else { 2594 } else {
2595 VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
2596 EmitLoadHomeObject(expr->obj()->AsSuperReference());
2597 __ Push(result_register());
2556 EmitNamedSuperPropertyLoad(expr); 2598 EmitNamedSuperPropertyLoad(expr);
2557 } 2599 }
2558 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2600 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2559 context()->Plug(rax); 2601 context()->Plug(rax);
2560 } else { 2602 } else {
2561 VisitForStackValue(expr->obj()); 2603 VisitForStackValue(expr->obj());
2562 VisitForAccumulatorValue(expr->key()); 2604 VisitForAccumulatorValue(expr->key());
2563 __ Move(LoadDescriptor::NameRegister(), rax); 2605 __ Move(LoadDescriptor::NameRegister(), rax);
2564 __ Pop(LoadDescriptor::ReceiverRegister()); 2606 __ Pop(LoadDescriptor::ReceiverRegister());
2565 EmitKeyedPropertyLoad(expr); 2607 EmitKeyedPropertyLoad(expr);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2614 2656
2615 SetSourcePosition(prop->position()); 2657 SetSourcePosition(prop->position());
2616 Literal* key = prop->key()->AsLiteral(); 2658 Literal* key = prop->key()->AsLiteral();
2617 DCHECK(!key->value()->IsSmi()); 2659 DCHECK(!key->value()->IsSmi());
2618 // Load the function from the receiver. 2660 // Load the function from the receiver.
2619 SuperReference* super_ref = prop->obj()->AsSuperReference(); 2661 SuperReference* super_ref = prop->obj()->AsSuperReference();
2620 EmitLoadHomeObject(super_ref); 2662 EmitLoadHomeObject(super_ref);
2621 __ Push(rax); 2663 __ Push(rax);
2622 VisitForAccumulatorValue(super_ref->this_var()); 2664 VisitForAccumulatorValue(super_ref->this_var());
2623 __ Push(rax); 2665 __ Push(rax);
2624 __ Push(Operand(rsp, kPointerSize));
2625 __ Push(rax); 2666 __ Push(rax);
2667 __ Push(Operand(rsp, kPointerSize * 2));
2626 __ Push(key->value()); 2668 __ Push(key->value());
2627 2669
2628 // Stack here: 2670 // Stack here:
2629 // - home_object 2671 // - home_object
2630 // - this (receiver) 2672 // - this (receiver)
2631 // - home_object <-- LoadFromSuper will pop here and below. 2673 // - this (receiver) <-- LoadFromSuper will pop here and below.
2632 // - this (receiver) 2674 // - home_object
2633 // - key 2675 // - key
2634 __ CallRuntime(Runtime::kLoadFromSuper, 3); 2676 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2635 2677
2636 // Replace home_object with target function. 2678 // Replace home_object with target function.
2637 __ movp(Operand(rsp, kPointerSize), rax); 2679 __ movp(Operand(rsp, kPointerSize), rax);
2638 2680
2639 // Stack here: 2681 // Stack here:
2640 // - target function 2682 // - target function
2641 // - this (receiver) 2683 // - this (receiver)
2642 EmitCall(expr, CallICState::METHOD); 2684 EmitCall(expr, CallICState::METHOD);
(...skipping 1661 matching lines...) Expand 10 before | Expand all | Expand 10 after
4304 // Expression can only be a property, a global or a (parameter or local) 4346 // Expression can only be a property, a global or a (parameter or local)
4305 // slot. 4347 // slot.
4306 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 4348 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
4307 LhsKind assign_type = VARIABLE; 4349 LhsKind assign_type = VARIABLE;
4308 Property* prop = expr->expression()->AsProperty(); 4350 Property* prop = expr->expression()->AsProperty();
4309 // In case of a property we use the uninitialized expression context 4351 // In case of a property we use the uninitialized expression context
4310 // of the key to detect a named property. 4352 // of the key to detect a named property.
4311 if (prop != NULL) { 4353 if (prop != NULL) {
4312 assign_type = 4354 assign_type =
4313 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 4355 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
4356 if (prop->IsSuperAccess()) {
4357 // throw exception.
4358 VisitSuperReference(prop->obj()->AsSuperReference());
4359 return;
4360 }
4314 } 4361 }
4315 4362
4316 // Evaluate expression and get value. 4363 // Evaluate expression and get value.
4317 if (assign_type == VARIABLE) { 4364 if (assign_type == VARIABLE) {
4318 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4365 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4319 AccumulatorValueContext context(this); 4366 AccumulatorValueContext context(this);
4320 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4367 EmitVariableLoad(expr->expression()->AsVariableProxy());
4321 } else { 4368 } else {
4322 // Reserve space for result of postfix operation. 4369 // Reserve space for result of postfix operation.
4323 if (expr->is_postfix() && !context()->IsEffect()) { 4370 if (expr->is_postfix() && !context()->IsEffect()) {
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
4916 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4963 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4917 Assembler::target_address_at(call_target_address, 4964 Assembler::target_address_at(call_target_address,
4918 unoptimized_code)); 4965 unoptimized_code));
4919 return OSR_AFTER_STACK_CHECK; 4966 return OSR_AFTER_STACK_CHECK;
4920 } 4967 }
4921 4968
4922 4969
4923 } } // namespace v8::internal 4970 } } // namespace v8::internal
4924 4971
4925 #endif // V8_TARGET_ARCH_X64 4972 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698