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

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: Fix typo on Arm64 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
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 Deoptimizer::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 Deoptimizer::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 Deoptimizer::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 Deoptimizer::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(),
401 Deoptimizer::BailoutState::NO_REGISTERS);
397 // Record a mapping of the OSR id to this PC. This is used if the OSR 402 // 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 403 // entry becomes the target of a bailout. We don't expect it to be, but
399 // we want it to work if it is. 404 // we want it to work if it is.
400 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 405 PrepareForBailoutForId(stmt->OsrEntryId(),
406 Deoptimizer::BailoutState::NO_REGISTERS);
401 } 407 }
402 408
403 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 409 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
404 bool is_tail_call) { 410 bool is_tail_call) {
405 // Pretend that the exit is a backwards jump to the entry. 411 // Pretend that the exit is a backwards jump to the entry.
406 int weight = 1; 412 int weight = 1;
407 if (info_->ShouldSelfOptimize()) { 413 if (info_->ShouldSelfOptimize()) {
408 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 414 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
409 } else { 415 } else {
410 int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2; 416 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 727 // Only prepare for bailouts before splits if we're in a test
722 // context. Otherwise, we let the Visit function deal with the 728 // context. Otherwise, we let the Visit function deal with the
723 // preparation to avoid preparing with the same AST id twice. 729 // preparation to avoid preparing with the same AST id twice.
724 if (!context()->IsTest()) return; 730 if (!context()->IsTest()) return;
725 731
726 // TODO(all): Investigate to see if there is something to work on here. 732 // TODO(all): Investigate to see if there is something to work on here.
727 Label skip; 733 Label skip;
728 if (should_normalize) { 734 if (should_normalize) {
729 __ B(&skip); 735 __ B(&skip);
730 } 736 }
731 PrepareForBailout(expr, TOS_REG); 737 PrepareForBailout(expr, Deoptimizer::BailoutState::TOS_REGISTER);
732 if (should_normalize) { 738 if (should_normalize) {
733 __ CompareRoot(x0, Heap::kTrueValueRootIndex); 739 __ CompareRoot(x0, Heap::kTrueValueRootIndex);
734 Split(eq, if_true, if_false, NULL); 740 Split(eq, if_true, if_false, NULL);
735 __ Bind(&skip); 741 __ Bind(&skip);
736 } 742 }
737 } 743 }
738 744
739 745
740 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 746 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
741 // The variable in the declaration always resides in the current function 747 // The variable in the declaration always resides in the current function
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 } 785 }
780 break; 786 break;
781 787
782 case VariableLocation::CONTEXT: 788 case VariableLocation::CONTEXT:
783 if (hole_init) { 789 if (hole_init) {
784 Comment cmnt(masm_, "[ VariableDeclaration"); 790 Comment cmnt(masm_, "[ VariableDeclaration");
785 EmitDebugCheckDeclarationContext(variable); 791 EmitDebugCheckDeclarationContext(variable);
786 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex); 792 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
787 __ Str(x10, ContextMemOperand(cp, variable->index())); 793 __ Str(x10, ContextMemOperand(cp, variable->index()));
788 // No write barrier since the_hole_value is in old space. 794 // No write barrier since the_hole_value is in old space.
789 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 795 PrepareForBailoutForId(proxy->id(),
796 Deoptimizer::BailoutState::NO_REGISTERS);
790 } 797 }
791 break; 798 break;
792 799
793 case VariableLocation::LOOKUP: { 800 case VariableLocation::LOOKUP: {
794 Comment cmnt(masm_, "[ VariableDeclaration"); 801 Comment cmnt(masm_, "[ VariableDeclaration");
795 __ Mov(x2, Operand(variable->name())); 802 __ Mov(x2, Operand(variable->name()));
796 // Declaration nodes are always introduced in one of four modes. 803 // Declaration nodes are always introduced in one of four modes.
797 DCHECK(IsDeclaredVariableMode(mode)); 804 DCHECK(IsDeclaredVariableMode(mode));
798 // Push initial value, if any. 805 // Push initial value, if any.
799 // Note: For variables we must not push an initial value (such as 806 // Note: For variables we must not push an initial value (such as
800 // 'undefined') because we may have a (legal) redeclaration and we 807 // 'undefined') because we may have a (legal) redeclaration and we
801 // must not destroy the current value. 808 // must not destroy the current value.
802 if (hole_init) { 809 if (hole_init) {
803 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex); 810 __ LoadRoot(x0, Heap::kTheHoleValueRootIndex);
804 __ Push(x2, x0); 811 __ Push(x2, x0);
805 } else { 812 } else {
806 // Pushing 0 (xzr) indicates no initial value. 813 // Pushing 0 (xzr) indicates no initial value.
807 __ Push(x2, xzr); 814 __ Push(x2, xzr);
808 } 815 }
809 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 816 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
810 __ CallRuntime(Runtime::kDeclareLookupSlot); 817 __ CallRuntime(Runtime::kDeclareLookupSlot);
811 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 818 PrepareForBailoutForId(proxy->id(),
819 Deoptimizer::BailoutState::NO_REGISTERS);
812 break; 820 break;
813 } 821 }
814 } 822 }
815 } 823 }
816 824
817 825
818 void FullCodeGenerator::VisitFunctionDeclaration( 826 void FullCodeGenerator::VisitFunctionDeclaration(
819 FunctionDeclaration* declaration) { 827 FunctionDeclaration* declaration) {
820 VariableProxy* proxy = declaration->proxy(); 828 VariableProxy* proxy = declaration->proxy();
821 Variable* variable = proxy->var(); 829 Variable* variable = proxy->var();
(...skipping 25 matching lines...) Expand all
847 int offset = Context::SlotOffset(variable->index()); 855 int offset = Context::SlotOffset(variable->index());
848 // We know that we have written a function, which is not a smi. 856 // We know that we have written a function, which is not a smi.
849 __ RecordWriteContextSlot(cp, 857 __ RecordWriteContextSlot(cp,
850 offset, 858 offset,
851 result_register(), 859 result_register(),
852 x2, 860 x2,
853 kLRHasBeenSaved, 861 kLRHasBeenSaved,
854 kDontSaveFPRegs, 862 kDontSaveFPRegs,
855 EMIT_REMEMBERED_SET, 863 EMIT_REMEMBERED_SET,
856 OMIT_SMI_CHECK); 864 OMIT_SMI_CHECK);
857 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 865 PrepareForBailoutForId(proxy->id(),
866 Deoptimizer::BailoutState::NO_REGISTERS);
858 break; 867 break;
859 } 868 }
860 869
861 case VariableLocation::LOOKUP: { 870 case VariableLocation::LOOKUP: {
862 Comment cmnt(masm_, "[ Function Declaration"); 871 Comment cmnt(masm_, "[ Function Declaration");
863 __ Mov(x2, Operand(variable->name())); 872 __ Mov(x2, Operand(variable->name()));
864 PushOperand(x2); 873 PushOperand(x2);
865 // Push initial value for function declaration. 874 // Push initial value for function declaration.
866 VisitForStackValue(declaration->fun()); 875 VisitForStackValue(declaration->fun());
867 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 876 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
868 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 877 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
869 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 878 PrepareForBailoutForId(proxy->id(),
879 Deoptimizer::BailoutState::NO_REGISTERS);
870 break; 880 break;
871 } 881 }
872 } 882 }
873 } 883 }
874 884
875 885
876 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 886 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
877 // Call the runtime to declare the globals. 887 // Call the runtime to declare the globals.
878 __ Mov(x11, Operand(pairs)); 888 __ Mov(x11, Operand(pairs));
879 Register flags = xzr; 889 Register flags = xzr;
(...skipping 16 matching lines...) Expand all
896 906
897 907
898 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 908 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
899 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement"); 909 ASM_LOCATION("FullCodeGenerator::VisitSwitchStatement");
900 Comment cmnt(masm_, "[ SwitchStatement"); 910 Comment cmnt(masm_, "[ SwitchStatement");
901 Breakable nested_statement(this, stmt); 911 Breakable nested_statement(this, stmt);
902 SetStatementPosition(stmt); 912 SetStatementPosition(stmt);
903 913
904 // Keep the switch value on the stack until a case matches. 914 // Keep the switch value on the stack until a case matches.
905 VisitForStackValue(stmt->tag()); 915 VisitForStackValue(stmt->tag());
906 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 916 PrepareForBailoutForId(stmt->EntryId(),
917 Deoptimizer::BailoutState::NO_REGISTERS);
907 918
908 ZoneList<CaseClause*>* clauses = stmt->cases(); 919 ZoneList<CaseClause*>* clauses = stmt->cases();
909 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 920 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
910 921
911 Label next_test; // Recycled for each test. 922 Label next_test; // Recycled for each test.
912 // Compile all the tests with branches to their bodies. 923 // Compile all the tests with branches to their bodies.
913 for (int i = 0; i < clauses->length(); i++) { 924 for (int i = 0; i < clauses->length(); i++) {
914 CaseClause* clause = clauses->at(i); 925 CaseClause* clause = clauses->at(i);
915 clause->body_target()->Unuse(); 926 clause->body_target()->Unuse();
916 927
(...skipping 26 matching lines...) Expand all
943 954
944 // Record position before stub call for type feedback. 955 // Record position before stub call for type feedback.
945 SetExpressionPosition(clause); 956 SetExpressionPosition(clause);
946 Handle<Code> ic = 957 Handle<Code> ic =
947 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 958 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
948 CallIC(ic, clause->CompareId()); 959 CallIC(ic, clause->CompareId());
949 patch_site.EmitPatchInfo(); 960 patch_site.EmitPatchInfo();
950 961
951 Label skip; 962 Label skip;
952 __ B(&skip); 963 __ B(&skip);
953 PrepareForBailout(clause, TOS_REG); 964 PrepareForBailout(clause, Deoptimizer::BailoutState::TOS_REGISTER);
954 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); 965 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test);
955 __ Drop(1); 966 __ Drop(1);
956 __ B(clause->body_target()); 967 __ B(clause->body_target());
957 __ Bind(&skip); 968 __ Bind(&skip);
958 969
959 __ Cbnz(x0, &next_test); 970 __ Cbnz(x0, &next_test);
960 __ Drop(1); // Switch value is no longer needed. 971 __ Drop(1); // Switch value is no longer needed.
961 __ B(clause->body_target()); 972 __ B(clause->body_target());
962 } 973 }
963 974
964 // Discard the test value and jump to the default if present, otherwise to 975 // Discard the test value and jump to the default if present, otherwise to
965 // the end of the statement. 976 // the end of the statement.
966 __ Bind(&next_test); 977 __ Bind(&next_test);
967 DropOperands(1); // Switch value is no longer needed. 978 DropOperands(1); // Switch value is no longer needed.
968 if (default_clause == NULL) { 979 if (default_clause == NULL) {
969 __ B(nested_statement.break_label()); 980 __ B(nested_statement.break_label());
970 } else { 981 } else {
971 __ B(default_clause->body_target()); 982 __ B(default_clause->body_target());
972 } 983 }
973 984
974 // Compile all the case bodies. 985 // Compile all the case bodies.
975 for (int i = 0; i < clauses->length(); i++) { 986 for (int i = 0; i < clauses->length(); i++) {
976 Comment cmnt(masm_, "[ Case body"); 987 Comment cmnt(masm_, "[ Case body");
977 CaseClause* clause = clauses->at(i); 988 CaseClause* clause = clauses->at(i);
978 __ Bind(clause->body_target()); 989 __ Bind(clause->body_target());
979 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 990 PrepareForBailoutForId(clause->EntryId(),
991 Deoptimizer::BailoutState::NO_REGISTERS);
980 VisitStatements(clause->statements()); 992 VisitStatements(clause->statements());
981 } 993 }
982 994
983 __ Bind(nested_statement.break_label()); 995 __ Bind(nested_statement.break_label());
984 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 996 PrepareForBailoutForId(stmt->ExitId(),
997 Deoptimizer::BailoutState::NO_REGISTERS);
985 } 998 }
986 999
987 1000
988 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1001 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
989 ASM_LOCATION("FullCodeGenerator::VisitForInStatement"); 1002 ASM_LOCATION("FullCodeGenerator::VisitForInStatement");
990 Comment cmnt(masm_, "[ ForInStatement"); 1003 Comment cmnt(masm_, "[ ForInStatement");
991 SetStatementPosition(stmt, SKIP_BREAK); 1004 SetStatementPosition(stmt, SKIP_BREAK);
992 1005
993 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 1006 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
994 1007
(...skipping 12 matching lines...) Expand all
1007 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. 1020 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4.
1008 Label convert, done_convert; 1021 Label convert, done_convert;
1009 __ JumpIfSmi(x0, &convert); 1022 __ JumpIfSmi(x0, &convert);
1010 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge); 1023 __ JumpIfObjectType(x0, x10, x11, FIRST_JS_RECEIVER_TYPE, &done_convert, ge);
1011 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit); 1024 __ JumpIfRoot(x0, Heap::kNullValueRootIndex, &exit);
1012 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); 1025 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit);
1013 __ Bind(&convert); 1026 __ Bind(&convert);
1014 ToObjectStub stub(isolate()); 1027 ToObjectStub stub(isolate());
1015 __ CallStub(&stub); 1028 __ CallStub(&stub);
1016 __ Bind(&done_convert); 1029 __ Bind(&done_convert);
1017 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); 1030 PrepareForBailoutForId(stmt->ToObjectId(),
1031 Deoptimizer::BailoutState::TOS_REGISTER);
1018 __ Push(x0); 1032 __ Push(x0);
1019 1033
1020 // Check cache validity in generated code. If we cannot guarantee cache 1034 // Check cache validity in generated code. If we cannot guarantee cache
1021 // validity, call the runtime system to check cache validity or get the 1035 // 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, 1036 // property names in a fixed array. Note: Proxies never have an enum cache,
1023 // so will always take the slow path. 1037 // so will always take the slow path.
1024 Label call_runtime; 1038 Label call_runtime;
1025 __ CheckEnumCache(x0, x15, x10, x11, x12, x13, &call_runtime); 1039 __ CheckEnumCache(x0, x15, x10, x11, x12, x13, &call_runtime);
1026 1040
1027 // The enum cache is valid. Load the map of the object being 1041 // The enum cache is valid. Load the map of the object being
1028 // iterated over and use the cache for the iteration. 1042 // iterated over and use the cache for the iteration.
1029 Label use_cache; 1043 Label use_cache;
1030 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset)); 1044 __ Ldr(x0, FieldMemOperand(x0, HeapObject::kMapOffset));
1031 __ B(&use_cache); 1045 __ B(&use_cache);
1032 1046
1033 // Get the set of properties to enumerate. 1047 // Get the set of properties to enumerate.
1034 __ Bind(&call_runtime); 1048 __ Bind(&call_runtime);
1035 __ Push(x0); // Duplicate the enumerable object on the stack. 1049 __ Push(x0); // Duplicate the enumerable object on the stack.
1036 __ CallRuntime(Runtime::kForInEnumerate); 1050 __ CallRuntime(Runtime::kForInEnumerate);
1037 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1051 PrepareForBailoutForId(stmt->EnumId(),
1052 Deoptimizer::BailoutState::TOS_REGISTER);
1038 1053
1039 // If we got a map from the runtime call, we can do a fast 1054 // 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 1055 // modification check. Otherwise, we got a fixed array, and we have
1041 // to do a slow check. 1056 // to do a slow check.
1042 Label fixed_array, no_descriptors; 1057 Label fixed_array, no_descriptors;
1043 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset)); 1058 __ Ldr(x2, FieldMemOperand(x0, HeapObject::kMapOffset));
1044 __ JumpIfNotRoot(x2, Heap::kMetaMapRootIndex, &fixed_array); 1059 __ JumpIfNotRoot(x2, Heap::kMetaMapRootIndex, &fixed_array);
1045 1060
1046 // We got a map in register x0. Get the enumeration cache from it. 1061 // We got a map in register x0. Get the enumeration cache from it.
1047 __ Bind(&use_cache); 1062 __ Bind(&use_cache);
(...skipping 15 matching lines...) Expand all
1063 __ Bind(&no_descriptors); 1078 __ Bind(&no_descriptors);
1064 __ Drop(1); 1079 __ Drop(1);
1065 __ B(&exit); 1080 __ B(&exit);
1066 1081
1067 // We got a fixed array in register x0. Iterate through that. 1082 // We got a fixed array in register x0. Iterate through that.
1068 __ Bind(&fixed_array); 1083 __ Bind(&fixed_array);
1069 1084
1070 __ Mov(x1, Smi::FromInt(1)); // Smi(1) indicates slow check. 1085 __ Mov(x1, Smi::FromInt(1)); // Smi(1) indicates slow check.
1071 __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset)); 1086 __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset));
1072 __ Push(x1, x0, x2); // Smi and array, fixed array length (as smi). 1087 __ Push(x1, x0, x2); // Smi and array, fixed array length (as smi).
1073 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); 1088 PrepareForBailoutForId(stmt->PrepareId(),
1089 Deoptimizer::BailoutState::NO_REGISTERS);
1074 __ Push(xzr); // Initial index. 1090 __ Push(xzr); // Initial index.
1075 1091
1076 // Generate code for doing the condition check. 1092 // Generate code for doing the condition check.
1077 __ Bind(&loop); 1093 __ Bind(&loop);
1078 SetExpressionAsStatementPosition(stmt->each()); 1094 SetExpressionAsStatementPosition(stmt->each());
1079 1095
1080 // Load the current count to x0, load the length to x1. 1096 // Load the current count to x0, load the length to x1.
1081 __ PeekPair(x0, x1, 0); 1097 __ PeekPair(x0, x1, 0);
1082 __ Cmp(x0, x1); // Compare to the array length. 1098 __ Cmp(x0, x1); // Compare to the array length.
1083 __ B(hs, loop_statement.break_label()); 1099 __ B(hs, loop_statement.break_label());
(...skipping 19 matching lines...) Expand all
1103 int const vector_index = SmiFromSlot(slot)->value(); 1119 int const vector_index = SmiFromSlot(slot)->value();
1104 __ EmitLoadTypeFeedbackVector(x0); 1120 __ EmitLoadTypeFeedbackVector(x0);
1105 __ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1121 __ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1106 __ Str(x10, FieldMemOperand(x0, FixedArray::OffsetOfElementAt(vector_index))); 1122 __ Str(x10, FieldMemOperand(x0, FixedArray::OffsetOfElementAt(vector_index)));
1107 1123
1108 // Convert the entry to a string or (smi) 0 if it isn't a property 1124 // 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 1125 // any more. If the property has been removed while iterating, we
1110 // just skip it. 1126 // just skip it.
1111 __ Push(x1, x3); 1127 __ Push(x1, x3);
1112 __ CallRuntime(Runtime::kForInFilter); 1128 __ CallRuntime(Runtime::kForInFilter);
1113 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1129 PrepareForBailoutForId(stmt->FilterId(),
1130 Deoptimizer::BailoutState::TOS_REGISTER);
1114 __ Mov(x3, x0); 1131 __ Mov(x3, x0);
1115 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, 1132 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex,
1116 loop_statement.continue_label()); 1133 loop_statement.continue_label());
1117 1134
1118 // Update the 'each' property or variable from the possibly filtered 1135 // Update the 'each' property or variable from the possibly filtered
1119 // entry in register x3. 1136 // entry in register x3.
1120 __ Bind(&update_each); 1137 __ Bind(&update_each);
1121 __ Mov(result_register(), x3); 1138 __ Mov(result_register(), x3);
1122 // Perform the assignment as if via '='. 1139 // Perform the assignment as if via '='.
1123 { EffectContext context(this); 1140 { EffectContext context(this);
1124 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1141 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1125 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1142 PrepareForBailoutForId(stmt->AssignmentId(),
1143 Deoptimizer::BailoutState::NO_REGISTERS);
1126 } 1144 }
1127 1145
1128 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1146 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1129 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1147 PrepareForBailoutForId(stmt->BodyId(),
1148 Deoptimizer::BailoutState::NO_REGISTERS);
1130 // Generate code for the body of the loop. 1149 // Generate code for the body of the loop.
1131 Visit(stmt->body()); 1150 Visit(stmt->body());
1132 1151
1133 // Generate code for going to the next element by incrementing 1152 // Generate code for going to the next element by incrementing
1134 // the index (smi) stored on top of the stack. 1153 // the index (smi) stored on top of the stack.
1135 __ Bind(loop_statement.continue_label()); 1154 __ Bind(loop_statement.continue_label());
1136 // TODO(all): We could use a callee saved register to avoid popping. 1155 // TODO(all): We could use a callee saved register to avoid popping.
1137 __ Pop(x0); 1156 __ Pop(x0);
1138 __ Add(x0, x0, Smi::FromInt(1)); 1157 __ Add(x0, x0, Smi::FromInt(1));
1139 __ Push(x0); 1158 __ Push(x0);
1140 1159
1141 EmitBackEdgeBookkeeping(stmt, &loop); 1160 EmitBackEdgeBookkeeping(stmt, &loop);
1142 __ B(&loop); 1161 __ B(&loop);
1143 1162
1144 // Remove the pointers stored on the stack. 1163 // Remove the pointers stored on the stack.
1145 __ Bind(loop_statement.break_label()); 1164 __ Bind(loop_statement.break_label());
1146 DropOperands(5); 1165 DropOperands(5);
1147 1166
1148 // Exit and decrement the loop depth. 1167 // Exit and decrement the loop depth.
1149 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1168 PrepareForBailoutForId(stmt->ExitId(),
1169 Deoptimizer::BailoutState::NO_REGISTERS);
1150 __ Bind(&exit); 1170 __ Bind(&exit);
1151 decrement_loop_depth(); 1171 decrement_loop_depth();
1152 } 1172 }
1153 1173
1154 1174
1155 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1175 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1156 FeedbackVectorSlot slot) { 1176 FeedbackVectorSlot slot) {
1157 DCHECK(NeedsHomeObject(initializer)); 1177 DCHECK(NeedsHomeObject(initializer));
1158 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1178 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1159 __ Mov(StoreDescriptor::NameRegister(), 1179 __ Mov(StoreDescriptor::NameRegister(),
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 __ Mov(LoadDescriptor::SlotRegister(), 1312 __ Mov(LoadDescriptor::SlotRegister(),
1293 SmiFromSlot(proxy->VariableFeedbackSlot())); 1313 SmiFromSlot(proxy->VariableFeedbackSlot()));
1294 CallLoadIC(typeof_mode); 1314 CallLoadIC(typeof_mode);
1295 } 1315 }
1296 1316
1297 1317
1298 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1318 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1299 TypeofMode typeof_mode) { 1319 TypeofMode typeof_mode) {
1300 // Record position before possible IC call. 1320 // Record position before possible IC call.
1301 SetExpressionPosition(proxy); 1321 SetExpressionPosition(proxy);
1302 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1322 PrepareForBailoutForId(proxy->BeforeId(),
1323 Deoptimizer::BailoutState::NO_REGISTERS);
1303 Variable* var = proxy->var(); 1324 Variable* var = proxy->var();
1304 1325
1305 // Three cases: global variables, lookup variables, and all other types of 1326 // Three cases: global variables, lookup variables, and all other types of
1306 // variables. 1327 // variables.
1307 switch (var->location()) { 1328 switch (var->location()) {
1308 case VariableLocation::GLOBAL: 1329 case VariableLocation::GLOBAL:
1309 case VariableLocation::UNALLOCATED: { 1330 case VariableLocation::UNALLOCATED: {
1310 Comment cmnt(masm_, "Global variable"); 1331 Comment cmnt(masm_, "Global variable");
1311 EmitGlobalVariableLoad(proxy, typeof_mode); 1332 EmitGlobalVariableLoad(proxy, typeof_mode);
1312 context()->Plug(x0); 1333 context()->Plug(x0);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 int flags = expr->ComputeFlags(); 1421 int flags = expr->ComputeFlags();
1401 __ Mov(x0, Smi::FromInt(flags)); 1422 __ Mov(x0, Smi::FromInt(flags));
1402 if (MustCreateObjectLiteralWithRuntime(expr)) { 1423 if (MustCreateObjectLiteralWithRuntime(expr)) {
1403 __ Push(x3, x2, x1, x0); 1424 __ Push(x3, x2, x1, x0);
1404 __ CallRuntime(Runtime::kCreateObjectLiteral); 1425 __ CallRuntime(Runtime::kCreateObjectLiteral);
1405 } else { 1426 } else {
1406 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1427 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1407 __ CallStub(&stub); 1428 __ CallStub(&stub);
1408 RestoreContext(); 1429 RestoreContext();
1409 } 1430 }
1410 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1431 PrepareForBailoutForId(expr->CreateLiteralId(),
1432 Deoptimizer::BailoutState::TOS_REGISTER);
1411 1433
1412 // If result_saved is true the result is on top of the stack. If 1434 // If result_saved is true the result is on top of the stack. If
1413 // result_saved is false the result is in x0. 1435 // result_saved is false the result is in x0.
1414 bool result_saved = false; 1436 bool result_saved = false;
1415 1437
1416 AccessorTable accessor_table(zone()); 1438 AccessorTable accessor_table(zone());
1417 int property_index = 0; 1439 int property_index = 0;
1418 for (; property_index < expr->properties()->length(); property_index++) { 1440 for (; property_index < expr->properties()->length(); property_index++) {
1419 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1441 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1420 if (property->is_computed_name()) break; 1442 if (property->is_computed_name()) break;
(...skipping 15 matching lines...) Expand all
1436 // It is safe to use [[Put]] here because the boilerplate already 1458 // It is safe to use [[Put]] here because the boilerplate already
1437 // contains computed properties with an uninitialized value. 1459 // contains computed properties with an uninitialized value.
1438 if (key->value()->IsInternalizedString()) { 1460 if (key->value()->IsInternalizedString()) {
1439 if (property->emit_store()) { 1461 if (property->emit_store()) {
1440 VisitForAccumulatorValue(value); 1462 VisitForAccumulatorValue(value);
1441 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 1463 DCHECK(StoreDescriptor::ValueRegister().is(x0));
1442 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); 1464 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1443 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1465 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1444 EmitLoadStoreICSlot(property->GetSlot(0)); 1466 EmitLoadStoreICSlot(property->GetSlot(0));
1445 CallStoreIC(); 1467 CallStoreIC();
1446 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1468 PrepareForBailoutForId(key->id(),
1469 Deoptimizer::BailoutState::NO_REGISTERS);
1447 1470
1448 if (NeedsHomeObject(value)) { 1471 if (NeedsHomeObject(value)) {
1449 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1472 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1450 } 1473 }
1451 } else { 1474 } else {
1452 VisitForEffect(value); 1475 VisitForEffect(value);
1453 } 1476 }
1454 break; 1477 break;
1455 } 1478 }
1456 __ Peek(x0, 0); 1479 __ Peek(x0, 0);
(...skipping 12 matching lines...) Expand all
1469 } 1492 }
1470 break; 1493 break;
1471 case ObjectLiteral::Property::PROTOTYPE: 1494 case ObjectLiteral::Property::PROTOTYPE:
1472 DCHECK(property->emit_store()); 1495 DCHECK(property->emit_store());
1473 // Duplicate receiver on stack. 1496 // Duplicate receiver on stack.
1474 __ Peek(x0, 0); 1497 __ Peek(x0, 0);
1475 PushOperand(x0); 1498 PushOperand(x0);
1476 VisitForStackValue(value); 1499 VisitForStackValue(value);
1477 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1500 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1478 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1501 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1479 NO_REGISTERS); 1502 Deoptimizer::BailoutState::NO_REGISTERS);
1480 break; 1503 break;
1481 case ObjectLiteral::Property::GETTER: 1504 case ObjectLiteral::Property::GETTER:
1482 if (property->emit_store()) { 1505 if (property->emit_store()) {
1483 accessor_table.lookup(key)->second->getter = property; 1506 accessor_table.lookup(key)->second->getter = property;
1484 } 1507 }
1485 break; 1508 break;
1486 case ObjectLiteral::Property::SETTER: 1509 case ObjectLiteral::Property::SETTER:
1487 if (property->emit_store()) { 1510 if (property->emit_store()) {
1488 accessor_table.lookup(key)->second->setter = property; 1511 accessor_table.lookup(key)->second->setter = property;
1489 } 1512 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 1549
1527 __ Peek(x10, 0); // Duplicate receiver. 1550 __ Peek(x10, 0); // Duplicate receiver.
1528 PushOperand(x10); 1551 PushOperand(x10);
1529 1552
1530 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1553 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1531 DCHECK(!property->is_computed_name()); 1554 DCHECK(!property->is_computed_name());
1532 VisitForStackValue(value); 1555 VisitForStackValue(value);
1533 DCHECK(property->emit_store()); 1556 DCHECK(property->emit_store());
1534 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1557 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1535 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1558 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1536 NO_REGISTERS); 1559 Deoptimizer::BailoutState::NO_REGISTERS);
1537 } else { 1560 } else {
1538 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1561 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1539 VisitForStackValue(value); 1562 VisitForStackValue(value);
1540 if (NeedsHomeObject(value)) { 1563 if (NeedsHomeObject(value)) {
1541 EmitSetHomeObject(value, 2, property->GetSlot()); 1564 EmitSetHomeObject(value, 2, property->GetSlot());
1542 } 1565 }
1543 1566
1544 switch (property->kind()) { 1567 switch (property->kind()) {
1545 case ObjectLiteral::Property::CONSTANT: 1568 case ObjectLiteral::Property::CONSTANT:
1546 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1569 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())); 1620 __ Mov(x2, Smi::FromInt(expr->literal_index()));
1598 __ Mov(x1, Operand(constant_elements)); 1621 __ Mov(x1, Operand(constant_elements));
1599 if (MustCreateArrayLiteralWithRuntime(expr)) { 1622 if (MustCreateArrayLiteralWithRuntime(expr)) {
1600 __ Mov(x0, Smi::FromInt(expr->ComputeFlags())); 1623 __ Mov(x0, Smi::FromInt(expr->ComputeFlags()));
1601 __ Push(x3, x2, x1, x0); 1624 __ Push(x3, x2, x1, x0);
1602 __ CallRuntime(Runtime::kCreateArrayLiteral); 1625 __ CallRuntime(Runtime::kCreateArrayLiteral);
1603 } else { 1626 } else {
1604 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1627 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1605 __ CallStub(&stub); 1628 __ CallStub(&stub);
1606 } 1629 }
1607 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1630 PrepareForBailoutForId(expr->CreateLiteralId(),
1631 Deoptimizer::BailoutState::TOS_REGISTER);
1608 1632
1609 bool result_saved = false; // Is the result saved to the stack? 1633 bool result_saved = false; // Is the result saved to the stack?
1610 ZoneList<Expression*>* subexprs = expr->values(); 1634 ZoneList<Expression*>* subexprs = expr->values();
1611 int length = subexprs->length(); 1635 int length = subexprs->length();
1612 1636
1613 // Emit code to evaluate all the non-constant subexpressions and to store 1637 // Emit code to evaluate all the non-constant subexpressions and to store
1614 // them into the newly cloned array. 1638 // them into the newly cloned array.
1615 int array_index = 0; 1639 int array_index = 0;
1616 for (; array_index < length; array_index++) { 1640 for (; array_index < length; array_index++) {
1617 Expression* subexpr = subexprs->at(array_index); 1641 Expression* subexpr = subexprs->at(array_index);
1618 DCHECK(!subexpr->IsSpread()); 1642 DCHECK(!subexpr->IsSpread());
1619 1643
1620 // If the subexpression is a literal or a simple materialized literal it 1644 // If the subexpression is a literal or a simple materialized literal it
1621 // is already set in the cloned array. 1645 // is already set in the cloned array.
1622 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1646 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1623 1647
1624 if (!result_saved) { 1648 if (!result_saved) {
1625 PushOperand(x0); 1649 PushOperand(x0);
1626 result_saved = true; 1650 result_saved = true;
1627 } 1651 }
1628 VisitForAccumulatorValue(subexpr); 1652 VisitForAccumulatorValue(subexpr);
1629 1653
1630 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index)); 1654 __ Mov(StoreDescriptor::NameRegister(), Smi::FromInt(array_index));
1631 __ Peek(StoreDescriptor::ReceiverRegister(), 0); 1655 __ Peek(StoreDescriptor::ReceiverRegister(), 0);
1632 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1656 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1633 Handle<Code> ic = 1657 Handle<Code> ic =
1634 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1658 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1635 CallIC(ic); 1659 CallIC(ic);
1636 1660
1637 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1661 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1662 Deoptimizer::BailoutState::NO_REGISTERS);
1638 } 1663 }
1639 1664
1640 // In case the array literal contains spread expressions it has two parts. The 1665 // 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 1666 // 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 1667 // 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 1668 // (inclusive) and these elements gets appended to the array. Note that the
1644 // number elements an iterable produces is unknown ahead of time. 1669 // number elements an iterable produces is unknown ahead of time.
1645 if (array_index < length && result_saved) { 1670 if (array_index < length && result_saved) {
1646 PopOperand(x0); 1671 PopOperand(x0);
1647 result_saved = false; 1672 result_saved = false;
1648 } 1673 }
1649 for (; array_index < length; array_index++) { 1674 for (; array_index < length; array_index++) {
1650 Expression* subexpr = subexprs->at(array_index); 1675 Expression* subexpr = subexprs->at(array_index);
1651 1676
1652 PushOperand(x0); 1677 PushOperand(x0);
1653 DCHECK(!subexpr->IsSpread()); 1678 DCHECK(!subexpr->IsSpread());
1654 VisitForStackValue(subexpr); 1679 VisitForStackValue(subexpr);
1655 CallRuntimeWithOperands(Runtime::kAppendElement); 1680 CallRuntimeWithOperands(Runtime::kAppendElement);
1656 1681
1657 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1682 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1683 Deoptimizer::BailoutState::NO_REGISTERS);
1658 } 1684 }
1659 1685
1660 if (result_saved) { 1686 if (result_saved) {
1661 context()->PlugTOS(); 1687 context()->PlugTOS();
1662 } else { 1688 } else {
1663 context()->Plug(x0); 1689 context()->Plug(x0);
1664 } 1690 }
1665 } 1691 }
1666 1692
1667 1693
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 break; 1753 break;
1728 } 1754 }
1729 1755
1730 // For compound assignments we need another deoptimization point after the 1756 // For compound assignments we need another deoptimization point after the
1731 // variable/property load. 1757 // variable/property load.
1732 if (expr->is_compound()) { 1758 if (expr->is_compound()) {
1733 { AccumulatorValueContext context(this); 1759 { AccumulatorValueContext context(this);
1734 switch (assign_type) { 1760 switch (assign_type) {
1735 case VARIABLE: 1761 case VARIABLE:
1736 EmitVariableLoad(expr->target()->AsVariableProxy()); 1762 EmitVariableLoad(expr->target()->AsVariableProxy());
1737 PrepareForBailout(expr->target(), TOS_REG); 1763 PrepareForBailout(expr->target(),
1764 Deoptimizer::BailoutState::TOS_REGISTER);
1738 break; 1765 break;
1739 case NAMED_PROPERTY: 1766 case NAMED_PROPERTY:
1740 EmitNamedPropertyLoad(property); 1767 EmitNamedPropertyLoad(property);
1741 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1768 PrepareForBailoutForId(property->LoadId(),
1769 Deoptimizer::BailoutState::TOS_REGISTER);
1742 break; 1770 break;
1743 case NAMED_SUPER_PROPERTY: 1771 case NAMED_SUPER_PROPERTY:
1744 EmitNamedSuperPropertyLoad(property); 1772 EmitNamedSuperPropertyLoad(property);
1745 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1773 PrepareForBailoutForId(property->LoadId(),
1774 Deoptimizer::BailoutState::TOS_REGISTER);
1746 break; 1775 break;
1747 case KEYED_SUPER_PROPERTY: 1776 case KEYED_SUPER_PROPERTY:
1748 EmitKeyedSuperPropertyLoad(property); 1777 EmitKeyedSuperPropertyLoad(property);
1749 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1778 PrepareForBailoutForId(property->LoadId(),
1779 Deoptimizer::BailoutState::TOS_REGISTER);
1750 break; 1780 break;
1751 case KEYED_PROPERTY: 1781 case KEYED_PROPERTY:
1752 EmitKeyedPropertyLoad(property); 1782 EmitKeyedPropertyLoad(property);
1753 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1783 PrepareForBailoutForId(property->LoadId(),
1784 Deoptimizer::BailoutState::TOS_REGISTER);
1754 break; 1785 break;
1755 } 1786 }
1756 } 1787 }
1757 1788
1758 Token::Value op = expr->binary_op(); 1789 Token::Value op = expr->binary_op();
1759 PushOperand(x0); // Left operand goes on the stack. 1790 PushOperand(x0); // Left operand goes on the stack.
1760 VisitForAccumulatorValue(expr->value()); 1791 VisitForAccumulatorValue(expr->value());
1761 1792
1762 AccumulatorValueContext context(this); 1793 AccumulatorValueContext context(this);
1763 if (ShouldInlineSmiCase(op)) { 1794 if (ShouldInlineSmiCase(op)) {
1764 EmitInlineSmiBinaryOp(expr->binary_operation(), 1795 EmitInlineSmiBinaryOp(expr->binary_operation(),
1765 op, 1796 op,
1766 expr->target(), 1797 expr->target(),
1767 expr->value()); 1798 expr->value());
1768 } else { 1799 } else {
1769 EmitBinaryOp(expr->binary_operation(), op); 1800 EmitBinaryOp(expr->binary_operation(), op);
1770 } 1801 }
1771 1802
1772 // Deoptimization point in case the binary operation may have side effects. 1803 // Deoptimization point in case the binary operation may have side effects.
1773 PrepareForBailout(expr->binary_operation(), TOS_REG); 1804 PrepareForBailout(expr->binary_operation(),
1805 Deoptimizer::BailoutState::TOS_REGISTER);
1774 } else { 1806 } else {
1775 VisitForAccumulatorValue(expr->value()); 1807 VisitForAccumulatorValue(expr->value());
1776 } 1808 }
1777 1809
1778 SetExpressionPosition(expr); 1810 SetExpressionPosition(expr);
1779 1811
1780 // Store the value. 1812 // Store the value.
1781 switch (assign_type) { 1813 switch (assign_type) {
1782 case VARIABLE: 1814 case VARIABLE:
1783 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1815 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1784 expr->op(), expr->AssignmentSlot()); 1816 expr->op(), expr->AssignmentSlot());
1785 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1817 PrepareForBailoutForId(expr->AssignmentId(),
1818 Deoptimizer::BailoutState::TOS_REGISTER);
1786 context()->Plug(x0); 1819 context()->Plug(x0);
1787 break; 1820 break;
1788 case NAMED_PROPERTY: 1821 case NAMED_PROPERTY:
1789 EmitNamedPropertyAssignment(expr); 1822 EmitNamedPropertyAssignment(expr);
1790 break; 1823 break;
1791 case NAMED_SUPER_PROPERTY: 1824 case NAMED_SUPER_PROPERTY:
1792 EmitNamedSuperPropertyStore(property); 1825 EmitNamedSuperPropertyStore(property);
1793 context()->Plug(x0); 1826 context()->Plug(x0);
1794 break; 1827 break;
1795 case KEYED_SUPER_PROPERTY: 1828 case KEYED_SUPER_PROPERTY:
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 Property* prop = expr->target()->AsProperty(); 2188 Property* prop = expr->target()->AsProperty();
2156 DCHECK(prop != NULL); 2189 DCHECK(prop != NULL);
2157 DCHECK(prop->key()->IsLiteral()); 2190 DCHECK(prop->key()->IsLiteral());
2158 2191
2159 __ Mov(StoreDescriptor::NameRegister(), 2192 __ Mov(StoreDescriptor::NameRegister(),
2160 Operand(prop->key()->AsLiteral()->value())); 2193 Operand(prop->key()->AsLiteral()->value()));
2161 PopOperand(StoreDescriptor::ReceiverRegister()); 2194 PopOperand(StoreDescriptor::ReceiverRegister());
2162 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2195 EmitLoadStoreICSlot(expr->AssignmentSlot());
2163 CallStoreIC(); 2196 CallStoreIC();
2164 2197
2165 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2198 PrepareForBailoutForId(expr->AssignmentId(),
2199 Deoptimizer::BailoutState::TOS_REGISTER);
2166 context()->Plug(x0); 2200 context()->Plug(x0);
2167 } 2201 }
2168 2202
2169 2203
2170 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2204 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2171 // Assignment to named property of super. 2205 // Assignment to named property of super.
2172 // x0 : value 2206 // x0 : value
2173 // stack : receiver ('this'), home_object 2207 // stack : receiver ('this'), home_object
2174 DCHECK(prop != NULL); 2208 DCHECK(prop != NULL);
2175 Literal* key = prop->key()->AsLiteral(); 2209 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? 2237 // TODO(all): Could we pass this in registers rather than on the stack?
2204 PopOperands(StoreDescriptor::NameRegister(), 2238 PopOperands(StoreDescriptor::NameRegister(),
2205 StoreDescriptor::ReceiverRegister()); 2239 StoreDescriptor::ReceiverRegister());
2206 DCHECK(StoreDescriptor::ValueRegister().is(x0)); 2240 DCHECK(StoreDescriptor::ValueRegister().is(x0));
2207 2241
2208 Handle<Code> ic = 2242 Handle<Code> ic =
2209 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2243 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2210 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2244 EmitLoadStoreICSlot(expr->AssignmentSlot());
2211 CallIC(ic); 2245 CallIC(ic);
2212 2246
2213 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2247 PrepareForBailoutForId(expr->AssignmentId(),
2248 Deoptimizer::BailoutState::TOS_REGISTER);
2214 context()->Plug(x0); 2249 context()->Plug(x0);
2215 } 2250 }
2216 2251
2217 2252
2218 void FullCodeGenerator::CallIC(Handle<Code> code, 2253 void FullCodeGenerator::CallIC(Handle<Code> code,
2219 TypeFeedbackId ast_id) { 2254 TypeFeedbackId ast_id) {
2220 ic_total_count_++; 2255 ic_total_count_++;
2221 // All calls must have a predictable size in full-codegen code to ensure that 2256 // All calls must have a predictable size in full-codegen code to ensure that
2222 // the debugger can patch them correctly. 2257 // the debugger can patch them correctly.
2223 __ Call(code, RelocInfo::CODE_TARGET, ast_id); 2258 __ Call(code, RelocInfo::CODE_TARGET, ast_id);
2224 } 2259 }
2225 2260
2226 2261
2227 // Code common for calls using the IC. 2262 // Code common for calls using the IC.
2228 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2263 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2229 ASM_LOCATION("FullCodeGenerator::EmitCallWithLoadIC"); 2264 ASM_LOCATION("FullCodeGenerator::EmitCallWithLoadIC");
2230 Expression* callee = expr->expression(); 2265 Expression* callee = expr->expression();
2231 2266
2232 // Get the target function. 2267 // Get the target function.
2233 ConvertReceiverMode convert_mode; 2268 ConvertReceiverMode convert_mode;
2234 if (callee->IsVariableProxy()) { 2269 if (callee->IsVariableProxy()) {
2235 { StackValueContext context(this); 2270 { StackValueContext context(this);
2236 EmitVariableLoad(callee->AsVariableProxy()); 2271 EmitVariableLoad(callee->AsVariableProxy());
2237 PrepareForBailout(callee, NO_REGISTERS); 2272 PrepareForBailout(callee, Deoptimizer::BailoutState::NO_REGISTERS);
2238 } 2273 }
2239 // Push undefined as receiver. This is patched in the method prologue if it 2274 // Push undefined as receiver. This is patched in the method prologue if it
2240 // is a sloppy mode method. 2275 // is a sloppy mode method.
2241 { 2276 {
2242 UseScratchRegisterScope temps(masm_); 2277 UseScratchRegisterScope temps(masm_);
2243 Register temp = temps.AcquireX(); 2278 Register temp = temps.AcquireX();
2244 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex); 2279 __ LoadRoot(temp, Heap::kUndefinedValueRootIndex);
2245 PushOperand(temp); 2280 PushOperand(temp);
2246 } 2281 }
2247 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2282 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2248 } else { 2283 } else {
2249 // Load the function from the receiver. 2284 // Load the function from the receiver.
2250 DCHECK(callee->IsProperty()); 2285 DCHECK(callee->IsProperty());
2251 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2286 DCHECK(!callee->AsProperty()->IsSuperAccess());
2252 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 2287 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
2253 EmitNamedPropertyLoad(callee->AsProperty()); 2288 EmitNamedPropertyLoad(callee->AsProperty());
2254 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2289 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2290 Deoptimizer::BailoutState::TOS_REGISTER);
2255 // Push the target function under the receiver. 2291 // Push the target function under the receiver.
2256 PopOperand(x10); 2292 PopOperand(x10);
2257 PushOperands(x0, x10); 2293 PushOperands(x0, x10);
2258 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2294 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2259 } 2295 }
2260 2296
2261 EmitCall(expr, convert_mode); 2297 EmitCall(expr, convert_mode);
2262 } 2298 }
2263 2299
2264 2300
(...skipping 19 matching lines...) Expand all
2284 PushOperands(x0, scratch); 2320 PushOperands(x0, scratch);
2285 PushOperand(key->value()); 2321 PushOperand(key->value());
2286 2322
2287 // Stack here: 2323 // Stack here:
2288 // - home_object 2324 // - home_object
2289 // - this (receiver) 2325 // - this (receiver)
2290 // - this (receiver) <-- LoadFromSuper will pop here and below. 2326 // - this (receiver) <-- LoadFromSuper will pop here and below.
2291 // - home_object 2327 // - home_object
2292 // - key 2328 // - key
2293 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2329 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2294 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2330 PrepareForBailoutForId(prop->LoadId(),
2331 Deoptimizer::BailoutState::TOS_REGISTER);
2295 2332
2296 // Replace home_object with target function. 2333 // Replace home_object with target function.
2297 __ Poke(x0, kPointerSize); 2334 __ Poke(x0, kPointerSize);
2298 2335
2299 // Stack here: 2336 // Stack here:
2300 // - target function 2337 // - target function
2301 // - this (receiver) 2338 // - this (receiver)
2302 EmitCall(expr); 2339 EmitCall(expr);
2303 } 2340 }
2304 2341
2305 2342
2306 // Code common for calls using the IC. 2343 // Code common for calls using the IC.
2307 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2344 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2308 Expression* key) { 2345 Expression* key) {
2309 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); 2346 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC");
2310 // Load the key. 2347 // Load the key.
2311 VisitForAccumulatorValue(key); 2348 VisitForAccumulatorValue(key);
2312 2349
2313 Expression* callee = expr->expression(); 2350 Expression* callee = expr->expression();
2314 2351
2315 // Load the function from the receiver. 2352 // Load the function from the receiver.
2316 DCHECK(callee->IsProperty()); 2353 DCHECK(callee->IsProperty());
2317 __ Peek(LoadDescriptor::ReceiverRegister(), 0); 2354 __ Peek(LoadDescriptor::ReceiverRegister(), 0);
2318 __ Move(LoadDescriptor::NameRegister(), x0); 2355 __ Move(LoadDescriptor::NameRegister(), x0);
2319 EmitKeyedPropertyLoad(callee->AsProperty()); 2356 EmitKeyedPropertyLoad(callee->AsProperty());
2320 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2357 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2358 Deoptimizer::BailoutState::TOS_REGISTER);
2321 2359
2322 // Push the target function under the receiver. 2360 // Push the target function under the receiver.
2323 PopOperand(x10); 2361 PopOperand(x10);
2324 PushOperands(x0, x10); 2362 PushOperands(x0, x10);
2325 2363
2326 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2364 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2327 } 2365 }
2328 2366
2329 2367
2330 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { 2368 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
(...skipping 15 matching lines...) Expand all
2346 PushOperands(x0, scratch); 2384 PushOperands(x0, scratch);
2347 VisitForStackValue(prop->key()); 2385 VisitForStackValue(prop->key());
2348 2386
2349 // Stack here: 2387 // Stack here:
2350 // - home_object 2388 // - home_object
2351 // - this (receiver) 2389 // - this (receiver)
2352 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2390 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2353 // - home_object 2391 // - home_object
2354 // - key 2392 // - key
2355 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2393 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2356 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2394 PrepareForBailoutForId(prop->LoadId(),
2395 Deoptimizer::BailoutState::TOS_REGISTER);
2357 2396
2358 // Replace home_object with target function. 2397 // Replace home_object with target function.
2359 __ Poke(x0, kPointerSize); 2398 __ Poke(x0, kPointerSize);
2360 2399
2361 // Stack here: 2400 // Stack here:
2362 // - target function 2401 // - target function
2363 // - this (receiver) 2402 // - this (receiver)
2364 EmitCall(expr); 2403 EmitCall(expr);
2365 } 2404 }
2366 2405
2367 2406
2368 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2407 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2369 ASM_LOCATION("FullCodeGenerator::EmitCall"); 2408 ASM_LOCATION("FullCodeGenerator::EmitCall");
2370 // Load the arguments. 2409 // Load the arguments.
2371 ZoneList<Expression*>* args = expr->arguments(); 2410 ZoneList<Expression*>* args = expr->arguments();
2372 int arg_count = args->length(); 2411 int arg_count = args->length();
2373 for (int i = 0; i < arg_count; i++) { 2412 for (int i = 0; i < arg_count; i++) {
2374 VisitForStackValue(args->at(i)); 2413 VisitForStackValue(args->at(i));
2375 } 2414 }
2376 2415
2377 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2416 PrepareForBailoutForId(expr->CallId(),
2417 Deoptimizer::BailoutState::NO_REGISTERS);
2378 SetCallPosition(expr, expr->tail_call_mode()); 2418 SetCallPosition(expr, expr->tail_call_mode());
2379 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2419 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2380 if (FLAG_trace) { 2420 if (FLAG_trace) {
2381 __ CallRuntime(Runtime::kTraceTailCall); 2421 __ CallRuntime(Runtime::kTraceTailCall);
2382 } 2422 }
2383 // Update profiling counters before the tail call since we will 2423 // Update profiling counters before the tail call since we will
2384 // not return to this function. 2424 // not return to this function.
2385 EmitProfilingCounterHandlingForReturnSequence(true); 2425 EmitProfilingCounterHandlingForReturnSequence(true);
2386 } 2426 }
2387 Handle<Code> ic = 2427 Handle<Code> ic =
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 // Generate code for loading from variables potentially shadowed 2476 // Generate code for loading from variables potentially shadowed
2437 // by eval-introduced variables. 2477 // by eval-introduced variables.
2438 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2478 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2439 2479
2440 __ Bind(&slow); 2480 __ Bind(&slow);
2441 // Call the runtime to find the function to call (returned in x0) 2481 // Call the runtime to find the function to call (returned in x0)
2442 // and the object holding it (returned in x1). 2482 // and the object holding it (returned in x1).
2443 __ Push(callee->name()); 2483 __ Push(callee->name());
2444 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2484 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2445 PushOperands(x0, x1); // Receiver, function. 2485 PushOperands(x0, x1); // Receiver, function.
2446 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2486 PrepareForBailoutForId(expr->LookupId(),
2487 Deoptimizer::BailoutState::NO_REGISTERS);
2447 2488
2448 // If fast case code has been generated, emit code to push the 2489 // If fast case code has been generated, emit code to push the
2449 // function and receiver and have the slow path jump around this 2490 // function and receiver and have the slow path jump around this
2450 // code. 2491 // code.
2451 if (done.is_linked()) { 2492 if (done.is_linked()) {
2452 Label call; 2493 Label call;
2453 __ B(&call); 2494 __ B(&call);
2454 __ Bind(&done); 2495 __ Bind(&done);
2455 // Push function. 2496 // Push function.
2456 // The receiver is implicitly the global receiver. Indicate this 2497 // The receiver is implicitly the global receiver. Indicate this
(...skipping 28 matching lines...) Expand all
2485 2526
2486 // Push a copy of the function (found below the arguments) and 2527 // Push a copy of the function (found below the arguments) and
2487 // resolve eval. 2528 // resolve eval.
2488 __ Peek(x10, (arg_count + 1) * kPointerSize); 2529 __ Peek(x10, (arg_count + 1) * kPointerSize);
2489 __ Push(x10); 2530 __ Push(x10);
2490 EmitResolvePossiblyDirectEval(expr); 2531 EmitResolvePossiblyDirectEval(expr);
2491 2532
2492 // Touch up the stack with the resolved function. 2533 // Touch up the stack with the resolved function.
2493 __ Poke(x0, (arg_count + 1) * kPointerSize); 2534 __ Poke(x0, (arg_count + 1) * kPointerSize);
2494 2535
2495 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2536 PrepareForBailoutForId(expr->EvalId(),
2537 Deoptimizer::BailoutState::NO_REGISTERS);
2496 2538
2497 // Record source position for debugger. 2539 // Record source position for debugger.
2498 SetCallPosition(expr); 2540 SetCallPosition(expr);
2499 2541
2500 // Call the evaluated function. 2542 // Call the evaluated function.
2501 __ Peek(x1, (arg_count + 1) * kXRegSize); 2543 __ Peek(x1, (arg_count + 1) * kXRegSize);
2502 __ Mov(x0, arg_count); 2544 __ Mov(x0, arg_count);
2503 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2545 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2504 expr->tail_call_mode()), 2546 expr->tail_call_mode()),
2505 RelocInfo::CODE_TARGET); 2547 RelocInfo::CODE_TARGET);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2537 __ Mov(x0, arg_count); 2579 __ Mov(x0, arg_count);
2538 __ Peek(x1, arg_count * kXRegSize); 2580 __ Peek(x1, arg_count * kXRegSize);
2539 2581
2540 // Record call targets in unoptimized code. 2582 // Record call targets in unoptimized code.
2541 __ EmitLoadTypeFeedbackVector(x2); 2583 __ EmitLoadTypeFeedbackVector(x2);
2542 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot())); 2584 __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot()));
2543 2585
2544 CallConstructStub stub(isolate()); 2586 CallConstructStub stub(isolate());
2545 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2587 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2546 OperandStackDepthDecrement(arg_count + 1); 2588 OperandStackDepthDecrement(arg_count + 1);
2547 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2589 PrepareForBailoutForId(expr->ReturnId(),
2590 Deoptimizer::BailoutState::TOS_REGISTER);
2548 RestoreContext(); 2591 RestoreContext();
2549 context()->Plug(x0); 2592 context()->Plug(x0);
2550 } 2593 }
2551 2594
2552 2595
2553 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2596 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2554 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall"); 2597 ASM_LOCATION("FullCodeGenerator::EmitSuperConstructorCall");
2555 SuperCallReference* super_call_ref = 2598 SuperCallReference* super_call_ref =
2556 expr->expression()->AsSuperCallReference(); 2599 expr->expression()->AsSuperCallReference();
2557 DCHECK_NOT_NULL(super_call_ref); 2600 DCHECK_NOT_NULL(super_call_ref);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2970 3013
2971 3014
2972 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 3015 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
2973 ASM_LOCATION("FullCodeGenerator::EmitCall"); 3016 ASM_LOCATION("FullCodeGenerator::EmitCall");
2974 ZoneList<Expression*>* args = expr->arguments(); 3017 ZoneList<Expression*>* args = expr->arguments();
2975 DCHECK_LE(2, args->length()); 3018 DCHECK_LE(2, args->length());
2976 // Push target, receiver and arguments onto the stack. 3019 // Push target, receiver and arguments onto the stack.
2977 for (Expression* const arg : *args) { 3020 for (Expression* const arg : *args) {
2978 VisitForStackValue(arg); 3021 VisitForStackValue(arg);
2979 } 3022 }
2980 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3023 PrepareForBailoutForId(expr->CallId(),
3024 Deoptimizer::BailoutState::NO_REGISTERS);
2981 // Move target to x1. 3025 // Move target to x1.
2982 int const argc = args->length() - 2; 3026 int const argc = args->length() - 2;
2983 __ Peek(x1, (argc + 1) * kXRegSize); 3027 __ Peek(x1, (argc + 1) * kXRegSize);
2984 // Call the target. 3028 // Call the target.
2985 __ Mov(x0, argc); 3029 __ Mov(x0, argc);
2986 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3030 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2987 OperandStackDepthDecrement(argc + 1); 3031 OperandStackDepthDecrement(argc + 1);
2988 RestoreContext(); 3032 RestoreContext();
2989 // Discard the function left on TOS. 3033 // Discard the function left on TOS.
2990 context()->DropAndPlug(1, x0); 3034 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 3233 // TODO(jbramley): This could be much more efficient using (for
3190 // example) the CSEL instruction. 3234 // example) the CSEL instruction.
3191 Label materialize_true, materialize_false, done; 3235 Label materialize_true, materialize_false, done;
3192 VisitForControl(expr->expression(), 3236 VisitForControl(expr->expression(),
3193 &materialize_false, 3237 &materialize_false,
3194 &materialize_true, 3238 &materialize_true,
3195 &materialize_true); 3239 &materialize_true);
3196 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3240 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3197 3241
3198 __ Bind(&materialize_true); 3242 __ Bind(&materialize_true);
3199 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3243 PrepareForBailoutForId(expr->MaterializeTrueId(),
3244 Deoptimizer::BailoutState::NO_REGISTERS);
3200 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); 3245 __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
3201 __ B(&done); 3246 __ B(&done);
3202 3247
3203 __ Bind(&materialize_false); 3248 __ Bind(&materialize_false);
3204 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3249 PrepareForBailoutForId(expr->MaterializeFalseId(),
3250 Deoptimizer::BailoutState::NO_REGISTERS);
3205 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); 3251 __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
3206 __ B(&done); 3252 __ B(&done);
3207 3253
3208 __ Bind(&done); 3254 __ Bind(&done);
3209 if (context()->IsStackValue()) { 3255 if (context()->IsStackValue()) {
3210 __ Push(result_register()); 3256 __ Push(result_register());
3211 } 3257 }
3212 } 3258 }
3213 break; 3259 break;
3214 } 3260 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3294 } 3340 }
3295 3341
3296 case VARIABLE: 3342 case VARIABLE:
3297 UNREACHABLE(); 3343 UNREACHABLE();
3298 } 3344 }
3299 } 3345 }
3300 3346
3301 // We need a second deoptimization point after loading the value 3347 // We need a second deoptimization point after loading the value
3302 // in case evaluating the property load my have a side effect. 3348 // in case evaluating the property load my have a side effect.
3303 if (assign_type == VARIABLE) { 3349 if (assign_type == VARIABLE) {
3304 PrepareForBailout(expr->expression(), TOS_REG); 3350 PrepareForBailout(expr->expression(),
3351 Deoptimizer::BailoutState::TOS_REGISTER);
3305 } else { 3352 } else {
3306 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 3353 PrepareForBailoutForId(prop->LoadId(),
3354 Deoptimizer::BailoutState::TOS_REGISTER);
3307 } 3355 }
3308 3356
3309 // Inline smi case if we are in a loop. 3357 // Inline smi case if we are in a loop.
3310 Label stub_call, done; 3358 Label stub_call, done;
3311 JumpPatchSite patch_site(masm_); 3359 JumpPatchSite patch_site(masm_);
3312 3360
3313 int count_value = expr->op() == Token::INC ? 1 : -1; 3361 int count_value = expr->op() == Token::INC ? 1 : -1;
3314 if (ShouldInlineSmiCase(expr->op())) { 3362 if (ShouldInlineSmiCase(expr->op())) {
3315 Label slow; 3363 Label slow;
3316 patch_site.EmitJumpIfNotSmi(x0, &slow); 3364 patch_site.EmitJumpIfNotSmi(x0, &slow);
(...skipping 28 matching lines...) Expand all
3345 __ B(vc, &done); 3393 __ B(vc, &done);
3346 // Call stub. Undo operation first. 3394 // Call stub. Undo operation first.
3347 __ Sub(x0, x0, Smi::FromInt(count_value)); 3395 __ Sub(x0, x0, Smi::FromInt(count_value));
3348 __ B(&stub_call); 3396 __ B(&stub_call);
3349 __ Bind(&slow); 3397 __ Bind(&slow);
3350 } 3398 }
3351 3399
3352 // Convert old value into a number. 3400 // Convert old value into a number.
3353 ToNumberStub convert_stub(isolate()); 3401 ToNumberStub convert_stub(isolate());
3354 __ CallStub(&convert_stub); 3402 __ CallStub(&convert_stub);
3355 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); 3403 PrepareForBailoutForId(expr->ToNumberId(),
3404 Deoptimizer::BailoutState::TOS_REGISTER);
3356 3405
3357 // Save result for postfix expressions. 3406 // Save result for postfix expressions.
3358 if (expr->is_postfix()) { 3407 if (expr->is_postfix()) {
3359 if (!context()->IsEffect()) { 3408 if (!context()->IsEffect()) {
3360 // Save the result on the stack. If we have a named or keyed property 3409 // 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 3410 // we store the result under the receiver that is currently on top
3362 // of the stack. 3411 // of the stack.
3363 switch (assign_type) { 3412 switch (assign_type) {
3364 case VARIABLE: 3413 case VARIABLE:
3365 PushOperand(x0); 3414 PushOperand(x0);
(...skipping 28 matching lines...) Expand all
3394 } 3443 }
3395 __ Bind(&done); 3444 __ Bind(&done);
3396 3445
3397 // Store the value returned in x0. 3446 // Store the value returned in x0.
3398 switch (assign_type) { 3447 switch (assign_type) {
3399 case VARIABLE: 3448 case VARIABLE:
3400 if (expr->is_postfix()) { 3449 if (expr->is_postfix()) {
3401 { EffectContext context(this); 3450 { EffectContext context(this);
3402 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3451 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3403 Token::ASSIGN, expr->CountSlot()); 3452 Token::ASSIGN, expr->CountSlot());
3404 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3453 PrepareForBailoutForId(expr->AssignmentId(),
3454 Deoptimizer::BailoutState::TOS_REGISTER);
3405 context.Plug(x0); 3455 context.Plug(x0);
3406 } 3456 }
3407 // For all contexts except EffectConstant We have the result on 3457 // For all contexts except EffectConstant We have the result on
3408 // top of the stack. 3458 // top of the stack.
3409 if (!context()->IsEffect()) { 3459 if (!context()->IsEffect()) {
3410 context()->PlugTOS(); 3460 context()->PlugTOS();
3411 } 3461 }
3412 } else { 3462 } else {
3413 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3463 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3414 Token::ASSIGN, expr->CountSlot()); 3464 Token::ASSIGN, expr->CountSlot());
3415 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3465 PrepareForBailoutForId(expr->AssignmentId(),
3466 Deoptimizer::BailoutState::TOS_REGISTER);
3416 context()->Plug(x0); 3467 context()->Plug(x0);
3417 } 3468 }
3418 break; 3469 break;
3419 case NAMED_PROPERTY: { 3470 case NAMED_PROPERTY: {
3420 __ Mov(StoreDescriptor::NameRegister(), 3471 __ Mov(StoreDescriptor::NameRegister(),
3421 Operand(prop->key()->AsLiteral()->value())); 3472 Operand(prop->key()->AsLiteral()->value()));
3422 PopOperand(StoreDescriptor::ReceiverRegister()); 3473 PopOperand(StoreDescriptor::ReceiverRegister());
3423 EmitLoadStoreICSlot(expr->CountSlot()); 3474 EmitLoadStoreICSlot(expr->CountSlot());
3424 CallStoreIC(); 3475 CallStoreIC();
3425 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3476 PrepareForBailoutForId(expr->AssignmentId(),
3477 Deoptimizer::BailoutState::TOS_REGISTER);
3426 if (expr->is_postfix()) { 3478 if (expr->is_postfix()) {
3427 if (!context()->IsEffect()) { 3479 if (!context()->IsEffect()) {
3428 context()->PlugTOS(); 3480 context()->PlugTOS();
3429 } 3481 }
3430 } else { 3482 } else {
3431 context()->Plug(x0); 3483 context()->Plug(x0);
3432 } 3484 }
3433 break; 3485 break;
3434 } 3486 }
3435 case NAMED_SUPER_PROPERTY: { 3487 case NAMED_SUPER_PROPERTY: {
(...skipping 18 matching lines...) Expand all
3454 } 3506 }
3455 break; 3507 break;
3456 } 3508 }
3457 case KEYED_PROPERTY: { 3509 case KEYED_PROPERTY: {
3458 PopOperand(StoreDescriptor::NameRegister()); 3510 PopOperand(StoreDescriptor::NameRegister());
3459 PopOperand(StoreDescriptor::ReceiverRegister()); 3511 PopOperand(StoreDescriptor::ReceiverRegister());
3460 Handle<Code> ic = 3512 Handle<Code> ic =
3461 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3513 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3462 EmitLoadStoreICSlot(expr->CountSlot()); 3514 EmitLoadStoreICSlot(expr->CountSlot());
3463 CallIC(ic); 3515 CallIC(ic);
3464 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3516 PrepareForBailoutForId(expr->AssignmentId(),
3517 Deoptimizer::BailoutState::TOS_REGISTER);
3465 if (expr->is_postfix()) { 3518 if (expr->is_postfix()) {
3466 if (!context()->IsEffect()) { 3519 if (!context()->IsEffect()) {
3467 context()->PlugTOS(); 3520 context()->PlugTOS();
3468 } 3521 }
3469 } else { 3522 } else {
3470 context()->Plug(x0); 3523 context()->Plug(x0);
3471 } 3524 }
3472 break; 3525 break;
3473 } 3526 }
3474 } 3527 }
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
3991 } 4044 }
3992 4045
3993 return INTERRUPT; 4046 return INTERRUPT;
3994 } 4047 }
3995 4048
3996 4049
3997 } // namespace internal 4050 } // namespace internal
3998 } // namespace v8 4051 } // namespace v8
3999 4052
4000 #endif // V8_TARGET_ARCH_ARM64 4053 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698