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

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: Review comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/deoptimizer.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 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 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 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 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(), BailoutState::NO_REGISTERS);
409 // Record a mapping of the OSR id to this PC. This is used if the OSR 413 // 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 414 // entry becomes the target of a bailout. We don't expect it to be, but
411 // we want it to work if it is. 415 // we want it to work if it is.
412 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 416 PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS);
413 } 417 }
414 418
415 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 419 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
416 bool is_tail_call) { 420 bool is_tail_call) {
417 // Pretend that the exit is a backwards jump to the entry. 421 // Pretend that the exit is a backwards jump to the entry.
418 int weight = 1; 422 int weight = 1;
419 if (info_->ShouldSelfOptimize()) { 423 if (info_->ShouldSelfOptimize()) {
420 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 424 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
421 } else { 425 } else {
422 int distance = masm_->pc_offset(); 426 int distance = masm_->pc_offset();
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 bool should_normalize, 728 bool should_normalize,
725 Label* if_true, 729 Label* if_true,
726 Label* if_false) { 730 Label* if_false) {
727 // Only prepare for bailouts before splits if we're in a test 731 // Only prepare for bailouts before splits if we're in a test
728 // context. Otherwise, we let the Visit function deal with the 732 // context. Otherwise, we let the Visit function deal with the
729 // preparation to avoid preparing with the same AST id twice. 733 // preparation to avoid preparing with the same AST id twice.
730 if (!context()->IsTest()) return; 734 if (!context()->IsTest()) return;
731 735
732 Label skip; 736 Label skip;
733 if (should_normalize) __ b(&skip); 737 if (should_normalize) __ b(&skip);
734 PrepareForBailout(expr, TOS_REG); 738 PrepareForBailout(expr, BailoutState::TOS_REGISTER);
735 if (should_normalize) { 739 if (should_normalize) {
736 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 740 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
737 __ cmp(r0, ip); 741 __ cmp(r0, ip);
738 Split(eq, if_true, if_false, NULL); 742 Split(eq, if_true, if_false, NULL);
739 __ bind(&skip); 743 __ bind(&skip);
740 } 744 }
741 } 745 }
742 746
743 747
744 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 748 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 786 }
783 break; 787 break;
784 788
785 case VariableLocation::CONTEXT: 789 case VariableLocation::CONTEXT:
786 if (hole_init) { 790 if (hole_init) {
787 Comment cmnt(masm_, "[ VariableDeclaration"); 791 Comment cmnt(masm_, "[ VariableDeclaration");
788 EmitDebugCheckDeclarationContext(variable); 792 EmitDebugCheckDeclarationContext(variable);
789 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 793 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
790 __ str(r0, ContextMemOperand(cp, variable->index())); 794 __ str(r0, ContextMemOperand(cp, variable->index()));
791 // No write barrier since the_hole_value is in old space. 795 // No write barrier since the_hole_value is in old space.
792 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 796 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
793 } 797 }
794 break; 798 break;
795 799
796 case VariableLocation::LOOKUP: { 800 case VariableLocation::LOOKUP: {
797 Comment cmnt(masm_, "[ VariableDeclaration"); 801 Comment cmnt(masm_, "[ VariableDeclaration");
798 __ mov(r2, Operand(variable->name())); 802 __ mov(r2, Operand(variable->name()));
799 // Declaration nodes are always introduced in one of four modes. 803 // Declaration nodes are always introduced in one of four modes.
800 DCHECK(IsDeclaredVariableMode(mode)); 804 DCHECK(IsDeclaredVariableMode(mode));
801 // Push initial value, if any. 805 // Push initial value, if any.
802 // 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
803 // 'undefined') because we may have a (legal) redeclaration and we 807 // 'undefined') because we may have a (legal) redeclaration and we
804 // must not destroy the current value. 808 // must not destroy the current value.
805 if (hole_init) { 809 if (hole_init) {
806 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 810 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
807 } else { 811 } else {
808 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. 812 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value.
809 } 813 }
810 __ Push(r2, r0); 814 __ Push(r2, r0);
811 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 815 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
812 __ CallRuntime(Runtime::kDeclareLookupSlot); 816 __ CallRuntime(Runtime::kDeclareLookupSlot);
813 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 817 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
814 break; 818 break;
815 } 819 }
816 } 820 }
817 } 821 }
818 822
819 823
820 void FullCodeGenerator::VisitFunctionDeclaration( 824 void FullCodeGenerator::VisitFunctionDeclaration(
821 FunctionDeclaration* declaration) { 825 FunctionDeclaration* declaration) {
822 VariableProxy* proxy = declaration->proxy(); 826 VariableProxy* proxy = declaration->proxy();
823 Variable* variable = proxy->var(); 827 Variable* variable = proxy->var();
(...skipping 25 matching lines...) Expand all
849 int offset = Context::SlotOffset(variable->index()); 853 int offset = Context::SlotOffset(variable->index());
850 // We know that we have written a function, which is not a smi. 854 // We know that we have written a function, which is not a smi.
851 __ RecordWriteContextSlot(cp, 855 __ RecordWriteContextSlot(cp,
852 offset, 856 offset,
853 result_register(), 857 result_register(),
854 r2, 858 r2,
855 kLRHasBeenSaved, 859 kLRHasBeenSaved,
856 kDontSaveFPRegs, 860 kDontSaveFPRegs,
857 EMIT_REMEMBERED_SET, 861 EMIT_REMEMBERED_SET,
858 OMIT_SMI_CHECK); 862 OMIT_SMI_CHECK);
859 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 863 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
860 break; 864 break;
861 } 865 }
862 866
863 case VariableLocation::LOOKUP: { 867 case VariableLocation::LOOKUP: {
864 Comment cmnt(masm_, "[ FunctionDeclaration"); 868 Comment cmnt(masm_, "[ FunctionDeclaration");
865 __ mov(r2, Operand(variable->name())); 869 __ mov(r2, Operand(variable->name()));
866 PushOperand(r2); 870 PushOperand(r2);
867 // Push initial value for function declaration. 871 // Push initial value for function declaration.
868 VisitForStackValue(declaration->fun()); 872 VisitForStackValue(declaration->fun());
869 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 873 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
870 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 874 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
871 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 875 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
872 break; 876 break;
873 } 877 }
874 } 878 }
875 } 879 }
876 880
877 881
878 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 882 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
879 // Call the runtime to declare the globals. 883 // Call the runtime to declare the globals.
880 __ mov(r1, Operand(pairs)); 884 __ mov(r1, Operand(pairs));
881 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 885 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
(...skipping 11 matching lines...) Expand all
893 } 897 }
894 898
895 899
896 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 900 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
897 Comment cmnt(masm_, "[ SwitchStatement"); 901 Comment cmnt(masm_, "[ SwitchStatement");
898 Breakable nested_statement(this, stmt); 902 Breakable nested_statement(this, stmt);
899 SetStatementPosition(stmt); 903 SetStatementPosition(stmt);
900 904
901 // Keep the switch value on the stack until a case matches. 905 // Keep the switch value on the stack until a case matches.
902 VisitForStackValue(stmt->tag()); 906 VisitForStackValue(stmt->tag());
903 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 907 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
904 908
905 ZoneList<CaseClause*>* clauses = stmt->cases(); 909 ZoneList<CaseClause*>* clauses = stmt->cases();
906 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 910 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
907 911
908 Label next_test; // Recycled for each test. 912 Label next_test; // Recycled for each test.
909 // Compile all the tests with branches to their bodies. 913 // Compile all the tests with branches to their bodies.
910 for (int i = 0; i < clauses->length(); i++) { 914 for (int i = 0; i < clauses->length(); i++) {
911 CaseClause* clause = clauses->at(i); 915 CaseClause* clause = clauses->at(i);
912 clause->body_target()->Unuse(); 916 clause->body_target()->Unuse();
913 917
(...skipping 28 matching lines...) Expand all
942 946
943 // Record position before stub call for type feedback. 947 // Record position before stub call for type feedback.
944 SetExpressionPosition(clause); 948 SetExpressionPosition(clause);
945 Handle<Code> ic = 949 Handle<Code> ic =
946 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 950 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
947 CallIC(ic, clause->CompareId()); 951 CallIC(ic, clause->CompareId());
948 patch_site.EmitPatchInfo(); 952 patch_site.EmitPatchInfo();
949 953
950 Label skip; 954 Label skip;
951 __ b(&skip); 955 __ b(&skip);
952 PrepareForBailout(clause, TOS_REG); 956 PrepareForBailout(clause, BailoutState::TOS_REGISTER);
953 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 957 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
954 __ cmp(r0, ip); 958 __ cmp(r0, ip);
955 __ b(ne, &next_test); 959 __ b(ne, &next_test);
956 __ Drop(1); 960 __ Drop(1);
957 __ jmp(clause->body_target()); 961 __ jmp(clause->body_target());
958 __ bind(&skip); 962 __ bind(&skip);
959 963
960 __ cmp(r0, Operand::Zero()); 964 __ cmp(r0, Operand::Zero());
961 __ b(ne, &next_test); 965 __ b(ne, &next_test);
962 __ Drop(1); // Switch value is no longer needed. 966 __ Drop(1); // Switch value is no longer needed.
963 __ b(clause->body_target()); 967 __ b(clause->body_target());
964 } 968 }
965 969
966 // Discard the test value and jump to the default if present, otherwise to 970 // Discard the test value and jump to the default if present, otherwise to
967 // the end of the statement. 971 // the end of the statement.
968 __ bind(&next_test); 972 __ bind(&next_test);
969 DropOperands(1); // Switch value is no longer needed. 973 DropOperands(1); // Switch value is no longer needed.
970 if (default_clause == NULL) { 974 if (default_clause == NULL) {
971 __ b(nested_statement.break_label()); 975 __ b(nested_statement.break_label());
972 } else { 976 } else {
973 __ b(default_clause->body_target()); 977 __ b(default_clause->body_target());
974 } 978 }
975 979
976 // Compile all the case bodies. 980 // Compile all the case bodies.
977 for (int i = 0; i < clauses->length(); i++) { 981 for (int i = 0; i < clauses->length(); i++) {
978 Comment cmnt(masm_, "[ Case body"); 982 Comment cmnt(masm_, "[ Case body");
979 CaseClause* clause = clauses->at(i); 983 CaseClause* clause = clauses->at(i);
980 __ bind(clause->body_target()); 984 __ bind(clause->body_target());
981 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 985 PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS);
982 VisitStatements(clause->statements()); 986 VisitStatements(clause->statements());
983 } 987 }
984 988
985 __ bind(nested_statement.break_label()); 989 __ bind(nested_statement.break_label());
986 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 990 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
987 } 991 }
988 992
989 993
990 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 994 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
991 Comment cmnt(masm_, "[ ForInStatement"); 995 Comment cmnt(masm_, "[ ForInStatement");
992 SetStatementPosition(stmt, SKIP_BREAK); 996 SetStatementPosition(stmt, SKIP_BREAK);
993 997
994 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 998 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
995 999
996 // Get the object to enumerate over. 1000 // Get the object to enumerate over.
(...skipping 12 matching lines...) Expand all
1009 __ CompareObjectType(r0, r1, r1, FIRST_JS_RECEIVER_TYPE); 1013 __ CompareObjectType(r0, r1, r1, FIRST_JS_RECEIVER_TYPE);
1010 __ b(ge, &done_convert); 1014 __ b(ge, &done_convert);
1011 __ CompareRoot(r0, Heap::kNullValueRootIndex); 1015 __ CompareRoot(r0, Heap::kNullValueRootIndex);
1012 __ b(eq, &exit); 1016 __ b(eq, &exit);
1013 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); 1017 __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
1014 __ b(eq, &exit); 1018 __ b(eq, &exit);
1015 __ bind(&convert); 1019 __ bind(&convert);
1016 ToObjectStub stub(isolate()); 1020 ToObjectStub stub(isolate());
1017 __ CallStub(&stub); 1021 __ CallStub(&stub);
1018 __ bind(&done_convert); 1022 __ bind(&done_convert);
1019 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); 1023 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
1020 __ push(r0); 1024 __ push(r0);
1021 1025
1022 // Check cache validity in generated code. If we cannot guarantee cache 1026 // Check cache validity in generated code. If we cannot guarantee cache
1023 // validity, call the runtime system to check cache validity or get the 1027 // 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, 1028 // property names in a fixed array. Note: Proxies never have an enum cache,
1025 // so will always take the slow path. 1029 // so will always take the slow path.
1026 Label call_runtime; 1030 Label call_runtime;
1027 __ CheckEnumCache(&call_runtime); 1031 __ CheckEnumCache(&call_runtime);
1028 1032
1029 // The enum cache is valid. Load the map of the object being 1033 // The enum cache is valid. Load the map of the object being
1030 // iterated over and use the cache for the iteration. 1034 // iterated over and use the cache for the iteration.
1031 Label use_cache; 1035 Label use_cache;
1032 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); 1036 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
1033 __ b(&use_cache); 1037 __ b(&use_cache);
1034 1038
1035 // Get the set of properties to enumerate. 1039 // Get the set of properties to enumerate.
1036 __ bind(&call_runtime); 1040 __ bind(&call_runtime);
1037 __ push(r0); // Duplicate the enumerable object on the stack. 1041 __ push(r0); // Duplicate the enumerable object on the stack.
1038 __ CallRuntime(Runtime::kForInEnumerate); 1042 __ CallRuntime(Runtime::kForInEnumerate);
1039 PrepareForBailoutForId(stmt->EnumId(), TOS_REG); 1043 PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER);
1040 1044
1041 // If we got a map from the runtime call, we can do a fast 1045 // 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 1046 // modification check. Otherwise, we got a fixed array, and we have
1043 // to do a slow check. 1047 // to do a slow check.
1044 Label fixed_array; 1048 Label fixed_array;
1045 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 1049 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1046 __ LoadRoot(ip, Heap::kMetaMapRootIndex); 1050 __ LoadRoot(ip, Heap::kMetaMapRootIndex);
1047 __ cmp(r2, ip); 1051 __ cmp(r2, ip);
1048 __ b(ne, &fixed_array); 1052 __ b(ne, &fixed_array);
1049 1053
(...skipping 20 matching lines...) Expand all
1070 __ Drop(1); 1074 __ Drop(1);
1071 __ jmp(&exit); 1075 __ jmp(&exit);
1072 1076
1073 // We got a fixed array in register r0. Iterate through that. 1077 // We got a fixed array in register r0. Iterate through that.
1074 __ bind(&fixed_array); 1078 __ bind(&fixed_array);
1075 1079
1076 __ mov(r1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check 1080 __ mov(r1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check
1077 __ Push(r1, r0); // Smi and array 1081 __ Push(r1, r0); // Smi and array
1078 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); 1082 __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
1079 __ Push(r1); // Fixed array length (as smi). 1083 __ Push(r1); // Fixed array length (as smi).
1080 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); 1084 PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS);
1081 __ mov(r0, Operand(Smi::FromInt(0))); 1085 __ mov(r0, Operand(Smi::FromInt(0)));
1082 __ Push(r0); // Initial index. 1086 __ Push(r0); // Initial index.
1083 1087
1084 // Generate code for doing the condition check. 1088 // Generate code for doing the condition check.
1085 __ bind(&loop); 1089 __ bind(&loop);
1086 SetExpressionAsStatementPosition(stmt->each()); 1090 SetExpressionAsStatementPosition(stmt->each());
1087 1091
1088 // Load the current count to r0, load the length to r1. 1092 // Load the current count to r0, load the length to r1.
1089 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize)); 1093 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
1090 __ cmp(r0, r1); // Compare to the array length. 1094 __ cmp(r0, r1); // Compare to the array length.
(...skipping 21 matching lines...) Expand all
1112 __ EmitLoadTypeFeedbackVector(r0); 1116 __ EmitLoadTypeFeedbackVector(r0);
1113 __ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1117 __ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1114 __ str(r2, FieldMemOperand(r0, FixedArray::OffsetOfElementAt(vector_index))); 1118 __ str(r2, FieldMemOperand(r0, FixedArray::OffsetOfElementAt(vector_index)));
1115 1119
1116 // Convert the entry to a string or (smi) 0 if it isn't a property 1120 // 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 1121 // any more. If the property has been removed while iterating, we
1118 // just skip it. 1122 // just skip it.
1119 __ push(r1); // Enumerable. 1123 __ push(r1); // Enumerable.
1120 __ push(r3); // Current entry. 1124 __ push(r3); // Current entry.
1121 __ CallRuntime(Runtime::kForInFilter); 1125 __ CallRuntime(Runtime::kForInFilter);
1122 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1126 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
1123 __ mov(r3, Operand(r0)); 1127 __ mov(r3, Operand(r0));
1124 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1128 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1125 __ cmp(r0, ip); 1129 __ cmp(r0, ip);
1126 __ b(eq, loop_statement.continue_label()); 1130 __ b(eq, loop_statement.continue_label());
1127 1131
1128 // Update the 'each' property or variable from the possibly filtered 1132 // Update the 'each' property or variable from the possibly filtered
1129 // entry in register r3. 1133 // entry in register r3.
1130 __ bind(&update_each); 1134 __ bind(&update_each);
1131 __ mov(result_register(), r3); 1135 __ mov(result_register(), r3);
1132 // Perform the assignment as if via '='. 1136 // Perform the assignment as if via '='.
1133 { EffectContext context(this); 1137 { EffectContext context(this);
1134 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1138 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1135 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1139 PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS);
1136 } 1140 }
1137 1141
1138 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1142 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1139 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1143 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
1140 // Generate code for the body of the loop. 1144 // Generate code for the body of the loop.
1141 Visit(stmt->body()); 1145 Visit(stmt->body());
1142 1146
1143 // Generate code for the going to the next element by incrementing 1147 // Generate code for the going to the next element by incrementing
1144 // the index (smi) stored on top of the stack. 1148 // the index (smi) stored on top of the stack.
1145 __ bind(loop_statement.continue_label()); 1149 __ bind(loop_statement.continue_label());
1146 __ pop(r0); 1150 __ pop(r0);
1147 __ add(r0, r0, Operand(Smi::FromInt(1))); 1151 __ add(r0, r0, Operand(Smi::FromInt(1)));
1148 __ push(r0); 1152 __ push(r0);
1149 1153
1150 EmitBackEdgeBookkeeping(stmt, &loop); 1154 EmitBackEdgeBookkeeping(stmt, &loop);
1151 __ b(&loop); 1155 __ b(&loop);
1152 1156
1153 // Remove the pointers stored on the stack. 1157 // Remove the pointers stored on the stack.
1154 __ bind(loop_statement.break_label()); 1158 __ bind(loop_statement.break_label());
1155 DropOperands(5); 1159 DropOperands(5);
1156 1160
1157 // Exit and decrement the loop depth. 1161 // Exit and decrement the loop depth.
1158 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1162 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1159 __ bind(&exit); 1163 __ bind(&exit);
1160 decrement_loop_depth(); 1164 decrement_loop_depth();
1161 } 1165 }
1162 1166
1163 1167
1164 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1168 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1165 FeedbackVectorSlot slot) { 1169 FeedbackVectorSlot slot) {
1166 DCHECK(NeedsHomeObject(initializer)); 1170 DCHECK(NeedsHomeObject(initializer));
1167 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1171 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1168 __ mov(StoreDescriptor::NameRegister(), 1172 __ mov(StoreDescriptor::NameRegister(),
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 __ mov(LoadDescriptor::SlotRegister(), 1311 __ mov(LoadDescriptor::SlotRegister(),
1308 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1312 Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
1309 CallLoadIC(typeof_mode); 1313 CallLoadIC(typeof_mode);
1310 } 1314 }
1311 1315
1312 1316
1313 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1317 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1314 TypeofMode typeof_mode) { 1318 TypeofMode typeof_mode) {
1315 // Record position before possible IC call. 1319 // Record position before possible IC call.
1316 SetExpressionPosition(proxy); 1320 SetExpressionPosition(proxy);
1317 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); 1321 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1318 Variable* var = proxy->var(); 1322 Variable* var = proxy->var();
1319 1323
1320 // Three cases: global variables, lookup variables, and all other types of 1324 // Three cases: global variables, lookup variables, and all other types of
1321 // variables. 1325 // variables.
1322 switch (var->location()) { 1326 switch (var->location()) {
1323 case VariableLocation::GLOBAL: 1327 case VariableLocation::GLOBAL:
1324 case VariableLocation::UNALLOCATED: { 1328 case VariableLocation::UNALLOCATED: {
1325 Comment cmnt(masm_, "[ Global variable"); 1329 Comment cmnt(masm_, "[ Global variable");
1326 EmitGlobalVariableLoad(proxy, typeof_mode); 1330 EmitGlobalVariableLoad(proxy, typeof_mode);
1327 context()->Plug(r0); 1331 context()->Plug(r0);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 int flags = expr->ComputeFlags(); 1418 int flags = expr->ComputeFlags();
1415 __ mov(r0, Operand(Smi::FromInt(flags))); 1419 __ mov(r0, Operand(Smi::FromInt(flags)));
1416 if (MustCreateObjectLiteralWithRuntime(expr)) { 1420 if (MustCreateObjectLiteralWithRuntime(expr)) {
1417 __ Push(r3, r2, r1, r0); 1421 __ Push(r3, r2, r1, r0);
1418 __ CallRuntime(Runtime::kCreateObjectLiteral); 1422 __ CallRuntime(Runtime::kCreateObjectLiteral);
1419 } else { 1423 } else {
1420 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1424 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1421 __ CallStub(&stub); 1425 __ CallStub(&stub);
1422 RestoreContext(); 1426 RestoreContext();
1423 } 1427 }
1424 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1428 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1425 1429
1426 // If result_saved is true the result is on top of the stack. If 1430 // If result_saved is true the result is on top of the stack. If
1427 // result_saved is false the result is in r0. 1431 // result_saved is false the result is in r0.
1428 bool result_saved = false; 1432 bool result_saved = false;
1429 1433
1430 AccessorTable accessor_table(zone()); 1434 AccessorTable accessor_table(zone());
1431 int property_index = 0; 1435 int property_index = 0;
1432 for (; property_index < expr->properties()->length(); property_index++) { 1436 for (; property_index < expr->properties()->length(); property_index++) {
1433 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1437 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1434 if (property->is_computed_name()) break; 1438 if (property->is_computed_name()) break;
(...skipping 15 matching lines...) Expand all
1450 // It is safe to use [[Put]] here because the boilerplate already 1454 // It is safe to use [[Put]] here because the boilerplate already
1451 // contains computed properties with an uninitialized value. 1455 // contains computed properties with an uninitialized value.
1452 if (key->value()->IsInternalizedString()) { 1456 if (key->value()->IsInternalizedString()) {
1453 if (property->emit_store()) { 1457 if (property->emit_store()) {
1454 VisitForAccumulatorValue(value); 1458 VisitForAccumulatorValue(value);
1455 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 1459 DCHECK(StoreDescriptor::ValueRegister().is(r0));
1456 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); 1460 __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1457 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1461 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1458 EmitLoadStoreICSlot(property->GetSlot(0)); 1462 EmitLoadStoreICSlot(property->GetSlot(0));
1459 CallStoreIC(); 1463 CallStoreIC();
1460 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1464 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS);
1461 1465
1462 if (NeedsHomeObject(value)) { 1466 if (NeedsHomeObject(value)) {
1463 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1467 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1464 } 1468 }
1465 } else { 1469 } else {
1466 VisitForEffect(value); 1470 VisitForEffect(value);
1467 } 1471 }
1468 break; 1472 break;
1469 } 1473 }
1470 // Duplicate receiver on stack. 1474 // Duplicate receiver on stack.
(...skipping 13 matching lines...) Expand all
1484 } 1488 }
1485 break; 1489 break;
1486 case ObjectLiteral::Property::PROTOTYPE: 1490 case ObjectLiteral::Property::PROTOTYPE:
1487 // Duplicate receiver on stack. 1491 // Duplicate receiver on stack.
1488 __ ldr(r0, MemOperand(sp)); 1492 __ ldr(r0, MemOperand(sp));
1489 PushOperand(r0); 1493 PushOperand(r0);
1490 VisitForStackValue(value); 1494 VisitForStackValue(value);
1491 DCHECK(property->emit_store()); 1495 DCHECK(property->emit_store());
1492 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1496 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1493 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1497 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1494 NO_REGISTERS); 1498 BailoutState::NO_REGISTERS);
1495 break; 1499 break;
1496 1500
1497 case ObjectLiteral::Property::GETTER: 1501 case ObjectLiteral::Property::GETTER:
1498 if (property->emit_store()) { 1502 if (property->emit_store()) {
1499 accessor_table.lookup(key)->second->getter = property; 1503 accessor_table.lookup(key)->second->getter = property;
1500 } 1504 }
1501 break; 1505 break;
1502 case ObjectLiteral::Property::SETTER: 1506 case ObjectLiteral::Property::SETTER:
1503 if (property->emit_store()) { 1507 if (property->emit_store()) {
1504 accessor_table.lookup(key)->second->setter = property; 1508 accessor_table.lookup(key)->second->setter = property;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 1546
1543 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. 1547 __ ldr(r0, MemOperand(sp)); // Duplicate receiver.
1544 PushOperand(r0); 1548 PushOperand(r0);
1545 1549
1546 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1550 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1547 DCHECK(!property->is_computed_name()); 1551 DCHECK(!property->is_computed_name());
1548 VisitForStackValue(value); 1552 VisitForStackValue(value);
1549 DCHECK(property->emit_store()); 1553 DCHECK(property->emit_store());
1550 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1554 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1551 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1555 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1552 NO_REGISTERS); 1556 BailoutState::NO_REGISTERS);
1553 } else { 1557 } else {
1554 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1558 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1555 VisitForStackValue(value); 1559 VisitForStackValue(value);
1556 if (NeedsHomeObject(value)) { 1560 if (NeedsHomeObject(value)) {
1557 EmitSetHomeObject(value, 2, property->GetSlot()); 1561 EmitSetHomeObject(value, 2, property->GetSlot());
1558 } 1562 }
1559 1563
1560 switch (property->kind()) { 1564 switch (property->kind()) {
1561 case ObjectLiteral::Property::CONSTANT: 1565 case ObjectLiteral::Property::CONSTANT:
1562 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1566 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()))); 1619 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
1616 __ mov(r1, Operand(constant_elements)); 1620 __ mov(r1, Operand(constant_elements));
1617 if (MustCreateArrayLiteralWithRuntime(expr)) { 1621 if (MustCreateArrayLiteralWithRuntime(expr)) {
1618 __ mov(r0, Operand(Smi::FromInt(expr->ComputeFlags()))); 1622 __ mov(r0, Operand(Smi::FromInt(expr->ComputeFlags())));
1619 __ Push(r3, r2, r1, r0); 1623 __ Push(r3, r2, r1, r0);
1620 __ CallRuntime(Runtime::kCreateArrayLiteral); 1624 __ CallRuntime(Runtime::kCreateArrayLiteral);
1621 } else { 1625 } else {
1622 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1626 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1623 __ CallStub(&stub); 1627 __ CallStub(&stub);
1624 } 1628 }
1625 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1629 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1626 1630
1627 bool result_saved = false; // Is the result saved to the stack? 1631 bool result_saved = false; // Is the result saved to the stack?
1628 ZoneList<Expression*>* subexprs = expr->values(); 1632 ZoneList<Expression*>* subexprs = expr->values();
1629 int length = subexprs->length(); 1633 int length = subexprs->length();
1630 1634
1631 // Emit code to evaluate all the non-constant subexpressions and to store 1635 // Emit code to evaluate all the non-constant subexpressions and to store
1632 // them into the newly cloned array. 1636 // them into the newly cloned array.
1633 int array_index = 0; 1637 int array_index = 0;
1634 for (; array_index < length; array_index++) { 1638 for (; array_index < length; array_index++) {
1635 Expression* subexpr = subexprs->at(array_index); 1639 Expression* subexpr = subexprs->at(array_index);
1636 DCHECK(!subexpr->IsSpread()); 1640 DCHECK(!subexpr->IsSpread());
1637 1641
1638 // If the subexpression is a literal or a simple materialized literal it 1642 // If the subexpression is a literal or a simple materialized literal it
1639 // is already set in the cloned array. 1643 // is already set in the cloned array.
1640 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1644 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1641 1645
1642 if (!result_saved) { 1646 if (!result_saved) {
1643 PushOperand(r0); 1647 PushOperand(r0);
1644 result_saved = true; 1648 result_saved = true;
1645 } 1649 }
1646 VisitForAccumulatorValue(subexpr); 1650 VisitForAccumulatorValue(subexpr);
1647 1651
1648 __ mov(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); 1652 __ mov(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index)));
1649 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1653 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1650 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1654 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1651 Handle<Code> ic = 1655 Handle<Code> ic =
1652 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1656 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1653 CallIC(ic); 1657 CallIC(ic);
1654 1658
1655 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1659 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1660 BailoutState::NO_REGISTERS);
1656 } 1661 }
1657 1662
1658 // In case the array literal contains spread expressions it has two parts. The 1663 // 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 1664 // 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 1665 // 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 1666 // (inclusive) and these elements gets appended to the array. Note that the
1662 // number elements an iterable produces is unknown ahead of time. 1667 // number elements an iterable produces is unknown ahead of time.
1663 if (array_index < length && result_saved) { 1668 if (array_index < length && result_saved) {
1664 PopOperand(r0); 1669 PopOperand(r0);
1665 result_saved = false; 1670 result_saved = false;
1666 } 1671 }
1667 for (; array_index < length; array_index++) { 1672 for (; array_index < length; array_index++) {
1668 Expression* subexpr = subexprs->at(array_index); 1673 Expression* subexpr = subexprs->at(array_index);
1669 1674
1670 PushOperand(r0); 1675 PushOperand(r0);
1671 DCHECK(!subexpr->IsSpread()); 1676 DCHECK(!subexpr->IsSpread());
1672 VisitForStackValue(subexpr); 1677 VisitForStackValue(subexpr);
1673 CallRuntimeWithOperands(Runtime::kAppendElement); 1678 CallRuntimeWithOperands(Runtime::kAppendElement);
1674 1679
1675 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); 1680 PrepareForBailoutForId(expr->GetIdForElement(array_index),
1681 BailoutState::NO_REGISTERS);
1676 } 1682 }
1677 1683
1678 if (result_saved) { 1684 if (result_saved) {
1679 context()->PlugTOS(); 1685 context()->PlugTOS();
1680 } else { 1686 } else {
1681 context()->Plug(r0); 1687 context()->Plug(r0);
1682 } 1688 }
1683 } 1689 }
1684 1690
1685 1691
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1748 break; 1754 break;
1749 } 1755 }
1750 1756
1751 // For compound assignments we need another deoptimization point after the 1757 // For compound assignments we need another deoptimization point after the
1752 // variable/property load. 1758 // variable/property load.
1753 if (expr->is_compound()) { 1759 if (expr->is_compound()) {
1754 { AccumulatorValueContext context(this); 1760 { AccumulatorValueContext context(this);
1755 switch (assign_type) { 1761 switch (assign_type) {
1756 case VARIABLE: 1762 case VARIABLE:
1757 EmitVariableLoad(expr->target()->AsVariableProxy()); 1763 EmitVariableLoad(expr->target()->AsVariableProxy());
1758 PrepareForBailout(expr->target(), TOS_REG); 1764 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER);
1759 break; 1765 break;
1760 case NAMED_PROPERTY: 1766 case NAMED_PROPERTY:
1761 EmitNamedPropertyLoad(property); 1767 EmitNamedPropertyLoad(property);
1762 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1768 PrepareForBailoutForId(property->LoadId(),
1769 BailoutState::TOS_REGISTER);
1763 break; 1770 break;
1764 case NAMED_SUPER_PROPERTY: 1771 case NAMED_SUPER_PROPERTY:
1765 EmitNamedSuperPropertyLoad(property); 1772 EmitNamedSuperPropertyLoad(property);
1766 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1773 PrepareForBailoutForId(property->LoadId(),
1774 BailoutState::TOS_REGISTER);
1767 break; 1775 break;
1768 case KEYED_SUPER_PROPERTY: 1776 case KEYED_SUPER_PROPERTY:
1769 EmitKeyedSuperPropertyLoad(property); 1777 EmitKeyedSuperPropertyLoad(property);
1770 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1778 PrepareForBailoutForId(property->LoadId(),
1779 BailoutState::TOS_REGISTER);
1771 break; 1780 break;
1772 case KEYED_PROPERTY: 1781 case KEYED_PROPERTY:
1773 EmitKeyedPropertyLoad(property); 1782 EmitKeyedPropertyLoad(property);
1774 PrepareForBailoutForId(property->LoadId(), TOS_REG); 1783 PrepareForBailoutForId(property->LoadId(),
1784 BailoutState::TOS_REGISTER);
1775 break; 1785 break;
1776 } 1786 }
1777 } 1787 }
1778 1788
1779 Token::Value op = expr->binary_op(); 1789 Token::Value op = expr->binary_op();
1780 PushOperand(r0); // Left operand goes on the stack. 1790 PushOperand(r0); // Left operand goes on the stack.
1781 VisitForAccumulatorValue(expr->value()); 1791 VisitForAccumulatorValue(expr->value());
1782 1792
1783 AccumulatorValueContext context(this); 1793 AccumulatorValueContext context(this);
1784 if (ShouldInlineSmiCase(op)) { 1794 if (ShouldInlineSmiCase(op)) {
1785 EmitInlineSmiBinaryOp(expr->binary_operation(), 1795 EmitInlineSmiBinaryOp(expr->binary_operation(),
1786 op, 1796 op,
1787 expr->target(), 1797 expr->target(),
1788 expr->value()); 1798 expr->value());
1789 } else { 1799 } else {
1790 EmitBinaryOp(expr->binary_operation(), op); 1800 EmitBinaryOp(expr->binary_operation(), op);
1791 } 1801 }
1792 1802
1793 // Deoptimization point in case the binary operation may have side effects. 1803 // Deoptimization point in case the binary operation may have side effects.
1794 PrepareForBailout(expr->binary_operation(), TOS_REG); 1804 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER);
1795 } else { 1805 } else {
1796 VisitForAccumulatorValue(expr->value()); 1806 VisitForAccumulatorValue(expr->value());
1797 } 1807 }
1798 1808
1799 SetExpressionPosition(expr); 1809 SetExpressionPosition(expr);
1800 1810
1801 // Store the value. 1811 // Store the value.
1802 switch (assign_type) { 1812 switch (assign_type) {
1803 case VARIABLE: 1813 case VARIABLE:
1804 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1814 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1805 expr->op(), expr->AssignmentSlot()); 1815 expr->op(), expr->AssignmentSlot());
1806 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1816 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1807 context()->Plug(r0); 1817 context()->Plug(r0);
1808 break; 1818 break;
1809 case NAMED_PROPERTY: 1819 case NAMED_PROPERTY:
1810 EmitNamedPropertyAssignment(expr); 1820 EmitNamedPropertyAssignment(expr);
1811 break; 1821 break;
1812 case NAMED_SUPER_PROPERTY: 1822 case NAMED_SUPER_PROPERTY:
1813 EmitNamedSuperPropertyStore(property); 1823 EmitNamedSuperPropertyStore(property);
1814 context()->Plug(r0); 1824 context()->Plug(r0);
1815 break; 1825 break;
1816 case KEYED_SUPER_PROPERTY: 1826 case KEYED_SUPER_PROPERTY:
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 Property* prop = expr->target()->AsProperty(); 2274 Property* prop = expr->target()->AsProperty();
2265 DCHECK(prop != NULL); 2275 DCHECK(prop != NULL);
2266 DCHECK(prop->key()->IsLiteral()); 2276 DCHECK(prop->key()->IsLiteral());
2267 2277
2268 __ mov(StoreDescriptor::NameRegister(), 2278 __ mov(StoreDescriptor::NameRegister(),
2269 Operand(prop->key()->AsLiteral()->value())); 2279 Operand(prop->key()->AsLiteral()->value()));
2270 PopOperand(StoreDescriptor::ReceiverRegister()); 2280 PopOperand(StoreDescriptor::ReceiverRegister());
2271 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2281 EmitLoadStoreICSlot(expr->AssignmentSlot());
2272 CallStoreIC(); 2282 CallStoreIC();
2273 2283
2274 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2284 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2275 context()->Plug(r0); 2285 context()->Plug(r0);
2276 } 2286 }
2277 2287
2278 2288
2279 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2289 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2280 // Assignment to named property of super. 2290 // Assignment to named property of super.
2281 // r0 : value 2291 // r0 : value
2282 // stack : receiver ('this'), home_object 2292 // stack : receiver ('this'), home_object
2283 DCHECK(prop != NULL); 2293 DCHECK(prop != NULL);
2284 Literal* key = prop->key()->AsLiteral(); 2294 Literal* key = prop->key()->AsLiteral();
(...skipping 24 matching lines...) Expand all
2309 // Assignment to a property, using a keyed store IC. 2319 // Assignment to a property, using a keyed store IC.
2310 PopOperands(StoreDescriptor::ReceiverRegister(), 2320 PopOperands(StoreDescriptor::ReceiverRegister(),
2311 StoreDescriptor::NameRegister()); 2321 StoreDescriptor::NameRegister());
2312 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 2322 DCHECK(StoreDescriptor::ValueRegister().is(r0));
2313 2323
2314 Handle<Code> ic = 2324 Handle<Code> ic =
2315 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2325 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2316 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2326 EmitLoadStoreICSlot(expr->AssignmentSlot());
2317 CallIC(ic); 2327 CallIC(ic);
2318 2328
2319 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2329 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2320 context()->Plug(r0); 2330 context()->Plug(r0);
2321 } 2331 }
2322 2332
2323 2333
2324 void FullCodeGenerator::CallIC(Handle<Code> code, 2334 void FullCodeGenerator::CallIC(Handle<Code> code,
2325 TypeFeedbackId ast_id) { 2335 TypeFeedbackId ast_id) {
2326 ic_total_count_++; 2336 ic_total_count_++;
2327 // All calls must have a predictable size in full-codegen code to ensure that 2337 // All calls must have a predictable size in full-codegen code to ensure that
2328 // the debugger can patch them correctly. 2338 // the debugger can patch them correctly.
2329 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, 2339 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2330 NEVER_INLINE_TARGET_ADDRESS); 2340 NEVER_INLINE_TARGET_ADDRESS);
2331 } 2341 }
2332 2342
2333 2343
2334 // Code common for calls using the IC. 2344 // Code common for calls using the IC.
2335 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2345 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2336 Expression* callee = expr->expression(); 2346 Expression* callee = expr->expression();
2337 2347
2338 // Get the target function. 2348 // Get the target function.
2339 ConvertReceiverMode convert_mode; 2349 ConvertReceiverMode convert_mode;
2340 if (callee->IsVariableProxy()) { 2350 if (callee->IsVariableProxy()) {
2341 { StackValueContext context(this); 2351 { StackValueContext context(this);
2342 EmitVariableLoad(callee->AsVariableProxy()); 2352 EmitVariableLoad(callee->AsVariableProxy());
2343 PrepareForBailout(callee, NO_REGISTERS); 2353 PrepareForBailout(callee, BailoutState::NO_REGISTERS);
2344 } 2354 }
2345 // Push undefined as receiver. This is patched in the method prologue if it 2355 // Push undefined as receiver. This is patched in the method prologue if it
2346 // is a sloppy mode method. 2356 // is a sloppy mode method.
2347 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 2357 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2348 PushOperand(ip); 2358 PushOperand(ip);
2349 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2359 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2350 } else { 2360 } else {
2351 // Load the function from the receiver. 2361 // Load the function from the receiver.
2352 DCHECK(callee->IsProperty()); 2362 DCHECK(callee->IsProperty());
2353 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2363 DCHECK(!callee->AsProperty()->IsSuperAccess());
2354 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2364 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2355 EmitNamedPropertyLoad(callee->AsProperty()); 2365 EmitNamedPropertyLoad(callee->AsProperty());
2356 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2366 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2367 BailoutState::TOS_REGISTER);
2357 // Push the target function under the receiver. 2368 // Push the target function under the receiver.
2358 __ ldr(ip, MemOperand(sp, 0)); 2369 __ ldr(ip, MemOperand(sp, 0));
2359 PushOperand(ip); 2370 PushOperand(ip);
2360 __ str(r0, MemOperand(sp, kPointerSize)); 2371 __ str(r0, MemOperand(sp, kPointerSize));
2361 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2372 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2362 } 2373 }
2363 2374
2364 EmitCall(expr, convert_mode); 2375 EmitCall(expr, convert_mode);
2365 } 2376 }
2366 2377
(...skipping 18 matching lines...) Expand all
2385 PushOperand(scratch); 2396 PushOperand(scratch);
2386 PushOperand(key->value()); 2397 PushOperand(key->value());
2387 2398
2388 // Stack here: 2399 // Stack here:
2389 // - home_object 2400 // - home_object
2390 // - this (receiver) 2401 // - this (receiver)
2391 // - this (receiver) <-- LoadFromSuper will pop here and below. 2402 // - this (receiver) <-- LoadFromSuper will pop here and below.
2392 // - home_object 2403 // - home_object
2393 // - key 2404 // - key
2394 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2405 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2395 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2406 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2396 2407
2397 // Replace home_object with target function. 2408 // Replace home_object with target function.
2398 __ str(r0, MemOperand(sp, kPointerSize)); 2409 __ str(r0, MemOperand(sp, kPointerSize));
2399 2410
2400 // Stack here: 2411 // Stack here:
2401 // - target function 2412 // - target function
2402 // - this (receiver) 2413 // - this (receiver)
2403 EmitCall(expr); 2414 EmitCall(expr);
2404 } 2415 }
2405 2416
2406 2417
2407 // Code common for calls using the IC. 2418 // Code common for calls using the IC.
2408 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2419 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2409 Expression* key) { 2420 Expression* key) {
2410 // Load the key. 2421 // Load the key.
2411 VisitForAccumulatorValue(key); 2422 VisitForAccumulatorValue(key);
2412 2423
2413 Expression* callee = expr->expression(); 2424 Expression* callee = expr->expression();
2414 2425
2415 // Load the function from the receiver. 2426 // Load the function from the receiver.
2416 DCHECK(callee->IsProperty()); 2427 DCHECK(callee->IsProperty());
2417 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2428 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2418 __ Move(LoadDescriptor::NameRegister(), r0); 2429 __ Move(LoadDescriptor::NameRegister(), r0);
2419 EmitKeyedPropertyLoad(callee->AsProperty()); 2430 EmitKeyedPropertyLoad(callee->AsProperty());
2420 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2431 PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2432 BailoutState::TOS_REGISTER);
2421 2433
2422 // Push the target function under the receiver. 2434 // Push the target function under the receiver.
2423 __ ldr(ip, MemOperand(sp, 0)); 2435 __ ldr(ip, MemOperand(sp, 0));
2424 PushOperand(ip); 2436 PushOperand(ip);
2425 __ str(r0, MemOperand(sp, kPointerSize)); 2437 __ str(r0, MemOperand(sp, kPointerSize));
2426 2438
2427 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2439 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2428 } 2440 }
2429 2441
2430 2442
(...skipping 15 matching lines...) Expand all
2446 PushOperand(scratch); 2458 PushOperand(scratch);
2447 VisitForStackValue(prop->key()); 2459 VisitForStackValue(prop->key());
2448 2460
2449 // Stack here: 2461 // Stack here:
2450 // - home_object 2462 // - home_object
2451 // - this (receiver) 2463 // - this (receiver)
2452 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2464 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2453 // - home_object 2465 // - home_object
2454 // - key 2466 // - key
2455 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2467 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2456 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 2468 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2457 2469
2458 // Replace home_object with target function. 2470 // Replace home_object with target function.
2459 __ str(r0, MemOperand(sp, kPointerSize)); 2471 __ str(r0, MemOperand(sp, kPointerSize));
2460 2472
2461 // Stack here: 2473 // Stack here:
2462 // - target function 2474 // - target function
2463 // - this (receiver) 2475 // - this (receiver)
2464 EmitCall(expr); 2476 EmitCall(expr);
2465 } 2477 }
2466 2478
2467 2479
2468 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2480 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2469 // Load the arguments. 2481 // Load the arguments.
2470 ZoneList<Expression*>* args = expr->arguments(); 2482 ZoneList<Expression*>* args = expr->arguments();
2471 int arg_count = args->length(); 2483 int arg_count = args->length();
2472 for (int i = 0; i < arg_count; i++) { 2484 for (int i = 0; i < arg_count; i++) {
2473 VisitForStackValue(args->at(i)); 2485 VisitForStackValue(args->at(i));
2474 } 2486 }
2475 2487
2476 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 2488 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2477 SetCallPosition(expr, expr->tail_call_mode()); 2489 SetCallPosition(expr, expr->tail_call_mode());
2478 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2490 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2479 if (FLAG_trace) { 2491 if (FLAG_trace) {
2480 __ CallRuntime(Runtime::kTraceTailCall); 2492 __ CallRuntime(Runtime::kTraceTailCall);
2481 } 2493 }
2482 // Update profiling counters before the tail call since we will 2494 // Update profiling counters before the tail call since we will
2483 // not return to this function. 2495 // not return to this function.
2484 EmitProfilingCounterHandlingForReturnSequence(true); 2496 EmitProfilingCounterHandlingForReturnSequence(true);
2485 } 2497 }
2486 Handle<Code> ic = 2498 Handle<Code> ic =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 // Generate code for loading from variables potentially shadowed 2546 // Generate code for loading from variables potentially shadowed
2535 // by eval-introduced variables. 2547 // by eval-introduced variables.
2536 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2548 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2537 2549
2538 __ bind(&slow); 2550 __ bind(&slow);
2539 // Call the runtime to find the function to call (returned in r0) 2551 // Call the runtime to find the function to call (returned in r0)
2540 // and the object holding it (returned in edx). 2552 // and the object holding it (returned in edx).
2541 __ Push(callee->name()); 2553 __ Push(callee->name());
2542 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2554 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2543 PushOperands(r0, r1); // Function, receiver. 2555 PushOperands(r0, r1); // Function, receiver.
2544 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); 2556 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
2545 2557
2546 // If fast case code has been generated, emit code to push the 2558 // If fast case code has been generated, emit code to push the
2547 // function and receiver and have the slow path jump around this 2559 // function and receiver and have the slow path jump around this
2548 // code. 2560 // code.
2549 if (done.is_linked()) { 2561 if (done.is_linked()) {
2550 Label call; 2562 Label call;
2551 __ b(&call); 2563 __ b(&call);
2552 __ bind(&done); 2564 __ bind(&done);
2553 // Push function. 2565 // Push function.
2554 __ push(r0); 2566 __ push(r0);
(...skipping 28 matching lines...) Expand all
2583 2595
2584 // Push a copy of the function (found below the arguments) and 2596 // Push a copy of the function (found below the arguments) and
2585 // resolve eval. 2597 // resolve eval.
2586 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2598 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2587 __ push(r1); 2599 __ push(r1);
2588 EmitResolvePossiblyDirectEval(expr); 2600 EmitResolvePossiblyDirectEval(expr);
2589 2601
2590 // Touch up the stack with the resolved function. 2602 // Touch up the stack with the resolved function.
2591 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2603 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2592 2604
2593 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); 2605 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2594 2606
2595 // Record source position for debugger. 2607 // Record source position for debugger.
2596 SetCallPosition(expr); 2608 SetCallPosition(expr);
2597 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2609 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2598 __ mov(r0, Operand(arg_count)); 2610 __ mov(r0, Operand(arg_count));
2599 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2611 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2600 expr->tail_call_mode()), 2612 expr->tail_call_mode()),
2601 RelocInfo::CODE_TARGET); 2613 RelocInfo::CODE_TARGET);
2602 OperandStackDepthDecrement(arg_count + 1); 2614 OperandStackDepthDecrement(arg_count + 1);
2603 RecordJSReturnSite(expr); 2615 RecordJSReturnSite(expr);
(...skipping 29 matching lines...) Expand all
2633 __ mov(r0, Operand(arg_count)); 2645 __ mov(r0, Operand(arg_count));
2634 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2646 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2635 2647
2636 // Record call targets in unoptimized code. 2648 // Record call targets in unoptimized code.
2637 __ EmitLoadTypeFeedbackVector(r2); 2649 __ EmitLoadTypeFeedbackVector(r2);
2638 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2650 __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2639 2651
2640 CallConstructStub stub(isolate()); 2652 CallConstructStub stub(isolate());
2641 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2653 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2642 OperandStackDepthDecrement(arg_count + 1); 2654 OperandStackDepthDecrement(arg_count + 1);
2643 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2655 PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER);
2644 RestoreContext(); 2656 RestoreContext();
2645 context()->Plug(r0); 2657 context()->Plug(r0);
2646 } 2658 }
2647 2659
2648 2660
2649 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2661 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2650 SuperCallReference* super_call_ref = 2662 SuperCallReference* super_call_ref =
2651 expr->expression()->AsSuperCallReference(); 2663 expr->expression()->AsSuperCallReference();
2652 DCHECK_NOT_NULL(super_call_ref); 2664 DCHECK_NOT_NULL(super_call_ref);
2653 2665
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
3065 } 3077 }
3066 3078
3067 3079
3068 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 3080 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
3069 ZoneList<Expression*>* args = expr->arguments(); 3081 ZoneList<Expression*>* args = expr->arguments();
3070 DCHECK_LE(2, args->length()); 3082 DCHECK_LE(2, args->length());
3071 // Push target, receiver and arguments onto the stack. 3083 // Push target, receiver and arguments onto the stack.
3072 for (Expression* const arg : *args) { 3084 for (Expression* const arg : *args) {
3073 VisitForStackValue(arg); 3085 VisitForStackValue(arg);
3074 } 3086 }
3075 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); 3087 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
3076 // Move target to r1. 3088 // Move target to r1.
3077 int const argc = args->length() - 2; 3089 int const argc = args->length() - 2;
3078 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); 3090 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
3079 // Call the target. 3091 // Call the target.
3080 __ mov(r0, Operand(argc)); 3092 __ mov(r0, Operand(argc));
3081 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3093 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3082 OperandStackDepthDecrement(argc + 1); 3094 OperandStackDepthDecrement(argc + 1);
3083 RestoreContext(); 3095 RestoreContext();
3084 // Discard the function left on TOS. 3096 // Discard the function left on TOS.
3085 context()->DropAndPlug(1, r0); 3097 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 3287 // because we need to prepare a pair of extra administrative AST ids
3276 // for the optimizing compiler. 3288 // for the optimizing compiler.
3277 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3289 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3278 Label materialize_true, materialize_false, done; 3290 Label materialize_true, materialize_false, done;
3279 VisitForControl(expr->expression(), 3291 VisitForControl(expr->expression(),
3280 &materialize_false, 3292 &materialize_false,
3281 &materialize_true, 3293 &materialize_true,
3282 &materialize_true); 3294 &materialize_true);
3283 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3295 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3284 __ bind(&materialize_true); 3296 __ bind(&materialize_true);
3285 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 3297 PrepareForBailoutForId(expr->MaterializeTrueId(),
3298 BailoutState::NO_REGISTERS);
3286 __ LoadRoot(r0, Heap::kTrueValueRootIndex); 3299 __ LoadRoot(r0, Heap::kTrueValueRootIndex);
3287 if (context()->IsStackValue()) __ push(r0); 3300 if (context()->IsStackValue()) __ push(r0);
3288 __ jmp(&done); 3301 __ jmp(&done);
3289 __ bind(&materialize_false); 3302 __ bind(&materialize_false);
3290 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 3303 PrepareForBailoutForId(expr->MaterializeFalseId(),
3304 BailoutState::NO_REGISTERS);
3291 __ LoadRoot(r0, Heap::kFalseValueRootIndex); 3305 __ LoadRoot(r0, Heap::kFalseValueRootIndex);
3292 if (context()->IsStackValue()) __ push(r0); 3306 if (context()->IsStackValue()) __ push(r0);
3293 __ bind(&done); 3307 __ bind(&done);
3294 } 3308 }
3295 break; 3309 break;
3296 } 3310 }
3297 3311
3298 case Token::TYPEOF: { 3312 case Token::TYPEOF: {
3299 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3313 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3300 { 3314 {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 } 3396 }
3383 3397
3384 case VARIABLE: 3398 case VARIABLE:
3385 UNREACHABLE(); 3399 UNREACHABLE();
3386 } 3400 }
3387 } 3401 }
3388 3402
3389 // We need a second deoptimization point after loading the value 3403 // We need a second deoptimization point after loading the value
3390 // in case evaluating the property load my have a side effect. 3404 // in case evaluating the property load my have a side effect.
3391 if (assign_type == VARIABLE) { 3405 if (assign_type == VARIABLE) {
3392 PrepareForBailout(expr->expression(), TOS_REG); 3406 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER);
3393 } else { 3407 } else {
3394 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 3408 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
3395 } 3409 }
3396 3410
3397 // Inline smi case if we are in a loop. 3411 // Inline smi case if we are in a loop.
3398 Label stub_call, done; 3412 Label stub_call, done;
3399 JumpPatchSite patch_site(masm_); 3413 JumpPatchSite patch_site(masm_);
3400 3414
3401 int count_value = expr->op() == Token::INC ? 1 : -1; 3415 int count_value = expr->op() == Token::INC ? 1 : -1;
3402 if (ShouldInlineSmiCase(expr->op())) { 3416 if (ShouldInlineSmiCase(expr->op())) {
3403 Label slow; 3417 Label slow;
3404 patch_site.EmitJumpIfNotSmi(r0, &slow); 3418 patch_site.EmitJumpIfNotSmi(r0, &slow);
(...skipping 28 matching lines...) Expand all
3433 __ b(vc, &done); 3447 __ b(vc, &done);
3434 // Call stub. Undo operation first. 3448 // Call stub. Undo operation first.
3435 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); 3449 __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
3436 __ jmp(&stub_call); 3450 __ jmp(&stub_call);
3437 __ bind(&slow); 3451 __ bind(&slow);
3438 } 3452 }
3439 3453
3440 // Convert old value into a number. 3454 // Convert old value into a number.
3441 ToNumberStub convert_stub(isolate()); 3455 ToNumberStub convert_stub(isolate());
3442 __ CallStub(&convert_stub); 3456 __ CallStub(&convert_stub);
3443 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); 3457 PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
3444 3458
3445 // Save result for postfix expressions. 3459 // Save result for postfix expressions.
3446 if (expr->is_postfix()) { 3460 if (expr->is_postfix()) {
3447 if (!context()->IsEffect()) { 3461 if (!context()->IsEffect()) {
3448 // Save the result on the stack. If we have a named or keyed property 3462 // 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 3463 // we store the result under the receiver that is currently on top
3450 // of the stack. 3464 // of the stack.
3451 switch (assign_type) { 3465 switch (assign_type) {
3452 case VARIABLE: 3466 case VARIABLE:
3453 PushOperand(r0); 3467 PushOperand(r0);
(...skipping 26 matching lines...) Expand all
3480 patch_site.EmitPatchInfo(); 3494 patch_site.EmitPatchInfo();
3481 __ bind(&done); 3495 __ bind(&done);
3482 3496
3483 // Store the value returned in r0. 3497 // Store the value returned in r0.
3484 switch (assign_type) { 3498 switch (assign_type) {
3485 case VARIABLE: 3499 case VARIABLE:
3486 if (expr->is_postfix()) { 3500 if (expr->is_postfix()) {
3487 { EffectContext context(this); 3501 { EffectContext context(this);
3488 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3502 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3489 Token::ASSIGN, expr->CountSlot()); 3503 Token::ASSIGN, expr->CountSlot());
3490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3504 PrepareForBailoutForId(expr->AssignmentId(),
3505 BailoutState::TOS_REGISTER);
3491 context.Plug(r0); 3506 context.Plug(r0);
3492 } 3507 }
3493 // For all contexts except EffectConstant We have the result on 3508 // For all contexts except EffectConstant We have the result on
3494 // top of the stack. 3509 // top of the stack.
3495 if (!context()->IsEffect()) { 3510 if (!context()->IsEffect()) {
3496 context()->PlugTOS(); 3511 context()->PlugTOS();
3497 } 3512 }
3498 } else { 3513 } else {
3499 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3514 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3500 Token::ASSIGN, expr->CountSlot()); 3515 Token::ASSIGN, expr->CountSlot());
3501 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3516 PrepareForBailoutForId(expr->AssignmentId(),
3517 BailoutState::TOS_REGISTER);
3502 context()->Plug(r0); 3518 context()->Plug(r0);
3503 } 3519 }
3504 break; 3520 break;
3505 case NAMED_PROPERTY: { 3521 case NAMED_PROPERTY: {
3506 __ mov(StoreDescriptor::NameRegister(), 3522 __ mov(StoreDescriptor::NameRegister(),
3507 Operand(prop->key()->AsLiteral()->value())); 3523 Operand(prop->key()->AsLiteral()->value()));
3508 PopOperand(StoreDescriptor::ReceiverRegister()); 3524 PopOperand(StoreDescriptor::ReceiverRegister());
3509 EmitLoadStoreICSlot(expr->CountSlot()); 3525 EmitLoadStoreICSlot(expr->CountSlot());
3510 CallStoreIC(); 3526 CallStoreIC();
3511 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3527 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3512 if (expr->is_postfix()) { 3528 if (expr->is_postfix()) {
3513 if (!context()->IsEffect()) { 3529 if (!context()->IsEffect()) {
3514 context()->PlugTOS(); 3530 context()->PlugTOS();
3515 } 3531 }
3516 } else { 3532 } else {
3517 context()->Plug(r0); 3533 context()->Plug(r0);
3518 } 3534 }
3519 break; 3535 break;
3520 } 3536 }
3521 case NAMED_SUPER_PROPERTY: { 3537 case NAMED_SUPER_PROPERTY: {
(...skipping 18 matching lines...) Expand all
3540 } 3556 }
3541 break; 3557 break;
3542 } 3558 }
3543 case KEYED_PROPERTY: { 3559 case KEYED_PROPERTY: {
3544 PopOperands(StoreDescriptor::ReceiverRegister(), 3560 PopOperands(StoreDescriptor::ReceiverRegister(),
3545 StoreDescriptor::NameRegister()); 3561 StoreDescriptor::NameRegister());
3546 Handle<Code> ic = 3562 Handle<Code> ic =
3547 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3563 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3548 EmitLoadStoreICSlot(expr->CountSlot()); 3564 EmitLoadStoreICSlot(expr->CountSlot());
3549 CallIC(ic); 3565 CallIC(ic);
3550 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3566 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3551 if (expr->is_postfix()) { 3567 if (expr->is_postfix()) {
3552 if (!context()->IsEffect()) { 3568 if (!context()->IsEffect()) {
3553 context()->PlugTOS(); 3569 context()->PlugTOS();
3554 } 3570 }
3555 } else { 3571 } else {
3556 context()->Plug(r0); 3572 context()->Plug(r0);
3557 } 3573 }
3558 break; 3574 break;
3559 } 3575 }
3560 } 3576 }
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
3990 DCHECK(interrupt_address == 4006 DCHECK(interrupt_address ==
3991 isolate->builtins()->OnStackReplacement()->entry()); 4007 isolate->builtins()->OnStackReplacement()->entry());
3992 return ON_STACK_REPLACEMENT; 4008 return ON_STACK_REPLACEMENT;
3993 } 4009 }
3994 4010
3995 4011
3996 } // namespace internal 4012 } // namespace internal
3997 } // namespace v8 4013 } // namespace v8
3998 4014
3999 #endif // V8_TARGET_ARCH_ARM 4015 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/deoptimizer.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698