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

Side by Side Diff: src/mips64/full-codegen-mips64.cc

Issue 616463002: MIPS: Stores and compound assignments for named super properties. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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
« no previous file with comments | « src/mips/full-codegen-mips.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/mips/full-codegen-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698