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

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

Issue 1986353002: Revert of [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « src/full-codegen/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.h » ('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 // 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 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 172
173 if (info->scope()->num_heap_slots() > 0) { 173 if (info->scope()->num_heap_slots() > 0) {
174 // Argument to NewContext is the function, which is still in x1. 174 // Argument to NewContext is the function, which is still in x1.
175 Comment cmnt(masm_, "[ Allocate context"); 175 Comment cmnt(masm_, "[ Allocate context");
176 bool need_write_barrier = true; 176 bool need_write_barrier = true;
177 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 177 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
178 if (info->scope()->is_script_scope()) { 178 if (info->scope()->is_script_scope()) {
179 __ Mov(x10, Operand(info->scope()->GetScopeInfo(info->isolate()))); 179 __ Mov(x10, Operand(info->scope()->GetScopeInfo(info->isolate())));
180 __ Push(x1, x10); 180 __ Push(x1, x10);
181 __ CallRuntime(Runtime::kNewScriptContext); 181 __ CallRuntime(Runtime::kNewScriptContext);
182 PrepareForBailoutForId(BailoutId::ScriptContext(), 182 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
183 BailoutState::TOS_REGISTER);
184 // The new target value is not used, clobbering is safe. 183 // The new target value is not used, clobbering is safe.
185 DCHECK_NULL(info->scope()->new_target_var()); 184 DCHECK_NULL(info->scope()->new_target_var());
186 } else { 185 } else {
187 if (info->scope()->new_target_var() != nullptr) { 186 if (info->scope()->new_target_var() != nullptr) {
188 __ Push(x3); // Preserve new target. 187 __ Push(x3); // Preserve new target.
189 } 188 }
190 if (slots <= FastNewContextStub::kMaximumSlots) { 189 if (slots <= FastNewContextStub::kMaximumSlots) {
191 FastNewContextStub stub(isolate(), slots); 190 FastNewContextStub stub(isolate(), slots);
192 __ CallStub(&stub); 191 __ CallStub(&stub);
193 // Result of FastNewContextStub is always in new space. 192 // Result of FastNewContextStub is always in new space.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 __ Abort(kExpectedNewSpaceObject); 228 __ Abort(kExpectedNewSpaceObject);
230 __ bind(&done); 229 __ bind(&done);
231 } 230 }
232 } 231 }
233 } 232 }
234 } 233 }
235 234
236 // Register holding this function and new target are both trashed in case we 235 // Register holding this function and new target are both trashed in case we
237 // bailout here. But since that can happen only when new target is not used 236 // bailout here. But since that can happen only when new target is not used
238 // and we allocate a context, the value of |function_in_register| is correct. 237 // and we allocate a context, the value of |function_in_register| is correct.
239 PrepareForBailoutForId(BailoutId::FunctionContext(), 238 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS);
240 BailoutState::NO_REGISTERS);
241 239
242 // Possibly set up a local binding to the this function which is used in 240 // Possibly set up a local binding to the this function which is used in
243 // derived constructors with super calls. 241 // derived constructors with super calls.
244 Variable* this_function_var = scope()->this_function_var(); 242 Variable* this_function_var = scope()->this_function_var();
245 if (this_function_var != nullptr) { 243 if (this_function_var != nullptr) {
246 Comment cmnt(masm_, "[ This function"); 244 Comment cmnt(masm_, "[ This function");
247 if (!function_in_register_x1) { 245 if (!function_in_register_x1) {
248 __ Ldr(x1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 246 __ Ldr(x1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
249 // The write barrier clobbers register again, keep it marked as such. 247 // The write barrier clobbers register again, keep it marked as such.
250 } 248 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 } 290 }
293 291
294 SetVar(arguments, x0, x1, x2); 292 SetVar(arguments, x0, x1, x2);
295 } 293 }
296 294
297 if (FLAG_trace) { 295 if (FLAG_trace) {
298 __ CallRuntime(Runtime::kTraceEnter); 296 __ CallRuntime(Runtime::kTraceEnter);
299 } 297 }
300 298
301 // Visit the declarations and body. 299 // Visit the declarations and body.
302 PrepareForBailoutForId(BailoutId::FunctionEntry(), 300 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
303 BailoutState::NO_REGISTERS);
304 { 301 {
305 Comment cmnt(masm_, "[ Declarations"); 302 Comment cmnt(masm_, "[ Declarations");
306 VisitDeclarations(scope()->declarations()); 303 VisitDeclarations(scope()->declarations());
307 } 304 }
308 305
309 // Assert that the declarations do not use ICs. Otherwise the debugger 306 // Assert that the declarations do not use ICs. Otherwise the debugger
310 // won't be able to redirect a PC at an IC to the correct IC in newly 307 // won't be able to redirect a PC at an IC to the correct IC in newly
311 // recompiled code. 308 // recompiled code.
312 DCHECK_EQ(0, ic_total_count_); 309 DCHECK_EQ(0, ic_total_count_);
313 310
314 { 311 {
315 Comment cmnt(masm_, "[ Stack check"); 312 Comment cmnt(masm_, "[ Stack check");
316 PrepareForBailoutForId(BailoutId::Declarations(), 313 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
317 BailoutState::NO_REGISTERS);
318 Label ok; 314 Label ok;
319 DCHECK(jssp.Is(__ StackPointer())); 315 DCHECK(jssp.Is(__ StackPointer()));
320 __ CompareRoot(jssp, Heap::kStackLimitRootIndex); 316 __ CompareRoot(jssp, Heap::kStackLimitRootIndex);
321 __ B(hs, &ok); 317 __ B(hs, &ok);
322 PredictableCodeSizeScope predictable(masm_, 318 PredictableCodeSizeScope predictable(masm_,
323 Assembler::kCallSizeWithRelocation); 319 Assembler::kCallSizeWithRelocation);
324 __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); 320 __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
325 __ Bind(&ok); 321 __ Bind(&ok);
326 } 322 }
327 323
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 386 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
391 387
392 // Record a mapping of this PC offset to the OSR id. This is used to find 388 // Record a mapping of this PC offset to the OSR id. This is used to find
393 // the AST id from the unoptimized code in order to use it as a key into 389 // the AST id from the unoptimized code in order to use it as a key into
394 // the deoptimization input data found in the optimized code. 390 // the deoptimization input data found in the optimized code.
395 RecordBackEdge(stmt->OsrEntryId()); 391 RecordBackEdge(stmt->OsrEntryId());
396 392
397 EmitProfilingCounterReset(); 393 EmitProfilingCounterReset();
398 394
399 __ Bind(&ok); 395 __ Bind(&ok);
400 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); 396 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
401 // Record a mapping of the OSR id to this PC. This is used if the OSR 397 // Record a mapping of the OSR id to this PC. This is used if the OSR
402 // entry becomes the target of a bailout. We don't expect it to be, but 398 // entry becomes the target of a bailout. We don't expect it to be, but
403 // we want it to work if it is. 399 // we want it to work if it is.
404 PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); 400 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
405 } 401 }
406 402
407 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 403 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
408 bool is_tail_call) { 404 bool is_tail_call) {
409 // Pretend that the exit is a backwards jump to the entry. 405 // Pretend that the exit is a backwards jump to the entry.
410 int weight = 1; 406 int weight = 1;
411 if (info_->ShouldSelfOptimize()) { 407 if (info_->ShouldSelfOptimize()) {
412 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 408 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
413 } else { 409 } else {
414 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2; 410 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2;
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 // Only prepare for bailouts before splits if we're in a test 721 // Only prepare for bailouts before splits if we're in a test
726 // context. Otherwise, we let the Visit function deal with the 722 // context. Otherwise, we let the Visit function deal with the
727 // preparation to avoid preparing with the same AST id twice. 723 // preparation to avoid preparing with the same AST id twice.
728 if (!context()->IsTest()) return; 724 if (!context()->IsTest()) return;
729 725
730 // TODO(all): Investigate to see if there is something to work on here. 726 // TODO(all): Investigate to see if there is something to work on here.
731 Label skip; 727 Label skip;
732 if (should_normalize) { 728 if (should_normalize) {
733 __ B(&skip); 729 __ B(&skip);
734 } 730 }
735 PrepareForBailout(expr, BailoutState::TOS_REGISTER); 731 PrepareForBailout(expr, TOS_REG);
736 if (should_normalize) { 732 if (should_normalize) {
737 __ CompareRoot(x0, Heap::kTrueValueRootIndex); 733 __ CompareRoot(x0, Heap::kTrueValueRootIndex);
738 Split(eq, if_true, if_false, NULL); 734 Split(eq, if_true, if_false, NULL);
739 __ Bind(&skip); 735 __ Bind(&skip);
740 } 736 }
741 } 737 }
742 738
743 739
744 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 740 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
745 // The variable in the declaration always resides in the current function 741 // The variable in the declaration always resides in the current function
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 } 779 }
784 break; 780 break;
785 781
786 case VariableLocation::CONTEXT: 782 case VariableLocation::CONTEXT:
787 if (hole_init) { 783 if (hole_init) {
788 Comment cmnt(masm_, "[ VariableDeclaration"); 784 Comment cmnt(masm_, "[ VariableDeclaration");
789 EmitDebugCheckDeclarationContext(variable); 785 EmitDebugCheckDeclarationContext(variable);
790 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex); 786 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
791 __ Str(x10, ContextMemOperand(cp, variable->index())); 787 __ Str(x10, ContextMemOperand(cp, variable->index()));
792 // No write barrier since the_hole_value is in old space. 788 // No write barrier since the_hole_value is in old space.
793 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 789 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
794 } 790 }
795 break; 791 break;
796 792
797 case VariableLocation::LOOKUP: { 793 case VariableLocation::LOOKUP: {
798 Comment cmnt(masm_, "[ VariableDeclaration"); 794 Comment cmnt(masm_, "[ VariableDeclaration");
799 __ Mov(x2, Operand(variable->name())); 795 __ Mov(x2, Operand(variable->name()));
800 // Declaration nodes are always introduced in one of four modes. 796 // Declaration nodes are always introduced in one of four modes.
801 DCHECK(IsDeclaredVariableMode(mode)); 797 DCHECK(IsDeclaredVariableMode(mode));
802 // Push initial value, if any. 798 // Push initial value, if any.
803 // Note: For variables we must not push an initial value (such as 799 // Note: For variables we must not push an initial value (such as
804 // 'undefined') because we may have a (legal) redeclaration and we 800 // 'undefined') because we may have a (legal) redeclaration and we
805 // must not destroy the current value. 801 // must not destroy the current value.
806 if (hole_init) { 802 if (hole_init) {
807 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); 803 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex);
808 __ Push(x2, x0); 804 __ Push(x2, x0);
809 } else { 805 } else {
810 // Pushing 0 (xzr) indicates no initial value. 806 // Pushing 0 (xzr) indicates no initial value.
811 __ Push(x2, xzr); 807 __ Push(x2, xzr);
812 } 808 }
813 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 809 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
814 __ CallRuntime(Runtime::kDeclareLookupSlot); 810 __ CallRuntime(Runtime::kDeclareLookupSlot);
815 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 811 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
816 break; 812 break;
817 } 813 }
818 } 814 }
819 } 815 }
820 816
821 817
822 void FullCodeGenerator::VisitFunctionDeclaration( 818 void FullCodeGenerator::VisitFunctionDeclaration(
823 FunctionDeclaration* declaration) { 819 FunctionDeclaration* declaration) {
824 VariableProxy* proxy = declaration->proxy(); 820 VariableProxy* proxy = declaration->proxy();
825 Variable* variable = proxy->var(); 821 Variable* variable = proxy->var();
(...skipping 25 matching lines...) Expand all
851 int offset = Context::SlotOffset(variable->index()); 847 int offset = Context::SlotOffset(variable->index());
852 // We know that we have written a function, which is not a smi. 848 // We know that we have written a function, which is not a smi.
853 __ RecordWriteContextSlot(cp, 849 __ RecordWriteContextSlot(cp,
854 offset, 850 offset,
855 result_register(), 851 result_register(),
856 x2, 852 x2,
857 kLRHasBeenSaved, 853 kLRHasBeenSaved,
858 kDontSaveFPRegs, 854 kDontSaveFPRegs,
859 EMIT_REMEMBERED_SET, 855 EMIT_REMEMBERED_SET,
860 OMIT_SMI_CHECK); 856 OMIT_SMI_CHECK);
861 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 857 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
862 break; 858 break;
863 } 859 }
864 860
865 case VariableLocation::LOOKUP: { 861 case VariableLocation::LOOKUP: {
866 Comment cmnt(masm_, "[ Function Declaration"); 862 Comment cmnt(masm_, "[ Function Declaration");
867 __ Mov(x2, Operand(variable->name())); 863 __ Mov(x2, Operand(variable->name()));
868 PushOperand(x2); 864 PushOperand(x2);
869 // Push initial value for function declaration. 865 // Push initial value for function declaration.
870 VisitForStackValue(declaration->fun()); 866 VisitForStackValue(declaration->fun());
871 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 867 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
872 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 868 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
873 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 869 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
874 break; 870 break;
875 } 871 }
876 } 872 }
877 } 873 }
878 874
879 875
880 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 876 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
881 // Call the runtime to declare the globals. 877 // Call the runtime to declare the globals.
882 __ Mov(x11, Operand(pairs)); 878 __ Mov(x11, Operand(pairs));
883 Register flags = xzr; 879 Register flags = xzr;
(...skipping 16 matching lines...) Expand all
900 896
901 897
902 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 898 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
903 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement"); 899 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement");
904 Comment cmnt(masm_, "[ SwitchStatement"); 900 Comment cmnt(masm_, "[ SwitchStatement");
905 Breakable nested_statement(this, stmt); 901 Breakable nested_statement(this, stmt);
906 SetStatementPosition(stmt); 902 SetStatementPosition(stmt);
907 903
908 // Keep the switch value on the stack until a case matches. 904 // Keep the switch value on the stack until a case matches.
909 VisitForStackValue(stmt->tag()); 905 VisitForStackValue(stmt->tag());
910 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); 906 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
911 907
912 ZoneList<CaseClause*>* clauses = stmt->cases(); 908 ZoneList<CaseClause*>* clauses = stmt->cases();
913 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 909 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
914 910
915 Label next_test; // Recycled for each test. 911 Label next_test; // Recycled for each test.
916 // Compile all the tests with branches to their bodies. 912 // Compile all the tests with branches to their bodies.
917 for (int i = 0; i < clauses->length(); i++) { 913 for (int i = 0; i < clauses->length(); i++) {
918 CaseClause* clause = clauses->at(i); 914 CaseClause* clause = clauses->at(i);
919 clause->body_target()->Unuse(); 915 clause->body_target()->Unuse();
920 916
(...skipping 26 matching lines...) Expand all
947 943
948 // Record position before stub call for type feedback. 944 // Record position before stub call for type feedback.
949 SetExpressionPosition(clause); 945 SetExpressionPosition(clause);
950 Handle<Code> ic = 946 Handle<Code> ic =
951 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 947 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
952 CallIC(ic, clause->CompareId()); 948 CallIC(ic, clause->CompareId());
953 patch_site.EmitPatchInfo(); 949 patch_site.EmitPatchInfo();
954 950
955 Label skip; 951 Label skip;
956 __ B(&skip); 952 __ B(&skip);
957 PrepareForBailout(clause, BailoutState::TOS_REGISTER); 953 PrepareForBailout(clause, TOS_REG);
958 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); 954 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test);
959 __ Drop(1); 955 __ Drop(1);
960 __ B(clause->body_target()); 956 __ B(clause->body_target());
961 __ Bind(&skip); 957 __ Bind(&skip);
962 958
963 __ Cbnz(x0, &next_test); 959 __ Cbnz(x0, &next_test);
964 __ Drop(1); // Switch value is no longer needed. 960 __ Drop(1); // Switch value is no longer needed.
965 __ B(clause->body_target()); 961 __ B(clause->body_target());
966 } 962 }
967 963
968 // Discard the test value and jump to the default if present, otherwise to 964 // Discard the test value and jump to the default if present, otherwise to
969 // the end of the statement. 965 // the end of the statement.
970 __ Bind(&next_test); 966 __ Bind(&next_test);
971 DropOperands(1); // Switch value is no longer needed. 967 DropOperands(1); // Switch value is no longer needed.
972 if (default_clause == NULL) { 968 if (default_clause == NULL) {
973 __ B(nested_statement.break_label()); 969 __ B(nested_statement.break_label());
974 } else { 970 } else {
975 __ B(default_clause->body_target()); 971 __ B(default_clause->body_target());
976 } 972 }
977 973
978 // Compile all the case bodies. 974 // Compile all the case bodies.
979 for (int i = 0; i < clauses->length(); i++) { 975 for (int i = 0; i < clauses->length(); i++) {
980 Comment cmnt(masm_, "[ Case body"); 976 Comment cmnt(masm_, "[ Case body");
981 CaseClause* clause = clauses->at(i); 977 CaseClause* clause = clauses->at(i);
982 __ Bind(clause->body_target()); 978 __ Bind(clause->body_target());
983 PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); 979 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
984 VisitStatements(clause->statements()); 980 VisitStatements(clause->statements());
985 } 981 }
986 982
987 __ Bind(nested_statement.break_label()); 983 __ Bind(nested_statement.break_label());
988 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); 984 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
989 } 985 }
990 986
991 987
992 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 988 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
993 ASM_LOCATION("FullCodeGenerator::VisitForInStatement"); 989 ASM_LOCATION("FullCodeGenerator::VisitForInStatement");
994 Comment cmnt(masm_, "[ ForInStatement"); 990 Comment cmnt(masm_, "[ ForInStatement");
995 SetStatementPosition(stmt, SKIP_BREAK); 991 SetStatementPosition(stmt, SKIP_BREAK);
996 992
997 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 993 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
998 994
(...skipping 12 matching lines...) Expand all
1011 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 1007 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
1012 Label convert, done_convert; 1008 Label convert, done_convert;
1013 __ JumpIfSmi(x0, &convert); 1009 __ JumpIfSmi(x0, &convert);
1014 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); 1010 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge);
1015 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); 1011 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit);
1016 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); 1012 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit);
1017 __ Bind(&convert); 1013 __ Bind(&convert);
1018 ToObjectStub stub(isolate()); 1014 ToObjectStub stub(isolate());
1019 __ CallStub(&stub); 1015 __ CallStub(&stub);
1020 __ Bind(&done_convert); 1016 __ Bind(&done_convert);
1021 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); 1017 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
1022 __ Push(x0); 1018 __ Push(x0);
1023 1019
1024 // Check cache validity in generated code. If we cannot guarantee cache 1020 // Check cache validity in generated code. If we cannot guarantee cache
1025 // validity, call the runtime system to check cache validity or get the 1021 // validity, call the runtime system to check cache validity or get the
1026 // property names in a fixed array. Note: Proxies never have an enum cache, 1022 // property names in a fixed array. Note: Proxies never have an enum cache,
1027 // so will always take the slow path. 1023 // so will always take the slow path.
1028 Label call_runtime; 1024 Label call_runtime;
1029 __ CheckEnumCache(x0, x15, x10, x11, x12, x13, &call_runtime); 1025 __ CheckEnumCache(x0, x15, x10, x11, x12, x13, &call_runtime);
1030 1026
1031 // The enum cache is valid. Load the map of the object being 1027 // The enum cache is valid. Load the map of the object being
1032 // iterated over and use the cache for the iteration. 1028 // iterated over and use the cache for the iteration.
1033 Label use_cache; 1029 Label use_cache;
1034 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset)); 1030 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset));
1035 __ B(&use_cache); 1031 __ B(&use_cache);
1036 1032
1037 // Get the set of properties to enumerate. 1033 // Get the set of properties to enumerate.
1038 __ Bind(&call_runtime); 1034 __ Bind(&call_runtime);
1039 __ Push(x0); // Duplicate the enumerable object on the stack. 1035 __ Push(x0); // Duplicate the enumerable object on the stack.
1040 __ CallRuntime(Runtime::kForInEnumerate); 1036 __ CallRuntime(Runtime::kForInEnumerate);
1041 PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER); 1037 PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
1042 1038
1043 // If we got a map from the runtime call, we can do a fast 1039 // If we got a map from the runtime call, we can do a fast
1044 // modification check. Otherwise, we got a fixed array, and we have 1040 // modification check. Otherwise, we got a fixed array, and we have
1045 // to do a slow check. 1041 // to do a slow check.
1046 Label fixed_array, no_descriptors; 1042 Label fixed_array, no_descriptors;
1047 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset)); 1043 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset));
1048 __ JumpIfNotRoot(x2, Heap::kMetaMapRootIndex, &fixed_array); 1044 __ JumpIfNotRoot(x2, Heap::kMetaMapRootIndex, &fixed_array);
1049 1045
1050 // We got a map in register x0. Get the enumeration cache from it. 1046 // We got a map in register x0. Get the enumeration cache from it.
1051 __ Bind(&use_cache); 1047 __ Bind(&use_cache);
(...skipping 15 matching lines...) Expand all
1067 __ Bind(&no_descriptors); 1063 __ Bind(&no_descriptors);
1068 __ Drop(1); 1064 __ Drop(1);
1069 __ B(&exit); 1065 __ B(&exit);
1070 1066
1071 // We got a fixed array in register x0. Iterate through that. 1067 // We got a fixed array in register x0. Iterate through that.
1072 __ Bind(&fixed_array); 1068 __ Bind(&fixed_array);
1073 1069
1074 __ Mov(x1, Smi::FromInt(1)); // Smi(1) indicates slow check. 1070 __ Mov(x1, Smi::FromInt(1)); // Smi(1) indicates slow check.
1075 __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset)); 1071 __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset));
1076 __ Push(x1, x0, x2); // Smi and array, fixed array length (as smi). 1072 __ Push(x1, x0, x2); // Smi and array, fixed array length (as smi).
1077 PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); 1073 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS);
1078 __ Push(xzr); // Initial index. 1074 __ Push(xzr); // Initial index.
1079 1075
1080 // Generate code for doing the condition check. 1076 // Generate code for doing the condition check.
1081 __ Bind(&loop); 1077 __ Bind(&loop);
1082 SetExpressionAsStatementPosition(stmt->each()); 1078 SetExpressionAsStatementPosition(stmt->each());
1083 1079
1084 // Load the current count to x0, load the length to x1. 1080 // Load the current count to x0, load the length to x1.
1085 __ PeekPair(x0, x1, 0); 1081 __ PeekPair(x0, x1, 0);
1086 __ Cmp(x0, x1); // Compare to the array length. 1082 __ Cmp(x0, x1); // Compare to the array length.
1087 __ B(hs, loop_statement.break_label()); 1083 __ B(hs, loop_statement.break_label());
(...skipping 19 matching lines...) Expand all
1107 int const vector_index = SmiFromSlot(slot)->value(); 1103 int const vector_index = SmiFromSlot(slot)->value();
1108 __ EmitLoadTypeFeedbackVector(x0); 1104 __ EmitLoadTypeFeedbackVector(x0);
1109 __ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1105 __ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1110 __ Str(x10, FieldMemOperand(x0, FixedArray::OffsetOfElementAt(vector_index))); 1106 __ Str(x10, FieldMemOperand(x0, FixedArray::OffsetOfElementAt(vector_index)));
1111 1107
1112 // Convert the entry to a string or (smi) 0 if it isn't a property 1108 // Convert the entry to a string or (smi) 0 if it isn't a property
1113 // any more. If the property has been removed while iterating, we 1109 // any more. If the property has been removed while iterating, we
1114 // just skip it. 1110 // just skip it.
1115 __ Push(x1, x3); 1111 __ Push(x1, x3);
1116 __ CallRuntime(Runtime::kForInFilter); 1112 __ CallRuntime(Runtime::kForInFilter);
1117 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); 1113 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1118 __ Mov(x3, x0); 1114 __ Mov(x3, x0);
1119 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, 1115 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex,
1120 loop_statement.continue_label()); 1116 loop_statement.continue_label());
1121 1117
1122 // Update the 'each' property or variable from the possibly filtered 1118 // Update the 'each' property or variable from the possibly filtered
1123 // entry in register x3. 1119 // entry in register x3.
1124 __ Bind(&update_each); 1120 __ Bind(&update_each);
1125 __ Mov(result_register(), x3); 1121 __ Mov(result_register(), x3);
1126 // Perform the assignment as if via '='. 1122 // Perform the assignment as if via '='.
1127 { EffectContext context(this); 1123 { EffectContext context(this);
1128 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1124 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1129 PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); 1125 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS);
1130 } 1126 }
1131 1127
1132 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1128 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1133 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); 1129 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1134 // Generate code for the body of the loop. 1130 // Generate code for the body of the loop.
1135 Visit(stmt->body()); 1131 Visit(stmt->body());
1136 1132
1137 // Generate code for going to the next element by incrementing 1133 // Generate code for going to the next element by incrementing
1138 // the index (smi) stored on top of the stack. 1134 // the index (smi) stored on top of the stack.
1139 __ Bind(loop_statement.continue_label()); 1135 __ Bind(loop_statement.continue_label());
1140 // TODO(all): We could use a callee saved register to avoid popping. 1136 // TODO(all): We could use a callee saved register to avoid popping.
1141 __ Pop(x0); 1137 __ Pop(x0);
1142 __ Add(x0, x0, Smi::FromInt(1)); 1138 __ Add(x0, x0, Smi::FromInt(1));
1143 __ Push(x0); 1139 __ Push(x0);
1144 1140
1145 EmitBackEdgeBookkeeping(stmt, &loop); 1141 EmitBackEdgeBookkeeping(stmt, &loop);
1146 __ B(&loop); 1142 __ B(&loop);
1147 1143
1148 // Remove the pointers stored on the stack. 1144 // Remove the pointers stored on the stack.
1149 __ Bind(loop_statement.break_label()); 1145 __ Bind(loop_statement.break_label());
1150 DropOperands(5); 1146 DropOperands(5);
1151 1147
1152 // Exit and decrement the loop depth. 1148 // Exit and decrement the loop depth.
1153 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); 1149 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1154 __ Bind(&exit); 1150 __ Bind(&exit);
1155 decrement_loop_depth(); 1151 decrement_loop_depth();
1156 } 1152 }
1157 1153
1158 1154
1159 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1155 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1160 FeedbackVectorSlot slot) { 1156 FeedbackVectorSlot slot) {
1161 DCHECK(NeedsHomeObject(initializer)); 1157 DCHECK(NeedsHomeObject(initializer));
1162 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1158 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1163 __ Mov(StoreDescriptor::NameRegister(), 1159 __ Mov(StoreDescriptor::NameRegister(),
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 __ Mov(LoadDescriptor::SlotRegister(), 1292 __ Mov(LoadDescriptor::SlotRegister(),
1297 SmiFromSlot(proxy->VariableFeedbackSlot())); 1293 SmiFromSlot(proxy->VariableFeedbackSlot()));
1298 CallLoadIC(typeof_mode); 1294 CallLoadIC(typeof_mode);
1299 } 1295 }
1300 1296
1301 1297
1302 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1298 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1303 TypeofMode typeof_mode) { 1299 TypeofMode typeof_mode) {
1304 // Record position before possible IC call. 1300 // Record position before possible IC call.
1305 SetExpressionPosition(proxy); 1301 SetExpressionPosition(proxy);
1306 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1302 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1307 Variable* var = proxy->var(); 1303 Variable* var = proxy->var();
1308 1304
1309 // Three cases: global variables, lookup variables, and all other types of 1305 // Three cases: global variables, lookup variables, and all other types of
1310 // variables. 1306 // variables.
1311 switch (var->location()) { 1307 switch (var->location()) {
1312 case VariableLocation::GLOBAL: 1308 case VariableLocation::GLOBAL:
1313 case VariableLocation::UNALLOCATED: { 1309 case VariableLocation::UNALLOCATED: {
1314 Comment cmnt(masm_, "Global variable"); 1310 Comment cmnt(masm_, "Global variable");
1315 EmitGlobalVariableLoad(proxy, typeof_mode); 1311 EmitGlobalVariableLoad(proxy, typeof_mode);
1316 context()->Plug(x0); 1312 context()->Plug(x0);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 int flags = expr->ComputeFlags(); 1400 int flags = expr->ComputeFlags();
1405 __ Mov(x0, Smi::FromInt(flags)); 1401 __ Mov(x0, Smi::FromInt(flags));
1406 if (MustCreateObjectLiteralWithRuntime(expr)) { 1402 if (MustCreateObjectLiteralWithRuntime(expr)) {
1407 __ Push(x3, x2, x1, x0); 1403 __ Push(x3, x2, x1, x0);
1408 __ CallRuntime(Runtime::kCreateObjectLiteral); 1404 __ CallRuntime(Runtime::kCreateObjectLiteral);
1409 } else { 1405 } else {
1410 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1406 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1411 __ CallStub(&stub); 1407 __ CallStub(&stub);
1412 RestoreContext(); 1408 RestoreContext();
1413 } 1409 }
1414 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); 1410 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1415 1411
1416 // If result_saved is true the result is on top of the stack. If 1412 // If result_saved is true the result is on top of the stack. If
1417 // result_saved is false the result is in x0. 1413 // result_saved is false the result is in x0.
1418 bool result_saved = false; 1414 bool result_saved = false;
1419 1415
1420 AccessorTable accessor_table(zone()); 1416 AccessorTable accessor_table(zone());
1421 int property_index = 0; 1417 int property_index = 0;
1422 for (; property_index < expr->properties()->length(); property_index++) { 1418 for (; property_index < expr->properties()->length(); property_index++) {
1423 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1419 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1424 if (property->is_computed_name()) break; 1420 if (property->is_computed_name()) break;
(...skipping 15 matching lines...) Expand all
1440 // It is safe to use [[Put]] here because the boilerplate already 1436 // It is safe to use [[Put]] here because the boilerplate already
1441 // contains computed properties with an uninitialized value. 1437 // contains computed properties with an uninitialized value.
1442 if (key->value()->IsInternalizedString()) { 1438 if (key->value()->IsInternalizedString()) {
1443 if (property->emit_store()) { 1439 if (property->emit_store()) {
1444 VisitForAccumulatorValue(value); 1440 VisitForAccumulatorValue(value);
1445 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 1441 DCHECK(StoreDescriptor::ValueRegister().is(x0));
1446 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); 1442 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1447 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1443 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1448 EmitLoadStoreICSlot(property->GetSlot(0)); 1444 EmitLoadStoreICSlot(property->GetSlot(0));
1449 CallStoreIC(); 1445 CallStoreIC();
1450 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); 1446 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1451 1447
1452 if (NeedsHomeObject(value)) { 1448 if (NeedsHomeObject(value)) {
1453 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1449 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1454 } 1450 }
1455 } else { 1451 } else {
1456 VisitForEffect(value); 1452 VisitForEffect(value);
1457 } 1453 }
1458 break; 1454 break;
1459 } 1455 }
1460 __ Peek(x0, 0); 1456 __ Peek(x0, 0);
(...skipping 12 matching lines...) Expand all
1473 } 1469 }
1474 break; 1470 break;
1475 case ObjectLiteral::Property::PROTOTYPE: 1471 case ObjectLiteral::Property::PROTOTYPE:
1476 DCHECK(property->emit_store()); 1472 DCHECK(property->emit_store());
1477 // Duplicate receiver on stack. 1473 // Duplicate receiver on stack.
1478 __ Peek(x0, 0); 1474 __ Peek(x0, 0);
1479 PushOperand(x0); 1475 PushOperand(x0);
1480 VisitForStackValue(value); 1476 VisitForStackValue(value);
1481 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1477 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1482 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1478 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1483 BailoutState::NO_REGISTERS); 1479 NO_REGISTERS);
1484 break; 1480 break;
1485 case ObjectLiteral::Property::GETTER: 1481 case ObjectLiteral::Property::GETTER:
1486 if (property->emit_store()) { 1482 if (property->emit_store()) {
1487 accessor_table.lookup(key)->second->getter = property; 1483 accessor_table.lookup(key)->second->getter = property;
1488 } 1484 }
1489 break; 1485 break;
1490 case ObjectLiteral::Property::SETTER: 1486 case ObjectLiteral::Property::SETTER:
1491 if (property->emit_store()) { 1487 if (property->emit_store()) {
1492 accessor_table.lookup(key)->second->setter = property; 1488 accessor_table.lookup(key)->second->setter = property;
1493 } 1489 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 1526
1531 __ Peek(x10, 0); // Duplicate receiver. 1527 __ Peek(x10, 0); // Duplicate receiver.
1532 PushOperand(x10); 1528 PushOperand(x10);
1533 1529
1534 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1530 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1535 DCHECK(!property->is_computed_name()); 1531 DCHECK(!property->is_computed_name());
1536 VisitForStackValue(value); 1532 VisitForStackValue(value);
1537 DCHECK(property->emit_store()); 1533 DCHECK(property->emit_store());
1538 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1534 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1539 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1535 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1540 BailoutState::NO_REGISTERS); 1536 NO_REGISTERS);
1541 } else { 1537 } else {
1542 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1538 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1543 VisitForStackValue(value); 1539 VisitForStackValue(value);
1544 if (NeedsHomeObject(value)) { 1540 if (NeedsHomeObject(value)) {
1545 EmitSetHomeObject(value, 2, property->GetSlot()); 1541 EmitSetHomeObject(value, 2, property->GetSlot());
1546 } 1542 }
1547 1543
1548 switch (property->kind()) { 1544 switch (property->kind()) {
1549 case ObjectLiteral::Property::CONSTANT: 1545 case ObjectLiteral::Property::CONSTANT:
1550 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1546 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 __ Mov(x2, Smi::FromInt(expr->literal_index())); 1597 __ Mov(x2, Smi::FromInt(expr->literal_index()));
1602 __ Mov(x1, Operand(constant_elements)); 1598 __ Mov(x1, Operand(constant_elements));
1603 if (MustCreateArrayLiteralWithRuntime(expr)) { 1599 if (MustCreateArrayLiteralWithRuntime(expr)) {
1604 __ Mov(x0, Smi::FromInt(expr->ComputeFlags())); 1600 __ Mov(x0, Smi::FromInt(expr->ComputeFlags()));
1605 __ Push(x3, x2, x1, x0); 1601 __ Push(x3, x2, x1, x0);
1606 __ CallRuntime(Runtime::kCreateArrayLiteral); 1602 __ CallRuntime(Runtime::kCreateArrayLiteral);
1607 } else { 1603 } else {
1608 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1604 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1609 __ CallStub(&stub); 1605 __ CallStub(&stub);
1610 } 1606 }
1611 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); 1607 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1612 1608
1613 bool result_saved = false; // Is the result saved to the stack? 1609 bool result_saved = false; // Is the result saved to the stack?
1614 ZoneList<Expression*>* subexprs = expr->values(); 1610 ZoneList<Expression*>* subexprs = expr->values();
1615 int length = subexprs->length(); 1611 int length = subexprs->length();
1616 1612
1617 // Emit code to evaluate all the non-constant subexpressions and to store 1613 // Emit code to evaluate all the non-constant subexpressions and to store
1618 // them into the newly cloned array. 1614 // them into the newly cloned array.
1619 int array_index = 0; 1615 int array_index = 0;
1620 for (; array_index < length; array_index++) { 1616 for (; array_index < length; array_index++) {
1621 Expression* subexpr = subexprs->at(array_index); 1617 Expression* subexpr = subexprs->at(array_index);
1622 DCHECK(!subexpr->IsSpread()); 1618 DCHECK(!subexpr->IsSpread());
1623 1619
1624 // If the subexpression is a literal or a simple materialized literal it 1620 // If the subexpression is a literal or a simple materialized literal it
1625 // is already set in the cloned array. 1621 // is already set in the cloned array.
1626 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1622 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1627 1623
1628 if (!result_saved) { 1624 if (!result_saved) {
1629 PushOperand(x0); 1625 PushOperand(x0);
1630 result_saved = true; 1626 result_saved = true;
1631 } 1627 }
1632 VisitForAccumulatorValue(subexpr); 1628 VisitForAccumulatorValue(subexpr);
1633 1629
1634 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); 1630 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index));
1635 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1631 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1636 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1632 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1637 Handle<Code> ic = 1633 Handle<Code> ic =
1638 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1634 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1639 CallIC(ic); 1635 CallIC(ic);
1640 1636
1641 PrepareForBailoutForId(expr->GetIdForElement(array_index), 1637 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1642 BailoutState::NO_REGISTERS);
1643 } 1638 }
1644 1639
1645 // In case the array literal contains spread expressions it has two parts. The 1640 // In case the array literal contains spread expressions it has two parts. The
1646 // first part is the "static" array which has a literal index is handled 1641 // first part is the "static" array which has a literal index is handled
1647 // above. The second part is the part after the first spread expression 1642 // above. The second part is the part after the first spread expression
1648 // (inclusive) and these elements gets appended to the array. Note that the 1643 // (inclusive) and these elements gets appended to the array. Note that the
1649 // number elements an iterable produces is unknown ahead of time. 1644 // number elements an iterable produces is unknown ahead of time.
1650 if (array_index < length && result_saved) { 1645 if (array_index < length && result_saved) {
1651 PopOperand(x0); 1646 PopOperand(x0);
1652 result_saved = false; 1647 result_saved = false;
1653 } 1648 }
1654 for (; array_index < length; array_index++) { 1649 for (; array_index < length; array_index++) {
1655 Expression* subexpr = subexprs->at(array_index); 1650 Expression* subexpr = subexprs->at(array_index);
1656 1651
1657 PushOperand(x0); 1652 PushOperand(x0);
1658 DCHECK(!subexpr->IsSpread()); 1653 DCHECK(!subexpr->IsSpread());
1659 VisitForStackValue(subexpr); 1654 VisitForStackValue(subexpr);
1660 CallRuntimeWithOperands(Runtime::kAppendElement); 1655 CallRuntimeWithOperands(Runtime::kAppendElement);
1661 1656
1662 PrepareForBailoutForId(expr->GetIdForElement(array_index), 1657 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1663 BailoutState::NO_REGISTERS);
1664 } 1658 }
1665 1659
1666 if (result_saved) { 1660 if (result_saved) {
1667 context()->PlugTOS(); 1661 context()->PlugTOS();
1668 } else { 1662 } else {
1669 context()->Plug(x0); 1663 context()->Plug(x0);
1670 } 1664 }
1671 } 1665 }
1672 1666
1673 1667
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 break; 1727 break;
1734 } 1728 }
1735 1729
1736 // For compound assignments we need another deoptimization point after the 1730 // For compound assignments we need another deoptimization point after the
1737 // variable/property load. 1731 // variable/property load.
1738 if (expr->is_compound()) { 1732 if (expr->is_compound()) {
1739 { AccumulatorValueContext context(this); 1733 { AccumulatorValueContext context(this);
1740 switch (assign_type) { 1734 switch (assign_type) {
1741 case VARIABLE: 1735 case VARIABLE:
1742 EmitVariableLoad(expr->target()->AsVariableProxy()); 1736 EmitVariableLoad(expr->target()->AsVariableProxy());
1743 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); 1737 PrepareForBailout(expr->target(), TOS_REG);
1744 break; 1738 break;
1745 case NAMED_PROPERTY: 1739 case NAMED_PROPERTY:
1746 EmitNamedPropertyLoad(property); 1740 EmitNamedPropertyLoad(property);
1747 PrepareForBailoutForId(property->LoadId(), 1741 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1748 BailoutState::TOS_REGISTER);
1749 break; 1742 break;
1750 case NAMED_SUPER_PROPERTY: 1743 case NAMED_SUPER_PROPERTY:
1751 EmitNamedSuperPropertyLoad(property); 1744 EmitNamedSuperPropertyLoad(property);
1752 PrepareForBailoutForId(property->LoadId(), 1745 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1753 BailoutState::TOS_REGISTER);
1754 break; 1746 break;
1755 case KEYED_SUPER_PROPERTY: 1747 case KEYED_SUPER_PROPERTY:
1756 EmitKeyedSuperPropertyLoad(property); 1748 EmitKeyedSuperPropertyLoad(property);
1757 PrepareForBailoutForId(property->LoadId(), 1749 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1758 BailoutState::TOS_REGISTER);
1759 break; 1750 break;
1760 case KEYED_PROPERTY: 1751 case KEYED_PROPERTY:
1761 EmitKeyedPropertyLoad(property); 1752 EmitKeyedPropertyLoad(property);
1762 PrepareForBailoutForId(property->LoadId(), 1753 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1763 BailoutState::TOS_REGISTER);
1764 break; 1754 break;
1765 } 1755 }
1766 } 1756 }
1767 1757
1768 Token::Value op = expr->binary_op(); 1758 Token::Value op = expr->binary_op();
1769 PushOperand(x0); // Left operand goes on the stack. 1759 PushOperand(x0); // Left operand goes on the stack.
1770 VisitForAccumulatorValue(expr->value()); 1760 VisitForAccumulatorValue(expr->value());
1771 1761
1772 AccumulatorValueContext context(this); 1762 AccumulatorValueContext context(this);
1773 if (ShouldInlineSmiCase(op)) { 1763 if (ShouldInlineSmiCase(op)) {
1774 EmitInlineSmiBinaryOp(expr->binary_operation(), 1764 EmitInlineSmiBinaryOp(expr->binary_operation(),
1775 op, 1765 op,
1776 expr->target(), 1766 expr->target(),
1777 expr->value()); 1767 expr->value());
1778 } else { 1768 } else {
1779 EmitBinaryOp(expr->binary_operation(), op); 1769 EmitBinaryOp(expr->binary_operation(), op);
1780 } 1770 }
1781 1771
1782 // Deoptimization point in case the binary operation may have side effects. 1772 // Deoptimization point in case the binary operation may have side effects.
1783 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); 1773 PrepareForBailout(expr->binary_operation(), TOS_REG);
1784 } else { 1774 } else {
1785 VisitForAccumulatorValue(expr->value()); 1775 VisitForAccumulatorValue(expr->value());
1786 } 1776 }
1787 1777
1788 SetExpressionPosition(expr); 1778 SetExpressionPosition(expr);
1789 1779
1790 // Store the value. 1780 // Store the value.
1791 switch (assign_type) { 1781 switch (assign_type) {
1792 case VARIABLE: 1782 case VARIABLE:
1793 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1783 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1794 expr->op(), expr->AssignmentSlot()); 1784 expr->op(), expr->AssignmentSlot());
1795 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 1785 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1796 context()->Plug(x0); 1786 context()->Plug(x0);
1797 break; 1787 break;
1798 case NAMED_PROPERTY: 1788 case NAMED_PROPERTY:
1799 EmitNamedPropertyAssignment(expr); 1789 EmitNamedPropertyAssignment(expr);
1800 break; 1790 break;
1801 case NAMED_SUPER_PROPERTY: 1791 case NAMED_SUPER_PROPERTY:
1802 EmitNamedSuperPropertyStore(property); 1792 EmitNamedSuperPropertyStore(property);
1803 context()->Plug(x0); 1793 context()->Plug(x0);
1804 break; 1794 break;
1805 case KEYED_SUPER_PROPERTY: 1795 case KEYED_SUPER_PROPERTY:
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 Property* prop = expr->target()->AsProperty(); 2155 Property* prop = expr->target()->AsProperty();
2166 DCHECK(prop != NULL); 2156 DCHECK(prop != NULL);
2167 DCHECK(prop->key()->IsLiteral()); 2157 DCHECK(prop->key()->IsLiteral());
2168 2158
2169 __ Mov(StoreDescriptor::NameRegister(), 2159 __ Mov(StoreDescriptor::NameRegister(),
2170 Operand(prop->key()->AsLiteral()->value())); 2160 Operand(prop->key()->AsLiteral()->value()));
2171 PopOperand(StoreDescriptor::ReceiverRegister()); 2161 PopOperand(StoreDescriptor::ReceiverRegister());
2172 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2162 EmitLoadStoreICSlot(expr->AssignmentSlot());
2173 CallStoreIC(); 2163 CallStoreIC();
2174 2164
2175 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2165 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2176 context()->Plug(x0); 2166 context()->Plug(x0);
2177 } 2167 }
2178 2168
2179 2169
2180 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2170 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2181 // Assignment to named property of super. 2171 // Assignment to named property of super.
2182 // x0 : value 2172 // x0 : value
2183 // stack : receiver ('this'), home_object 2173 // stack : receiver ('this'), home_object
2184 DCHECK(prop != NULL); 2174 DCHECK(prop != NULL);
2185 Literal* key = prop->key()->AsLiteral(); 2175 Literal* key = prop->key()->AsLiteral();
(...skipping 27 matching lines...) Expand all
2213 // TODO(all): Could we pass this in registers rather than on the stack? 2203 // TODO(all): Could we pass this in registers rather than on the stack?
2214 PopOperands(StoreDescriptor::NameRegister(), 2204 PopOperands(StoreDescriptor::NameRegister(),
2215 StoreDescriptor::ReceiverRegister()); 2205 StoreDescriptor::ReceiverRegister());
2216 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 2206 DCHECK(StoreDescriptor::ValueRegister().is(x0));
2217 2207
2218 Handle<Code> ic = 2208 Handle<Code> ic =
2219 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2209 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2220 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2210 EmitLoadStoreICSlot(expr->AssignmentSlot());
2221 CallIC(ic); 2211 CallIC(ic);
2222 2212
2223 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2213 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2224 context()->Plug(x0); 2214 context()->Plug(x0);
2225 } 2215 }
2226 2216
2227 2217
2228 void FullCodeGenerator::CallIC(Handle<Code> code, 2218 void FullCodeGenerator::CallIC(Handle<Code> code,
2229 TypeFeedbackId ast_id) { 2219 TypeFeedbackId ast_id) {
2230 ic_total_count_++; 2220 ic_total_count_++;
2231 // All calls must have a predictable size in full-codegen code to ensure that 2221 // All calls must have a predictable size in full-codegen code to ensure that
2232 // the debugger can patch them correctly. 2222 // the debugger can patch them correctly.
2233 __ Call(code, RelocInfo::CODE_TARGET, ast_id); 2223 __ Call(code, RelocInfo::CODE_TARGET, ast_id);
2234 } 2224 }
2235 2225
2236 2226
2237 // Code common for calls using the IC. 2227 // Code common for calls using the IC.
2238 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2228 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2239 ASM_LOCATION("FullCodeGenerator::EmitCallWithLoadIC"); 2229 ASM_LOCATION("FullCodeGenerator::EmitCallWithLoadIC");
2240 Expression* callee = expr->expression(); 2230 Expression* callee = expr->expression();
2241 2231
2242 // Get the target function. 2232 // Get the target function.
2243 ConvertReceiverMode convert_mode; 2233 ConvertReceiverMode convert_mode;
2244 if (callee->IsVariableProxy()) { 2234 if (callee->IsVariableProxy()) {
2245 { StackValueContext context(this); 2235 { StackValueContext context(this);
2246 EmitVariableLoad(callee->AsVariableProxy()); 2236 EmitVariableLoad(callee->AsVariableProxy());
2247 PrepareForBailout(callee, BailoutState::NO_REGISTERS); 2237 PrepareForBailout(callee, NO_REGISTERS);
2248 } 2238 }
2249 // Push undefined as receiver. This is patched in the method prologue if it 2239 // Push undefined as receiver. This is patched in the method prologue if it
2250 // is a sloppy mode method. 2240 // is a sloppy mode method.
2251 { 2241 {
2252 UseScratchRegisterScope temps(masm_); 2242 UseScratchRegisterScope temps(masm_);
2253 Register temp = temps.AcquireX(); 2243 Register temp = temps.AcquireX();
2254 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); 2244 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex);
2255 PushOperand(temp); 2245 PushOperand(temp);
2256 } 2246 }
2257 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2247 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2258 } else { 2248 } else {
2259 // Load the function from the receiver. 2249 // Load the function from the receiver.
2260 DCHECK(callee->IsProperty()); 2250 DCHECK(callee->IsProperty());
2261 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2251 DCHECK(!callee->AsProperty()->IsSuperAccess());
2262 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 2252 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
2263 EmitNamedPropertyLoad(callee->AsProperty()); 2253 EmitNamedPropertyLoad(callee->AsProperty());
2264 PrepareForBailoutForId(callee->AsProperty()->LoadId(), 2254 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2265 BailoutState::TOS_REGISTER);
2266 // Push the target function under the receiver. 2255 // Push the target function under the receiver.
2267 PopOperand(x10); 2256 PopOperand(x10);
2268 PushOperands(x0, x10); 2257 PushOperands(x0, x10);
2269 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2258 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2270 } 2259 }
2271 2260
2272 EmitCall(expr, convert_mode); 2261 EmitCall(expr, convert_mode);
2273 } 2262 }
2274 2263
2275 2264
(...skipping 19 matching lines...) Expand all
2295 PushOperands(x0, scratch); 2284 PushOperands(x0, scratch);
2296 PushOperand(key->value()); 2285 PushOperand(key->value());
2297 2286
2298 // Stack here: 2287 // Stack here:
2299 // - home_object 2288 // - home_object
2300 // - this (receiver) 2289 // - this (receiver)
2301 // - this (receiver) <-- LoadFromSuper will pop here and below. 2290 // - this (receiver) <-- LoadFromSuper will pop here and below.
2302 // - home_object 2291 // - home_object
2303 // - key 2292 // - key
2304 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2293 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2305 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); 2294 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
2306 2295
2307 // Replace home_object with target function. 2296 // Replace home_object with target function.
2308 __ Poke(x0, kPointerSize); 2297 __ Poke(x0, kPointerSize);
2309 2298
2310 // Stack here: 2299 // Stack here:
2311 // - target function 2300 // - target function
2312 // - this (receiver) 2301 // - this (receiver)
2313 EmitCall(expr); 2302 EmitCall(expr);
2314 } 2303 }
2315 2304
2316 2305
2317 // Code common for calls using the IC. 2306 // Code common for calls using the IC.
2318 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2307 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2319 Expression* key) { 2308 Expression* key) {
2320 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); 2309 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC");
2321 // Load the key. 2310 // Load the key.
2322 VisitForAccumulatorValue(key); 2311 VisitForAccumulatorValue(key);
2323 2312
2324 Expression* callee = expr->expression(); 2313 Expression* callee = expr->expression();
2325 2314
2326 // Load the function from the receiver. 2315 // Load the function from the receiver.
2327 DCHECK(callee->IsProperty()); 2316 DCHECK(callee->IsProperty());
2328 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 2317 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
2329 __ Move(LoadDescriptor::NameRegister(), x0); 2318 __ Move(LoadDescriptor::NameRegister(), x0);
2330 EmitKeyedPropertyLoad(callee->AsProperty()); 2319 EmitKeyedPropertyLoad(callee->AsProperty());
2331 PrepareForBailoutForId(callee->AsProperty()->LoadId(), 2320 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2332 BailoutState::TOS_REGISTER);
2333 2321
2334 // Push the target function under the receiver. 2322 // Push the target function under the receiver.
2335 PopOperand(x10); 2323 PopOperand(x10);
2336 PushOperands(x0, x10); 2324 PushOperands(x0, x10);
2337 2325
2338 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2326 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2339 } 2327 }
2340 2328
2341 2329
2342 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2330 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
(...skipping 15 matching lines...) Expand all
2358 PushOperands(x0, scratch); 2346 PushOperands(x0, scratch);
2359 VisitForStackValue(prop->key()); 2347 VisitForStackValue(prop->key());
2360 2348
2361 // Stack here: 2349 // Stack here:
2362 // - home_object 2350 // - home_object
2363 // - this (receiver) 2351 // - this (receiver)
2364 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2352 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2365 // - home_object 2353 // - home_object
2366 // - key 2354 // - key
2367 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2355 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2368 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); 2356 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
2369 2357
2370 // Replace home_object with target function. 2358 // Replace home_object with target function.
2371 __ Poke(x0, kPointerSize); 2359 __ Poke(x0, kPointerSize);
2372 2360
2373 // Stack here: 2361 // Stack here:
2374 // - target function 2362 // - target function
2375 // - this (receiver) 2363 // - this (receiver)
2376 EmitCall(expr); 2364 EmitCall(expr);
2377 } 2365 }
2378 2366
2379 2367
2380 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2368 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2381 ASM_LOCATION("FullCodeGenerator::EmitCall"); 2369 ASM_LOCATION("FullCodeGenerator::EmitCall");
2382 // Load the arguments. 2370 // Load the arguments.
2383 ZoneList<Expression*>* args = expr->arguments(); 2371 ZoneList<Expression*>* args = expr->arguments();
2384 int arg_count = args->length(); 2372 int arg_count = args->length();
2385 for (int i = 0; i < arg_count; i++) { 2373 for (int i = 0; i < arg_count; i++) {
2386 VisitForStackValue(args->at(i)); 2374 VisitForStackValue(args->at(i));
2387 } 2375 }
2388 2376
2389 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); 2377 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
2390 SetCallPosition(expr, expr->tail_call_mode()); 2378 SetCallPosition(expr, expr->tail_call_mode());
2391 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2379 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2392 if (FLAG_trace) { 2380 if (FLAG_trace) {
2393 __ CallRuntime(Runtime::kTraceTailCall); 2381 __ CallRuntime(Runtime::kTraceTailCall);
2394 } 2382 }
2395 // Update profiling counters before the tail call since we will 2383 // Update profiling counters before the tail call since we will
2396 // not return to this function. 2384 // not return to this function.
2397 EmitProfilingCounterHandlingForReturnSequence(true); 2385 EmitProfilingCounterHandlingForReturnSequence(true);
2398 } 2386 }
2399 Handle<Code> ic = 2387 Handle<Code> ic =
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 // Generate code for loading from variables potentially shadowed 2436 // Generate code for loading from variables potentially shadowed
2449 // by eval-introduced variables. 2437 // by eval-introduced variables.
2450 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2438 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2451 2439
2452 __ Bind(&slow); 2440 __ Bind(&slow);
2453 // Call the runtime to find the function to call (returned in x0) 2441 // Call the runtime to find the function to call (returned in x0)
2454 // and the object holding it (returned in x1). 2442 // and the object holding it (returned in x1).
2455 __ Push(callee->name()); 2443 __ Push(callee->name());
2456 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2444 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2457 PushOperands(x0, x1); // Receiver, function. 2445 PushOperands(x0, x1); // Receiver, function.
2458 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); 2446 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2459 2447
2460 // If fast case code has been generated, emit code to push the 2448 // If fast case code has been generated, emit code to push the
2461 // function and receiver and have the slow path jump around this 2449 // function and receiver and have the slow path jump around this
2462 // code. 2450 // code.
2463 if (done.is_linked()) { 2451 if (done.is_linked()) {
2464 Label call; 2452 Label call;
2465 __ B(&call); 2453 __ B(&call);
2466 __ Bind(&done); 2454 __ Bind(&done);
2467 // Push function. 2455 // Push function.
2468 // The receiver is implicitly the global receiver. Indicate this 2456 // The receiver is implicitly the global receiver. Indicate this
(...skipping 28 matching lines...) Expand all
2497 2485
2498 // Push a copy of the function (found below the arguments) and 2486 // Push a copy of the function (found below the arguments) and
2499 // resolve eval. 2487 // resolve eval.
2500 __ Peek(x10, (arg_count + 1) * kPointerSize); 2488 __ Peek(x10, (arg_count + 1) * kPointerSize);
2501 __ Push(x10); 2489 __ Push(x10);
2502 EmitResolvePossiblyDirectEval(expr); 2490 EmitResolvePossiblyDirectEval(expr);
2503 2491
2504 // Touch up the stack with the resolved function. 2492 // Touch up the stack with the resolved function.
2505 __ Poke(x0, (arg_count + 1) * kPointerSize); 2493 __ Poke(x0, (arg_count + 1) * kPointerSize);
2506 2494
2507 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); 2495 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2508 2496
2509 // Record source position for debugger. 2497 // Record source position for debugger.
2510 SetCallPosition(expr); 2498 SetCallPosition(expr);
2511 2499
2512 // Call the evaluated function. 2500 // Call the evaluated function.
2513 __ Peek(x1, (arg_count + 1) * kXRegSize); 2501 __ Peek(x1, (arg_count + 1) * kXRegSize);
2514 __ Mov(x0, arg_count); 2502 __ Mov(x0, arg_count);
2515 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2503 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2516 expr->tail_call_mode()), 2504 expr->tail_call_mode()),
2517 RelocInfo::CODE_TARGET); 2505 RelocInfo::CODE_TARGET);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2549 __ Mov(x0, arg_count); 2537 __ Mov(x0, arg_count);
2550 __ Peek(x1, arg_count * kXRegSize); 2538 __ Peek(x1, arg_count * kXRegSize);
2551 2539
2552 // Record call targets in unoptimized code. 2540 // Record call targets in unoptimized code.
2553 __ EmitLoadTypeFeedbackVector(x2); 2541 __ EmitLoadTypeFeedbackVector(x2);
2554 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); 2542 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot()));
2555 2543
2556 CallConstructStub stub(isolate()); 2544 CallConstructStub stub(isolate());
2557 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2545 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2558 OperandStackDepthDecrement(arg_count + 1); 2546 OperandStackDepthDecrement(arg_count + 1);
2559 PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); 2547 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2560 RestoreContext(); 2548 RestoreContext();
2561 context()->Plug(x0); 2549 context()->Plug(x0);
2562 } 2550 }
2563 2551
2564 2552
2565 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2553 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2566 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); 2554 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall");
2567 SuperCallReference* super_call_ref = 2555 SuperCallReference* super_call_ref =
2568 expr->expression()->AsSuperCallReference(); 2556 expr->expression()->AsSuperCallReference();
2569 DCHECK_NOT_NULL(super_call_ref); 2557 DCHECK_NOT_NULL(super_call_ref);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2982 2970
2983 2971
2984 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 2972 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
2985 ASM_LOCATION("FullCodeGenerator::EmitCall"); 2973 ASM_LOCATION("FullCodeGenerator::EmitCall");
2986 ZoneList<Expression*>* args = expr->arguments(); 2974 ZoneList<Expression*>* args = expr->arguments();
2987 DCHECK_LE(2, args->length()); 2975 DCHECK_LE(2, args->length());
2988 // Push target, receiver and arguments onto the stack. 2976 // Push target, receiver and arguments onto the stack.
2989 for (Expression* const arg : *args) { 2977 for (Expression* const arg : *args) {
2990 VisitForStackValue(arg); 2978 VisitForStackValue(arg);
2991 } 2979 }
2992 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); 2980 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
2993 // Move target to x1. 2981 // Move target to x1.
2994 int const argc = args->length() - 2; 2982 int const argc = args->length() - 2;
2995 __ Peek(x1, (argc + 1) * kXRegSize); 2983 __ Peek(x1, (argc + 1) * kXRegSize);
2996 // Call the target. 2984 // Call the target.
2997 __ Mov(x0, argc); 2985 __ Mov(x0, argc);
2998 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 2986 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2999 OperandStackDepthDecrement(argc + 1); 2987 OperandStackDepthDecrement(argc + 1);
3000 RestoreContext(); 2988 RestoreContext();
3001 // Discard the function left on TOS. 2989 // Discard the function left on TOS.
3002 context()->DropAndPlug(1, x0); 2990 context()->DropAndPlug(1, x0);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
3201 // TODO(jbramley): This could be much more efficient using (for 3189 // TODO(jbramley): This could be much more efficient using (for
3202 // example) the CSEL instruction. 3190 // example) the CSEL instruction.
3203 Label materialize_true, materialize_false, done; 3191 Label materialize_true, materialize_false, done;
3204 VisitForControl(expr->expression(), 3192 VisitForControl(expr->expression(),
3205 &materialize_false, 3193 &materialize_false,
3206 &materialize_true, 3194 &materialize_true,
3207 &materialize_true); 3195 &materialize_true);
3208 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3196 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3209 3197
3210 __ Bind(&materialize_true); 3198 __ Bind(&materialize_true);
3211 PrepareForBailoutForId(expr->MaterializeTrueId(), 3199 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3212 BailoutState::NO_REGISTERS);
3213 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); 3200 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
3214 __ B(&done); 3201 __ B(&done);
3215 3202
3216 __ Bind(&materialize_false); 3203 __ Bind(&materialize_false);
3217 PrepareForBailoutForId(expr->MaterializeFalseId(), 3204 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3218 BailoutState::NO_REGISTERS);
3219 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); 3205 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
3220 __ B(&done); 3206 __ B(&done);
3221 3207
3222 __ Bind(&done); 3208 __ Bind(&done);
3223 if (context()->IsStackValue()) { 3209 if (context()->IsStackValue()) {
3224 __ Push(result_register()); 3210 __ Push(result_register());
3225 } 3211 }
3226 } 3212 }
3227 break; 3213 break;
3228 } 3214 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3308 } 3294 }
3309 3295
3310 case VARIABLE: 3296 case VARIABLE:
3311 UNREACHABLE(); 3297 UNREACHABLE();
3312 } 3298 }
3313 } 3299 }
3314 3300
3315 // We need a second deoptimization point after loading the value 3301 // We need a second deoptimization point after loading the value
3316 // in case evaluating the property load my have a side effect. 3302 // in case evaluating the property load my have a side effect.
3317 if (assign_type == VARIABLE) { 3303 if (assign_type == VARIABLE) {
3318 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); 3304 PrepareForBailout(expr->expression(), TOS_REG);
3319 } else { 3305 } else {
3320 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); 3306 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
3321 } 3307 }
3322 3308
3323 // Inline smi case if we are in a loop. 3309 // Inline smi case if we are in a loop.
3324 Label stub_call, done; 3310 Label stub_call, done;
3325 JumpPatchSite patch_site(masm_); 3311 JumpPatchSite patch_site(masm_);
3326 3312
3327 int count_value = expr->op() == Token::INC ? 1 : -1; 3313 int count_value = expr->op() == Token::INC ? 1 : -1;
3328 if (ShouldInlineSmiCase(expr->op())) { 3314 if (ShouldInlineSmiCase(expr->op())) {
3329 Label slow; 3315 Label slow;
3330 patch_site.EmitJumpIfNotSmi(x0, &slow); 3316 patch_site.EmitJumpIfNotSmi(x0, &slow);
(...skipping 28 matching lines...) Expand all
3359 __ B(vc, &done); 3345 __ B(vc, &done);
3360 // Call stub. Undo operation first. 3346 // Call stub. Undo operation first.
3361 __ Sub(x0, x0, Smi::FromInt(count_value)); 3347 __ Sub(x0, x0, Smi::FromInt(count_value));
3362 __ B(&stub_call); 3348 __ B(&stub_call);
3363 __ Bind(&slow); 3349 __ Bind(&slow);
3364 } 3350 }
3365 3351
3366 // Convert old value into a number. 3352 // Convert old value into a number.
3367 ToNumberStub convert_stub(isolate()); 3353 ToNumberStub convert_stub(isolate());
3368 __ CallStub(&convert_stub); 3354 __ CallStub(&convert_stub);
3369 PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); 3355 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG);
3370 3356
3371 // Save result for postfix expressions. 3357 // Save result for postfix expressions.
3372 if (expr->is_postfix()) { 3358 if (expr->is_postfix()) {
3373 if (!context()->IsEffect()) { 3359 if (!context()->IsEffect()) {
3374 // Save the result on the stack. If we have a named or keyed property 3360 // Save the result on the stack. If we have a named or keyed property
3375 // we store the result under the receiver that is currently on top 3361 // we store the result under the receiver that is currently on top
3376 // of the stack. 3362 // of the stack.
3377 switch (assign_type) { 3363 switch (assign_type) {
3378 case VARIABLE: 3364 case VARIABLE:
3379 PushOperand(x0); 3365 PushOperand(x0);
(...skipping 28 matching lines...) Expand all
3408 } 3394 }
3409 __ Bind(&done); 3395 __ Bind(&done);
3410 3396
3411 // Store the value returned in x0. 3397 // Store the value returned in x0.
3412 switch (assign_type) { 3398 switch (assign_type) {
3413 case VARIABLE: 3399 case VARIABLE:
3414 if (expr->is_postfix()) { 3400 if (expr->is_postfix()) {
3415 { EffectContext context(this); 3401 { EffectContext context(this);
3416 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3402 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3417 Token::ASSIGN, expr->CountSlot()); 3403 Token::ASSIGN, expr->CountSlot());
3418 PrepareForBailoutForId(expr->AssignmentId(), 3404 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3419 BailoutState::TOS_REGISTER);
3420 context.Plug(x0); 3405 context.Plug(x0);
3421 } 3406 }
3422 // For all contexts except EffectConstant We have the result on 3407 // For all contexts except EffectConstant We have the result on
3423 // top of the stack. 3408 // top of the stack.
3424 if (!context()->IsEffect()) { 3409 if (!context()->IsEffect()) {
3425 context()->PlugTOS(); 3410 context()->PlugTOS();
3426 } 3411 }
3427 } else { 3412 } else {
3428 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3413 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3429 Token::ASSIGN, expr->CountSlot()); 3414 Token::ASSIGN, expr->CountSlot());
3430 PrepareForBailoutForId(expr->AssignmentId(), 3415 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3431 BailoutState::TOS_REGISTER);
3432 context()->Plug(x0); 3416 context()->Plug(x0);
3433 } 3417 }
3434 break; 3418 break;
3435 case NAMED_PROPERTY: { 3419 case NAMED_PROPERTY: {
3436 __ Mov(StoreDescriptor::NameRegister(), 3420 __ Mov(StoreDescriptor::NameRegister(),
3437 Operand(prop->key()->AsLiteral()->value())); 3421 Operand(prop->key()->AsLiteral()->value()));
3438 PopOperand(StoreDescriptor::ReceiverRegister()); 3422 PopOperand(StoreDescriptor::ReceiverRegister());
3439 EmitLoadStoreICSlot(expr->CountSlot()); 3423 EmitLoadStoreICSlot(expr->CountSlot());
3440 CallStoreIC(); 3424 CallStoreIC();
3441 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 3425 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3442 if (expr->is_postfix()) { 3426 if (expr->is_postfix()) {
3443 if (!context()->IsEffect()) { 3427 if (!context()->IsEffect()) {
3444 context()->PlugTOS(); 3428 context()->PlugTOS();
3445 } 3429 }
3446 } else { 3430 } else {
3447 context()->Plug(x0); 3431 context()->Plug(x0);
3448 } 3432 }
3449 break; 3433 break;
3450 } 3434 }
3451 case NAMED_SUPER_PROPERTY: { 3435 case NAMED_SUPER_PROPERTY: {
(...skipping 18 matching lines...) Expand all
3470 } 3454 }
3471 break; 3455 break;
3472 } 3456 }
3473 case KEYED_PROPERTY: { 3457 case KEYED_PROPERTY: {
3474 PopOperand(StoreDescriptor::NameRegister()); 3458 PopOperand(StoreDescriptor::NameRegister());
3475 PopOperand(StoreDescriptor::ReceiverRegister()); 3459 PopOperand(StoreDescriptor::ReceiverRegister());
3476 Handle<Code> ic = 3460 Handle<Code> ic =
3477 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3461 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3478 EmitLoadStoreICSlot(expr->CountSlot()); 3462 EmitLoadStoreICSlot(expr->CountSlot());
3479 CallIC(ic); 3463 CallIC(ic);
3480 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 3464 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3481 if (expr->is_postfix()) { 3465 if (expr->is_postfix()) {
3482 if (!context()->IsEffect()) { 3466 if (!context()->IsEffect()) {
3483 context()->PlugTOS(); 3467 context()->PlugTOS();
3484 } 3468 }
3485 } else { 3469 } else {
3486 context()->Plug(x0); 3470 context()->Plug(x0);
3487 } 3471 }
3488 break; 3472 break;
3489 } 3473 }
3490 } 3474 }
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
4007 } 3991 }
4008 3992
4009 return INTERRUPT; 3993 return INTERRUPT;
4010 } 3994 }
4011 3995
4012 3996
4013 } // namespace internal 3997 } // namespace internal
4014 } // namespace v8 3998 } // namespace v8
4015 3999
4016 #endif // V8_TARGET_ARCH_ARM64 4000 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/full-codegen/arm/full-codegen-arm.cc ('k') | src/full-codegen/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698