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

Side by Side Diff: src/full-codegen/arm/full-codegen-arm.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_ARM 5 #if V8_TARGET_ARCH_ARM
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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 // Possibly allocate a local context. 169 // Possibly allocate a local context.
170 if (info->scope()->num_heap_slots() > 0) { 170 if (info->scope()->num_heap_slots() > 0) {
171 // Argument to NewContext is the function, which is still in r1. 171 // Argument to NewContext is the function, which is still in r1.
172 Comment cmnt(masm_, "[ Allocate context"); 172 Comment cmnt(masm_, "[ Allocate context");
173 bool need_write_barrier = true; 173 bool need_write_barrier = true;
174 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 174 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
175 if (info->scope()->is_script_scope()) { 175 if (info->scope()->is_script_scope()) {
176 __ push(r1); 176 __ push(r1);
177 __ Push(info->scope()->GetScopeInfo(info->isolate())); 177 __ Push(info->scope()->GetScopeInfo(info->isolate()));
178 __ CallRuntime(Runtime::kNewScriptContext); 178 __ CallRuntime(Runtime::kNewScriptContext);
179 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); 179 PrepareForBailoutForId(BailoutId::ScriptContext(),
180 Deoptimizer::BailoutState::TOS_REGISTER);
180 // The new target value is not used, clobbering is safe. 181 // The new target value is not used, clobbering is safe.
181 DCHECK_NULL(info->scope()->new_target_var()); 182 DCHECK_NULL(info->scope()->new_target_var());
182 } else { 183 } else {
183 if (info->scope()->new_target_var() != nullptr) { 184 if (info->scope()->new_target_var() != nullptr) {
184 __ push(r3); // Preserve new target. 185 __ push(r3); // Preserve new target.
185 } 186 }
186 if (slots <= FastNewContextStub::kMaximumSlots) { 187 if (slots <= FastNewContextStub::kMaximumSlots) {
187 FastNewContextStub stub(isolate(), slots); 188 FastNewContextStub stub(isolate(), slots);
188 __ CallStub(&stub); 189 __ CallStub(&stub);
189 // Result of FastNewContextStub is always in new space. 190 // Result of FastNewContextStub is always in new space.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 __ Abort(kExpectedNewSpaceObject); 226 __ Abort(kExpectedNewSpaceObject);
226 __ bind(&done); 227 __ bind(&done);
227 } 228 }
228 } 229 }
229 } 230 }
230 } 231 }
231 232
232 // Register holding this function and new target are both trashed in case we 233 // Register holding this function and new target are both trashed in case we
233 // bailout here. But since that can happen only when new target is not used 234 // bailout here. But since that can happen only when new target is not used
234 // and we allocate a context, the value of |function_in_register| is correct. 235 // and we allocate a context, the value of |function_in_register| is correct.
235 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); 236 PrepareForBailoutForId(BailoutId::FunctionContext(),
237 Deoptimizer::BailoutState::NO_REGISTERS);
236 238
237 // Possibly set up a local binding to the this function which is used in 239 // Possibly set up a local binding to the this function which is used in
238 // derived constructors with super calls. 240 // derived constructors with super calls.
239 Variable* this_function_var = scope()->this_function_var(); 241 Variable* this_function_var = scope()->this_function_var();
240 if (this_function_var != nullptr) { 242 if (this_function_var != nullptr) {
241 Comment cmnt(masm_, "[ This function"); 243 Comment cmnt(masm_, "[ This function");
242 if (!function_in_register_r1) { 244 if (!function_in_register_r1) {
243 __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 245 __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
244 // The write barrier clobbers register again, keep it marked as such. 246 // The write barrier clobbers register again, keep it marked as such.
245 } 247 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 289 }
288 290
289 SetVar(arguments, r0, r1, r2); 291 SetVar(arguments, r0, r1, r2);
290 } 292 }
291 293
292 if (FLAG_trace) { 294 if (FLAG_trace) {
293 __ CallRuntime(Runtime::kTraceEnter); 295 __ CallRuntime(Runtime::kTraceEnter);
294 } 296 }
295 297
296 // Visit the declarations and body. 298 // Visit the declarations and body.
297 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 299 PrepareForBailoutForId(BailoutId::FunctionEntry(),
300 Deoptimizer::BailoutState::NO_REGISTERS);
298 { 301 {
299 Comment cmnt(masm_, "[ Declarations"); 302 Comment cmnt(masm_, "[ Declarations");
300 VisitDeclarations(scope()->declarations()); 303 VisitDeclarations(scope()->declarations());
301 } 304 }
302 305
303 // Assert that the declarations do not use ICs. Otherwise the debugger 306 // Assert that the declarations do not use ICs. Otherwise the debugger
304 // won't be able to redirect a PC at an IC to the correct IC in newly 307 // won't be able to redirect a PC at an IC to the correct IC in newly
305 // recompiled code. 308 // recompiled code.
306 DCHECK_EQ(0, ic_total_count_); 309 DCHECK_EQ(0, ic_total_count_);
307 310
308 { 311 {
309 Comment cmnt(masm_, "[ Stack check"); 312 Comment cmnt(masm_, "[ Stack check");
310 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 313 PrepareForBailoutForId(BailoutId::Declarations(),
314 Deoptimizer::BailoutState::NO_REGISTERS);
311 Label ok; 315 Label ok;
312 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 316 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
313 __ cmp(sp, Operand(ip)); 317 __ cmp(sp, Operand(ip));
314 __ b(hs, &ok); 318 __ b(hs, &ok);
315 Handle<Code> stack_check = isolate()->builtins()->StackCheck(); 319 Handle<Code> stack_check = isolate()->builtins()->StackCheck();
316 PredictableCodeSizeScope predictable(masm_); 320 PredictableCodeSizeScope predictable(masm_);
317 predictable.ExpectSize( 321 predictable.ExpectSize(
318 masm_->CallSize(stack_check, RelocInfo::CODE_TARGET)); 322 masm_->CallSize(stack_check, RelocInfo::CODE_TARGET));
319 __ Call(stack_check, RelocInfo::CODE_TARGET); 323 __ Call(stack_check, RelocInfo::CODE_TARGET);
320 __ bind(&ok); 324 __ bind(&ok);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 402 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
399 403
400 // Record a mapping of this PC offset to the OSR id. This is used to find 404 // Record a mapping of this PC offset to the OSR id. This is used to find
401 // the AST id from the unoptimized code in order to use it as a key into 405 // the AST id from the unoptimized code in order to use it as a key into
402 // the deoptimization input data found in the optimized code. 406 // the deoptimization input data found in the optimized code.
403 RecordBackEdge(stmt->OsrEntryId()); 407 RecordBackEdge(stmt->OsrEntryId());
404 408
405 EmitProfilingCounterReset(); 409 EmitProfilingCounterReset();
406 410
407 __ bind(&ok); 411 __ bind(&ok);
408 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 412 PrepareForBailoutForId(stmt->EntryId(),
413 Deoptimizer::BailoutState::NO_REGISTERS);
409 // Record a mapping of the OSR id to this PC. This is used if the OSR 414 // Record a mapping of the OSR id to this PC. This is used if the OSR
410 // entry becomes the target of a bailout. We don't expect it to be, but 415 // entry becomes the target of a bailout. We don't expect it to be, but
411 // we want it to work if it is. 416 // we want it to work if it is.
412 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 417 PrepareForBailoutForId(stmt->OsrEntryId(),
418 Deoptimizer::BailoutState::NO_REGISTERS);
413 } 419 }
414 420
415 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 421 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
416 bool is_tail_call) { 422 bool is_tail_call) {
417 // Pretend that the exit is a backwards jump to the entry. 423 // Pretend that the exit is a backwards jump to the entry.
418 int weight = 1; 424 int weight = 1;
419 if (info_->ShouldSelfOptimize()) { 425 if (info_->ShouldSelfOptimize()) {
420 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 426 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
421 } else { 427 } else {
422 int distance = masm_->pc_offset(); 428 int distance = masm_->pc_offset();
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 bool should_normalize, 730 bool should_normalize,
725 Label* if_true, 731 Label* if_true,
726 Label* if_false) { 732 Label* if_false) {
727 // Only prepare for bailouts before splits if we're in a test 733 // Only prepare for bailouts before splits if we're in a test
728 // context. Otherwise, we let the Visit function deal with the 734 // context. Otherwise, we let the Visit function deal with the
729 // preparation to avoid preparing with the same AST id twice. 735 // preparation to avoid preparing with the same AST id twice.
730 if (!context()->IsTest()) return; 736 if (!context()->IsTest()) return;
731 737
732 Label skip; 738 Label skip;
733 if (should_normalize) __ b(&skip); 739 if (should_normalize) __ b(&skip);
734 PrepareForBailout(expr, TOS_REG); 740 PrepareForBailout(expr, Deoptimizer::BailoutState::TOS_REGISTER);
735 if (should_normalize) { 741 if (should_normalize) {
736 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 742 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
737 __ cmp(r0, ip); 743 __ cmp(r0, ip);
738 Split(eq, if_true, if_false, NULL); 744 Split(eq, if_true, if_false, NULL);
739 __ bind(&skip); 745 __ bind(&skip);
740 } 746 }
741 } 747 }
742 748
743 749
744 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 750 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 788 }
783 break; 789 break;
784 790
785 case VariableLocation::CONTEXT: 791 case VariableLocation::CONTEXT:
786 if (hole_init) { 792 if (hole_init) {
787 Comment cmnt(masm_, "[ VariableDeclaration"); 793 Comment cmnt(masm_, "[ VariableDeclaration");
788 EmitDebugCheckDeclarationContext(variable); 794 EmitDebugCheckDeclarationContext(variable);
789 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 795 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
790 __ str(r0, ContextMemOperand(cp, variable->index())); 796 __ str(r0, ContextMemOperand(cp, variable->index()));
791 // No write barrier since the_hole_value is in old space. 797 // No write barrier since the_hole_value is in old space.
792 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 798 PrepareForBailoutForId(proxy->id(),
799 Deoptimizer::BailoutState::NO_REGISTERS);
793 } 800 }
794 break; 801 break;
795 802
796 case VariableLocation::LOOKUP: { 803 case VariableLocation::LOOKUP: {
797 Comment cmnt(masm_, "[ VariableDeclaration"); 804 Comment cmnt(masm_, "[ VariableDeclaration");
798 __ mov(r2, Operand(variable->name())); 805 __ mov(r2, Operand(variable->name()));
799 // Declaration nodes are always introduced in one of four modes. 806 // Declaration nodes are always introduced in one of four modes.
800 DCHECK(IsDeclaredVariableMode(mode)); 807 DCHECK(IsDeclaredVariableMode(mode));
801 // Push initial value, if any. 808 // Push initial value, if any.
802 // Note: For variables we must not push an initial value (such as 809 // Note: For variables we must not push an initial value (such as
803 // 'undefined') because we may have a (legal) redeclaration and we 810 // 'undefined') because we may have a (legal) redeclaration and we
804 // must not destroy the current value. 811 // must not destroy the current value.
805 if (hole_init) { 812 if (hole_init) {
806 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 813 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
807 } else { 814 } else {
808 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. 815 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value.
809 } 816 }
810 __ Push(r2, r0); 817 __ Push(r2, r0);
811 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 818 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
812 __ CallRuntime(Runtime::kDeclareLookupSlot); 819 __ CallRuntime(Runtime::kDeclareLookupSlot);
813 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 820 PrepareForBailoutForId(proxy->id(),
821 Deoptimizer::BailoutState::NO_REGISTERS);
814 break; 822 break;
815 } 823 }
816 } 824 }
817 } 825 }
818 826
819 827
820 void FullCodeGenerator::VisitFunctionDeclaration( 828 void FullCodeGenerator::VisitFunctionDeclaration(
821 FunctionDeclaration* declaration) { 829 FunctionDeclaration* declaration) {
822 VariableProxy* proxy = declaration->proxy(); 830 VariableProxy* proxy = declaration->proxy();
823 Variable* variable = proxy->var(); 831 Variable* variable = proxy->var();
(...skipping 25 matching lines...) Expand all
849 int offset = Context::SlotOffset(variable->index()); 857 int offset = Context::SlotOffset(variable->index());
850 // We know that we have written a function, which is not a smi. 858 // We know that we have written a function, which is not a smi.
851 __ RecordWriteContextSlot(cp, 859 __ RecordWriteContextSlot(cp,
852 offset, 860 offset,
853 result_register(), 861 result_register(),
854 r2, 862 r2,
855 kLRHasBeenSaved, 863 kLRHasBeenSaved,
856 kDontSaveFPRegs, 864 kDontSaveFPRegs,
857 EMIT_REMEMBERED_SET, 865 EMIT_REMEMBERED_SET,
858 OMIT_SMI_CHECK); 866 OMIT_SMI_CHECK);
859 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 867 PrepareForBailoutForId(proxy->id(),
868 Deoptimizer::BailoutState::NO_REGISTERS);
860 break; 869 break;
861 } 870 }
862 871
863 case VariableLocation::LOOKUP: { 872 case VariableLocation::LOOKUP: {
864 Comment cmnt(masm_, "[ FunctionDeclaration"); 873 Comment cmnt(masm_, "[ FunctionDeclaration");
865 __ mov(r2, Operand(variable->name())); 874 __ mov(r2, Operand(variable->name()));
866 PushOperand(r2); 875 PushOperand(r2);
867 // Push initial value for function declaration. 876 // Push initial value for function declaration.
868 VisitForStackValue(declaration->fun()); 877 VisitForStackValue(declaration->fun());
869 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 878 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
870 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 879 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
871 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 880 PrepareForBailoutForId(proxy->id(),
881 Deoptimizer::BailoutState::NO_REGISTERS);
872 break; 882 break;
873 } 883 }
874 } 884 }
875 } 885 }
876 886
877 887
878 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 888 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
879 // Call the runtime to declare the globals. 889 // Call the runtime to declare the globals.
880 __ mov(r1, Operand(pairs)); 890 __ mov(r1, Operand(pairs));
881 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 891 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
(...skipping 11 matching lines...) Expand all
893 } 903 }
894 904
895 905
896 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 906 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
897 Comment cmnt(masm_, "[ SwitchStatement"); 907 Comment cmnt(masm_, "[ SwitchStatement");
898 Breakable nested_statement(this, stmt); 908 Breakable nested_statement(this, stmt);
899 SetStatementPosition(stmt); 909 SetStatementPosition(stmt);
900 910
901 // Keep the switch value on the stack until a case matches. 911 // Keep the switch value on the stack until a case matches.
902 VisitForStackValue(stmt->tag()); 912 VisitForStackValue(stmt->tag());
903 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 913 PrepareForBailoutForId(stmt->EntryId(),
914 Deoptimizer::BailoutState::NO_REGISTERS);
904 915
905 ZoneList<CaseClause*>* clauses = stmt->cases(); 916 ZoneList<CaseClause*>* clauses = stmt->cases();
906 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 917 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
907 918
908 Label next_test; // Recycled for each test. 919 Label next_test; // Recycled for each test.
909 // Compile all the tests with branches to their bodies. 920 // Compile all the tests with branches to their bodies.
910 for (int i = 0; i < clauses->length(); i++) { 921 for (int i = 0; i < clauses->length(); i++) {
911 CaseClause* clause = clauses->at(i); 922 CaseClause* clause = clauses->at(i);
912 clause->body_target()->Unuse(); 923 clause->body_target()->Unuse();
913 924
(...skipping 28 matching lines...) Expand all
942 953
943 // Record position before stub call for type feedback. 954 // Record position before stub call for type feedback.
944 SetExpressionPosition(clause); 955 SetExpressionPosition(clause);
945 Handle<Code> ic = 956 Handle<Code> ic =
946 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 957 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
947 CallIC(ic, clause->CompareId()); 958 CallIC(ic, clause->CompareId());
948 patch_site.EmitPatchInfo(); 959 patch_site.EmitPatchInfo();
949 960
950 Label skip; 961 Label skip;
951 __ b(&skip); 962 __ b(&skip);
952 PrepareForBailout(clause, TOS_REG); 963 PrepareForBailout(clause, Deoptimizer::BailoutState::TOS_REGISTER);
953 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 964 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
954 __ cmp(r0, ip); 965 __ cmp(r0, ip);
955 __ b(ne, &next_test); 966 __ b(ne, &next_test);
956 __ Drop(1); 967 __ Drop(1);
957 __ jmp(clause->body_target()); 968 __ jmp(clause->body_target());
958 __ bind(&skip); 969 __ bind(&skip);
959 970
960 __ cmp(r0, Operand::Zero()); 971 __ cmp(r0, Operand::Zero());
961 __ b(ne, &next_test); 972 __ b(ne, &next_test);
962 __ Drop(1); // Switch value is no longer needed. 973 __ Drop(1); // Switch value is no longer needed.
963 __ b(clause->body_target()); 974 __ b(clause->body_target());
964 } 975 }
965 976
966 // Discard the test value and jump to the default if present, otherwise to 977 // Discard the test value and jump to the default if present, otherwise to
967 // the end of the statement. 978 // the end of the statement.
968 __ bind(&next_test); 979 __ bind(&next_test);
969 DropOperands(1); // Switch value is no longer needed. 980 DropOperands(1); // Switch value is no longer needed.
970 if (default_clause == NULL) { 981 if (default_clause == NULL) {
971 __ b(nested_statement.break_label()); 982 __ b(nested_statement.break_label());
972 } else { 983 } else {
973 __ b(default_clause->body_target()); 984 __ b(default_clause->body_target());
974 } 985 }
975 986
976 // Compile all the case bodies. 987 // Compile all the case bodies.
977 for (int i = 0; i < clauses->length(); i++) { 988 for (int i = 0; i < clauses->length(); i++) {
978 Comment cmnt(masm_, "[ Case body"); 989 Comment cmnt(masm_, "[ Case body");
979 CaseClause* clause = clauses->at(i); 990 CaseClause* clause = clauses->at(i);
980 __ bind(clause->body_target()); 991 __ bind(clause->body_target());
981 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 992 PrepareForBailoutForId(clause->EntryId(),
993 Deoptimizer::BailoutState::NO_REGISTERS);
982 VisitStatements(clause->statements()); 994 VisitStatements(clause->statements());
983 } 995 }
984 996
985 __ bind(nested_statement.break_label()); 997 __ bind(nested_statement.break_label());
986 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 998 PrepareForBailoutForId(stmt->ExitId(),
999 Deoptimizer::BailoutState::NO_REGISTERS);
987 } 1000 }
988 1001
989 1002
990 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1003 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
991 Comment cmnt(masm_, "[ ForInStatement"); 1004 Comment cmnt(masm_, "[ ForInStatement");
992 SetStatementPosition(stmt, SKIP_BREAK); 1005 SetStatementPosition(stmt, SKIP_BREAK);
993 1006
994 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 1007 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
995 1008
996 // Get the object to enumerate over. 1009 // Get the object to enumerate over.
(...skipping 12 matching lines...) Expand all
1009 __ CompareObjectType(r0, r1, r1, FIRST_JS_RECEIVER_TYPE); 1022 __ CompareObjectType(r0, r1, r1, FIRST_JS_RECEIVER_TYPE);
1010 __ b(ge, &done_convert); 1023 __ b(ge, &done_convert);
1011 __ CompareRoot(r0, Heap::kNullValueRootIndex); 1024 __ CompareRoot(r0, Heap::kNullValueRootIndex);
1012 __ b(eq, &exit); 1025 __ b(eq, &exit);
1013 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); 1026 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
1014 __ b(eq, &exit); 1027 __ b(eq, &exit);
1015 __ bind(&convert); 1028 __ bind(&convert);
1016 ToObjectStub stub(isolate()); 1029 ToObjectStub stub(isolate());
1017 __ CallStub(&stub); 1030 __ CallStub(&stub);
1018 __ bind(&done_convert); 1031 __ bind(&done_convert);
1019 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); 1032 PrepareForBailoutForId(stmt->ToObjectId(),
1033 Deoptimizer::BailoutState::TOS_REGISTER);
1020 __ push(r0); 1034 __ push(r0);
1021 1035
1022 // Check cache validity in generated code. If we cannot guarantee cache 1036 // Check cache validity in generated code. If we cannot guarantee cache
1023 // validity, call the runtime system to check cache validity or get the 1037 // validity, call the runtime system to check cache validity or get the
1024 // property names in a fixed array. Note: Proxies never have an enum cache, 1038 // property names in a fixed array. Note: Proxies never have an enum cache,
1025 // so will always take the slow path. 1039 // so will always take the slow path.
1026 Label call_runtime; 1040 Label call_runtime;
1027 __ CheckEnumCache(&call_runtime); 1041 __ CheckEnumCache(&call_runtime);
1028 1042
1029 // The enum cache is valid. Load the map of the object being 1043 // The enum cache is valid. Load the map of the object being
1030 // iterated over and use the cache for the iteration. 1044 // iterated over and use the cache for the iteration.
1031 Label use_cache; 1045 Label use_cache;
1032 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); 1046 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
1033 __ b(&use_cache); 1047 __ b(&use_cache);
1034 1048
1035 // Get the set of properties to enumerate. 1049 // Get the set of properties to enumerate.
1036 __ bind(&call_runtime); 1050 __ bind(&call_runtime);
1037 __ push(r0); // Duplicate the enumerable object on the stack. 1051 __ push(r0); // Duplicate the enumerable object on the stack.
1038 __ CallRuntime(Runtime::kForInEnumerate); 1052 __ CallRuntime(Runtime::kForInEnumerate);
1039 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1053 PrepareForBailoutForId(stmt->EnumId(),
1054 Deoptimizer::BailoutState::TOS_REGISTER);
1040 1055
1041 // If we got a map from the runtime call, we can do a fast 1056 // If we got a map from the runtime call, we can do a fast
1042 // modification check. Otherwise, we got a fixed array, and we have 1057 // modification check. Otherwise, we got a fixed array, and we have
1043 // to do a slow check. 1058 // to do a slow check.
1044 Label fixed_array; 1059 Label fixed_array;
1045 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 1060 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1046 __ LoadRoot(ip, Heap::kMetaMapRootIndex); 1061 __ LoadRoot(ip, Heap::kMetaMapRootIndex);
1047 __ cmp(r2, ip); 1062 __ cmp(r2, ip);
1048 __ b(ne, &fixed_array); 1063 __ b(ne, &fixed_array);
1049 1064
(...skipping 20 matching lines...) Expand all
1070 __ Drop(1); 1085 __ Drop(1);
1071 __ jmp(&exit); 1086 __ jmp(&exit);
1072 1087
1073 // We got a fixed array in register r0. Iterate through that. 1088 // We got a fixed array in register r0. Iterate through that.
1074 __ bind(&fixed_array); 1089 __ bind(&fixed_array);
1075 1090
1076 __ mov(r1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check 1091 __ mov(r1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check
1077 __ Push(r1, r0); // Smi and array 1092 __ Push(r1, r0); // Smi and array
1078 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); 1093 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
1079 __ Push(r1); // Fixed array length (as smi). 1094 __ Push(r1); // Fixed array length (as smi).
1080 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); 1095 PrepareForBailoutForId(stmt->PrepareId(),
1096 Deoptimizer::BailoutState::NO_REGISTERS);
1081 __ mov(r0, Operand(Smi::FromInt(0))); 1097 __ mov(r0, Operand(Smi::FromInt(0)));
1082 __ Push(r0); // Initial index. 1098 __ Push(r0); // Initial index.
1083 1099
1084 // Generate code for doing the condition check. 1100 // Generate code for doing the condition check.
1085 __ bind(&loop); 1101 __ bind(&loop);
1086 SetExpressionAsStatementPosition(stmt->each()); 1102 SetExpressionAsStatementPosition(stmt->each());
1087 1103
1088 // Load the current count to r0, load the length to r1. 1104 // Load the current count to r0, load the length to r1.
1089 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize)); 1105 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
1090 __ cmp(r0, r1); // Compare to the array length. 1106 __ cmp(r0, r1); // Compare to the array length.
(...skipping 21 matching lines...) Expand all
1112 __ EmitLoadTypeFeedbackVector(r0); 1128 __ EmitLoadTypeFeedbackVector(r0);
1113 __ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1129 __ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1114 __ str(r2, FieldMemOperand(r0, FixedArray::OffsetOfElementAt(vector_index))); 1130 __ str(r2, FieldMemOperand(r0, FixedArray::OffsetOfElementAt(vector_index)));
1115 1131
1116 // Convert the entry to a string or (smi) 0 if it isn't a property 1132 // Convert the entry to a string or (smi) 0 if it isn't a property
1117 // any more. If the property has been removed while iterating, we 1133 // any more. If the property has been removed while iterating, we
1118 // just skip it. 1134 // just skip it.
1119 __ push(r1); // Enumerable. 1135 __ push(r1); // Enumerable.
1120 __ push(r3); // Current entry. 1136 __ push(r3); // Current entry.
1121 __ CallRuntime(Runtime::kForInFilter); 1137 __ CallRuntime(Runtime::kForInFilter);
1122 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1138 PrepareForBailoutForId(stmt->FilterId(),
1139 Deoptimizer::BailoutState::TOS_REGISTER);
1123 __ mov(r3, Operand(r0)); 1140 __ mov(r3, Operand(r0));
1124 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1141 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1125 __ cmp(r0, ip); 1142 __ cmp(r0, ip);
1126 __ b(eq, loop_statement.continue_label()); 1143 __ b(eq, loop_statement.continue_label());
1127 1144
1128 // Update the 'each' property or variable from the possibly filtered 1145 // Update the 'each' property or variable from the possibly filtered
1129 // entry in register r3. 1146 // entry in register r3.
1130 __ bind(&update_each); 1147 __ bind(&update_each);
1131 __ mov(result_register(), r3); 1148 __ mov(result_register(), r3);
1132 // Perform the assignment as if via '='. 1149 // Perform the assignment as if via '='.
1133 { EffectContext context(this); 1150 { EffectContext context(this);
1134 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1151 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1135 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1152 PrepareForBailoutForId(stmt->AssignmentId(),
1153 Deoptimizer::BailoutState::NO_REGISTERS);
1136 } 1154 }
1137 1155
1138 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1156 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1139 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1157 PrepareForBailoutForId(stmt->BodyId(),
1158 Deoptimizer::BailoutState::NO_REGISTERS);
1140 // Generate code for the body of the loop. 1159 // Generate code for the body of the loop.
1141 Visit(stmt->body()); 1160 Visit(stmt->body());
1142 1161
1143 // Generate code for the going to the next element by incrementing 1162 // Generate code for the going to the next element by incrementing
1144 // the index (smi) stored on top of the stack. 1163 // the index (smi) stored on top of the stack.
1145 __ bind(loop_statement.continue_label()); 1164 __ bind(loop_statement.continue_label());
1146 __ pop(r0); 1165 __ pop(r0);
1147 __ add(r0, r0, Operand(Smi::FromInt(1))); 1166 __ add(r0, r0, Operand(Smi::FromInt(1)));
1148 __ push(r0); 1167 __ push(r0);
1149 1168
1150 EmitBackEdgeBookkeeping(stmt, &loop); 1169 EmitBackEdgeBookkeeping(stmt, &loop);
1151 __ b(&loop); 1170 __ b(&loop);
1152 1171
1153 // Remove the pointers stored on the stack. 1172 // Remove the pointers stored on the stack.
1154 __ bind(loop_statement.break_label()); 1173 __ bind(loop_statement.break_label());
1155 DropOperands(5); 1174 DropOperands(5);
1156 1175
1157 // Exit and decrement the loop depth. 1176 // Exit and decrement the loop depth.
1158 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1177 PrepareForBailoutForId(stmt->ExitId(),
1178 Deoptimizer::BailoutState::NO_REGISTERS);
1159 __ bind(&exit); 1179 __ bind(&exit);
1160 decrement_loop_depth(); 1180 decrement_loop_depth();
1161 } 1181 }
1162 1182
1163 1183
1164 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1184 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1165 FeedbackVectorSlot slot) { 1185 FeedbackVectorSlot slot) {
1166 DCHECK(NeedsHomeObject(initializer)); 1186 DCHECK(NeedsHomeObject(initializer));
1167 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1187 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1168 __ mov(StoreDescriptor::NameRegister(), 1188 __ mov(StoreDescriptor::NameRegister(),
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 __ mov(LoadDescriptor::SlotRegister(), 1327 __ mov(LoadDescriptor::SlotRegister(),
1308 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1328 Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
1309 CallLoadIC(typeof_mode); 1329 CallLoadIC(typeof_mode);
1310 } 1330 }
1311 1331
1312 1332
1313 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1333 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1314 TypeofMode typeof_mode) { 1334 TypeofMode typeof_mode) {
1315 // Record position before possible IC call. 1335 // Record position before possible IC call.
1316 SetExpressionPosition(proxy); 1336 SetExpressionPosition(proxy);
1317 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1337 PrepareForBailoutForId(proxy->BeforeId(),
1338 Deoptimizer::BailoutState::NO_REGISTERS);
1318 Variable* var = proxy->var(); 1339 Variable* var = proxy->var();
1319 1340
1320 // Three cases: global variables, lookup variables, and all other types of 1341 // Three cases: global variables, lookup variables, and all other types of
1321 // variables. 1342 // variables.
1322 switch (var->location()) { 1343 switch (var->location()) {
1323 case VariableLocation::GLOBAL: 1344 case VariableLocation::GLOBAL:
1324 case VariableLocation::UNALLOCATED: { 1345 case VariableLocation::UNALLOCATED: {
1325 Comment cmnt(masm_, "[ Global variable"); 1346 Comment cmnt(masm_, "[ Global variable");
1326 EmitGlobalVariableLoad(proxy, typeof_mode); 1347 EmitGlobalVariableLoad(proxy, typeof_mode);
1327 context()->Plug(r0); 1348 context()->Plug(r0);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 int flags = expr->ComputeFlags(); 1435 int flags = expr->ComputeFlags();
1415 __ mov(r0, Operand(Smi::FromInt(flags))); 1436 __ mov(r0, Operand(Smi::FromInt(flags)));
1416 if (MustCreateObjectLiteralWithRuntime(expr)) { 1437 if (MustCreateObjectLiteralWithRuntime(expr)) {
1417 __ Push(r3, r2, r1, r0); 1438 __ Push(r3, r2, r1, r0);
1418 __ CallRuntime(Runtime::kCreateObjectLiteral); 1439 __ CallRuntime(Runtime::kCreateObjectLiteral);
1419 } else { 1440 } else {
1420 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1441 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1421 __ CallStub(&stub); 1442 __ CallStub(&stub);
1422 RestoreContext(); 1443 RestoreContext();
1423 } 1444 }
1424 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1445 PrepareForBailoutForId(expr->CreateLiteralId(),
1446 Deoptimizer::BailoutState::TOS_REGISTER);
1425 1447
1426 // If result_saved is true the result is on top of the stack. If 1448 // If result_saved is true the result is on top of the stack. If
1427 // result_saved is false the result is in r0. 1449 // result_saved is false the result is in r0.
1428 bool result_saved = false; 1450 bool result_saved = false;
1429 1451
1430 AccessorTable accessor_table(zone()); 1452 AccessorTable accessor_table(zone());
1431 int property_index = 0; 1453 int property_index = 0;
1432 for (; property_index < expr->properties()->length(); property_index++) { 1454 for (; property_index < expr->properties()->length(); property_index++) {
1433 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1455 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1434 if (property->is_computed_name()) break; 1456 if (property->is_computed_name()) break;
(...skipping 15 matching lines...) Expand all
1450 // It is safe to use [[Put]] here because the boilerplate already 1472 // It is safe to use [[Put]] here because the boilerplate already
1451 // contains computed properties with an uninitialized value. 1473 // contains computed properties with an uninitialized value.
1452 if (key->value()->IsInternalizedString()) { 1474 if (key->value()->IsInternalizedString()) {
1453 if (property->emit_store()) { 1475 if (property->emit_store()) {
1454 VisitForAccumulatorValue(value); 1476 VisitForAccumulatorValue(value);
1455 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 1477 DCHECK(StoreDescriptor::ValueRegister().is(r0));
1456 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); 1478 __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1457 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1479 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1458 EmitLoadStoreICSlot(property->GetSlot(0)); 1480 EmitLoadStoreICSlot(property->GetSlot(0));
1459 CallStoreIC(); 1481 CallStoreIC();
1460 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1482 PrepareForBailoutForId(key->id(),
1483 Deoptimizer::BailoutState::NO_REGISTERS);
1461 1484
1462 if (NeedsHomeObject(value)) { 1485 if (NeedsHomeObject(value)) {
1463 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1486 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1464 } 1487 }
1465 } else { 1488 } else {
1466 VisitForEffect(value); 1489 VisitForEffect(value);
1467 } 1490 }
1468 break; 1491 break;
1469 } 1492 }
1470 // Duplicate receiver on stack. 1493 // Duplicate receiver on stack.
(...skipping 13 matching lines...) Expand all
1484 } 1507 }
1485 break; 1508 break;
1486 case ObjectLiteral::Property::PROTOTYPE: 1509 case ObjectLiteral::Property::PROTOTYPE:
1487 // Duplicate receiver on stack. 1510 // Duplicate receiver on stack.
1488 __ ldr(r0, MemOperand(sp)); 1511 __ ldr(r0, MemOperand(sp));
1489 PushOperand(r0); 1512 PushOperand(r0);
1490 VisitForStackValue(value); 1513 VisitForStackValue(value);
1491 DCHECK(property->emit_store()); 1514 DCHECK(property->emit_store());
1492 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1515 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1493 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1516 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1494 NO_REGISTERS); 1517 Deoptimizer::BailoutState::NO_REGISTERS);
1495 break; 1518 break;
1496 1519
1497 case ObjectLiteral::Property::GETTER: 1520 case ObjectLiteral::Property::GETTER:
1498 if (property->emit_store()) { 1521 if (property->emit_store()) {
1499 accessor_table.lookup(key)->second->getter = property; 1522 accessor_table.lookup(key)->second->getter = property;
1500 } 1523 }
1501 break; 1524 break;
1502 case ObjectLiteral::Property::SETTER: 1525 case ObjectLiteral::Property::SETTER:
1503 if (property->emit_store()) { 1526 if (property->emit_store()) {
1504 accessor_table.lookup(key)->second->setter = property; 1527 accessor_table.lookup(key)->second->setter = property;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 1565
1543 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. 1566 __ ldr(r0, MemOperand(sp)); // Duplicate receiver.
1544 PushOperand(r0); 1567 PushOperand(r0);
1545 1568
1546 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1569 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1547 DCHECK(!property->is_computed_name()); 1570 DCHECK(!property->is_computed_name());
1548 VisitForStackValue(value); 1571 VisitForStackValue(value);
1549 DCHECK(property->emit_store()); 1572 DCHECK(property->emit_store());
1550 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1573 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1551 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1574 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1552 NO_REGISTERS); 1575 Deoptimizer::BailoutState::NO_REGISTERS);
1553 } else { 1576 } else {
1554 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1577 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1555 VisitForStackValue(value); 1578 VisitForStackValue(value);
1556 if (NeedsHomeObject(value)) { 1579 if (NeedsHomeObject(value)) {
1557 EmitSetHomeObject(value, 2, property->GetSlot()); 1580 EmitSetHomeObject(value, 2, property->GetSlot());
1558 } 1581 }
1559 1582
1560 switch (property->kind()) { 1583 switch (property->kind()) {
1561 case ObjectLiteral::Property::CONSTANT: 1584 case ObjectLiteral::Property::CONSTANT:
1562 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1585 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 __ mov(r2, Operand(Smi::FromInt(expr->literal_index()))); 1638 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
1616 __ mov(r1, Operand(constant_elements)); 1639 __ mov(r1, Operand(constant_elements));
1617 if (MustCreateArrayLiteralWithRuntime(expr)) { 1640 if (MustCreateArrayLiteralWithRuntime(expr)) {
1618 __ mov(r0, Operand(Smi::FromInt(expr->ComputeFlags()))); 1641 __ mov(r0, Operand(Smi::FromInt(expr->ComputeFlags())));
1619 __ Push(r3, r2, r1, r0); 1642 __ Push(r3, r2, r1, r0);
1620 __ CallRuntime(Runtime::kCreateArrayLiteral); 1643 __ CallRuntime(Runtime::kCreateArrayLiteral);
1621 } else { 1644 } else {
1622 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1645 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1623 __ CallStub(&stub); 1646 __ CallStub(&stub);
1624 } 1647 }
1625 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1648 PrepareForBailoutForId(expr->CreateLiteralId(),
1649 Deoptimizer::BailoutState::TOS_REGISTER);
1626 1650
1627 bool result_saved = false; // Is the result saved to the stack? 1651 bool result_saved = false; // Is the result saved to the stack?
1628 ZoneList<Expression*>* subexprs = expr->values(); 1652 ZoneList<Expression*>* subexprs = expr->values();
1629 int length = subexprs->length(); 1653 int length = subexprs->length();
1630 1654
1631 // Emit code to evaluate all the non-constant subexpressions and to store 1655 // Emit code to evaluate all the non-constant subexpressions and to store
1632 // them into the newly cloned array. 1656 // them into the newly cloned array.
1633 int array_index = 0; 1657 int array_index = 0;
1634 for (; array_index < length; array_index++) { 1658 for (; array_index < length; array_index++) {
1635 Expression* subexpr = subexprs->at(array_index); 1659 Expression* subexpr = subexprs->at(array_index);
1636 DCHECK(!subexpr->IsSpread()); 1660 DCHECK(!subexpr->IsSpread());
1637 1661
1638 // If the subexpression is a literal or a simple materialized literal it 1662 // If the subexpression is a literal or a simple materialized literal it
1639 // is already set in the cloned array. 1663 // is already set in the cloned array.
1640 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1664 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1641 1665
1642 if (!result_saved) { 1666 if (!result_saved) {
1643 PushOperand(r0); 1667 PushOperand(r0);
1644 result_saved = true; 1668 result_saved = true;
1645 } 1669 }
1646 VisitForAccumulatorValue(subexpr); 1670 VisitForAccumulatorValue(subexpr);
1647 1671
1648 __ mov(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); 1672 __ mov(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index)));
1649 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1673 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1650 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1674 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1651 Handle<Code> ic = 1675 Handle<Code> ic =
1652 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1676 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1653 CallIC(ic); 1677 CallIC(ic);
1654 1678
1655 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1679 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1680 Deoptimizer::BailoutState::NO_REGISTERS);
1656 } 1681 }
1657 1682
1658 // In case the array literal contains spread expressions it has two parts. The 1683 // In case the array literal contains spread expressions it has two parts. The
1659 // first part is the "static" array which has a literal index is handled 1684 // first part is the "static" array which has a literal index is handled
1660 // above. The second part is the part after the first spread expression 1685 // above. The second part is the part after the first spread expression
1661 // (inclusive) and these elements gets appended to the array. Note that the 1686 // (inclusive) and these elements gets appended to the array. Note that the
1662 // number elements an iterable produces is unknown ahead of time. 1687 // number elements an iterable produces is unknown ahead of time.
1663 if (array_index < length && result_saved) { 1688 if (array_index < length && result_saved) {
1664 PopOperand(r0); 1689 PopOperand(r0);
1665 result_saved = false; 1690 result_saved = false;
1666 } 1691 }
1667 for (; array_index < length; array_index++) { 1692 for (; array_index < length; array_index++) {
1668 Expression* subexpr = subexprs->at(array_index); 1693 Expression* subexpr = subexprs->at(array_index);
1669 1694
1670 PushOperand(r0); 1695 PushOperand(r0);
1671 DCHECK(!subexpr->IsSpread()); 1696 DCHECK(!subexpr->IsSpread());
1672 VisitForStackValue(subexpr); 1697 VisitForStackValue(subexpr);
1673 CallRuntimeWithOperands(Runtime::kAppendElement); 1698 CallRuntimeWithOperands(Runtime::kAppendElement);
1674 1699
1675 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1700 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1701 Deoptimizer::BailoutState::NO_REGISTERS);
1676 } 1702 }
1677 1703
1678 if (result_saved) { 1704 if (result_saved) {
1679 context()->PlugTOS(); 1705 context()->PlugTOS();
1680 } else { 1706 } else {
1681 context()->Plug(r0); 1707 context()->Plug(r0);
1682 } 1708 }
1683 } 1709 }
1684 1710
1685 1711
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1748 break; 1774 break;
1749 } 1775 }
1750 1776
1751 // For compound assignments we need another deoptimization point after the 1777 // For compound assignments we need another deoptimization point after the
1752 // variable/property load. 1778 // variable/property load.
1753 if (expr->is_compound()) { 1779 if (expr->is_compound()) {
1754 { AccumulatorValueContext context(this); 1780 { AccumulatorValueContext context(this);
1755 switch (assign_type) { 1781 switch (assign_type) {
1756 case VARIABLE: 1782 case VARIABLE:
1757 EmitVariableLoad(expr->target()->AsVariableProxy()); 1783 EmitVariableLoad(expr->target()->AsVariableProxy());
1758 PrepareForBailout(expr->target(), TOS_REG); 1784 PrepareForBailout(expr->target(),
1785 Deoptimizer::BailoutState::TOS_REGISTER);
1759 break; 1786 break;
1760 case NAMED_PROPERTY: 1787 case NAMED_PROPERTY:
1761 EmitNamedPropertyLoad(property); 1788 EmitNamedPropertyLoad(property);
1762 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1789 PrepareForBailoutForId(property->LoadId(),
1790 Deoptimizer::BailoutState::TOS_REGISTER);
1763 break; 1791 break;
1764 case NAMED_SUPER_PROPERTY: 1792 case NAMED_SUPER_PROPERTY:
1765 EmitNamedSuperPropertyLoad(property); 1793 EmitNamedSuperPropertyLoad(property);
1766 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1794 PrepareForBailoutForId(property->LoadId(),
1795 Deoptimizer::BailoutState::TOS_REGISTER);
1767 break; 1796 break;
1768 case KEYED_SUPER_PROPERTY: 1797 case KEYED_SUPER_PROPERTY:
1769 EmitKeyedSuperPropertyLoad(property); 1798 EmitKeyedSuperPropertyLoad(property);
1770 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1799 PrepareForBailoutForId(property->LoadId(),
1800 Deoptimizer::BailoutState::TOS_REGISTER);
1771 break; 1801 break;
1772 case KEYED_PROPERTY: 1802 case KEYED_PROPERTY:
1773 EmitKeyedPropertyLoad(property); 1803 EmitKeyedPropertyLoad(property);
1774 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1804 PrepareForBailoutForId(property->LoadId(),
1805 Deoptimizer::BailoutState::TOS_REGISTER);
1775 break; 1806 break;
1776 } 1807 }
1777 } 1808 }
1778 1809
1779 Token::Value op = expr->binary_op(); 1810 Token::Value op = expr->binary_op();
1780 PushOperand(r0); // Left operand goes on the stack. 1811 PushOperand(r0); // Left operand goes on the stack.
1781 VisitForAccumulatorValue(expr->value()); 1812 VisitForAccumulatorValue(expr->value());
1782 1813
1783 AccumulatorValueContext context(this); 1814 AccumulatorValueContext context(this);
1784 if (ShouldInlineSmiCase(op)) { 1815 if (ShouldInlineSmiCase(op)) {
1785 EmitInlineSmiBinaryOp(expr->binary_operation(), 1816 EmitInlineSmiBinaryOp(expr->binary_operation(),
1786 op, 1817 op,
1787 expr->target(), 1818 expr->target(),
1788 expr->value()); 1819 expr->value());
1789 } else { 1820 } else {
1790 EmitBinaryOp(expr->binary_operation(), op); 1821 EmitBinaryOp(expr->binary_operation(), op);
1791 } 1822 }
1792 1823
1793 // Deoptimization point in case the binary operation may have side effects. 1824 // Deoptimization point in case the binary operation may have side effects.
1794 PrepareForBailout(expr->binary_operation(), TOS_REG); 1825 PrepareForBailout(expr->binary_operation(),
1826 Deoptimizer::BailoutState::TOS_REGISTER);
1795 } else { 1827 } else {
1796 VisitForAccumulatorValue(expr->value()); 1828 VisitForAccumulatorValue(expr->value());
1797 } 1829 }
1798 1830
1799 SetExpressionPosition(expr); 1831 SetExpressionPosition(expr);
1800 1832
1801 // Store the value. 1833 // Store the value.
1802 switch (assign_type) { 1834 switch (assign_type) {
1803 case VARIABLE: 1835 case VARIABLE:
1804 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1836 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1805 expr->op(), expr->AssignmentSlot()); 1837 expr->op(), expr->AssignmentSlot());
1806 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1838 PrepareForBailoutForId(expr->AssignmentId(),
1839 Deoptimizer::BailoutState::TOS_REGISTER);
1807 context()->Plug(r0); 1840 context()->Plug(r0);
1808 break; 1841 break;
1809 case NAMED_PROPERTY: 1842 case NAMED_PROPERTY:
1810 EmitNamedPropertyAssignment(expr); 1843 EmitNamedPropertyAssignment(expr);
1811 break; 1844 break;
1812 case NAMED_SUPER_PROPERTY: 1845 case NAMED_SUPER_PROPERTY:
1813 EmitNamedSuperPropertyStore(property); 1846 EmitNamedSuperPropertyStore(property);
1814 context()->Plug(r0); 1847 context()->Plug(r0);
1815 break; 1848 break;
1816 case KEYED_SUPER_PROPERTY: 1849 case KEYED_SUPER_PROPERTY:
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 Property* prop = expr->target()->AsProperty(); 2297 Property* prop = expr->target()->AsProperty();
2265 DCHECK(prop != NULL); 2298 DCHECK(prop != NULL);
2266 DCHECK(prop->key()->IsLiteral()); 2299 DCHECK(prop->key()->IsLiteral());
2267 2300
2268 __ mov(StoreDescriptor::NameRegister(), 2301 __ mov(StoreDescriptor::NameRegister(),
2269 Operand(prop->key()->AsLiteral()->value())); 2302 Operand(prop->key()->AsLiteral()->value()));
2270 PopOperand(StoreDescriptor::ReceiverRegister()); 2303 PopOperand(StoreDescriptor::ReceiverRegister());
2271 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2304 EmitLoadStoreICSlot(expr->AssignmentSlot());
2272 CallStoreIC(); 2305 CallStoreIC();
2273 2306
2274 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2307 PrepareForBailoutForId(expr->AssignmentId(),
2308 Deoptimizer::BailoutState::TOS_REGISTER);
2275 context()->Plug(r0); 2309 context()->Plug(r0);
2276 } 2310 }
2277 2311
2278 2312
2279 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2313 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2280 // Assignment to named property of super. 2314 // Assignment to named property of super.
2281 // r0 : value 2315 // r0 : value
2282 // stack : receiver ('this'), home_object 2316 // stack : receiver ('this'), home_object
2283 DCHECK(prop != NULL); 2317 DCHECK(prop != NULL);
2284 Literal* key = prop->key()->AsLiteral(); 2318 Literal* key = prop->key()->AsLiteral();
(...skipping 24 matching lines...) Expand all
2309 // Assignment to a property, using a keyed store IC. 2343 // Assignment to a property, using a keyed store IC.
2310 PopOperands(StoreDescriptor::ReceiverRegister(), 2344 PopOperands(StoreDescriptor::ReceiverRegister(),
2311 StoreDescriptor::NameRegister()); 2345 StoreDescriptor::NameRegister());
2312 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 2346 DCHECK(StoreDescriptor::ValueRegister().is(r0));
2313 2347
2314 Handle<Code> ic = 2348 Handle<Code> ic =
2315 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2349 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2316 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2350 EmitLoadStoreICSlot(expr->AssignmentSlot());
2317 CallIC(ic); 2351 CallIC(ic);
2318 2352
2319 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2353 PrepareForBailoutForId(expr->AssignmentId(),
2354 Deoptimizer::BailoutState::TOS_REGISTER);
2320 context()->Plug(r0); 2355 context()->Plug(r0);
2321 } 2356 }
2322 2357
2323 2358
2324 void FullCodeGenerator::CallIC(Handle<Code> code, 2359 void FullCodeGenerator::CallIC(Handle<Code> code,
2325 TypeFeedbackId ast_id) { 2360 TypeFeedbackId ast_id) {
2326 ic_total_count_++; 2361 ic_total_count_++;
2327 // All calls must have a predictable size in full-codegen code to ensure that 2362 // All calls must have a predictable size in full-codegen code to ensure that
2328 // the debugger can patch them correctly. 2363 // the debugger can patch them correctly.
2329 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, 2364 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2330 NEVER_INLINE_TARGET_ADDRESS); 2365 NEVER_INLINE_TARGET_ADDRESS);
2331 } 2366 }
2332 2367
2333 2368
2334 // Code common for calls using the IC. 2369 // Code common for calls using the IC.
2335 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2370 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2336 Expression* callee = expr->expression(); 2371 Expression* callee = expr->expression();
2337 2372
2338 // Get the target function. 2373 // Get the target function.
2339 ConvertReceiverMode convert_mode; 2374 ConvertReceiverMode convert_mode;
2340 if (callee->IsVariableProxy()) { 2375 if (callee->IsVariableProxy()) {
2341 { StackValueContext context(this); 2376 { StackValueContext context(this);
2342 EmitVariableLoad(callee->AsVariableProxy()); 2377 EmitVariableLoad(callee->AsVariableProxy());
2343 PrepareForBailout(callee, NO_REGISTERS); 2378 PrepareForBailout(callee, Deoptimizer::BailoutState::NO_REGISTERS);
2344 } 2379 }
2345 // Push undefined as receiver. This is patched in the method prologue if it 2380 // Push undefined as receiver. This is patched in the method prologue if it
2346 // is a sloppy mode method. 2381 // is a sloppy mode method.
2347 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 2382 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2348 PushOperand(ip); 2383 PushOperand(ip);
2349 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2384 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2350 } else { 2385 } else {
2351 // Load the function from the receiver. 2386 // Load the function from the receiver.
2352 DCHECK(callee->IsProperty()); 2387 DCHECK(callee->IsProperty());
2353 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2388 DCHECK(!callee->AsProperty()->IsSuperAccess());
2354 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2389 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2355 EmitNamedPropertyLoad(callee->AsProperty()); 2390 EmitNamedPropertyLoad(callee->AsProperty());
2356 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2391 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2392 Deoptimizer::BailoutState::TOS_REGISTER);
2357 // Push the target function under the receiver. 2393 // Push the target function under the receiver.
2358 __ ldr(ip, MemOperand(sp, 0)); 2394 __ ldr(ip, MemOperand(sp, 0));
2359 PushOperand(ip); 2395 PushOperand(ip);
2360 __ str(r0, MemOperand(sp, kPointerSize)); 2396 __ str(r0, MemOperand(sp, kPointerSize));
2361 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2397 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2362 } 2398 }
2363 2399
2364 EmitCall(expr, convert_mode); 2400 EmitCall(expr, convert_mode);
2365 } 2401 }
2366 2402
(...skipping 18 matching lines...) Expand all
2385 PushOperand(scratch); 2421 PushOperand(scratch);
2386 PushOperand(key->value()); 2422 PushOperand(key->value());
2387 2423
2388 // Stack here: 2424 // Stack here:
2389 // - home_object 2425 // - home_object
2390 // - this (receiver) 2426 // - this (receiver)
2391 // - this (receiver) <-- LoadFromSuper will pop here and below. 2427 // - this (receiver) <-- LoadFromSuper will pop here and below.
2392 // - home_object 2428 // - home_object
2393 // - key 2429 // - key
2394 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2430 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2395 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2431 PrepareForBailoutForId(prop->LoadId(),
2432 Deoptimizer::BailoutState::TOS_REGISTER);
2396 2433
2397 // Replace home_object with target function. 2434 // Replace home_object with target function.
2398 __ str(r0, MemOperand(sp, kPointerSize)); 2435 __ str(r0, MemOperand(sp, kPointerSize));
2399 2436
2400 // Stack here: 2437 // Stack here:
2401 // - target function 2438 // - target function
2402 // - this (receiver) 2439 // - this (receiver)
2403 EmitCall(expr); 2440 EmitCall(expr);
2404 } 2441 }
2405 2442
2406 2443
2407 // Code common for calls using the IC. 2444 // Code common for calls using the IC.
2408 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2445 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2409 Expression* key) { 2446 Expression* key) {
2410 // Load the key. 2447 // Load the key.
2411 VisitForAccumulatorValue(key); 2448 VisitForAccumulatorValue(key);
2412 2449
2413 Expression* callee = expr->expression(); 2450 Expression* callee = expr->expression();
2414 2451
2415 // Load the function from the receiver. 2452 // Load the function from the receiver.
2416 DCHECK(callee->IsProperty()); 2453 DCHECK(callee->IsProperty());
2417 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2454 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2418 __ Move(LoadDescriptor::NameRegister(), r0); 2455 __ Move(LoadDescriptor::NameRegister(), r0);
2419 EmitKeyedPropertyLoad(callee->AsProperty()); 2456 EmitKeyedPropertyLoad(callee->AsProperty());
2420 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2457 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2458 Deoptimizer::BailoutState::TOS_REGISTER);
2421 2459
2422 // Push the target function under the receiver. 2460 // Push the target function under the receiver.
2423 __ ldr(ip, MemOperand(sp, 0)); 2461 __ ldr(ip, MemOperand(sp, 0));
2424 PushOperand(ip); 2462 PushOperand(ip);
2425 __ str(r0, MemOperand(sp, kPointerSize)); 2463 __ str(r0, MemOperand(sp, kPointerSize));
2426 2464
2427 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2465 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2428 } 2466 }
2429 2467
2430 2468
(...skipping 15 matching lines...) Expand all
2446 PushOperand(scratch); 2484 PushOperand(scratch);
2447 VisitForStackValue(prop->key()); 2485 VisitForStackValue(prop->key());
2448 2486
2449 // Stack here: 2487 // Stack here:
2450 // - home_object 2488 // - home_object
2451 // - this (receiver) 2489 // - this (receiver)
2452 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2490 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2453 // - home_object 2491 // - home_object
2454 // - key 2492 // - key
2455 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2493 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2456 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2494 PrepareForBailoutForId(prop->LoadId(),
2495 Deoptimizer::BailoutState::TOS_REGISTER);
2457 2496
2458 // Replace home_object with target function. 2497 // Replace home_object with target function.
2459 __ str(r0, MemOperand(sp, kPointerSize)); 2498 __ str(r0, MemOperand(sp, kPointerSize));
2460 2499
2461 // Stack here: 2500 // Stack here:
2462 // - target function 2501 // - target function
2463 // - this (receiver) 2502 // - this (receiver)
2464 EmitCall(expr); 2503 EmitCall(expr);
2465 } 2504 }
2466 2505
2467 2506
2468 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2507 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2469 // Load the arguments. 2508 // Load the arguments.
2470 ZoneList<Expression*>* args = expr->arguments(); 2509 ZoneList<Expression*>* args = expr->arguments();
2471 int arg_count = args->length(); 2510 int arg_count = args->length();
2472 for (int i = 0; i < arg_count; i++) { 2511 for (int i = 0; i < arg_count; i++) {
2473 VisitForStackValue(args->at(i)); 2512 VisitForStackValue(args->at(i));
2474 } 2513 }
2475 2514
2476 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2515 PrepareForBailoutForId(expr->CallId(),
2516 Deoptimizer::BailoutState::NO_REGISTERS);
2477 SetCallPosition(expr, expr->tail_call_mode()); 2517 SetCallPosition(expr, expr->tail_call_mode());
2478 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2518 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2479 if (FLAG_trace) { 2519 if (FLAG_trace) {
2480 __ CallRuntime(Runtime::kTraceTailCall); 2520 __ CallRuntime(Runtime::kTraceTailCall);
2481 } 2521 }
2482 // Update profiling counters before the tail call since we will 2522 // Update profiling counters before the tail call since we will
2483 // not return to this function. 2523 // not return to this function.
2484 EmitProfilingCounterHandlingForReturnSequence(true); 2524 EmitProfilingCounterHandlingForReturnSequence(true);
2485 } 2525 }
2486 Handle<Code> ic = 2526 Handle<Code> ic =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 // Generate code for loading from variables potentially shadowed 2574 // Generate code for loading from variables potentially shadowed
2535 // by eval-introduced variables. 2575 // by eval-introduced variables.
2536 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2576 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2537 2577
2538 __ bind(&slow); 2578 __ bind(&slow);
2539 // Call the runtime to find the function to call (returned in r0) 2579 // Call the runtime to find the function to call (returned in r0)
2540 // and the object holding it (returned in edx). 2580 // and the object holding it (returned in edx).
2541 __ Push(callee->name()); 2581 __ Push(callee->name());
2542 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2582 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2543 PushOperands(r0, r1); // Function, receiver. 2583 PushOperands(r0, r1); // Function, receiver.
2544 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2584 PrepareForBailoutForId(expr->LookupId(),
2585 Deoptimizer::BailoutState::NO_REGISTERS);
2545 2586
2546 // If fast case code has been generated, emit code to push the 2587 // If fast case code has been generated, emit code to push the
2547 // function and receiver and have the slow path jump around this 2588 // function and receiver and have the slow path jump around this
2548 // code. 2589 // code.
2549 if (done.is_linked()) { 2590 if (done.is_linked()) {
2550 Label call; 2591 Label call;
2551 __ b(&call); 2592 __ b(&call);
2552 __ bind(&done); 2593 __ bind(&done);
2553 // Push function. 2594 // Push function.
2554 __ push(r0); 2595 __ push(r0);
(...skipping 28 matching lines...) Expand all
2583 2624
2584 // Push a copy of the function (found below the arguments) and 2625 // Push a copy of the function (found below the arguments) and
2585 // resolve eval. 2626 // resolve eval.
2586 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2627 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2587 __ push(r1); 2628 __ push(r1);
2588 EmitResolvePossiblyDirectEval(expr); 2629 EmitResolvePossiblyDirectEval(expr);
2589 2630
2590 // Touch up the stack with the resolved function. 2631 // Touch up the stack with the resolved function.
2591 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2632 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2592 2633
2593 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2634 PrepareForBailoutForId(expr->EvalId(),
2635 Deoptimizer::BailoutState::NO_REGISTERS);
2594 2636
2595 // Record source position for debugger. 2637 // Record source position for debugger.
2596 SetCallPosition(expr); 2638 SetCallPosition(expr);
2597 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2639 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2598 __ mov(r0, Operand(arg_count)); 2640 __ mov(r0, Operand(arg_count));
2599 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2641 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2600 expr->tail_call_mode()), 2642 expr->tail_call_mode()),
2601 RelocInfo::CODE_TARGET); 2643 RelocInfo::CODE_TARGET);
2602 OperandStackDepthDecrement(arg_count + 1); 2644 OperandStackDepthDecrement(arg_count + 1);
2603 RecordJSReturnSite(expr); 2645 RecordJSReturnSite(expr);
(...skipping 29 matching lines...) Expand all
2633 __ mov(r0, Operand(arg_count)); 2675 __ mov(r0, Operand(arg_count));
2634 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2676 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2635 2677
2636 // Record call targets in unoptimized code. 2678 // Record call targets in unoptimized code.
2637 __ EmitLoadTypeFeedbackVector(r2); 2679 __ EmitLoadTypeFeedbackVector(r2);
2638 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2680 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2639 2681
2640 CallConstructStub stub(isolate()); 2682 CallConstructStub stub(isolate());
2641 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2683 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2642 OperandStackDepthDecrement(arg_count + 1); 2684 OperandStackDepthDecrement(arg_count + 1);
2643 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2685 PrepareForBailoutForId(expr->ReturnId(),
2686 Deoptimizer::BailoutState::TOS_REGISTER);
2644 RestoreContext(); 2687 RestoreContext();
2645 context()->Plug(r0); 2688 context()->Plug(r0);
2646 } 2689 }
2647 2690
2648 2691
2649 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2692 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2650 SuperCallReference* super_call_ref = 2693 SuperCallReference* super_call_ref =
2651 expr->expression()->AsSuperCallReference(); 2694 expr->expression()->AsSuperCallReference();
2652 DCHECK_NOT_NULL(super_call_ref); 2695 DCHECK_NOT_NULL(super_call_ref);
2653 2696
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
3065 } 3108 }
3066 3109
3067 3110
3068 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 3111 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
3069 ZoneList<Expression*>* args = expr->arguments(); 3112 ZoneList<Expression*>* args = expr->arguments();
3070 DCHECK_LE(2, args->length()); 3113 DCHECK_LE(2, args->length());
3071 // Push target, receiver and arguments onto the stack. 3114 // Push target, receiver and arguments onto the stack.
3072 for (Expression* const arg : *args) { 3115 for (Expression* const arg : *args) {
3073 VisitForStackValue(arg); 3116 VisitForStackValue(arg);
3074 } 3117 }
3075 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3118 PrepareForBailoutForId(expr->CallId(),
3119 Deoptimizer::BailoutState::NO_REGISTERS);
3076 // Move target to r1. 3120 // Move target to r1.
3077 int const argc = args->length() - 2; 3121 int const argc = args->length() - 2;
3078 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); 3122 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
3079 // Call the target. 3123 // Call the target.
3080 __ mov(r0, Operand(argc)); 3124 __ mov(r0, Operand(argc));
3081 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3125 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3082 OperandStackDepthDecrement(argc + 1); 3126 OperandStackDepthDecrement(argc + 1);
3083 RestoreContext(); 3127 RestoreContext();
3084 // Discard the function left on TOS. 3128 // Discard the function left on TOS.
3085 context()->DropAndPlug(1, r0); 3129 context()->DropAndPlug(1, r0);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3275 // because we need to prepare a pair of extra administrative AST ids 3319 // because we need to prepare a pair of extra administrative AST ids
3276 // for the optimizing compiler. 3320 // for the optimizing compiler.
3277 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3321 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3278 Label materialize_true, materialize_false, done; 3322 Label materialize_true, materialize_false, done;
3279 VisitForControl(expr->expression(), 3323 VisitForControl(expr->expression(),
3280 &materialize_false, 3324 &materialize_false,
3281 &materialize_true, 3325 &materialize_true,
3282 &materialize_true); 3326 &materialize_true);
3283 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3327 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3284 __ bind(&materialize_true); 3328 __ bind(&materialize_true);
3285 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3329 PrepareForBailoutForId(expr->MaterializeTrueId(),
3330 Deoptimizer::BailoutState::NO_REGISTERS);
3286 __ LoadRoot(r0, Heap::kTrueValueRootIndex); 3331 __ LoadRoot(r0, Heap::kTrueValueRootIndex);
3287 if (context()->IsStackValue()) __ push(r0); 3332 if (context()->IsStackValue()) __ push(r0);
3288 __ jmp(&done); 3333 __ jmp(&done);
3289 __ bind(&materialize_false); 3334 __ bind(&materialize_false);
3290 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3335 PrepareForBailoutForId(expr->MaterializeFalseId(),
3336 Deoptimizer::BailoutState::NO_REGISTERS);
3291 __ LoadRoot(r0, Heap::kFalseValueRootIndex); 3337 __ LoadRoot(r0, Heap::kFalseValueRootIndex);
3292 if (context()->IsStackValue()) __ push(r0); 3338 if (context()->IsStackValue()) __ push(r0);
3293 __ bind(&done); 3339 __ bind(&done);
3294 } 3340 }
3295 break; 3341 break;
3296 } 3342 }
3297 3343
3298 case Token::TYPEOF: { 3344 case Token::TYPEOF: {
3299 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3345 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3300 { 3346 {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 } 3428 }
3383 3429
3384 case VARIABLE: 3430 case VARIABLE:
3385 UNREACHABLE(); 3431 UNREACHABLE();
3386 } 3432 }
3387 } 3433 }
3388 3434
3389 // We need a second deoptimization point after loading the value 3435 // We need a second deoptimization point after loading the value
3390 // in case evaluating the property load my have a side effect. 3436 // in case evaluating the property load my have a side effect.
3391 if (assign_type == VARIABLE) { 3437 if (assign_type == VARIABLE) {
3392 PrepareForBailout(expr->expression(), TOS_REG); 3438 PrepareForBailout(expr->expression(),
3439 Deoptimizer::BailoutState::TOS_REGISTER);
3393 } else { 3440 } else {
3394 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 3441 PrepareForBailoutForId(prop->LoadId(),
3442 Deoptimizer::BailoutState::TOS_REGISTER);
3395 } 3443 }
3396 3444
3397 // Inline smi case if we are in a loop. 3445 // Inline smi case if we are in a loop.
3398 Label stub_call, done; 3446 Label stub_call, done;
3399 JumpPatchSite patch_site(masm_); 3447 JumpPatchSite patch_site(masm_);
3400 3448
3401 int count_value = expr->op() == Token::INC ? 1 : -1; 3449 int count_value = expr->op() == Token::INC ? 1 : -1;
3402 if (ShouldInlineSmiCase(expr->op())) { 3450 if (ShouldInlineSmiCase(expr->op())) {
3403 Label slow; 3451 Label slow;
3404 patch_site.EmitJumpIfNotSmi(r0, &slow); 3452 patch_site.EmitJumpIfNotSmi(r0, &slow);
(...skipping 28 matching lines...) Expand all
3433 __ b(vc, &done); 3481 __ b(vc, &done);
3434 // Call stub. Undo operation first. 3482 // Call stub. Undo operation first.
3435 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); 3483 __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
3436 __ jmp(&stub_call); 3484 __ jmp(&stub_call);
3437 __ bind(&slow); 3485 __ bind(&slow);
3438 } 3486 }
3439 3487
3440 // Convert old value into a number. 3488 // Convert old value into a number.
3441 ToNumberStub convert_stub(isolate()); 3489 ToNumberStub convert_stub(isolate());
3442 __ CallStub(&convert_stub); 3490 __ CallStub(&convert_stub);
3443 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); 3491 PrepareForBailoutForId(expr->ToNumberId(),
3492 Deoptimizer::BailoutState::TOS_REGISTER);
3444 3493
3445 // Save result for postfix expressions. 3494 // Save result for postfix expressions.
3446 if (expr->is_postfix()) { 3495 if (expr->is_postfix()) {
3447 if (!context()->IsEffect()) { 3496 if (!context()->IsEffect()) {
3448 // Save the result on the stack. If we have a named or keyed property 3497 // Save the result on the stack. If we have a named or keyed property
3449 // we store the result under the receiver that is currently on top 3498 // we store the result under the receiver that is currently on top
3450 // of the stack. 3499 // of the stack.
3451 switch (assign_type) { 3500 switch (assign_type) {
3452 case VARIABLE: 3501 case VARIABLE:
3453 PushOperand(r0); 3502 PushOperand(r0);
(...skipping 26 matching lines...) Expand all
3480 patch_site.EmitPatchInfo(); 3529 patch_site.EmitPatchInfo();
3481 __ bind(&done); 3530 __ bind(&done);
3482 3531
3483 // Store the value returned in r0. 3532 // Store the value returned in r0.
3484 switch (assign_type) { 3533 switch (assign_type) {
3485 case VARIABLE: 3534 case VARIABLE:
3486 if (expr->is_postfix()) { 3535 if (expr->is_postfix()) {
3487 { EffectContext context(this); 3536 { EffectContext context(this);
3488 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3537 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3489 Token::ASSIGN, expr->CountSlot()); 3538 Token::ASSIGN, expr->CountSlot());
3490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3539 PrepareForBailoutForId(expr->AssignmentId(),
3540 Deoptimizer::BailoutState::TOS_REGISTER);
3491 context.Plug(r0); 3541 context.Plug(r0);
3492 } 3542 }
3493 // For all contexts except EffectConstant We have the result on 3543 // For all contexts except EffectConstant We have the result on
3494 // top of the stack. 3544 // top of the stack.
3495 if (!context()->IsEffect()) { 3545 if (!context()->IsEffect()) {
3496 context()->PlugTOS(); 3546 context()->PlugTOS();
3497 } 3547 }
3498 } else { 3548 } else {
3499 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3549 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3500 Token::ASSIGN, expr->CountSlot()); 3550 Token::ASSIGN, expr->CountSlot());
3501 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3551 PrepareForBailoutForId(expr->AssignmentId(),
3552 Deoptimizer::BailoutState::TOS_REGISTER);
3502 context()->Plug(r0); 3553 context()->Plug(r0);
3503 } 3554 }
3504 break; 3555 break;
3505 case NAMED_PROPERTY: { 3556 case NAMED_PROPERTY: {
3506 __ mov(StoreDescriptor::NameRegister(), 3557 __ mov(StoreDescriptor::NameRegister(),
3507 Operand(prop->key()->AsLiteral()->value())); 3558 Operand(prop->key()->AsLiteral()->value()));
3508 PopOperand(StoreDescriptor::ReceiverRegister()); 3559 PopOperand(StoreDescriptor::ReceiverRegister());
3509 EmitLoadStoreICSlot(expr->CountSlot()); 3560 EmitLoadStoreICSlot(expr->CountSlot());
3510 CallStoreIC(); 3561 CallStoreIC();
3511 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3562 PrepareForBailoutForId(expr->AssignmentId(),
3563 Deoptimizer::BailoutState::TOS_REGISTER);
3512 if (expr->is_postfix()) { 3564 if (expr->is_postfix()) {
3513 if (!context()->IsEffect()) { 3565 if (!context()->IsEffect()) {
3514 context()->PlugTOS(); 3566 context()->PlugTOS();
3515 } 3567 }
3516 } else { 3568 } else {
3517 context()->Plug(r0); 3569 context()->Plug(r0);
3518 } 3570 }
3519 break; 3571 break;
3520 } 3572 }
3521 case NAMED_SUPER_PROPERTY: { 3573 case NAMED_SUPER_PROPERTY: {
(...skipping 18 matching lines...) Expand all
3540 } 3592 }
3541 break; 3593 break;
3542 } 3594 }
3543 case KEYED_PROPERTY: { 3595 case KEYED_PROPERTY: {
3544 PopOperands(StoreDescriptor::ReceiverRegister(), 3596 PopOperands(StoreDescriptor::ReceiverRegister(),
3545 StoreDescriptor::NameRegister()); 3597 StoreDescriptor::NameRegister());
3546 Handle<Code> ic = 3598 Handle<Code> ic =
3547 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3599 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3548 EmitLoadStoreICSlot(expr->CountSlot()); 3600 EmitLoadStoreICSlot(expr->CountSlot());
3549 CallIC(ic); 3601 CallIC(ic);
3550 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3602 PrepareForBailoutForId(expr->AssignmentId(),
3603 Deoptimizer::BailoutState::TOS_REGISTER);
3551 if (expr->is_postfix()) { 3604 if (expr->is_postfix()) {
3552 if (!context()->IsEffect()) { 3605 if (!context()->IsEffect()) {
3553 context()->PlugTOS(); 3606 context()->PlugTOS();
3554 } 3607 }
3555 } else { 3608 } else {
3556 context()->Plug(r0); 3609 context()->Plug(r0);
3557 } 3610 }
3558 break; 3611 break;
3559 } 3612 }
3560 } 3613 }
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
3990 DCHECK(interrupt_address == 4043 DCHECK(interrupt_address ==
3991 isolate->builtins()->OnStackReplacement()->entry()); 4044 isolate->builtins()->OnStackReplacement()->entry());
3992 return ON_STACK_REPLACEMENT; 4045 return ON_STACK_REPLACEMENT;
3993 } 4046 }
3994 4047
3995 4048
3996 } // namespace internal 4049 } // namespace internal
3997 } // namespace v8 4050 } // namespace v8
3998 4051
3999 #endif // V8_TARGET_ARCH_ARM 4052 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698