OLD | NEW |
---|---|
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 1798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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) | 1817 // Left-hand side can only be a property, a global or a (parameter or local) |
1818 // slot. | 1818 // slot. |
1819 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 1819 enum LhsKind { |
1820 VARIABLE, | |
1821 NAMED_PROPERTY, | |
1822 KEYED_PROPERTY, | |
1823 NAMED_SUPER_PROPERTY | |
1824 }; | |
1820 LhsKind assign_type = VARIABLE; | 1825 LhsKind assign_type = VARIABLE; |
1821 Property* property = expr->target()->AsProperty(); | 1826 Property* property = expr->target()->AsProperty(); |
1822 if (property != NULL) { | 1827 if (property != NULL) { |
1823 assign_type = (property->key()->IsPropertyName()) | 1828 assign_type = (property->key()->IsPropertyName()) |
1824 ? NAMED_PROPERTY | 1829 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY |
1825 : KEYED_PROPERTY; | 1830 : NAMED_PROPERTY) |
1831 : KEYED_PROPERTY; | |
1826 } | 1832 } |
1827 | 1833 |
1828 // Evaluate LHS expression. | 1834 // Evaluate LHS expression. |
1829 switch (assign_type) { | 1835 switch (assign_type) { |
1830 case VARIABLE: | 1836 case VARIABLE: |
1831 // Nothing to do here. | 1837 // Nothing to do here. |
1832 break; | 1838 break; |
1839 case NAMED_SUPER_PROPERTY: | |
1840 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); | |
1841 EmitLoadHomeObject(property->obj()->AsSuperReference()); | |
1842 __ push(result_register()); | |
1843 __ push(MemOperand(esp, kPointerSize)); | |
1844 __ push(result_register()); | |
1845 break; | |
Igor Sheludko
2014/09/25 08:06:02
I'm afraid that the second pair of receiver-home o
| |
1833 case NAMED_PROPERTY: | 1846 case NAMED_PROPERTY: |
1834 if (expr->is_compound()) { | 1847 if (expr->is_compound()) { |
1835 // We need the receiver both on the stack and in the register. | 1848 // We need the receiver both on the stack and in the register. |
1836 VisitForStackValue(property->obj()); | 1849 VisitForStackValue(property->obj()); |
1837 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1850 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1838 } else { | 1851 } else { |
1839 VisitForStackValue(property->obj()); | 1852 VisitForStackValue(property->obj()); |
1840 } | 1853 } |
1841 break; | 1854 break; |
1842 case KEYED_PROPERTY: { | 1855 case KEYED_PROPERTY: { |
(...skipping 13 matching lines...) Expand all Loading... | |
1856 // For compound assignments we need another deoptimization point after the | 1869 // For compound assignments we need another deoptimization point after the |
1857 // variable/property load. | 1870 // variable/property load. |
1858 if (expr->is_compound()) { | 1871 if (expr->is_compound()) { |
1859 AccumulatorValueContext result_context(this); | 1872 AccumulatorValueContext result_context(this); |
1860 { AccumulatorValueContext left_operand_context(this); | 1873 { AccumulatorValueContext left_operand_context(this); |
1861 switch (assign_type) { | 1874 switch (assign_type) { |
1862 case VARIABLE: | 1875 case VARIABLE: |
1863 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1876 EmitVariableLoad(expr->target()->AsVariableProxy()); |
1864 PrepareForBailout(expr->target(), TOS_REG); | 1877 PrepareForBailout(expr->target(), TOS_REG); |
1865 break; | 1878 break; |
1879 case NAMED_SUPER_PROPERTY: | |
1880 EmitNamedSuperPropertyLoad(property); | |
1881 PrepareForBailoutForId(property->LoadId(), TOS_REG); | |
1882 break; | |
1866 case NAMED_PROPERTY: | 1883 case NAMED_PROPERTY: |
1867 EmitNamedPropertyLoad(property); | 1884 EmitNamedPropertyLoad(property); |
1868 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1885 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1869 break; | 1886 break; |
1870 case KEYED_PROPERTY: | 1887 case KEYED_PROPERTY: |
1871 EmitKeyedPropertyLoad(property); | 1888 EmitKeyedPropertyLoad(property); |
1872 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1889 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1873 break; | 1890 break; |
1874 } | 1891 } |
1875 } | 1892 } |
(...skipping 29 matching lines...) Expand all Loading... | |
1905 switch (assign_type) { | 1922 switch (assign_type) { |
1906 case VARIABLE: | 1923 case VARIABLE: |
1907 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1924 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1908 expr->op()); | 1925 expr->op()); |
1909 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1926 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
1910 context()->Plug(eax); | 1927 context()->Plug(eax); |
1911 break; | 1928 break; |
1912 case NAMED_PROPERTY: | 1929 case NAMED_PROPERTY: |
1913 EmitNamedPropertyAssignment(expr); | 1930 EmitNamedPropertyAssignment(expr); |
1914 break; | 1931 break; |
1932 case NAMED_SUPER_PROPERTY: | |
1933 EmitNamedSuperPropertyAssignment(expr); | |
1934 break; | |
1915 case KEYED_PROPERTY: | 1935 case KEYED_PROPERTY: |
1916 EmitKeyedPropertyAssignment(expr); | 1936 EmitKeyedPropertyAssignment(expr); |
1917 break; | 1937 break; |
1918 } | 1938 } |
1919 } | 1939 } |
1920 | 1940 |
1921 | 1941 |
1922 void FullCodeGenerator::VisitYield(Yield* expr) { | 1942 void FullCodeGenerator::VisitYield(Yield* expr) { |
1923 Comment cmnt(masm_, "[ Yield"); | 1943 Comment cmnt(masm_, "[ Yield"); |
1924 // Evaluate yielded value first; the initial iterator definition depends on | 1944 // Evaluate yielded value first; the initial iterator definition depends on |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2244 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2264 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2245 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2265 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2246 CallLoadIC(NOT_CONTEXTUAL); | 2266 CallLoadIC(NOT_CONTEXTUAL); |
2247 } else { | 2267 } else { |
2248 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2268 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2249 } | 2269 } |
2250 } | 2270 } |
2251 | 2271 |
2252 | 2272 |
2253 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2273 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
2274 // Stack: receiver, home_object. | |
2254 SetSourcePosition(prop->position()); | 2275 SetSourcePosition(prop->position()); |
2255 Literal* key = prop->key()->AsLiteral(); | 2276 Literal* key = prop->key()->AsLiteral(); |
2256 DCHECK(!key->value()->IsSmi()); | 2277 DCHECK(!key->value()->IsSmi()); |
2257 DCHECK(prop->IsSuperAccess()); | 2278 DCHECK(prop->IsSuperAccess()); |
2258 | 2279 |
2259 SuperReference* super_ref = prop->obj()->AsSuperReference(); | |
2260 EmitLoadHomeObject(super_ref); | |
2261 __ push(eax); | |
2262 VisitForStackValue(super_ref->this_var()); | |
2263 __ push(Immediate(key->value())); | 2280 __ push(Immediate(key->value())); |
2264 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2281 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2265 } | 2282 } |
2266 | 2283 |
2267 | 2284 |
2268 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2285 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2269 SetSourcePosition(prop->position()); | 2286 SetSourcePosition(prop->position()); |
2270 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 2287 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2271 if (FLAG_vector_ics) { | 2288 if (FLAG_vector_ics) { |
2272 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2289 __ mov(VectorLoadICDescriptor::SlotRegister(), |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2523 // Record source code position before IC call. | 2540 // Record source code position before IC call. |
2524 SetSourcePosition(expr->position()); | 2541 SetSourcePosition(expr->position()); |
2525 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2542 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
2526 __ pop(StoreDescriptor::ReceiverRegister()); | 2543 __ pop(StoreDescriptor::ReceiverRegister()); |
2527 CallStoreIC(expr->AssignmentFeedbackId()); | 2544 CallStoreIC(expr->AssignmentFeedbackId()); |
2528 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2545 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2529 context()->Plug(eax); | 2546 context()->Plug(eax); |
2530 } | 2547 } |
2531 | 2548 |
2532 | 2549 |
2550 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { | |
2551 // Assignment to named property of super. | |
2552 // eax : 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(eax); | |
2560 __ push(Immediate(key->value())); | |
2561 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict | |
2562 : Runtime::kStoreToSuper_Sloppy), | |
2563 4); | |
2564 } | |
2565 | |
2566 | |
2533 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2567 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2534 // Assignment to a property, using a keyed store IC. | 2568 // Assignment to a property, using a keyed store IC. |
2535 // eax : value | 2569 // eax : value |
2536 // esp[0] : key | 2570 // esp[0] : key |
2537 // esp[kPointerSize] : receiver | 2571 // esp[kPointerSize] : receiver |
2538 | 2572 |
2539 __ pop(StoreDescriptor::NameRegister()); // Key. | 2573 __ pop(StoreDescriptor::NameRegister()); // Key. |
2540 __ pop(StoreDescriptor::ReceiverRegister()); | 2574 __ pop(StoreDescriptor::ReceiverRegister()); |
2541 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2575 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2542 // Record source code position before IC call. | 2576 // Record source code position before IC call. |
2543 SetSourcePosition(expr->position()); | 2577 SetSourcePosition(expr->position()); |
2544 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 2578 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2545 CallIC(ic, expr->AssignmentFeedbackId()); | 2579 CallIC(ic, expr->AssignmentFeedbackId()); |
2546 | 2580 |
2547 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2581 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2548 context()->Plug(eax); | 2582 context()->Plug(eax); |
2549 } | 2583 } |
2550 | 2584 |
2551 | 2585 |
2552 void FullCodeGenerator::VisitProperty(Property* expr) { | 2586 void FullCodeGenerator::VisitProperty(Property* expr) { |
2553 Comment cmnt(masm_, "[ Property"); | 2587 Comment cmnt(masm_, "[ Property"); |
2554 Expression* key = expr->key(); | 2588 Expression* key = expr->key(); |
2555 | 2589 |
2556 if (key->IsPropertyName()) { | 2590 if (key->IsPropertyName()) { |
2557 if (!expr->IsSuperAccess()) { | 2591 if (!expr->IsSuperAccess()) { |
2558 VisitForAccumulatorValue(expr->obj()); | 2592 VisitForAccumulatorValue(expr->obj()); |
2559 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 2593 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
2560 EmitNamedPropertyLoad(expr); | 2594 EmitNamedPropertyLoad(expr); |
2561 } else { | 2595 } else { |
2596 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); | |
2597 EmitLoadHomeObject(expr->obj()->AsSuperReference()); | |
2598 __ push(result_register()); | |
2562 EmitNamedSuperPropertyLoad(expr); | 2599 EmitNamedSuperPropertyLoad(expr); |
2563 } | 2600 } |
2564 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2601 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2565 context()->Plug(eax); | 2602 context()->Plug(eax); |
2566 } else { | 2603 } else { |
2567 VisitForStackValue(expr->obj()); | 2604 VisitForStackValue(expr->obj()); |
2568 VisitForAccumulatorValue(expr->key()); | 2605 VisitForAccumulatorValue(expr->key()); |
2569 __ pop(LoadDescriptor::ReceiverRegister()); // Object. | 2606 __ pop(LoadDescriptor::ReceiverRegister()); // Object. |
2570 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. | 2607 __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. |
2571 EmitKeyedPropertyLoad(expr); | 2608 EmitKeyedPropertyLoad(expr); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2620 | 2657 |
2621 SetSourcePosition(prop->position()); | 2658 SetSourcePosition(prop->position()); |
2622 Literal* key = prop->key()->AsLiteral(); | 2659 Literal* key = prop->key()->AsLiteral(); |
2623 DCHECK(!key->value()->IsSmi()); | 2660 DCHECK(!key->value()->IsSmi()); |
2624 // Load the function from the receiver. | 2661 // Load the function from the receiver. |
2625 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); | 2662 SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); |
2626 EmitLoadHomeObject(super_ref); | 2663 EmitLoadHomeObject(super_ref); |
2627 __ push(eax); | 2664 __ push(eax); |
2628 VisitForAccumulatorValue(super_ref->this_var()); | 2665 VisitForAccumulatorValue(super_ref->this_var()); |
2629 __ push(eax); | 2666 __ push(eax); |
2630 __ push(Operand(esp, kPointerSize)); | |
2631 __ push(eax); | 2667 __ push(eax); |
2668 __ push(Operand(esp, kPointerSize * 2)); | |
2632 __ push(Immediate(key->value())); | 2669 __ push(Immediate(key->value())); |
2633 // Stack here: | 2670 // Stack here: |
2634 // - home_object | 2671 // - home_object |
2635 // - this (receiver) | 2672 // - this (receiver) |
2636 // - home_object <-- LoadFromSuper will pop here and below. | 2673 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2637 // - this (receiver) | 2674 // - home_object |
2638 // - key | 2675 // - key |
2639 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2676 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2640 | 2677 |
2641 // Replace home_object with target function. | 2678 // Replace home_object with target function. |
2642 __ mov(Operand(esp, kPointerSize), eax); | 2679 __ mov(Operand(esp, kPointerSize), eax); |
2643 | 2680 |
2644 // Stack here: | 2681 // Stack here: |
2645 // - target function | 2682 // - target function |
2646 // - this (receiver) | 2683 // - this (receiver) |
2647 EmitCall(expr, CallICState::METHOD); | 2684 EmitCall(expr, CallICState::METHOD); |
(...skipping 2256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4904 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4941 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4905 Assembler::target_address_at(call_target_address, | 4942 Assembler::target_address_at(call_target_address, |
4906 unoptimized_code)); | 4943 unoptimized_code)); |
4907 return OSR_AFTER_STACK_CHECK; | 4944 return OSR_AFTER_STACK_CHECK; |
4908 } | 4945 } |
4909 | 4946 |
4910 | 4947 |
4911 } } // namespace v8::internal | 4948 } } // namespace v8::internal |
4912 | 4949 |
4913 #endif // V8_TARGET_ARCH_IA32 | 4950 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |