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

Side by Side Diff: src/ia32/full-codegen-ia32.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: Stray edit 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_IA32 7 #if V8_TARGET_ARCH_IA32
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 1796 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 context()->Plug(eax); 1807 context()->Plug(eax);
1808 } 1808 }
1809 } 1809 }
1810 1810
1811 1811
1812 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1812 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1813 DCHECK(expr->target()->IsValidReferenceExpression()); 1813 DCHECK(expr->target()->IsValidReferenceExpression());
1814 1814
1815 Comment cmnt(masm_, "[ Assignment"); 1815 Comment cmnt(masm_, "[ Assignment");
1816 1816
1817 // Left-hand side can only be a property, a global or a (parameter or local)
1818 // slot.
1819 enum LhsKind {
1820 VARIABLE,
1821 NAMED_PROPERTY,
1822 KEYED_PROPERTY,
1823 NAMED_SUPER_PROPERTY
1824 };
1825 LhsKind assign_type = VARIABLE;
1826 Property* property = expr->target()->AsProperty(); 1817 Property* property = expr->target()->AsProperty();
1827 if (property != NULL) { 1818 LhsKind assign_type = GetAssignType(property);
1828 assign_type = (property->key()->IsPropertyName())
1829 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
1830 : NAMED_PROPERTY)
1831 : KEYED_PROPERTY;
1832 }
1833 1819
1834 // Evaluate LHS expression. 1820 // Evaluate LHS expression.
1835 switch (assign_type) { 1821 switch (assign_type) {
1836 case VARIABLE: 1822 case VARIABLE:
1837 // Nothing to do here. 1823 // Nothing to do here.
1838 break; 1824 break;
1839 case NAMED_SUPER_PROPERTY: 1825 case NAMED_SUPER_PROPERTY:
1840 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); 1826 VisitForStackValue(property->obj()->AsSuperReference()->this_var());
1841 EmitLoadHomeObject(property->obj()->AsSuperReference()); 1827 EmitLoadHomeObject(property->obj()->AsSuperReference());
1842 __ push(result_register()); 1828 __ push(result_register());
1843 if (expr->is_compound()) { 1829 if (expr->is_compound()) {
1844 __ push(MemOperand(esp, kPointerSize)); 1830 __ push(MemOperand(esp, kPointerSize));
1845 __ push(result_register()); 1831 __ push(result_register());
1846 } 1832 }
1847 break; 1833 break;
1848 case NAMED_PROPERTY: 1834 case NAMED_PROPERTY:
1849 if (expr->is_compound()) { 1835 if (expr->is_compound()) {
1850 // We need the receiver both on the stack and in the register. 1836 // We need the receiver both on the stack and in the register.
1851 VisitForStackValue(property->obj()); 1837 VisitForStackValue(property->obj());
1852 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 1838 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
1853 } else { 1839 } else {
1854 VisitForStackValue(property->obj()); 1840 VisitForStackValue(property->obj());
1855 } 1841 }
1856 break; 1842 break;
1843 case KEYED_SUPER_PROPERTY:
1844 VisitForStackValue(property->obj()->AsSuperReference()->this_var());
1845 EmitLoadHomeObject(property->obj()->AsSuperReference());
1846 __ Push(result_register());
1847 VisitForAccumulatorValue(property->key());
1848 __ Push(result_register());
1849 if (expr->is_compound()) {
1850 __ push(MemOperand(esp, 2 * kPointerSize));
1851 __ push(MemOperand(esp, 2 * kPointerSize));
1852 __ push(result_register());
1853 }
1854 break;
1857 case KEYED_PROPERTY: { 1855 case KEYED_PROPERTY: {
1858 if (expr->is_compound()) { 1856 if (expr->is_compound()) {
1859 VisitForStackValue(property->obj()); 1857 VisitForStackValue(property->obj());
1860 VisitForStackValue(property->key()); 1858 VisitForStackValue(property->key());
1861 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); 1859 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize));
1862 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); 1860 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));
1863 } else { 1861 } else {
1864 VisitForStackValue(property->obj()); 1862 VisitForStackValue(property->obj());
1865 VisitForStackValue(property->key()); 1863 VisitForStackValue(property->key());
1866 } 1864 }
(...skipping 12 matching lines...) Expand all
1879 PrepareForBailout(expr->target(), TOS_REG); 1877 PrepareForBailout(expr->target(), TOS_REG);
1880 break; 1878 break;
1881 case NAMED_SUPER_PROPERTY: 1879 case NAMED_SUPER_PROPERTY:
1882 EmitNamedSuperPropertyLoad(property); 1880 EmitNamedSuperPropertyLoad(property);
1883 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1881 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1884 break; 1882 break;
1885 case NAMED_PROPERTY: 1883 case NAMED_PROPERTY:
1886 EmitNamedPropertyLoad(property); 1884 EmitNamedPropertyLoad(property);
1887 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1885 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1888 break; 1886 break;
1887 case KEYED_SUPER_PROPERTY:
1888 EmitKeyedSuperPropertyLoad(property);
1889 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1890 break;
1889 case KEYED_PROPERTY: 1891 case KEYED_PROPERTY:
1890 EmitKeyedPropertyLoad(property); 1892 EmitKeyedPropertyLoad(property);
1891 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1893 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1892 break; 1894 break;
1893 } 1895 }
1894 } 1896 }
1895 1897
1896 Token::Value op = expr->binary_op(); 1898 Token::Value op = expr->binary_op();
1897 __ push(eax); // Left operand goes on the stack. 1899 __ push(eax); // Left operand goes on the stack.
1898 VisitForAccumulatorValue(expr->value()); 1900 VisitForAccumulatorValue(expr->value());
(...skipping 27 matching lines...) Expand all
1926 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1928 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1927 expr->op()); 1929 expr->op());
1928 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1930 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1929 context()->Plug(eax); 1931 context()->Plug(eax);
1930 break; 1932 break;
1931 case NAMED_PROPERTY: 1933 case NAMED_PROPERTY:
1932 EmitNamedPropertyAssignment(expr); 1934 EmitNamedPropertyAssignment(expr);
1933 break; 1935 break;
1934 case NAMED_SUPER_PROPERTY: 1936 case NAMED_SUPER_PROPERTY:
1935 EmitNamedSuperPropertyStore(property); 1937 EmitNamedSuperPropertyStore(property);
1936 context()->Plug(eax); 1938 context()->Plug(result_register());
1939 break;
1940 case KEYED_SUPER_PROPERTY:
1941 EmitKeyedSuperPropertyStore(property);
1942 context()->Plug(result_register());
1937 break; 1943 break;
1938 case KEYED_PROPERTY: 1944 case KEYED_PROPERTY:
1939 EmitKeyedPropertyAssignment(expr); 1945 EmitKeyedPropertyAssignment(expr);
1940 break; 1946 break;
1941 } 1947 }
1942 } 1948 }
1943 1949
1944 1950
1945 void FullCodeGenerator::VisitYield(Yield* expr) { 1951 void FullCodeGenerator::VisitYield(Yield* expr) {
1946 Comment cmnt(masm_, "[ Yield"); 1952 Comment cmnt(masm_, "[ Yield");
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
2561 2567
2562 2568
2563 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2569 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2564 // Assignment to named property of super. 2570 // Assignment to named property of super.
2565 // eax : value 2571 // eax : value
2566 // stack : receiver ('this'), home_object 2572 // stack : receiver ('this'), home_object
2567 DCHECK(prop != NULL); 2573 DCHECK(prop != NULL);
2568 Literal* key = prop->key()->AsLiteral(); 2574 Literal* key = prop->key()->AsLiteral();
2569 DCHECK(key != NULL); 2575 DCHECK(key != NULL);
2570 2576
2577 __ push(Immediate(key->value()));
2571 __ push(eax); 2578 __ push(eax);
2572 __ push(Immediate(key->value()));
2573 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict 2579 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
2574 : Runtime::kStoreToSuper_Sloppy), 2580 : Runtime::kStoreToSuper_Sloppy),
2575 4); 2581 4);
2576 } 2582 }
2577 2583
2578 2584
2585 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2586 // Assignment to named property of super.
2587 // eax : value
2588 // stack : receiver ('this'), home_object, key
2589
2590 __ push(eax);
2591 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
2592 : Runtime::kStoreKeyedToSuper_Sloppy),
2593 4);
2594 }
2595
2596
2579 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2597 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2580 // Assignment to a property, using a keyed store IC. 2598 // Assignment to a property, using a keyed store IC.
2581 // eax : value 2599 // eax : value
2582 // esp[0] : key 2600 // esp[0] : key
2583 // esp[kPointerSize] : receiver 2601 // esp[kPointerSize] : receiver
2584 2602
2585 __ pop(StoreDescriptor::NameRegister()); // Key. 2603 __ pop(StoreDescriptor::NameRegister()); // Key.
2586 __ pop(StoreDescriptor::ReceiverRegister()); 2604 __ pop(StoreDescriptor::ReceiverRegister());
2587 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 2605 DCHECK(StoreDescriptor::ValueRegister().is(eax));
2588 // Record source code position before IC call. 2606 // Record source code position before IC call.
(...skipping 1789 matching lines...) Expand 10 before | Expand all | Expand 10 after
4378 } 4396 }
4379 } 4397 }
4380 4398
4381 4399
4382 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4400 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4383 DCHECK(expr->expression()->IsValidReferenceExpression()); 4401 DCHECK(expr->expression()->IsValidReferenceExpression());
4384 4402
4385 Comment cmnt(masm_, "[ CountOperation"); 4403 Comment cmnt(masm_, "[ CountOperation");
4386 SetSourcePosition(expr->position()); 4404 SetSourcePosition(expr->position());
4387 4405
4388 // Expression can only be a property, a global or a (parameter or local)
4389 // slot.
4390 enum LhsKind {
4391 VARIABLE,
4392 NAMED_PROPERTY,
4393 KEYED_PROPERTY,
4394 NAMED_SUPER_PROPERTY
4395 };
4396 LhsKind assign_type = VARIABLE;
4397 Property* prop = expr->expression()->AsProperty(); 4406 Property* prop = expr->expression()->AsProperty();
4398 // In case of a property we use the uninitialized expression context 4407 LhsKind assign_type = GetAssignType(prop);
4399 // of the key to detect a named property.
4400 if (prop != NULL) {
4401 assign_type =
4402 (prop->key()->IsPropertyName())
4403 ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
4404 : KEYED_PROPERTY;
4405 }
4406 4408
4407 // Evaluate expression and get value. 4409 // Evaluate expression and get value.
4408 if (assign_type == VARIABLE) { 4410 if (assign_type == VARIABLE) {
4409 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4411 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4410 AccumulatorValueContext context(this); 4412 AccumulatorValueContext context(this);
4411 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4413 EmitVariableLoad(expr->expression()->AsVariableProxy());
4412 } else { 4414 } else {
4413 // Reserve space for result of postfix operation. 4415 // Reserve space for result of postfix operation.
4414 if (expr->is_postfix() && !context()->IsEffect()) { 4416 if (expr->is_postfix() && !context()->IsEffect()) {
4415 __ push(Immediate(Smi::FromInt(0))); 4417 __ push(Immediate(Smi::FromInt(0)));
4416 } 4418 }
4417 if (assign_type == NAMED_PROPERTY) { 4419 if (assign_type == NAMED_PROPERTY) {
arv (Not doing code reviews) 2014/10/07 15:05:38 maybe switch here?
Dmitry Lomov (no reviews) 2014/10/07 15:53:37 Done.
4418 // Put the object both on the stack and in the register. 4420 // Put the object both on the stack and in the register.
4419 VisitForStackValue(prop->obj()); 4421 VisitForStackValue(prop->obj());
4420 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 4422 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
4421 EmitNamedPropertyLoad(prop); 4423 EmitNamedPropertyLoad(prop);
4422 } else if (assign_type == NAMED_SUPER_PROPERTY) { 4424 } else if (assign_type == NAMED_SUPER_PROPERTY) {
4423 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); 4425 VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
4424 EmitLoadHomeObject(prop->obj()->AsSuperReference()); 4426 EmitLoadHomeObject(prop->obj()->AsSuperReference());
4425 __ push(result_register()); 4427 __ push(result_register());
4426 __ push(MemOperand(esp, kPointerSize)); 4428 __ push(MemOperand(esp, kPointerSize));
4427 __ push(result_register()); 4429 __ push(result_register());
4428 EmitNamedSuperPropertyLoad(prop); 4430 EmitNamedSuperPropertyLoad(prop);
4431 } else if (assign_type == KEYED_SUPER_PROPERTY) {
4432 VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
4433 EmitLoadHomeObject(prop->obj()->AsSuperReference());
4434 __ push(result_register());
4435 VisitForAccumulatorValue(prop->key());
4436 __ push(result_register());
4437 __ push(MemOperand(esp, 2 * kPointerSize));
4438 __ push(MemOperand(esp, 2 * kPointerSize));
4439 __ push(result_register());
4440 EmitKeyedSuperPropertyLoad(prop);
4429 } else { 4441 } else {
4430 VisitForStackValue(prop->obj()); 4442 VisitForStackValue(prop->obj());
4431 VisitForStackValue(prop->key()); 4443 VisitForStackValue(prop->key());
4432 __ mov(LoadDescriptor::ReceiverRegister(), 4444 __ mov(LoadDescriptor::ReceiverRegister(),
4433 Operand(esp, kPointerSize)); // Object. 4445 Operand(esp, kPointerSize)); // Object.
4434 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. 4446 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key.
4435 EmitKeyedPropertyLoad(prop); 4447 EmitKeyedPropertyLoad(prop);
4436 } 4448 }
4437 } 4449 }
4438 4450
(...skipping 24 matching lines...) Expand all
4463 break; 4475 break;
4464 case NAMED_PROPERTY: 4476 case NAMED_PROPERTY:
4465 __ mov(Operand(esp, kPointerSize), eax); 4477 __ mov(Operand(esp, kPointerSize), eax);
4466 break; 4478 break;
4467 case NAMED_SUPER_PROPERTY: 4479 case NAMED_SUPER_PROPERTY:
4468 __ mov(Operand(esp, 2 * kPointerSize), eax); 4480 __ mov(Operand(esp, 2 * kPointerSize), eax);
4469 break; 4481 break;
4470 case KEYED_PROPERTY: 4482 case KEYED_PROPERTY:
4471 __ mov(Operand(esp, 2 * kPointerSize), eax); 4483 __ mov(Operand(esp, 2 * kPointerSize), eax);
4472 break; 4484 break;
4485 case KEYED_SUPER_PROPERTY:
4486 __ mov(Operand(esp, 3 * kPointerSize), eax);
4487 break;
4473 } 4488 }
4474 } 4489 }
4475 } 4490 }
4476 4491
4477 if (expr->op() == Token::INC) { 4492 if (expr->op() == Token::INC) {
4478 __ add(eax, Immediate(Smi::FromInt(1))); 4493 __ add(eax, Immediate(Smi::FromInt(1)));
4479 } else { 4494 } else {
4480 __ sub(eax, Immediate(Smi::FromInt(1))); 4495 __ sub(eax, Immediate(Smi::FromInt(1)));
4481 } 4496 }
4482 __ j(no_overflow, &done, Label::kNear); 4497 __ j(no_overflow, &done, Label::kNear);
(...skipping 21 matching lines...) Expand all
4504 break; 4519 break;
4505 case NAMED_PROPERTY: 4520 case NAMED_PROPERTY:
4506 __ mov(Operand(esp, kPointerSize), eax); 4521 __ mov(Operand(esp, kPointerSize), eax);
4507 break; 4522 break;
4508 case NAMED_SUPER_PROPERTY: 4523 case NAMED_SUPER_PROPERTY:
4509 __ mov(Operand(esp, 2 * kPointerSize), eax); 4524 __ mov(Operand(esp, 2 * kPointerSize), eax);
4510 break; 4525 break;
4511 case KEYED_PROPERTY: 4526 case KEYED_PROPERTY:
4512 __ mov(Operand(esp, 2 * kPointerSize), eax); 4527 __ mov(Operand(esp, 2 * kPointerSize), eax);
4513 break; 4528 break;
4529 case KEYED_SUPER_PROPERTY:
4530 __ mov(Operand(esp, 3 * kPointerSize), eax);
4531 break;
4514 } 4532 }
4515 } 4533 }
4516 } 4534 }
4517 4535
4518 // Record position before stub call. 4536 // Record position before stub call.
4519 SetSourcePosition(expr->position()); 4537 SetSourcePosition(expr->position());
4520 4538
4521 // Call stub for +1/-1. 4539 // Call stub for +1/-1.
4522 __ bind(&stub_call); 4540 __ bind(&stub_call);
4523 __ mov(edx, eax); 4541 __ mov(edx, eax);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4571 EmitNamedSuperPropertyStore(prop); 4589 EmitNamedSuperPropertyStore(prop);
4572 if (expr->is_postfix()) { 4590 if (expr->is_postfix()) {
4573 if (!context()->IsEffect()) { 4591 if (!context()->IsEffect()) {
4574 context()->PlugTOS(); 4592 context()->PlugTOS();
4575 } 4593 }
4576 } else { 4594 } else {
4577 context()->Plug(eax); 4595 context()->Plug(eax);
4578 } 4596 }
4579 break; 4597 break;
4580 } 4598 }
4599 case KEYED_SUPER_PROPERTY: {
4600 EmitKeyedSuperPropertyStore(prop);
4601 if (expr->is_postfix()) {
4602 if (!context()->IsEffect()) {
4603 context()->PlugTOS();
4604 }
4605 } else {
4606 context()->Plug(eax);
4607 }
4608 break;
4609 }
4581 case KEYED_PROPERTY: { 4610 case KEYED_PROPERTY: {
4582 __ pop(StoreDescriptor::NameRegister()); 4611 __ pop(StoreDescriptor::NameRegister());
4583 __ pop(StoreDescriptor::ReceiverRegister()); 4612 __ pop(StoreDescriptor::ReceiverRegister());
4584 Handle<Code> ic = 4613 Handle<Code> ic =
4585 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 4614 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
4586 CallIC(ic, expr->CountStoreFeedbackId()); 4615 CallIC(ic, expr->CountStoreFeedbackId());
4587 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4616 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4588 if (expr->is_postfix()) { 4617 if (expr->is_postfix()) {
4589 // Result is on the stack 4618 // Result is on the stack
4590 if (!context()->IsEffect()) { 4619 if (!context()->IsEffect()) {
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
5032 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 5061 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
5033 Assembler::target_address_at(call_target_address, 5062 Assembler::target_address_at(call_target_address,
5034 unoptimized_code)); 5063 unoptimized_code));
5035 return OSR_AFTER_STACK_CHECK; 5064 return OSR_AFTER_STACK_CHECK;
5036 } 5065 }
5037 5066
5038 5067
5039 } } // namespace v8::internal 5068 } } // namespace v8::internal
5040 5069
5041 #endif // V8_TARGET_ARCH_IA32 5070 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/runtime/runtime.h » ('j') | src/runtime/runtime.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698