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

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

Issue 593073002: Stores and compound assignments for named super properties. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased for landing 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/arm64/full-codegen-arm64.cc » ('j') | src/full-codegen.h » ('J')
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_ARM 7 #if V8_TARGET_ARCH_ARM
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 1867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 } 1878 }
1879 1879
1880 1880
1881 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1881 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1882 DCHECK(expr->target()->IsValidReferenceExpression()); 1882 DCHECK(expr->target()->IsValidReferenceExpression());
1883 1883
1884 Comment cmnt(masm_, "[ Assignment"); 1884 Comment cmnt(masm_, "[ Assignment");
1885 1885
1886 // Left-hand side can only be a property, a global or a (parameter or local) 1886 // Left-hand side can only be a property, a global or a (parameter or local)
1887 // slot. 1887 // slot.
1888 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1888 enum LhsKind {
1889 VARIABLE,
1890 NAMED_PROPERTY,
1891 KEYED_PROPERTY,
1892 NAMED_SUPER_PROPERTY
1893 };
1889 LhsKind assign_type = VARIABLE; 1894 LhsKind assign_type = VARIABLE;
1890 Property* property = expr->target()->AsProperty(); 1895 Property* property = expr->target()->AsProperty();
1891 if (property != NULL) { 1896 if (property != NULL) {
1892 assign_type = (property->key()->IsPropertyName()) 1897 assign_type = (property->key()->IsPropertyName())
1893 ? NAMED_PROPERTY 1898 ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
1894 : KEYED_PROPERTY; 1899 : NAMED_PROPERTY)
1900 : KEYED_PROPERTY;
1895 } 1901 }
1896 1902
1897 // Evaluate LHS expression. 1903 // Evaluate LHS expression.
1898 switch (assign_type) { 1904 switch (assign_type) {
1899 case VARIABLE: 1905 case VARIABLE:
1900 // Nothing to do here. 1906 // Nothing to do here.
1901 break; 1907 break;
1902 case NAMED_PROPERTY: 1908 case NAMED_PROPERTY:
1903 if (expr->is_compound()) { 1909 if (expr->is_compound()) {
1904 // We need the receiver both on the stack and in the register. 1910 // We need the receiver both on the stack and in the register.
1905 VisitForStackValue(property->obj()); 1911 VisitForStackValue(property->obj());
1906 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1912 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1907 } else { 1913 } else {
1908 VisitForStackValue(property->obj()); 1914 VisitForStackValue(property->obj());
1909 } 1915 }
1910 break; 1916 break;
1917 case NAMED_SUPER_PROPERTY:
1918 VisitForStackValue(property->obj()->AsSuperReference()->this_var());
1919 EmitLoadHomeObject(property->obj()->AsSuperReference());
1920 __ Push(result_register());
1921 if (expr->is_compound()) {
1922 const Register scratch = r1;
1923 __ ldr(scratch, MemOperand(sp, kPointerSize));
1924 __ Push(scratch);
1925 __ Push(result_register());
1926 }
1927 break;
1911 case KEYED_PROPERTY: 1928 case KEYED_PROPERTY:
1912 if (expr->is_compound()) { 1929 if (expr->is_compound()) {
1913 VisitForStackValue(property->obj()); 1930 VisitForStackValue(property->obj());
1914 VisitForStackValue(property->key()); 1931 VisitForStackValue(property->key());
1915 __ ldr(LoadDescriptor::ReceiverRegister(), 1932 __ ldr(LoadDescriptor::ReceiverRegister(),
1916 MemOperand(sp, 1 * kPointerSize)); 1933 MemOperand(sp, 1 * kPointerSize));
1917 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); 1934 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
1918 } else { 1935 } else {
1919 VisitForStackValue(property->obj()); 1936 VisitForStackValue(property->obj());
1920 VisitForStackValue(property->key()); 1937 VisitForStackValue(property->key());
1921 } 1938 }
1922 break; 1939 break;
1923 } 1940 }
1924 1941
1925 // For compound assignments we need another deoptimization point after the 1942 // For compound assignments we need another deoptimization point after the
1926 // variable/property load. 1943 // variable/property load.
1927 if (expr->is_compound()) { 1944 if (expr->is_compound()) {
1928 { AccumulatorValueContext context(this); 1945 { AccumulatorValueContext context(this);
1929 switch (assign_type) { 1946 switch (assign_type) {
1930 case VARIABLE: 1947 case VARIABLE:
1931 EmitVariableLoad(expr->target()->AsVariableProxy()); 1948 EmitVariableLoad(expr->target()->AsVariableProxy());
1932 PrepareForBailout(expr->target(), TOS_REG); 1949 PrepareForBailout(expr->target(), TOS_REG);
1933 break; 1950 break;
1934 case NAMED_PROPERTY: 1951 case NAMED_PROPERTY:
1935 EmitNamedPropertyLoad(property); 1952 EmitNamedPropertyLoad(property);
1936 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1953 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1937 break; 1954 break;
1955 case NAMED_SUPER_PROPERTY:
1956 EmitNamedSuperPropertyLoad(property);
1957 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1958 break;
1938 case KEYED_PROPERTY: 1959 case KEYED_PROPERTY:
1939 EmitKeyedPropertyLoad(property); 1960 EmitKeyedPropertyLoad(property);
1940 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1961 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1941 break; 1962 break;
1942 } 1963 }
1943 } 1964 }
1944 1965
1945 Token::Value op = expr->binary_op(); 1966 Token::Value op = expr->binary_op();
1946 __ push(r0); // Left operand goes on the stack. 1967 __ push(r0); // Left operand goes on the stack.
1947 VisitForAccumulatorValue(expr->value()); 1968 VisitForAccumulatorValue(expr->value());
(...skipping 26 matching lines...) Expand all
1974 switch (assign_type) { 1995 switch (assign_type) {
1975 case VARIABLE: 1996 case VARIABLE:
1976 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1997 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1977 expr->op()); 1998 expr->op());
1978 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1999 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1979 context()->Plug(r0); 2000 context()->Plug(r0);
1980 break; 2001 break;
1981 case NAMED_PROPERTY: 2002 case NAMED_PROPERTY:
1982 EmitNamedPropertyAssignment(expr); 2003 EmitNamedPropertyAssignment(expr);
1983 break; 2004 break;
2005 case NAMED_SUPER_PROPERTY:
2006 EmitNamedSuperPropertyAssignment(expr);
2007 break;
1984 case KEYED_PROPERTY: 2008 case KEYED_PROPERTY:
1985 EmitKeyedPropertyAssignment(expr); 2009 EmitKeyedPropertyAssignment(expr);
1986 break; 2010 break;
1987 } 2011 }
1988 } 2012 }
1989 2013
1990 2014
1991 void FullCodeGenerator::VisitYield(Yield* expr) { 2015 void FullCodeGenerator::VisitYield(Yield* expr) {
1992 Comment cmnt(masm_, "[ Yield"); 2016 Comment cmnt(masm_, "[ Yield");
1993 // Evaluate yielded value first; the initial iterator definition depends on 2017 // Evaluate yielded value first; the initial iterator definition depends on
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
2312 // Only the value field needs a write barrier, as the other values are in the 2336 // Only the value field needs a write barrier, as the other values are in the
2313 // root set. 2337 // root set.
2314 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, 2338 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset,
2315 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); 2339 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs);
2316 } 2340 }
2317 2341
2318 2342
2319 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2343 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2320 SetSourcePosition(prop->position()); 2344 SetSourcePosition(prop->position());
2321 Literal* key = prop->key()->AsLiteral(); 2345 Literal* key = prop->key()->AsLiteral();
2346 DCHECK(!prop->IsSuperAccess());
2322 2347
2323 __ mov(LoadDescriptor::NameRegister(), Operand(key->value())); 2348 __ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
2324 if (FLAG_vector_ics) { 2349 if (FLAG_vector_ics) {
2325 __ mov(VectorLoadICDescriptor::SlotRegister(), 2350 __ mov(VectorLoadICDescriptor::SlotRegister(),
2326 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2351 Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
2327 CallLoadIC(NOT_CONTEXTUAL); 2352 CallLoadIC(NOT_CONTEXTUAL);
2328 } else { 2353 } else {
2329 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2354 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2330 } 2355 }
2331 } 2356 }
2332 2357
2333 2358
2334 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2359 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
2360 // Stack: receiver, home_object.
2335 SetSourcePosition(prop->position()); 2361 SetSourcePosition(prop->position());
2336 Literal* key = prop->key()->AsLiteral(); 2362 Literal* key = prop->key()->AsLiteral();
2337 DCHECK(!key->value()->IsSmi()); 2363 DCHECK(!key->value()->IsSmi());
2338 DCHECK(prop->IsSuperAccess()); 2364 DCHECK(prop->IsSuperAccess());
2339 2365
2340 SuperReference* super_ref = prop->obj()->AsSuperReference();
2341 EmitLoadHomeObject(super_ref);
2342 __ Push(r0);
2343 VisitForStackValue(super_ref->this_var());
2344 __ Push(key->value()); 2366 __ Push(key->value());
2345 __ CallRuntime(Runtime::kLoadFromSuper, 3); 2367 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2346 } 2368 }
2347 2369
2348 2370
2349 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2371 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2350 SetSourcePosition(prop->position()); 2372 SetSourcePosition(prop->position());
2351 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 2373 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
2352 if (FLAG_vector_ics) { 2374 if (FLAG_vector_ics) {
2353 __ mov(VectorLoadICDescriptor::SlotRegister(), 2375 __ mov(VectorLoadICDescriptor::SlotRegister(),
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 __ mov(StoreDescriptor::NameRegister(), 2627 __ mov(StoreDescriptor::NameRegister(),
2606 Operand(prop->key()->AsLiteral()->value())); 2628 Operand(prop->key()->AsLiteral()->value()));
2607 __ pop(StoreDescriptor::ReceiverRegister()); 2629 __ pop(StoreDescriptor::ReceiverRegister());
2608 CallStoreIC(expr->AssignmentFeedbackId()); 2630 CallStoreIC(expr->AssignmentFeedbackId());
2609 2631
2610 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2632 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2611 context()->Plug(r0); 2633 context()->Plug(r0);
2612 } 2634 }
2613 2635
2614 2636
2637 void FullCodeGenerator::EmitNamedSuperPropertyAssignment(Assignment* expr) {
2638 // Assignment to named property of super.
2639 // r0 : value
2640 // stack : receiver ('this'), home_object
2641 Property* prop = expr->target()->AsProperty();
2642 DCHECK(prop != NULL);
2643 Literal* key = prop->key()->AsLiteral();
2644 DCHECK(key != NULL);
2645
2646 __ Push(r0);
2647 __ Push(key->value());
2648 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
2649 : Runtime::kStoreToSuper_Sloppy),
2650 4);
2651 context()->Plug(r0);
2652 }
2653
2654
2615 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2655 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2616 // Assignment to a property, using a keyed store IC. 2656 // Assignment to a property, using a keyed store IC.
2617 2657
2618 // Record source code position before IC call. 2658 // Record source code position before IC call.
2619 SetSourcePosition(expr->position()); 2659 SetSourcePosition(expr->position());
2620 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2660 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2621 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 2661 DCHECK(StoreDescriptor::ValueRegister().is(r0));
2622 2662
2623 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 2663 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
2624 CallIC(ic, expr->AssignmentFeedbackId()); 2664 CallIC(ic, expr->AssignmentFeedbackId());
2625 2665
2626 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2666 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2627 context()->Plug(r0); 2667 context()->Plug(r0);
2628 } 2668 }
2629 2669
2630 2670
2631 void FullCodeGenerator::VisitProperty(Property* expr) { 2671 void FullCodeGenerator::VisitProperty(Property* expr) {
2632 Comment cmnt(masm_, "[ Property"); 2672 Comment cmnt(masm_, "[ Property");
2633 Expression* key = expr->key(); 2673 Expression* key = expr->key();
2634 2674
2635 if (key->IsPropertyName()) { 2675 if (key->IsPropertyName()) {
2636 if (!expr->IsSuperAccess()) { 2676 if (!expr->IsSuperAccess()) {
2637 VisitForAccumulatorValue(expr->obj()); 2677 VisitForAccumulatorValue(expr->obj());
2638 __ Move(LoadDescriptor::ReceiverRegister(), r0); 2678 __ Move(LoadDescriptor::ReceiverRegister(), r0);
2639 EmitNamedPropertyLoad(expr); 2679 EmitNamedPropertyLoad(expr);
2640 } else { 2680 } else {
2681 VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
2682 EmitLoadHomeObject(expr->obj()->AsSuperReference());
2683 __ Push(result_register());
2641 EmitNamedSuperPropertyLoad(expr); 2684 EmitNamedSuperPropertyLoad(expr);
2642 } 2685 }
2643 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2686 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2644 context()->Plug(r0); 2687 context()->Plug(r0);
2645 } else { 2688 } else {
2646 VisitForStackValue(expr->obj()); 2689 VisitForStackValue(expr->obj());
2647 VisitForAccumulatorValue(expr->key()); 2690 VisitForAccumulatorValue(expr->key());
2648 __ Move(LoadDescriptor::NameRegister(), r0); 2691 __ Move(LoadDescriptor::NameRegister(), r0);
2649 __ pop(LoadDescriptor::ReceiverRegister()); 2692 __ pop(LoadDescriptor::ReceiverRegister());
2650 EmitKeyedPropertyLoad(expr); 2693 EmitKeyedPropertyLoad(expr);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 SetSourcePosition(prop->position()); 2748 SetSourcePosition(prop->position());
2706 Literal* key = prop->key()->AsLiteral(); 2749 Literal* key = prop->key()->AsLiteral();
2707 DCHECK(!key->value()->IsSmi()); 2750 DCHECK(!key->value()->IsSmi());
2708 // Load the function from the receiver. 2751 // Load the function from the receiver.
2709 const Register scratch = r1; 2752 const Register scratch = r1;
2710 SuperReference* super_ref = prop->obj()->AsSuperReference(); 2753 SuperReference* super_ref = prop->obj()->AsSuperReference();
2711 EmitLoadHomeObject(super_ref); 2754 EmitLoadHomeObject(super_ref);
2712 __ Push(r0); 2755 __ Push(r0);
2713 VisitForAccumulatorValue(super_ref->this_var()); 2756 VisitForAccumulatorValue(super_ref->this_var());
2714 __ Push(r0); 2757 __ Push(r0);
2715 __ ldr(scratch, MemOperand(sp, kPointerSize)); 2758 __ Push(r0);
2759 __ ldr(scratch, MemOperand(sp, kPointerSize * 2));
2716 __ Push(scratch); 2760 __ Push(scratch);
2717 __ Push(r0);
2718 __ Push(key->value()); 2761 __ Push(key->value());
2719 2762
2720 // Stack here: 2763 // Stack here:
2721 // - home_object 2764 // - home_object
2722 // - this (receiver) 2765 // - this (receiver)
2723 // - home_object <-- LoadFromSuper will pop here and below. 2766 // - this (receiver) <-- LoadFromSuper will pop here and below.
2724 // - this (receiver) 2767 // - home_object
2725 // - key 2768 // - key
2726 __ CallRuntime(Runtime::kLoadFromSuper, 3); 2769 __ CallRuntime(Runtime::kLoadFromSuper, 3);
2727 2770
2728 // Replace home_object with target function. 2771 // Replace home_object with target function.
2729 __ str(r0, MemOperand(sp, kPointerSize)); 2772 __ str(r0, MemOperand(sp, kPointerSize));
2730 2773
2731 // Stack here: 2774 // Stack here:
2732 // - target function 2775 // - target function
2733 // - this (receiver) 2776 // - this (receiver)
2734 EmitCall(expr, CallICState::METHOD); 2777 EmitCall(expr, CallICState::METHOD);
(...skipping 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after
4332 // Expression can only be a property, a global or a (parameter or local) 4375 // Expression can only be a property, a global or a (parameter or local)
4333 // slot. 4376 // slot.
4334 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 4377 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
4335 LhsKind assign_type = VARIABLE; 4378 LhsKind assign_type = VARIABLE;
4336 Property* prop = expr->expression()->AsProperty(); 4379 Property* prop = expr->expression()->AsProperty();
4337 // In case of a property we use the uninitialized expression context 4380 // In case of a property we use the uninitialized expression context
4338 // of the key to detect a named property. 4381 // of the key to detect a named property.
4339 if (prop != NULL) { 4382 if (prop != NULL) {
4340 assign_type = 4383 assign_type =
4341 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 4384 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
4385 if (prop->IsSuperAccess()) {
4386 // throw exception.
4387 VisitSuperReference(prop->obj()->AsSuperReference());
4388 return;
4389 }
4342 } 4390 }
4343 4391
4344 // Evaluate expression and get value. 4392 // Evaluate expression and get value.
4345 if (assign_type == VARIABLE) { 4393 if (assign_type == VARIABLE) {
4346 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4394 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4347 AccumulatorValueContext context(this); 4395 AccumulatorValueContext context(this);
4348 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4396 EmitVariableLoad(expr->expression()->AsVariableProxy());
4349 } else { 4397 } else {
4350 // Reserve space for result of postfix operation. 4398 // Reserve space for result of postfix operation.
4351 if (expr->is_postfix() && !context()->IsEffect()) { 4399 if (expr->is_postfix() && !context()->IsEffect()) {
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
5008 5056
5009 DCHECK(interrupt_address == 5057 DCHECK(interrupt_address ==
5010 isolate->builtins()->OsrAfterStackCheck()->entry()); 5058 isolate->builtins()->OsrAfterStackCheck()->entry());
5011 return OSR_AFTER_STACK_CHECK; 5059 return OSR_AFTER_STACK_CHECK;
5012 } 5060 }
5013 5061
5014 5062
5015 } } // namespace v8::internal 5063 } } // namespace v8::internal
5016 5064
5017 #endif // V8_TARGET_ARCH_ARM 5065 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/full-codegen-arm64.cc » ('j') | src/full-codegen.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698