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

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

Powered by Google App Engine
This is Rietveld 408576698