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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 1853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1864 } | 1864 } |
1865 | 1865 |
1866 | 1866 |
1867 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1867 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1868 DCHECK(expr->target()->IsValidReferenceExpression()); | 1868 DCHECK(expr->target()->IsValidReferenceExpression()); |
1869 | 1869 |
1870 Comment cmnt(masm_, "[ Assignment"); | 1870 Comment cmnt(masm_, "[ Assignment"); |
1871 | 1871 |
1872 // Left-hand side can only be a property, a global or a (parameter or local) | 1872 // Left-hand side can only be a property, a global or a (parameter or local) |
1873 // slot. | 1873 // slot. |
1874 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 1874 enum LhsKind { |
| 1875 VARIABLE, |
| 1876 NAMED_PROPERTY, |
| 1877 KEYED_PROPERTY, |
| 1878 NAMED_SUPER_PROPERTY |
| 1879 }; |
1875 LhsKind assign_type = VARIABLE; | 1880 LhsKind assign_type = VARIABLE; |
1876 Property* property = expr->target()->AsProperty(); | 1881 Property* property = expr->target()->AsProperty(); |
1877 if (property != NULL) { | 1882 if (property != NULL) { |
1878 assign_type = (property->key()->IsPropertyName()) | 1883 assign_type = (property->key()->IsPropertyName()) |
1879 ? NAMED_PROPERTY | 1884 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY |
1880 : KEYED_PROPERTY; | 1885 : NAMED_PROPERTY) |
| 1886 : KEYED_PROPERTY; |
1881 } | 1887 } |
1882 | 1888 |
1883 // Evaluate LHS expression. | 1889 // Evaluate LHS expression. |
1884 switch (assign_type) { | 1890 switch (assign_type) { |
1885 case VARIABLE: | 1891 case VARIABLE: |
1886 // Nothing to do here. | 1892 // Nothing to do here. |
1887 break; | 1893 break; |
1888 case NAMED_PROPERTY: | 1894 case NAMED_PROPERTY: |
1889 if (expr->is_compound()) { | 1895 if (expr->is_compound()) { |
1890 // We need the receiver both on the stack and in the register. | 1896 // We need the receiver both on the stack and in the register. |
1891 VisitForStackValue(property->obj()); | 1897 VisitForStackValue(property->obj()); |
1892 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1898 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
1893 } else { | 1899 } else { |
1894 VisitForStackValue(property->obj()); | 1900 VisitForStackValue(property->obj()); |
1895 } | 1901 } |
1896 break; | 1902 break; |
| 1903 case NAMED_SUPER_PROPERTY: |
| 1904 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1905 EmitLoadHomeObject(property->obj()->AsSuperReference()); |
| 1906 __ Push(result_register()); |
| 1907 if (expr->is_compound()) { |
| 1908 const Register scratch = a1; |
| 1909 __ ld(scratch, MemOperand(sp, kPointerSize)); |
| 1910 __ Push(scratch, result_register()); |
| 1911 } |
| 1912 break; |
1897 case KEYED_PROPERTY: | 1913 case KEYED_PROPERTY: |
1898 // We need the key and receiver on both the stack and in v0 and a1. | 1914 // We need the key and receiver on both the stack and in v0 and a1. |
1899 if (expr->is_compound()) { | 1915 if (expr->is_compound()) { |
1900 VisitForStackValue(property->obj()); | 1916 VisitForStackValue(property->obj()); |
1901 VisitForStackValue(property->key()); | 1917 VisitForStackValue(property->key()); |
1902 __ ld(LoadDescriptor::ReceiverRegister(), | 1918 __ ld(LoadDescriptor::ReceiverRegister(), |
1903 MemOperand(sp, 1 * kPointerSize)); | 1919 MemOperand(sp, 1 * kPointerSize)); |
1904 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 1920 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
1905 } else { | 1921 } else { |
1906 VisitForStackValue(property->obj()); | 1922 VisitForStackValue(property->obj()); |
1907 VisitForStackValue(property->key()); | 1923 VisitForStackValue(property->key()); |
1908 } | 1924 } |
1909 break; | 1925 break; |
1910 } | 1926 } |
1911 | 1927 |
1912 // For compound assignments we need another deoptimization point after the | 1928 // For compound assignments we need another deoptimization point after the |
1913 // variable/property load. | 1929 // variable/property load. |
1914 if (expr->is_compound()) { | 1930 if (expr->is_compound()) { |
1915 { AccumulatorValueContext context(this); | 1931 { AccumulatorValueContext context(this); |
1916 switch (assign_type) { | 1932 switch (assign_type) { |
1917 case VARIABLE: | 1933 case VARIABLE: |
1918 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1934 EmitVariableLoad(expr->target()->AsVariableProxy()); |
1919 PrepareForBailout(expr->target(), TOS_REG); | 1935 PrepareForBailout(expr->target(), TOS_REG); |
1920 break; | 1936 break; |
1921 case NAMED_PROPERTY: | 1937 case NAMED_PROPERTY: |
1922 EmitNamedPropertyLoad(property); | 1938 EmitNamedPropertyLoad(property); |
1923 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1939 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1924 break; | 1940 break; |
| 1941 case NAMED_SUPER_PROPERTY: |
| 1942 EmitNamedSuperPropertyLoad(property); |
| 1943 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1944 break; |
1925 case KEYED_PROPERTY: | 1945 case KEYED_PROPERTY: |
1926 EmitKeyedPropertyLoad(property); | 1946 EmitKeyedPropertyLoad(property); |
1927 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1947 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
1928 break; | 1948 break; |
1929 } | 1949 } |
1930 } | 1950 } |
1931 | 1951 |
1932 Token::Value op = expr->binary_op(); | 1952 Token::Value op = expr->binary_op(); |
1933 __ push(v0); // Left operand goes on the stack. | 1953 __ push(v0); // Left operand goes on the stack. |
1934 VisitForAccumulatorValue(expr->value()); | 1954 VisitForAccumulatorValue(expr->value()); |
(...skipping 26 matching lines...) Expand all Loading... |
1961 switch (assign_type) { | 1981 switch (assign_type) { |
1962 case VARIABLE: | 1982 case VARIABLE: |
1963 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1983 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1964 expr->op()); | 1984 expr->op()); |
1965 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1985 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
1966 context()->Plug(v0); | 1986 context()->Plug(v0); |
1967 break; | 1987 break; |
1968 case NAMED_PROPERTY: | 1988 case NAMED_PROPERTY: |
1969 EmitNamedPropertyAssignment(expr); | 1989 EmitNamedPropertyAssignment(expr); |
1970 break; | 1990 break; |
| 1991 case NAMED_SUPER_PROPERTY: |
| 1992 EmitNamedSuperPropertyAssignment(expr); |
| 1993 break; |
1971 case KEYED_PROPERTY: | 1994 case KEYED_PROPERTY: |
1972 EmitKeyedPropertyAssignment(expr); | 1995 EmitKeyedPropertyAssignment(expr); |
1973 break; | 1996 break; |
1974 } | 1997 } |
1975 } | 1998 } |
1976 | 1999 |
1977 | 2000 |
1978 void FullCodeGenerator::VisitYield(Yield* expr) { | 2001 void FullCodeGenerator::VisitYield(Yield* expr) { |
1979 Comment cmnt(masm_, "[ Yield"); | 2002 Comment cmnt(masm_, "[ Yield"); |
1980 // Evaluate yielded value first; the initial iterator definition depends on | 2003 // Evaluate yielded value first; the initial iterator definition depends on |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2303 __ li(VectorLoadICDescriptor::SlotRegister(), | 2326 __ li(VectorLoadICDescriptor::SlotRegister(), |
2304 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2327 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2305 CallLoadIC(NOT_CONTEXTUAL); | 2328 CallLoadIC(NOT_CONTEXTUAL); |
2306 } else { | 2329 } else { |
2307 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2330 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2308 } | 2331 } |
2309 } | 2332 } |
2310 | 2333 |
2311 | 2334 |
2312 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2335 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2336 // Stack: receiver, home_object. |
2313 SetSourcePosition(prop->position()); | 2337 SetSourcePosition(prop->position()); |
2314 Literal* key = prop->key()->AsLiteral(); | 2338 Literal* key = prop->key()->AsLiteral(); |
2315 DCHECK(!key->value()->IsSmi()); | 2339 DCHECK(!key->value()->IsSmi()); |
2316 DCHECK(prop->IsSuperAccess()); | 2340 DCHECK(prop->IsSuperAccess()); |
2317 | 2341 |
2318 SuperReference* super_ref = prop->obj()->AsSuperReference(); | |
2319 EmitLoadHomeObject(super_ref); | |
2320 __ Push(v0); | |
2321 VisitForStackValue(super_ref->this_var()); | |
2322 __ Push(key->value()); | 2342 __ Push(key->value()); |
2323 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2343 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2324 } | 2344 } |
2325 | 2345 |
2326 | 2346 |
2327 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2347 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2328 SetSourcePosition(prop->position()); | 2348 SetSourcePosition(prop->position()); |
2329 // Call keyed load IC. It has register arguments receiver and key. | 2349 // Call keyed load IC. It has register arguments receiver and key. |
2330 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); | 2350 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2331 if (FLAG_vector_ics) { | 2351 if (FLAG_vector_ics) { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2586 __ li(StoreDescriptor::NameRegister(), | 2606 __ li(StoreDescriptor::NameRegister(), |
2587 Operand(prop->key()->AsLiteral()->value())); | 2607 Operand(prop->key()->AsLiteral()->value())); |
2588 __ pop(StoreDescriptor::ReceiverRegister()); | 2608 __ pop(StoreDescriptor::ReceiverRegister()); |
2589 CallStoreIC(expr->AssignmentFeedbackId()); | 2609 CallStoreIC(expr->AssignmentFeedbackId()); |
2590 | 2610 |
2591 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2611 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2592 context()->Plug(v0); | 2612 context()->Plug(v0); |
2593 } | 2613 } |
2594 | 2614 |
2595 | 2615 |
| 2616 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) { |
| 2617 // Assignment to named property of super. |
| 2618 // v0 : value |
| 2619 // stack : receiver ('this'), home_object |
| 2620 Property* prop = expr->target()->AsProperty(); |
| 2621 DCHECK(prop != NULL); |
| 2622 Literal* key = prop->key()->AsLiteral(); |
| 2623 DCHECK(key != NULL); |
| 2624 |
| 2625 __ Push(v0); |
| 2626 __ Push(key->value()); |
| 2627 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict |
| 2628 : Runtime::kStoreToSuper_Sloppy), |
| 2629 4); |
| 2630 context()->Plug(v0); |
| 2631 } |
| 2632 |
| 2633 |
2596 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2634 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2597 // Assignment to a property, using a keyed store IC. | 2635 // Assignment to a property, using a keyed store IC. |
2598 | 2636 |
2599 // Record source code position before IC call. | 2637 // Record source code position before IC call. |
2600 SetSourcePosition(expr->position()); | 2638 SetSourcePosition(expr->position()); |
2601 // Call keyed store IC. | 2639 // Call keyed store IC. |
2602 // The arguments are: | 2640 // The arguments are: |
2603 // - a0 is the value, | 2641 // - a0 is the value, |
2604 // - a1 is the key, | 2642 // - a1 is the key, |
2605 // - a2 is the receiver. | 2643 // - a2 is the receiver. |
(...skipping 12 matching lines...) Expand all Loading... |
2618 void FullCodeGenerator::VisitProperty(Property* expr) { | 2656 void FullCodeGenerator::VisitProperty(Property* expr) { |
2619 Comment cmnt(masm_, "[ Property"); | 2657 Comment cmnt(masm_, "[ Property"); |
2620 Expression* key = expr->key(); | 2658 Expression* key = expr->key(); |
2621 | 2659 |
2622 if (key->IsPropertyName()) { | 2660 if (key->IsPropertyName()) { |
2623 if (!expr->IsSuperAccess()) { | 2661 if (!expr->IsSuperAccess()) { |
2624 VisitForAccumulatorValue(expr->obj()); | 2662 VisitForAccumulatorValue(expr->obj()); |
2625 __ Move(LoadDescriptor::ReceiverRegister(), v0); | 2663 __ Move(LoadDescriptor::ReceiverRegister(), v0); |
2626 EmitNamedPropertyLoad(expr); | 2664 EmitNamedPropertyLoad(expr); |
2627 } else { | 2665 } else { |
| 2666 VisitForStackValue(expr->obj()->AsSuperReference()->this_var()); |
| 2667 EmitLoadHomeObject(expr->obj()->AsSuperReference()); |
| 2668 __ Push(result_register()); |
2628 EmitNamedSuperPropertyLoad(expr); | 2669 EmitNamedSuperPropertyLoad(expr); |
2629 } | 2670 } |
2630 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2671 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2631 context()->Plug(v0); | 2672 context()->Plug(v0); |
2632 } else { | 2673 } else { |
2633 VisitForStackValue(expr->obj()); | 2674 VisitForStackValue(expr->obj()); |
2634 VisitForAccumulatorValue(expr->key()); | 2675 VisitForAccumulatorValue(expr->key()); |
2635 __ Move(LoadDescriptor::NameRegister(), v0); | 2676 __ Move(LoadDescriptor::NameRegister(), v0); |
2636 __ pop(LoadDescriptor::ReceiverRegister()); | 2677 __ pop(LoadDescriptor::ReceiverRegister()); |
2637 EmitKeyedPropertyLoad(expr); | 2678 EmitKeyedPropertyLoad(expr); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2686 Property* prop = callee->AsProperty(); | 2727 Property* prop = callee->AsProperty(); |
2687 DCHECK(prop->IsSuperAccess()); | 2728 DCHECK(prop->IsSuperAccess()); |
2688 | 2729 |
2689 SetSourcePosition(prop->position()); | 2730 SetSourcePosition(prop->position()); |
2690 Literal* key = prop->key()->AsLiteral(); | 2731 Literal* key = prop->key()->AsLiteral(); |
2691 DCHECK(!key->value()->IsSmi()); | 2732 DCHECK(!key->value()->IsSmi()); |
2692 // Load the function from the receiver. | 2733 // Load the function from the receiver. |
2693 const Register scratch = a1; | 2734 const Register scratch = a1; |
2694 SuperReference* super_ref = prop->obj()->AsSuperReference(); | 2735 SuperReference* super_ref = prop->obj()->AsSuperReference(); |
2695 EmitLoadHomeObject(super_ref); | 2736 EmitLoadHomeObject(super_ref); |
2696 __ Push(v0); | 2737 __ mov(scratch, v0); |
2697 VisitForAccumulatorValue(super_ref->this_var()); | 2738 VisitForAccumulatorValue(super_ref->this_var()); |
2698 __ Push(v0); | 2739 __ Push(scratch, v0, v0, scratch); |
2699 __ ld(scratch, MemOperand(sp, kPointerSize)); | |
2700 __ Push(scratch, v0); | |
2701 __ Push(key->value()); | 2740 __ Push(key->value()); |
2702 | 2741 |
2703 // Stack here: | 2742 // Stack here: |
2704 // - home_object | 2743 // - home_object |
2705 // - this (receiver) | 2744 // - this (receiver) |
2706 // - home_object <-- LoadFromSuper will pop here and below. | 2745 // - this (receiver) <-- LoadFromSuper will pop here and below. |
2707 // - this (receiver) | 2746 // - home_object |
2708 // - key | 2747 // - key |
2709 __ CallRuntime(Runtime::kLoadFromSuper, 3); | 2748 __ CallRuntime(Runtime::kLoadFromSuper, 3); |
2710 | 2749 |
2711 // Replace home_object with target function. | 2750 // Replace home_object with target function. |
2712 __ sd(v0, MemOperand(sp, kPointerSize)); | 2751 __ sd(v0, MemOperand(sp, kPointerSize)); |
2713 | 2752 |
2714 // Stack here: | 2753 // Stack here: |
2715 // - target function | 2754 // - target function |
2716 // - this (receiver) | 2755 // - this (receiver) |
2717 EmitCall(expr, CallICState::METHOD); | 2756 EmitCall(expr, CallICState::METHOD); |
(...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4344 // Expression can only be a property, a global or a (parameter or local) | 4383 // Expression can only be a property, a global or a (parameter or local) |
4345 // slot. | 4384 // slot. |
4346 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 4385 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
4347 LhsKind assign_type = VARIABLE; | 4386 LhsKind assign_type = VARIABLE; |
4348 Property* prop = expr->expression()->AsProperty(); | 4387 Property* prop = expr->expression()->AsProperty(); |
4349 // In case of a property we use the uninitialized expression context | 4388 // In case of a property we use the uninitialized expression context |
4350 // of the key to detect a named property. | 4389 // of the key to detect a named property. |
4351 if (prop != NULL) { | 4390 if (prop != NULL) { |
4352 assign_type = | 4391 assign_type = |
4353 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 4392 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
| 4393 if (prop->IsSuperAccess()) { |
| 4394 // throw exception. |
| 4395 VisitSuperReference(prop->obj()->AsSuperReference()); |
| 4396 return; |
| 4397 } |
4354 } | 4398 } |
4355 | 4399 |
4356 // Evaluate expression and get value. | 4400 // Evaluate expression and get value. |
4357 if (assign_type == VARIABLE) { | 4401 if (assign_type == VARIABLE) { |
4358 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4402 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4359 AccumulatorValueContext context(this); | 4403 AccumulatorValueContext context(this); |
4360 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4404 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4361 } else { | 4405 } else { |
4362 // Reserve space for result of postfix operation. | 4406 // Reserve space for result of postfix operation. |
4363 if (expr->is_postfix() && !context()->IsEffect()) { | 4407 if (expr->is_postfix() && !context()->IsEffect()) { |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4961 Assembler::target_address_at(pc_immediate_load_address)) == | 5005 Assembler::target_address_at(pc_immediate_load_address)) == |
4962 reinterpret_cast<uint64_t>( | 5006 reinterpret_cast<uint64_t>( |
4963 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5007 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4964 return OSR_AFTER_STACK_CHECK; | 5008 return OSR_AFTER_STACK_CHECK; |
4965 } | 5009 } |
4966 | 5010 |
4967 | 5011 |
4968 } } // namespace v8::internal | 5012 } } // namespace v8::internal |
4969 | 5013 |
4970 #endif // V8_TARGET_ARCH_MIPS64 | 5014 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |