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

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

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