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

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

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