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

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

Issue 157543002: A64: Synchronize with r18581. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/a64/frames-a64.cc ('k') | src/a64/ic-a64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 136
137 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 137 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
138 138
139 #ifdef DEBUG 139 #ifdef DEBUG
140 if (strlen(FLAG_stop_at) > 0 && 140 if (strlen(FLAG_stop_at) > 0 &&
141 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 141 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
142 __ Debug("stop-at", __LINE__, BREAK); 142 __ Debug("stop-at", __LINE__, BREAK);
143 } 143 }
144 #endif 144 #endif
145 145
146 // Strict mode functions and builtins need to replace the receiver 146 // Classic mode functions and builtins need to replace the receiver with the
147 // with undefined when called as functions (without an explicit 147 // global proxy when called as functions (without an explicit receiver
148 // receiver object). x5 is zero for method calls and non-zero for 148 // object).
149 // function calls. 149 if (info->is_classic_mode() && !info->is_native()) {
150 if (!info->is_classic_mode() || info->is_native()) {
151 Label ok; 150 Label ok;
152 __ Cbz(x5, &ok); 151 __ Cbz(x5, &ok);
153 int receiver_offset = info->scope()->num_parameters() * kXRegSizeInBytes; 152 int receiver_offset = info->scope()->num_parameters() * kXRegSizeInBytes;
154 __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); 153 __ Peek(x10, receiver_offset);
154 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok);
155
156 __ Ldr(x10, GlobalObjectMemOperand());
157 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset));
155 __ Poke(x10, receiver_offset); 158 __ Poke(x10, receiver_offset);
159
156 __ Bind(&ok); 160 __ Bind(&ok);
157 } 161 }
158 162
159 163
160 // Open a frame scope to indicate that there is a frame on the stack. 164 // Open a frame scope to indicate that there is a frame on the stack.
161 // The MANUAL indicates that the scope shouldn't actually generate code 165 // The MANUAL indicates that the scope shouldn't actually generate code
162 // to set up the frame because we do it manually below. 166 // to set up the frame because we do it manually below.
163 FrameScope frame_scope(masm_, StackFrame::MANUAL); 167 FrameScope frame_scope(masm_, StackFrame::MANUAL);
164 168
165 // This call emits the following sequence in a way that can be patched for 169 // This call emits the following sequence in a way that can be patched for
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 } 657 }
654 } 658 }
655 } 659 }
656 660
657 661
658 void FullCodeGenerator::DoTest(Expression* condition, 662 void FullCodeGenerator::DoTest(Expression* condition,
659 Label* if_true, 663 Label* if_true,
660 Label* if_false, 664 Label* if_false,
661 Label* fall_through) { 665 Label* fall_through) {
662 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 666 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
663 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); 667 CallIC(ic, NOT_CONTEXTUAL, condition->test_id());
664 __ CompareAndSplit(result_register(), 0, ne, if_true, if_false, fall_through); 668 __ CompareAndSplit(result_register(), 0, ne, if_true, if_false, fall_through);
665 } 669 }
666 670
667 671
668 // If (cond), branch to if_true. 672 // If (cond), branch to if_true.
669 // If (!cond), branch to if_false. 673 // If (!cond), branch to if_false.
670 // fall_through is used as an optimization in cases where only one branch 674 // fall_through is used as an optimization in cases where only one branch
671 // instruction is necessary. 675 // instruction is necessary.
672 void FullCodeGenerator::Split(Condition cond, 676 void FullCodeGenerator::Split(Condition cond,
673 Label* if_true, 677 Label* if_true,
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 __ Cmp(x1, x0); 1025 __ Cmp(x1, x0);
1022 __ B(ne, &next_test); 1026 __ B(ne, &next_test);
1023 __ Drop(1); // Switch value is no longer needed. 1027 __ Drop(1); // Switch value is no longer needed.
1024 __ B(clause->body_target()); 1028 __ B(clause->body_target());
1025 __ Bind(&slow_case); 1029 __ Bind(&slow_case);
1026 } 1030 }
1027 1031
1028 // Record position before stub call for type feedback. 1032 // Record position before stub call for type feedback.
1029 SetSourcePosition(clause->position()); 1033 SetSourcePosition(clause->position());
1030 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 1034 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
1031 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); 1035 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId());
1032 patch_site.EmitPatchInfo(); 1036 patch_site.EmitPatchInfo();
1033 1037
1034 Label skip; 1038 Label skip;
1035 __ B(&skip); 1039 __ B(&skip);
1036 PrepareForBailout(clause, TOS_REG); 1040 PrepareForBailout(clause, TOS_REG);
1037 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); 1041 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test);
1038 __ Drop(1); 1042 __ Drop(1);
1039 __ B(clause->body_target()); 1043 __ B(clause->body_target());
1040 __ Bind(&skip); 1044 __ Bind(&skip);
1041 1045
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX)); 1380 __ Ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX));
1377 __ Cbnz(temp, slow); 1381 __ Cbnz(temp, slow);
1378 // Load next context in chain. 1382 // Load next context in chain.
1379 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX)); 1383 __ Ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX));
1380 __ B(&loop); 1384 __ B(&loop);
1381 __ Bind(&fast); 1385 __ Bind(&fast);
1382 } 1386 }
1383 1387
1384 __ Ldr(x0, GlobalObjectMemOperand()); 1388 __ Ldr(x0, GlobalObjectMemOperand());
1385 __ Mov(x2, Operand(var->name())); 1389 __ Mov(x2, Operand(var->name()));
1386 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1390 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL
1387 ? RelocInfo::CODE_TARGET 1391 : CONTEXTUAL;
1388 : RelocInfo::CODE_TARGET_CONTEXT; 1392 CallLoadIC(mode);
1389 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1390 CallIC(ic, mode);
1391 } 1393 }
1392 1394
1393 1395
1394 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1396 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1395 Label* slow) { 1397 Label* slow) {
1396 ASSERT(var->IsContextSlot()); 1398 ASSERT(var->IsContextSlot());
1397 Register context = cp; 1399 Register context = cp;
1398 Register next = x10; 1400 Register next = x10;
1399 Register temp = x11; 1401 Register temp = x11;
1400 1402
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 1462
1461 // Three cases: global variables, lookup variables, and all other types of 1463 // Three cases: global variables, lookup variables, and all other types of
1462 // variables. 1464 // variables.
1463 switch (var->location()) { 1465 switch (var->location()) {
1464 case Variable::UNALLOCATED: { 1466 case Variable::UNALLOCATED: {
1465 Comment cmnt(masm_, "Global variable"); 1467 Comment cmnt(masm_, "Global variable");
1466 // Use inline caching. Variable name is passed in x2 and the global 1468 // Use inline caching. Variable name is passed in x2 and the global
1467 // object (receiver) in x0. 1469 // object (receiver) in x0.
1468 __ Ldr(x0, GlobalObjectMemOperand()); 1470 __ Ldr(x0, GlobalObjectMemOperand());
1469 __ Mov(x2, Operand(var->name())); 1471 __ Mov(x2, Operand(var->name()));
1470 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1472 CallLoadIC(CONTEXTUAL);
1471 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1472 context()->Plug(x0); 1473 context()->Plug(x0);
1473 break; 1474 break;
1474 } 1475 }
1475 1476
1476 case Variable::PARAMETER: 1477 case Variable::PARAMETER:
1477 case Variable::LOCAL: 1478 case Variable::LOCAL:
1478 case Variable::CONTEXT: { 1479 case Variable::CONTEXT: {
1479 Comment cmnt(masm_, var->IsContextSlot() 1480 Comment cmnt(masm_, var->IsContextSlot()
1480 ? "Context variable" 1481 ? "Context variable"
1481 : "Stack variable"); 1482 : "Stack variable");
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 UNREACHABLE(); 1672 UNREACHABLE();
1672 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1673 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1673 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); 1674 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value()));
1674 // Fall through. 1675 // Fall through.
1675 case ObjectLiteral::Property::COMPUTED: 1676 case ObjectLiteral::Property::COMPUTED:
1676 if (key->value()->IsInternalizedString()) { 1677 if (key->value()->IsInternalizedString()) {
1677 if (property->emit_store()) { 1678 if (property->emit_store()) {
1678 VisitForAccumulatorValue(value); 1679 VisitForAccumulatorValue(value);
1679 __ Mov(x2, Operand(key->value())); 1680 __ Mov(x2, Operand(key->value()));
1680 __ Peek(x1, 0); 1681 __ Peek(x1, 0);
1681 Handle<Code> ic = is_classic_mode() 1682 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId());
1682 ? isolate()->builtins()->StoreIC_Initialize()
1683 : isolate()->builtins()->StoreIC_Initialize_Strict();
1684 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId());
1685 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1683 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1686 } else { 1684 } else {
1687 VisitForEffect(value); 1685 VisitForEffect(value);
1688 } 1686 }
1689 break; 1687 break;
1690 } 1688 }
1691 // Duplicate receiver on stack. 1689 // Duplicate receiver on stack.
1692 __ Peek(x0, 0); 1690 __ Peek(x0, 0);
1693 __ Push(x0); 1691 __ Push(x0);
1694 VisitForStackValue(key); 1692 VisitForStackValue(key);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 ZoneList<Expression*>* subexprs = expr->values(); 1761 ZoneList<Expression*>* subexprs = expr->values();
1764 int length = subexprs->length(); 1762 int length = subexprs->length();
1765 Handle<FixedArray> constant_elements = expr->constant_elements(); 1763 Handle<FixedArray> constant_elements = expr->constant_elements();
1766 ASSERT_EQ(2, constant_elements->length()); 1764 ASSERT_EQ(2, constant_elements->length());
1767 ElementsKind constant_elements_kind = 1765 ElementsKind constant_elements_kind =
1768 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); 1766 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
1769 bool has_fast_elements = IsFastObjectElementsKind(constant_elements_kind); 1767 bool has_fast_elements = IsFastObjectElementsKind(constant_elements_kind);
1770 Handle<FixedArrayBase> constant_elements_values( 1768 Handle<FixedArrayBase> constant_elements_values(
1771 FixedArrayBase::cast(constant_elements->get(1))); 1769 FixedArrayBase::cast(constant_elements->get(1)));
1772 1770
1773 AllocationSiteMode allocation_site_mode = 1771 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE;
1774 FLAG_track_allocation_sites ? TRACK_ALLOCATION_SITE
1775 : DONT_TRACK_ALLOCATION_SITE;
1776 if (has_fast_elements && !FLAG_allocation_site_pretenuring) { 1772 if (has_fast_elements && !FLAG_allocation_site_pretenuring) {
1777 // If the only customer of allocation sites is transitioning, then 1773 // If the only customer of allocation sites is transitioning, then
1778 // we can turn it off if we don't have anywhere else to transition to. 1774 // we can turn it off if we don't have anywhere else to transition to.
1779 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1775 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1780 } 1776 }
1781 1777
1782 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1778 __ Ldr(x3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1783 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset)); 1779 __ Ldr(x3, FieldMemOperand(x3, JSFunction::kLiteralsOffset));
1784 // TODO(jbramley): Can these Operand constructors be implicit? 1780 // TODO(jbramley): Can these Operand constructors be implicit?
1785 __ Mov(x2, Operand(Smi::FromInt(expr->literal_index()))); 1781 __ Mov(x2, Operand(Smi::FromInt(expr->literal_index())));
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1967 break; 1963 break;
1968 } 1964 }
1969 } 1965 }
1970 1966
1971 1967
1972 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1968 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1973 SetSourcePosition(prop->position()); 1969 SetSourcePosition(prop->position());
1974 Literal* key = prop->key()->AsLiteral(); 1970 Literal* key = prop->key()->AsLiteral();
1975 __ Mov(x2, Operand(key->value())); 1971 __ Mov(x2, Operand(key->value()));
1976 // Call load IC. It has arguments receiver and property name x0 and x2. 1972 // Call load IC. It has arguments receiver and property name x0 and x2.
1977 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1973 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
1978 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId());
1979 } 1974 }
1980 1975
1981 1976
1982 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1977 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1983 SetSourcePosition(prop->position()); 1978 SetSourcePosition(prop->position());
1984 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1979 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1985 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1980 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1986 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); 1981 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId());
1987 } 1982 }
1988 1983
1989 1984
1990 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1985 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1991 Token::Value op, 1986 Token::Value op,
1992 OverwriteMode mode, 1987 OverwriteMode mode,
1993 Expression* left_expr, 1988 Expression* left_expr,
1994 Expression* right_expr) { 1989 Expression* right_expr) {
1995 Label done, both_smis, stub_call; 1990 Label done, both_smis, stub_call;
1996 1991
1997 // Get the arguments. 1992 // Get the arguments.
1998 Register left = x1; 1993 Register left = x1;
1999 Register right = x0; 1994 Register right = x0;
2000 Register result = x0; 1995 Register result = x0;
2001 __ Pop(left); 1996 __ Pop(left);
2002 1997
2003 // Perform combined smi check on both operands. 1998 // Perform combined smi check on both operands.
2004 __ Orr(x10, left, right); 1999 __ Orr(x10, left, right);
2005 JumpPatchSite patch_site(masm_); 2000 JumpPatchSite patch_site(masm_);
2006 patch_site.EmitJumpIfSmi(x10, &both_smis); 2001 patch_site.EmitJumpIfSmi(x10, &both_smis);
2007 2002
2008 __ Bind(&stub_call); 2003 __ Bind(&stub_call);
2009 BinaryOpICStub stub(op, mode); 2004 BinaryOpICStub stub(op, mode);
2010 { 2005 {
2011 Assembler::BlockConstPoolScope scope(masm_); 2006 Assembler::BlockConstPoolScope scope(masm_);
2012 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 2007 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL,
2013 expr->BinaryOperationFeedbackId()); 2008 expr->BinaryOperationFeedbackId());
2014 patch_site.EmitPatchInfo(); 2009 patch_site.EmitPatchInfo();
2015 } 2010 }
2016 __ B(&done); 2011 __ B(&done);
2017 2012
2018 __ Bind(&both_smis); 2013 __ Bind(&both_smis);
2019 // Smi case. This code works in the same way as the smi-smi case in the type 2014 // Smi case. This code works in the same way as the smi-smi case in the type
2020 // recording binary operation stub, see 2015 // recording binary operation stub, see
2021 // BinaryOpStub::GenerateSmiSmiOperation for comments. 2016 // BinaryOpStub::GenerateSmiSmiOperation for comments.
2022 // TODO(all): That doesn't exist any more. Where are the comments? 2017 // TODO(all): That doesn't exist any more. Where are the comments?
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2089 2084
2090 2085
2091 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2086 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2092 Token::Value op, 2087 Token::Value op,
2093 OverwriteMode mode) { 2088 OverwriteMode mode) {
2094 __ Pop(x1); 2089 __ Pop(x1);
2095 BinaryOpICStub stub(op, mode); 2090 BinaryOpICStub stub(op, mode);
2096 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. 2091 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
2097 { 2092 {
2098 Assembler::BlockConstPoolScope scope(masm_); 2093 Assembler::BlockConstPoolScope scope(masm_);
2099 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 2094 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL,
2100 expr->BinaryOperationFeedbackId()); 2095 expr->BinaryOperationFeedbackId());
2101 patch_site.EmitPatchInfo(); 2096 patch_site.EmitPatchInfo();
2102 } 2097 }
2103 context()->Plug(x0); 2098 context()->Plug(x0);
2104 } 2099 }
2105 2100
2106 2101
2107 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2102 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2108 // Invalid left-hand sides are rewritten to have a 'throw 2103 // Invalid left-hand sides are rewritten to have a 'throw
2109 // ReferenceError' on the left-hand side. 2104 // ReferenceError' on the left-hand side.
(...skipping 21 matching lines...) Expand all
2131 break; 2126 break;
2132 } 2127 }
2133 case NAMED_PROPERTY: { 2128 case NAMED_PROPERTY: {
2134 __ Push(x0); // Preserve value. 2129 __ Push(x0); // Preserve value.
2135 VisitForAccumulatorValue(prop->obj()); 2130 VisitForAccumulatorValue(prop->obj());
2136 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid 2131 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid
2137 // this copy. 2132 // this copy.
2138 __ Mov(x1, x0); 2133 __ Mov(x1, x0);
2139 __ Pop(x0); // Restore value. 2134 __ Pop(x0); // Restore value.
2140 __ Mov(x2, Operand(prop->key()->AsLiteral()->value())); 2135 __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
2141 Handle<Code> ic = is_classic_mode() 2136 CallStoreIC(NOT_CONTEXTUAL);
2142 ? isolate()->builtins()->StoreIC_Initialize()
2143 : isolate()->builtins()->StoreIC_Initialize_Strict();
2144 CallIC(ic);
2145 break; 2137 break;
2146 } 2138 }
2147 case KEYED_PROPERTY: { 2139 case KEYED_PROPERTY: {
2148 __ Push(x0); // Preserve value. 2140 __ Push(x0); // Preserve value.
2149 VisitForStackValue(prop->obj()); 2141 VisitForStackValue(prop->obj());
2150 VisitForAccumulatorValue(prop->key()); 2142 VisitForAccumulatorValue(prop->key());
2151 __ Mov(x1, x0); 2143 __ Mov(x1, x0);
2152 __ Pop(x2, x0); 2144 __ Pop(x2, x0);
2153 Handle<Code> ic = is_classic_mode() 2145 Handle<Code> ic = is_classic_mode()
2154 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2146 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2155 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2147 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2156 CallIC(ic); 2148 CallIC(ic);
2157 break; 2149 break;
2158 } 2150 }
2159 } 2151 }
2160 context()->Plug(x0); 2152 context()->Plug(x0);
2161 } 2153 }
2162 2154
2163 2155
2164 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2156 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2165 Token::Value op) { 2157 Token::Value op) {
2166 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); 2158 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment");
2167 if (var->IsUnallocated()) { 2159 if (var->IsUnallocated()) {
2168 // Global var, const, or let. 2160 // Global var, const, or let.
2169 __ Mov(x2, Operand(var->name())); 2161 __ Mov(x2, Operand(var->name()));
2170 __ Ldr(x1, GlobalObjectMemOperand()); 2162 __ Ldr(x1, GlobalObjectMemOperand());
2171 Handle<Code> ic = is_classic_mode() 2163 CallStoreIC(CONTEXTUAL);
2172 ? isolate()->builtins()->StoreIC_Initialize()
2173 : isolate()->builtins()->StoreIC_Initialize_Strict();
2174 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
2175 2164
2176 } else if (op == Token::INIT_CONST) { 2165 } else if (op == Token::INIT_CONST) {
2177 // Const initializers need a write barrier. 2166 // Const initializers need a write barrier.
2178 ASSERT(!var->IsParameter()); // No const parameters. 2167 ASSERT(!var->IsParameter()); // No const parameters.
2179 if (var->IsStackLocal()) { 2168 if (var->IsStackLocal()) {
2180 Label skip; 2169 Label skip;
2181 __ Ldr(x1, StackOperand(var)); 2170 __ Ldr(x1, StackOperand(var));
2182 __ JumpIfNotRoot(x1, Heap::kTheHoleValueRootIndex, &skip); 2171 __ JumpIfNotRoot(x1, Heap::kTheHoleValueRootIndex, &skip);
2183 __ Str(result_register(), StackOperand(var)); 2172 __ Str(result_register(), StackOperand(var));
2184 __ Bind(&skip); 2173 __ Bind(&skip);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2263 // Assignment to a property, using a named store IC. 2252 // Assignment to a property, using a named store IC.
2264 Property* prop = expr->target()->AsProperty(); 2253 Property* prop = expr->target()->AsProperty();
2265 ASSERT(prop != NULL); 2254 ASSERT(prop != NULL);
2266 ASSERT(prop->key()->AsLiteral() != NULL); 2255 ASSERT(prop->key()->AsLiteral() != NULL);
2267 2256
2268 // Record source code position before IC call. 2257 // Record source code position before IC call.
2269 SetSourcePosition(expr->position()); 2258 SetSourcePosition(expr->position());
2270 __ Mov(x2, Operand(prop->key()->AsLiteral()->value())); 2259 __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
2271 __ Pop(x1); 2260 __ Pop(x1);
2272 2261
2273 Handle<Code> ic = is_classic_mode() 2262 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId());
2274 ? isolate()->builtins()->StoreIC_Initialize()
2275 : isolate()->builtins()->StoreIC_Initialize_Strict();
2276 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
2277 2263
2278 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2264 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2279 context()->Plug(x0); 2265 context()->Plug(x0);
2280 } 2266 }
2281 2267
2282 2268
2283 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2269 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2284 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); 2270 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
2285 // Assignment to a property, using a keyed store IC. 2271 // Assignment to a property, using a keyed store IC.
2286 2272
2287 // Record source code position before IC call. 2273 // Record source code position before IC call.
2288 SetSourcePosition(expr->position()); 2274 SetSourcePosition(expr->position());
2289 // TODO(all): Could we pass this in registers rather than on the stack? 2275 // TODO(all): Could we pass this in registers rather than on the stack?
2290 __ Pop(x1, x2); // Key and object holding the property. 2276 __ Pop(x1, x2); // Key and object holding the property.
2291 2277
2292 Handle<Code> ic = is_classic_mode() 2278 Handle<Code> ic = is_classic_mode()
2293 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2279 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2294 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2280 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2295 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2281 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId());
2296 2282
2297 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2283 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2298 context()->Plug(x0); 2284 context()->Plug(x0);
2299 } 2285 }
2300 2286
2301 2287
2302 void FullCodeGenerator::VisitProperty(Property* expr) { 2288 void FullCodeGenerator::VisitProperty(Property* expr) {
2303 Comment cmnt(masm_, "[ Property"); 2289 Comment cmnt(masm_, "[ Property");
2304 Expression* key = expr->key(); 2290 Expression* key = expr->key();
2305 2291
2306 if (key->IsPropertyName()) { 2292 if (key->IsPropertyName()) {
2307 VisitForAccumulatorValue(expr->obj()); 2293 VisitForAccumulatorValue(expr->obj());
2308 EmitNamedPropertyLoad(expr); 2294 EmitNamedPropertyLoad(expr);
2309 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2295 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2310 context()->Plug(x0); 2296 context()->Plug(x0);
2311 } else { 2297 } else {
2312 VisitForStackValue(expr->obj()); 2298 VisitForStackValue(expr->obj());
2313 VisitForAccumulatorValue(expr->key()); 2299 VisitForAccumulatorValue(expr->key());
2314 __ Pop(x1); 2300 __ Pop(x1);
2315 EmitKeyedPropertyLoad(expr); 2301 EmitKeyedPropertyLoad(expr);
2316 context()->Plug(x0); 2302 context()->Plug(x0);
2317 } 2303 }
2318 } 2304 }
2319 2305
2320 2306
2321 void FullCodeGenerator::CallIC(Handle<Code> code, 2307 void FullCodeGenerator::CallIC(Handle<Code> code,
2322 RelocInfo::Mode rmode, 2308 ContextualMode mode,
2323 TypeFeedbackId ast_id) { 2309 TypeFeedbackId ast_id) {
2324 ic_total_count_++; 2310 ic_total_count_++;
2325 // All calls must have a predictable size in full-codegen code to ensure that 2311 // All calls must have a predictable size in full-codegen code to ensure that
2326 // the debugger can patch them correctly. 2312 // the debugger can patch them correctly.
2327 __ Call(code, rmode, ast_id); 2313 ASSERT((mode != CONTEXTUAL) || ast_id.IsNone());
2314 __ Call(code, RelocInfo::CODE_TARGET, ast_id);
2328 } 2315 }
2329 2316
2330 2317
2331 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2318 void FullCodeGenerator::EmitCallWithIC(Call* expr,
2332 Handle<Object> name, 2319 Handle<Object> name,
2333 RelocInfo::Mode mode) { 2320 ContextualMode mode) {
2334 ASM_LOCATION("EmitCallWithIC"); 2321 ASM_LOCATION("EmitCallWithIC");
2335 // Code common for calls using the IC. 2322 // Code common for calls using the IC.
2336 ZoneList<Expression*>* args = expr->arguments(); 2323 ZoneList<Expression*>* args = expr->arguments();
2337 int arg_count = args->length(); 2324 int arg_count = args->length();
2338 { PreservePositionScope scope(masm()->positions_recorder()); 2325 { PreservePositionScope scope(masm()->positions_recorder());
2339 for (int i = 0; i < arg_count; i++) { 2326 for (int i = 0; i < arg_count; i++) {
2340 VisitForStackValue(args->at(i)); 2327 VisitForStackValue(args->at(i));
2341 } 2328 }
2342 __ Mov(x2, Operand(name)); 2329 __ Mov(x2, Operand(name));
2343 } 2330 }
2344 // Record source position for debugger. 2331 // Record source position for debugger.
2345 SetSourcePosition(expr->position()); 2332 SetSourcePosition(expr->position());
2346 // Call the IC initialization code. 2333 // Call the IC initialization code.
2347 Handle<Code> ic = 2334 Handle<Code> ic =
2348 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 2335 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
2349 CallIC(ic, mode, expr->CallFeedbackId()); 2336 TypeFeedbackId ast_id = mode == CONTEXTUAL
2337 ? TypeFeedbackId::None()
2338 : expr->CallFeedbackId();
2339 CallIC(ic, mode, ast_id);
2350 RecordJSReturnSite(expr); 2340 RecordJSReturnSite(expr);
2351 // Restore context register. 2341 // Restore context register.
2352 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2342 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2353 context()->Plug(x0); 2343 context()->Plug(x0);
2354 } 2344 }
2355 2345
2356 2346
2357 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2347 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2358 Expression* key) { 2348 Expression* key) {
2359 // Load the key. 2349 // Load the key.
(...skipping 12 matching lines...) Expand all
2372 for (int i = 0; i < arg_count; i++) { 2362 for (int i = 0; i < arg_count; i++) {
2373 VisitForStackValue(args->at(i)); 2363 VisitForStackValue(args->at(i));
2374 } 2364 }
2375 } 2365 }
2376 // Record source position for debugger. 2366 // Record source position for debugger.
2377 SetSourcePosition(expr->position()); 2367 SetSourcePosition(expr->position());
2378 // Call the IC initialization code. 2368 // Call the IC initialization code.
2379 Handle<Code> ic = 2369 Handle<Code> ic =
2380 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2370 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
2381 __ Peek(x2, (arg_count + 1) * kXRegSizeInBytes); // Key. 2371 __ Peek(x2, (arg_count + 1) * kXRegSizeInBytes); // Key.
2382 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); 2372 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId());
2383 RecordJSReturnSite(expr); 2373 RecordJSReturnSite(expr);
2384 // Restore context register. 2374 // Restore context register.
2385 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2375 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2386 context()->DropAndPlug(1, x0); // Drop the key still on the stack. 2376 context()->DropAndPlug(1, x0); // Drop the key still on the stack.
2387 } 2377 }
2388 2378
2389 2379
2390 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2380 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2391 // Code common for calls using the call stub. 2381 // Code common for calls using the call stub.
2392 ZoneList<Expression*>* args = expr->arguments(); 2382 ZoneList<Expression*>* args = expr->arguments();
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 2477
2488 // The runtime call returns a pair of values in x0 (function) and 2478 // The runtime call returns a pair of values in x0 (function) and
2489 // x1 (receiver). Touch up the stack with the right values. 2479 // x1 (receiver). Touch up the stack with the right values.
2490 __ PokePair(x1, x0, arg_count * kPointerSize); 2480 __ PokePair(x1, x0, arg_count * kPointerSize);
2491 } 2481 }
2492 2482
2493 // Record source position for debugger. 2483 // Record source position for debugger.
2494 SetSourcePosition(expr->position()); 2484 SetSourcePosition(expr->position());
2495 2485
2496 // Call the evaluated function. 2486 // Call the evaluated function.
2497 CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT); 2487 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS);
2498 __ Peek(x1, (arg_count + 1) * kXRegSizeInBytes); 2488 __ Peek(x1, (arg_count + 1) * kXRegSizeInBytes);
2499 __ CallStub(&stub); 2489 __ CallStub(&stub);
2500 RecordJSReturnSite(expr); 2490 RecordJSReturnSite(expr);
2501 // Restore context register. 2491 // Restore context register.
2502 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2492 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2503 context()->DropAndPlug(1, x0); 2493 context()->DropAndPlug(1, x0);
2504 2494
2505 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { 2495 } else if (proxy != NULL && proxy->var()->IsUnallocated()) {
2506 // Push global object as receiver for the call IC. 2496 // Push global object as receiver for the call IC.
2507 __ Ldr(x10, GlobalObjectMemOperand()); 2497 __ Ldr(x10, GlobalObjectMemOperand());
2508 __ Push(x10); 2498 __ Push(x10);
2509 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); 2499 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
2510 2500
2511 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 2501 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
2512 // Call to a lookup slot (dynamically introduced variable). 2502 // Call to a lookup slot (dynamically introduced variable).
2513 Label slow, done; 2503 Label slow, done;
2514 2504
2515 { PreservePositionScope scope(masm()->positions_recorder()); 2505 { PreservePositionScope scope(masm()->positions_recorder());
2516 // Generate code for loading from variables potentially shadowed 2506 // Generate code for loading from variables potentially shadowed
2517 // by eval-introduced variables. 2507 // by eval-introduced variables.
2518 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2508 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2519 } 2509 }
(...skipping 10 matching lines...) Expand all
2530 // If fast case code has been generated, emit code to push the 2520 // If fast case code has been generated, emit code to push the
2531 // function and receiver and have the slow path jump around this 2521 // function and receiver and have the slow path jump around this
2532 // code. 2522 // code.
2533 if (done.is_linked()) { 2523 if (done.is_linked()) {
2534 Label call; 2524 Label call;
2535 __ B(&call); 2525 __ B(&call);
2536 __ Bind(&done); 2526 __ Bind(&done);
2537 // Push function. 2527 // Push function.
2538 __ Push(x0); 2528 __ Push(x0);
2539 // The receiver is implicitly the global receiver. Indicate this 2529 // The receiver is implicitly the global receiver. Indicate this
2540 // by passing the hole to the call function stub. 2530 // by passing the undefined to the call function stub.
2541 __ LoadRoot(x1, Heap::kTheHoleValueRootIndex); 2531 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
2542 __ Push(x1); 2532 __ Push(x1);
2543 __ Bind(&call); 2533 __ Bind(&call);
2544 } 2534 }
2545 2535
2546 // The receiver is either the global receiver or an object found 2536 // The receiver is either the global receiver or an object found
2547 // by LoadContextSlot. That object could be the hole if the 2537 // by LoadContextSlot.
2548 // receiver is implicitly the global object. 2538 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2549 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT);
2550 } else if (property != NULL) { 2539 } else if (property != NULL) {
2551 { PreservePositionScope scope(masm()->positions_recorder()); 2540 { PreservePositionScope scope(masm()->positions_recorder());
2552 VisitForStackValue(property->obj()); 2541 VisitForStackValue(property->obj());
2553 } 2542 }
2554 if (property->key()->IsPropertyName()) { 2543 if (property->key()->IsPropertyName()) {
2555 EmitCallWithIC(expr, 2544 EmitCallWithIC(expr,
2556 property->key()->AsLiteral()->value(), 2545 property->key()->AsLiteral()->value(),
2557 RelocInfo::CODE_TARGET); 2546 NOT_CONTEXTUAL);
2558 } else { 2547 } else {
2559 EmitKeyedCallWithIC(expr, property->key()); 2548 EmitKeyedCallWithIC(expr, property->key());
2560 } 2549 }
2561 2550
2562 } else { 2551 } else {
2563 // Call to an arbitrary expression not handled specially above. 2552 // Call to an arbitrary expression not handled specially above.
2564 { PreservePositionScope scope(masm()->positions_recorder()); 2553 { PreservePositionScope scope(masm()->positions_recorder());
2565 VisitForStackValue(callee); 2554 VisitForStackValue(callee);
2566 } 2555 }
2567 // Load global receiver object. 2556 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
2568 __ Ldr(x1, GlobalObjectMemOperand());
2569 __ Ldr(x1, FieldMemOperand(x1, GlobalObject::kGlobalReceiverOffset));
2570 __ Push(x1); 2557 __ Push(x1);
2571 // Emit function call. 2558 // Emit function call.
2572 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); 2559 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
2573 } 2560 }
2574 2561
2575 #ifdef DEBUG 2562 #ifdef DEBUG
2576 // RecordJSReturnSite should have been called. 2563 // RecordJSReturnSite should have been called.
2577 ASSERT(expr->return_is_recorded_); 2564 ASSERT(expr->return_is_recorded_);
2578 #endif 2565 #endif
2579 } 2566 }
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
3506 3493
3507 Label runtime, done; 3494 Label runtime, done;
3508 // Check for non-function argument (including proxy). 3495 // Check for non-function argument (including proxy).
3509 __ JumpIfSmi(x0, &runtime); 3496 __ JumpIfSmi(x0, &runtime);
3510 __ JumpIfNotObjectType(x0, x1, x1, JS_FUNCTION_TYPE, &runtime); 3497 __ JumpIfNotObjectType(x0, x1, x1, JS_FUNCTION_TYPE, &runtime);
3511 3498
3512 // InvokeFunction requires the function in x1. Move it in there. 3499 // InvokeFunction requires the function in x1. Move it in there.
3513 __ Mov(x1, x0); 3500 __ Mov(x1, x0);
3514 ParameterCount count(arg_count); 3501 ParameterCount count(arg_count);
3515 __ InvokeFunction(x1, count, CALL_FUNCTION, 3502 __ InvokeFunction(x1, count, CALL_FUNCTION,
3516 NullCallWrapper(), CALL_AS_METHOD); 3503 NullCallWrapper(), CALL_AS_FUNCTION);
3517 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3504 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3518 __ B(&done); 3505 __ B(&done);
3519 3506
3520 __ Bind(&runtime); 3507 __ Bind(&runtime);
3521 __ Push(x0); 3508 __ Push(x0);
3522 __ CallRuntime(Runtime::kCall, args->length()); 3509 __ CallRuntime(Runtime::kCall, args->length());
3523 __ Bind(&done); 3510 __ Bind(&done);
3524 3511
3525 context()->Plug(x0); 3512 context()->Plug(x0);
3526 } 3513 }
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
3904 } 3891 }
3905 3892
3906 int arg_count = args->length(); 3893 int arg_count = args->length();
3907 for (int i = 0; i < arg_count; i++) { 3894 for (int i = 0; i < arg_count; i++) {
3908 VisitForStackValue(args->at(i)); 3895 VisitForStackValue(args->at(i));
3909 } 3896 }
3910 3897
3911 if (expr->is_jsruntime()) { 3898 if (expr->is_jsruntime()) {
3912 // Call the JS runtime function. 3899 // Call the JS runtime function.
3913 __ Mov(x2, Operand(expr->name())); 3900 __ Mov(x2, Operand(expr->name()));
3914 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 3901 ContextualMode mode = NOT_CONTEXTUAL;
3915 Handle<Code> ic = 3902 Handle<Code> ic =
3916 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 3903 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
3917 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); 3904 CallIC(ic, mode, expr->CallRuntimeFeedbackId());
3918 // Restore context register. 3905 // Restore context register.
3919 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3906 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3920 } else { 3907 } else {
3921 // Call the C runtime function. 3908 // Call the C runtime function.
3922 __ CallRuntime(expr->function(), arg_count); 3909 __ CallRuntime(expr->function(), arg_count);
3923 } 3910 }
3924 3911
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
4156 __ Bind(&stub_call); 4143 __ Bind(&stub_call);
4157 __ Mov(x1, x0); 4144 __ Mov(x1, x0);
4158 __ Mov(x0, Operand(Smi::FromInt(count_value))); 4145 __ Mov(x0, Operand(Smi::FromInt(count_value)));
4159 4146
4160 // Record position before stub call. 4147 // Record position before stub call.
4161 SetSourcePosition(expr->position()); 4148 SetSourcePosition(expr->position());
4162 4149
4163 { 4150 {
4164 Assembler::BlockConstPoolScope scope(masm_); 4151 Assembler::BlockConstPoolScope scope(masm_);
4165 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); 4152 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE);
4166 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 4153 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL,
4167 expr->CountBinOpFeedbackId()); 4154 expr->CountBinOpFeedbackId());
4168 patch_site.EmitPatchInfo(); 4155 patch_site.EmitPatchInfo();
4169 } 4156 }
4170 __ Bind(&done); 4157 __ Bind(&done);
4171 4158
4172 // Store the value returned in x0. 4159 // Store the value returned in x0.
4173 switch (assign_type) { 4160 switch (assign_type) {
4174 case VARIABLE: 4161 case VARIABLE:
4175 if (expr->is_postfix()) { 4162 if (expr->is_postfix()) {
4176 { EffectContext context(this); 4163 { EffectContext context(this);
(...skipping 10 matching lines...) Expand all
4187 } else { 4174 } else {
4188 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4175 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4189 Token::ASSIGN); 4176 Token::ASSIGN);
4190 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4177 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4191 context()->Plug(x0); 4178 context()->Plug(x0);
4192 } 4179 }
4193 break; 4180 break;
4194 case NAMED_PROPERTY: { 4181 case NAMED_PROPERTY: {
4195 __ Mov(x2, Operand(prop->key()->AsLiteral()->value())); 4182 __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
4196 __ Pop(x1); 4183 __ Pop(x1);
4197 Handle<Code> ic = is_classic_mode() 4184 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId());
4198 ? isolate()->builtins()->StoreIC_Initialize()
4199 : isolate()->builtins()->StoreIC_Initialize_Strict();
4200 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
4201 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4185 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4202 if (expr->is_postfix()) { 4186 if (expr->is_postfix()) {
4203 if (!context()->IsEffect()) { 4187 if (!context()->IsEffect()) {
4204 context()->PlugTOS(); 4188 context()->PlugTOS();
4205 } 4189 }
4206 } else { 4190 } else {
4207 context()->Plug(x0); 4191 context()->Plug(x0);
4208 } 4192 }
4209 break; 4193 break;
4210 } 4194 }
4211 case KEYED_PROPERTY: { 4195 case KEYED_PROPERTY: {
4212 __ Pop(x1); // Key. 4196 __ Pop(x1); // Key.
4213 __ Pop(x2); // Receiver. 4197 __ Pop(x2); // Receiver.
4214 Handle<Code> ic = is_classic_mode() 4198 Handle<Code> ic = is_classic_mode()
4215 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4199 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4216 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4200 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4217 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4201 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId());
4218 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4202 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4219 if (expr->is_postfix()) { 4203 if (expr->is_postfix()) {
4220 if (!context()->IsEffect()) { 4204 if (!context()->IsEffect()) {
4221 context()->PlugTOS(); 4205 context()->PlugTOS();
4222 } 4206 }
4223 } else { 4207 } else {
4224 context()->Plug(x0); 4208 context()->Plug(x0);
4225 } 4209 }
4226 break; 4210 break;
4227 } 4211 }
4228 } 4212 }
4229 } 4213 }
4230 4214
4231 4215
4232 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4216 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4233 ASSERT(!context()->IsEffect()); 4217 ASSERT(!context()->IsEffect());
4234 ASSERT(!context()->IsTest()); 4218 ASSERT(!context()->IsTest());
4235 VariableProxy* proxy = expr->AsVariableProxy(); 4219 VariableProxy* proxy = expr->AsVariableProxy();
4236 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4220 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4237 Comment cmnt(masm_, "Global variable"); 4221 Comment cmnt(masm_, "Global variable");
4238 __ Ldr(x0, GlobalObjectMemOperand()); 4222 __ Ldr(x0, GlobalObjectMemOperand());
4239 __ Mov(x2, Operand(proxy->name())); 4223 __ Mov(x2, Operand(proxy->name()));
4240 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
4241 // Use a regular load, not a contextual load, to avoid a reference 4224 // Use a regular load, not a contextual load, to avoid a reference
4242 // error. 4225 // error.
4243 CallIC(ic); 4226 CallLoadIC(NOT_CONTEXTUAL);
4244 PrepareForBailout(expr, TOS_REG); 4227 PrepareForBailout(expr, TOS_REG);
4245 context()->Plug(x0); 4228 context()->Plug(x0);
4246 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4229 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4247 Label done, slow; 4230 Label done, slow;
4248 4231
4249 // Generate code for loading from variables potentially shadowed 4232 // Generate code for loading from variables potentially shadowed
4250 // by eval-introduced variables. 4233 // by eval-introduced variables.
4251 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); 4234 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done);
4252 4235
4253 __ Bind(&slow); 4236 __ Bind(&slow);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
4405 Label slow_case; 4388 Label slow_case;
4406 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); 4389 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case);
4407 __ Cmp(x1, x0); 4390 __ Cmp(x1, x0);
4408 Split(cond, if_true, if_false, NULL); 4391 Split(cond, if_true, if_false, NULL);
4409 __ Bind(&slow_case); 4392 __ Bind(&slow_case);
4410 } 4393 }
4411 4394
4412 // Record position and call the compare IC. 4395 // Record position and call the compare IC.
4413 SetSourcePosition(expr->position()); 4396 SetSourcePosition(expr->position());
4414 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4397 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4415 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); 4398 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId());
4416 patch_site.EmitPatchInfo(); 4399 patch_site.EmitPatchInfo();
4417 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4400 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4418 __ CompareAndSplit(x0, 0, cond, if_true, if_false, fall_through); 4401 __ CompareAndSplit(x0, 0, cond, if_true, if_false, fall_through);
4419 } 4402 }
4420 } 4403 }
4421 4404
4422 // Convert the result of the comparison into one expected for this 4405 // Convert the result of the comparison into one expected for this
4423 // expression's context. 4406 // expression's context.
4424 context()->Plug(if_true, if_false); 4407 context()->Plug(if_true, if_false);
4425 } 4408 }
(...skipping 14 matching lines...) Expand all
4440 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4423 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4441 4424
4442 if (expr->op() == Token::EQ_STRICT) { 4425 if (expr->op() == Token::EQ_STRICT) {
4443 Heap::RootListIndex nil_value = nil == kNullValue ? 4426 Heap::RootListIndex nil_value = nil == kNullValue ?
4444 Heap::kNullValueRootIndex : 4427 Heap::kNullValueRootIndex :
4445 Heap::kUndefinedValueRootIndex; 4428 Heap::kUndefinedValueRootIndex;
4446 __ CompareRoot(x0, nil_value); 4429 __ CompareRoot(x0, nil_value);
4447 Split(eq, if_true, if_false, fall_through); 4430 Split(eq, if_true, if_false, fall_through);
4448 } else { 4431 } else {
4449 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4432 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4450 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); 4433 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId());
4451 __ CompareAndSplit(x0, 0, ne, if_true, if_false, fall_through); 4434 __ CompareAndSplit(x0, 0, ne, if_true, if_false, fall_through);
4452 } 4435 }
4453 4436
4454 context()->Plug(if_true, if_false); 4437 context()->Plug(if_true, if_false);
4455 } 4438 }
4456 4439
4457 4440
4458 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4441 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4459 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 4442 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
4460 context()->Plug(x0); 4443 context()->Plug(x0);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4590 // result = receiver[f](arg); 4573 // result = receiver[f](arg);
4591 __ Bind(&l_call); 4574 __ Bind(&l_call);
4592 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); 4575 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
4593 CallIC(ic); 4576 CallIC(ic);
4594 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4577 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4595 4578
4596 // if (!result.done) goto l_try; 4579 // if (!result.done) goto l_try;
4597 __ Bind(&l_loop); 4580 __ Bind(&l_loop);
4598 __ Push(x0); // save result 4581 __ Push(x0); // save result
4599 __ LoadRoot(x2, Heap::kdone_stringRootIndex); // "done" 4582 __ LoadRoot(x2, Heap::kdone_stringRootIndex); // "done"
4600 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); 4583 CallLoadIC(NOT_CONTEXTUAL); // result.done in x0
4601 CallIC(done_ic); // result.done in x0
4602 // The ToBooleanStub argument (result.done) is in x0. 4584 // The ToBooleanStub argument (result.done) is in x0.
4603 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 4585 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
4604 CallIC(bool_ic); 4586 CallIC(bool_ic);
4605 __ Cbz(x0, &l_try); 4587 __ Cbz(x0, &l_try);
4606 4588
4607 // result.value 4589 // result.value
4608 __ Pop(x0); // result 4590 __ Pop(x0); // result
4609 __ LoadRoot(x2, Heap::kvalue_stringRootIndex); // "value" 4591 __ LoadRoot(x2, Heap::kvalue_stringRootIndex); // "value"
4610 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); 4592 CallLoadIC(NOT_CONTEXTUAL); // result.value in x0
4611 CallIC(value_ic); // result.value in x0
4612 context()->DropAndPlug(2, x0); // drop iter and g 4593 context()->DropAndPlug(2, x0); // drop iter and g
4613 break; 4594 break;
4614 } 4595 }
4615 } 4596 }
4616 } 4597 }
4617 4598
4618 4599
4619 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, 4600 void FullCodeGenerator::EmitGeneratorResume(Expression *generator,
4620 Expression *value, 4601 Expression *value,
4621 JSGeneratorObject::ResumeMode resume_mode) { 4602 JSGeneratorObject::ResumeMode resume_mode) {
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
5025 return previous_; 5006 return previous_;
5026 } 5007 }
5027 5008
5028 5009
5029 #undef __ 5010 #undef __
5030 5011
5031 5012
5032 } } // namespace v8::internal 5013 } } // namespace v8::internal
5033 5014
5034 #endif // V8_TARGET_ARCH_A64 5015 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/frames-a64.cc ('k') | src/a64/ic-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698