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

Side by Side Diff: src/full-codegen/mips64/full-codegen-mips64.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/full-codegen/mips/full-codegen-mips.cc ('k') | src/full-codegen/x64/full-codegen-x64.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_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // Possibly allocate a local context. 178 // Possibly allocate a local context.
179 if (info->scope()->num_heap_slots() > 0) { 179 if (info->scope()->num_heap_slots() > 0) {
180 Comment cmnt(masm_, "[ Allocate context"); 180 Comment cmnt(masm_, "[ Allocate context");
181 // Argument to NewContext is the function, which is still in a1. 181 // Argument to NewContext is the function, which is still in a1.
182 bool need_write_barrier = true; 182 bool need_write_barrier = true;
183 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 183 int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
184 if (info->scope()->is_script_scope()) { 184 if (info->scope()->is_script_scope()) {
185 __ push(a1); 185 __ push(a1);
186 __ Push(info->scope()->GetScopeInfo(info->isolate())); 186 __ Push(info->scope()->GetScopeInfo(info->isolate()));
187 __ CallRuntime(Runtime::kNewScriptContext); 187 __ CallRuntime(Runtime::kNewScriptContext);
188 PrepareForBailoutForId(BailoutId::ScriptContext(), 188 PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG);
189 BailoutState::TOS_REGISTER);
190 // The new target value is not used, clobbering is safe. 189 // The new target value is not used, clobbering is safe.
191 DCHECK_NULL(info->scope()->new_target_var()); 190 DCHECK_NULL(info->scope()->new_target_var());
192 } else { 191 } else {
193 if (info->scope()->new_target_var() != nullptr) { 192 if (info->scope()->new_target_var() != nullptr) {
194 __ push(a3); // Preserve new target. 193 __ push(a3); // Preserve new target.
195 } 194 }
196 if (slots <= FastNewContextStub::kMaximumSlots) { 195 if (slots <= FastNewContextStub::kMaximumSlots) {
197 FastNewContextStub stub(isolate(), slots); 196 FastNewContextStub stub(isolate(), slots);
198 __ CallStub(&stub); 197 __ CallStub(&stub);
199 // Result of FastNewContextStub is always in new space. 198 // Result of FastNewContextStub is always in new space.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 __ Abort(kExpectedNewSpaceObject); 234 __ Abort(kExpectedNewSpaceObject);
236 __ bind(&done); 235 __ bind(&done);
237 } 236 }
238 } 237 }
239 } 238 }
240 } 239 }
241 240
242 // Register holding this function and new target are both trashed in case we 241 // Register holding this function and new target are both trashed in case we
243 // bailout here. But since that can happen only when new target is not used 242 // bailout here. But since that can happen only when new target is not used
244 // and we allocate a context, the value of |function_in_register| is correct. 243 // and we allocate a context, the value of |function_in_register| is correct.
245 PrepareForBailoutForId(BailoutId::FunctionContext(), 244 PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS);
246 BailoutState::NO_REGISTERS);
247 245
248 // Possibly set up a local binding to the this function which is used in 246 // Possibly set up a local binding to the this function which is used in
249 // derived constructors with super calls. 247 // derived constructors with super calls.
250 Variable* this_function_var = scope()->this_function_var(); 248 Variable* this_function_var = scope()->this_function_var();
251 if (this_function_var != nullptr) { 249 if (this_function_var != nullptr) {
252 Comment cmnt(masm_, "[ This function"); 250 Comment cmnt(masm_, "[ This function");
253 if (!function_in_register_a1) { 251 if (!function_in_register_a1) {
254 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 252 __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
255 // The write barrier clobbers register again, keep it marked as such. 253 // The write barrier clobbers register again, keep it marked as such.
256 } 254 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 } 295 }
298 296
299 SetVar(arguments, v0, a1, a2); 297 SetVar(arguments, v0, a1, a2);
300 } 298 }
301 299
302 if (FLAG_trace) { 300 if (FLAG_trace) {
303 __ CallRuntime(Runtime::kTraceEnter); 301 __ CallRuntime(Runtime::kTraceEnter);
304 } 302 }
305 303
306 // Visit the declarations and body. 304 // Visit the declarations and body.
307 PrepareForBailoutForId(BailoutId::FunctionEntry(), 305 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
308 BailoutState::NO_REGISTERS);
309 { 306 {
310 Comment cmnt(masm_, "[ Declarations"); 307 Comment cmnt(masm_, "[ Declarations");
311 VisitDeclarations(scope()->declarations()); 308 VisitDeclarations(scope()->declarations());
312 } 309 }
313 310
314 // Assert that the declarations do not use ICs. Otherwise the debugger 311 // Assert that the declarations do not use ICs. Otherwise the debugger
315 // won't be able to redirect a PC at an IC to the correct IC in newly 312 // won't be able to redirect a PC at an IC to the correct IC in newly
316 // recompiled code. 313 // recompiled code.
317 DCHECK_EQ(0, ic_total_count_); 314 DCHECK_EQ(0, ic_total_count_);
318 315
319 { 316 {
320 Comment cmnt(masm_, "[ Stack check"); 317 Comment cmnt(masm_, "[ Stack check");
321 PrepareForBailoutForId(BailoutId::Declarations(), 318 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
322 BailoutState::NO_REGISTERS);
323 Label ok; 319 Label ok;
324 __ LoadRoot(at, Heap::kStackLimitRootIndex); 320 __ LoadRoot(at, Heap::kStackLimitRootIndex);
325 __ Branch(&ok, hs, sp, Operand(at)); 321 __ Branch(&ok, hs, sp, Operand(at));
326 Handle<Code> stack_check = isolate()->builtins()->StackCheck(); 322 Handle<Code> stack_check = isolate()->builtins()->StackCheck();
327 PredictableCodeSizeScope predictable( 323 PredictableCodeSizeScope predictable(
328 masm_, masm_->CallSize(stack_check, RelocInfo::CODE_TARGET)); 324 masm_, masm_->CallSize(stack_check, RelocInfo::CODE_TARGET));
329 __ Call(stack_check, RelocInfo::CODE_TARGET); 325 __ Call(stack_check, RelocInfo::CODE_TARGET);
330 __ bind(&ok); 326 __ bind(&ok);
331 } 327 }
332 328
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 __ beq(at, zero_reg, &ok); 389 __ beq(at, zero_reg, &ok);
394 // Call will emit a li t9 first, so it is safe to use the delay slot. 390 // Call will emit a li t9 first, so it is safe to use the delay slot.
395 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 391 __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
396 // Record a mapping of this PC offset to the OSR id. This is used to find 392 // Record a mapping of this PC offset to the OSR id. This is used to find
397 // the AST id from the unoptimized code in order to use it as a key into 393 // the AST id from the unoptimized code in order to use it as a key into
398 // the deoptimization input data found in the optimized code. 394 // the deoptimization input data found in the optimized code.
399 RecordBackEdge(stmt->OsrEntryId()); 395 RecordBackEdge(stmt->OsrEntryId());
400 EmitProfilingCounterReset(); 396 EmitProfilingCounterReset();
401 397
402 __ bind(&ok); 398 __ bind(&ok);
403 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); 399 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
404 // Record a mapping of the OSR id to this PC. This is used if the OSR 400 // Record a mapping of the OSR id to this PC. This is used if the OSR
405 // entry becomes the target of a bailout. We don't expect it to be, but 401 // entry becomes the target of a bailout. We don't expect it to be, but
406 // we want it to work if it is. 402 // we want it to work if it is.
407 PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); 403 PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
408 } 404 }
409 405
410 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( 406 void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
411 bool is_tail_call) { 407 bool is_tail_call) {
412 // Pretend that the exit is a backwards jump to the entry. 408 // Pretend that the exit is a backwards jump to the entry.
413 int weight = 1; 409 int weight = 1;
414 if (info_->ShouldSelfOptimize()) { 410 if (info_->ShouldSelfOptimize()) {
415 weight = FLAG_interrupt_budget / FLAG_self_opt_count; 411 weight = FLAG_interrupt_budget / FLAG_self_opt_count;
416 } else { 412 } else {
417 int distance = masm_->pc_offset(); 413 int distance = masm_->pc_offset();
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 bool should_normalize, 719 bool should_normalize,
724 Label* if_true, 720 Label* if_true,
725 Label* if_false) { 721 Label* if_false) {
726 // Only prepare for bailouts before splits if we're in a test 722 // Only prepare for bailouts before splits if we're in a test
727 // context. Otherwise, we let the Visit function deal with the 723 // context. Otherwise, we let the Visit function deal with the
728 // preparation to avoid preparing with the same AST id twice. 724 // preparation to avoid preparing with the same AST id twice.
729 if (!context()->IsTest()) return; 725 if (!context()->IsTest()) return;
730 726
731 Label skip; 727 Label skip;
732 if (should_normalize) __ Branch(&skip); 728 if (should_normalize) __ Branch(&skip);
733 PrepareForBailout(expr, BailoutState::TOS_REGISTER); 729 PrepareForBailout(expr, TOS_REG);
734 if (should_normalize) { 730 if (should_normalize) {
735 __ LoadRoot(a4, Heap::kTrueValueRootIndex); 731 __ LoadRoot(a4, Heap::kTrueValueRootIndex);
736 Split(eq, a0, Operand(a4), if_true, if_false, NULL); 732 Split(eq, a0, Operand(a4), if_true, if_false, NULL);
737 __ bind(&skip); 733 __ bind(&skip);
738 } 734 }
739 } 735 }
740 736
741 737
742 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 738 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
743 // The variable in the declaration always resides in the current function 739 // The variable in the declaration always resides in the current function
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 778 }
783 break; 779 break;
784 780
785 case VariableLocation::CONTEXT: 781 case VariableLocation::CONTEXT:
786 if (hole_init) { 782 if (hole_init) {
787 Comment cmnt(masm_, "[ VariableDeclaration"); 783 Comment cmnt(masm_, "[ VariableDeclaration");
788 EmitDebugCheckDeclarationContext(variable); 784 EmitDebugCheckDeclarationContext(variable);
789 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 785 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
790 __ sd(at, ContextMemOperand(cp, variable->index())); 786 __ sd(at, ContextMemOperand(cp, variable->index()));
791 // No write barrier since the_hole_value is in old space. 787 // No write barrier since the_hole_value is in old space.
792 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 788 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
793 } 789 }
794 break; 790 break;
795 791
796 case VariableLocation::LOOKUP: { 792 case VariableLocation::LOOKUP: {
797 Comment cmnt(masm_, "[ VariableDeclaration"); 793 Comment cmnt(masm_, "[ VariableDeclaration");
798 __ li(a2, Operand(variable->name())); 794 __ li(a2, Operand(variable->name()));
799 // Declaration nodes are always introduced in one of four modes. 795 // Declaration nodes are always introduced in one of four modes.
800 DCHECK(IsDeclaredVariableMode(mode)); 796 DCHECK(IsDeclaredVariableMode(mode));
801 // Push initial value, if any. 797 // Push initial value, if any.
802 // Note: For variables we must not push an initial value (such as 798 // Note: For variables we must not push an initial value (such as
803 // 'undefined') because we may have a (legal) redeclaration and we 799 // 'undefined') because we may have a (legal) redeclaration and we
804 // must not destroy the current value. 800 // must not destroy the current value.
805 if (hole_init) { 801 if (hole_init) {
806 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex); 802 __ LoadRoot(a0, Heap::kTheHoleValueRootIndex);
807 } else { 803 } else {
808 DCHECK(Smi::FromInt(0) == 0); 804 DCHECK(Smi::FromInt(0) == 0);
809 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value. 805 __ mov(a0, zero_reg); // Smi::FromInt(0) indicates no initial value.
810 } 806 }
811 __ Push(a2, a0); 807 __ Push(a2, a0);
812 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); 808 __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes()));
813 __ CallRuntime(Runtime::kDeclareLookupSlot); 809 __ CallRuntime(Runtime::kDeclareLookupSlot);
814 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 810 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
815 break; 811 break;
816 } 812 }
817 } 813 }
818 } 814 }
819 815
820 816
821 void FullCodeGenerator::VisitFunctionDeclaration( 817 void FullCodeGenerator::VisitFunctionDeclaration(
822 FunctionDeclaration* declaration) { 818 FunctionDeclaration* declaration) {
823 VariableProxy* proxy = declaration->proxy(); 819 VariableProxy* proxy = declaration->proxy();
824 Variable* variable = proxy->var(); 820 Variable* variable = proxy->var();
(...skipping 25 matching lines...) Expand all
850 int offset = Context::SlotOffset(variable->index()); 846 int offset = Context::SlotOffset(variable->index());
851 // We know that we have written a function, which is not a smi. 847 // We know that we have written a function, which is not a smi.
852 __ RecordWriteContextSlot(cp, 848 __ RecordWriteContextSlot(cp,
853 offset, 849 offset,
854 result_register(), 850 result_register(),
855 a2, 851 a2,
856 kRAHasBeenSaved, 852 kRAHasBeenSaved,
857 kDontSaveFPRegs, 853 kDontSaveFPRegs,
858 EMIT_REMEMBERED_SET, 854 EMIT_REMEMBERED_SET,
859 OMIT_SMI_CHECK); 855 OMIT_SMI_CHECK);
860 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 856 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
861 break; 857 break;
862 } 858 }
863 859
864 case VariableLocation::LOOKUP: { 860 case VariableLocation::LOOKUP: {
865 Comment cmnt(masm_, "[ FunctionDeclaration"); 861 Comment cmnt(masm_, "[ FunctionDeclaration");
866 __ li(a2, Operand(variable->name())); 862 __ li(a2, Operand(variable->name()));
867 PushOperand(a2); 863 PushOperand(a2);
868 // Push initial value for function declaration. 864 // Push initial value for function declaration.
869 VisitForStackValue(declaration->fun()); 865 VisitForStackValue(declaration->fun());
870 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); 866 PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes()));
871 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); 867 CallRuntimeWithOperands(Runtime::kDeclareLookupSlot);
872 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 868 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
873 break; 869 break;
874 } 870 }
875 } 871 }
876 } 872 }
877 873
878 874
879 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 875 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
880 // Call the runtime to declare the globals. 876 // Call the runtime to declare the globals.
881 __ li(a1, Operand(pairs)); 877 __ li(a1, Operand(pairs));
882 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 878 __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
(...skipping 11 matching lines...) Expand all
894 } 890 }
895 891
896 892
897 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 893 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
898 Comment cmnt(masm_, "[ SwitchStatement"); 894 Comment cmnt(masm_, "[ SwitchStatement");
899 Breakable nested_statement(this, stmt); 895 Breakable nested_statement(this, stmt);
900 SetStatementPosition(stmt); 896 SetStatementPosition(stmt);
901 897
902 // Keep the switch value on the stack until a case matches. 898 // Keep the switch value on the stack until a case matches.
903 VisitForStackValue(stmt->tag()); 899 VisitForStackValue(stmt->tag());
904 PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); 900 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
905 901
906 ZoneList<CaseClause*>* clauses = stmt->cases(); 902 ZoneList<CaseClause*>* clauses = stmt->cases();
907 CaseClause* default_clause = NULL; // Can occur anywhere in the list. 903 CaseClause* default_clause = NULL; // Can occur anywhere in the list.
908 904
909 Label next_test; // Recycled for each test. 905 Label next_test; // Recycled for each test.
910 // Compile all the tests with branches to their bodies. 906 // Compile all the tests with branches to their bodies.
911 for (int i = 0; i < clauses->length(); i++) { 907 for (int i = 0; i < clauses->length(); i++) {
912 CaseClause* clause = clauses->at(i); 908 CaseClause* clause = clauses->at(i);
913 clause->body_target()->Unuse(); 909 clause->body_target()->Unuse();
914 910
(...skipping 29 matching lines...) Expand all
944 940
945 // Record position before stub call for type feedback. 941 // Record position before stub call for type feedback.
946 SetExpressionPosition(clause); 942 SetExpressionPosition(clause);
947 Handle<Code> ic = 943 Handle<Code> ic =
948 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 944 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
949 CallIC(ic, clause->CompareId()); 945 CallIC(ic, clause->CompareId());
950 patch_site.EmitPatchInfo(); 946 patch_site.EmitPatchInfo();
951 947
952 Label skip; 948 Label skip;
953 __ Branch(&skip); 949 __ Branch(&skip);
954 PrepareForBailout(clause, BailoutState::TOS_REGISTER); 950 PrepareForBailout(clause, TOS_REG);
955 __ LoadRoot(at, Heap::kTrueValueRootIndex); 951 __ LoadRoot(at, Heap::kTrueValueRootIndex);
956 __ Branch(&next_test, ne, v0, Operand(at)); 952 __ Branch(&next_test, ne, v0, Operand(at));
957 __ Drop(1); 953 __ Drop(1);
958 __ Branch(clause->body_target()); 954 __ Branch(clause->body_target());
959 __ bind(&skip); 955 __ bind(&skip);
960 956
961 __ Branch(&next_test, ne, v0, Operand(zero_reg)); 957 __ Branch(&next_test, ne, v0, Operand(zero_reg));
962 __ Drop(1); // Switch value is no longer needed. 958 __ Drop(1); // Switch value is no longer needed.
963 __ Branch(clause->body_target()); 959 __ Branch(clause->body_target());
964 } 960 }
965 961
966 // Discard the test value and jump to the default if present, otherwise to 962 // Discard the test value and jump to the default if present, otherwise to
967 // the end of the statement. 963 // the end of the statement.
968 __ bind(&next_test); 964 __ bind(&next_test);
969 DropOperands(1); // Switch value is no longer needed. 965 DropOperands(1); // Switch value is no longer needed.
970 if (default_clause == NULL) { 966 if (default_clause == NULL) {
971 __ Branch(nested_statement.break_label()); 967 __ Branch(nested_statement.break_label());
972 } else { 968 } else {
973 __ Branch(default_clause->body_target()); 969 __ Branch(default_clause->body_target());
974 } 970 }
975 971
976 // Compile all the case bodies. 972 // Compile all the case bodies.
977 for (int i = 0; i < clauses->length(); i++) { 973 for (int i = 0; i < clauses->length(); i++) {
978 Comment cmnt(masm_, "[ Case body"); 974 Comment cmnt(masm_, "[ Case body");
979 CaseClause* clause = clauses->at(i); 975 CaseClause* clause = clauses->at(i);
980 __ bind(clause->body_target()); 976 __ bind(clause->body_target());
981 PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); 977 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
982 VisitStatements(clause->statements()); 978 VisitStatements(clause->statements());
983 } 979 }
984 980
985 __ bind(nested_statement.break_label()); 981 __ bind(nested_statement.break_label());
986 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); 982 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
987 } 983 }
988 984
989 985
990 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 986 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
991 Comment cmnt(masm_, "[ ForInStatement"); 987 Comment cmnt(masm_, "[ ForInStatement");
992 SetStatementPosition(stmt, SKIP_BREAK); 988 SetStatementPosition(stmt, SKIP_BREAK);
993 989
994 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); 990 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
995 991
996 // Get the object to enumerate over. If the object is null or undefined, skip 992 // Get the object to enumerate over. If the object is null or undefined, skip
(...skipping 16 matching lines...) Expand all
1013 Operand(FIRST_JS_RECEIVER_TYPE)); 1009 Operand(FIRST_JS_RECEIVER_TYPE));
1014 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot. 1010 __ LoadRoot(at, Heap::kNullValueRootIndex); // In delay slot.
1015 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at)); 1011 __ Branch(USE_DELAY_SLOT, &exit, eq, a0, Operand(at));
1016 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); // In delay slot. 1012 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); // In delay slot.
1017 __ Branch(&exit, eq, a0, Operand(at)); 1013 __ Branch(&exit, eq, a0, Operand(at));
1018 __ bind(&convert); 1014 __ bind(&convert);
1019 ToObjectStub stub(isolate()); 1015 ToObjectStub stub(isolate());
1020 __ CallStub(&stub); 1016 __ CallStub(&stub);
1021 __ mov(a0, v0); 1017 __ mov(a0, v0);
1022 __ bind(&done_convert); 1018 __ bind(&done_convert);
1023 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); 1019 PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
1024 __ push(a0); 1020 __ push(a0);
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 __ ld(v0, FieldMemOperand(a0, HeapObject::kMapOffset)); 1032 __ ld(v0, FieldMemOperand(a0, HeapObject::kMapOffset));
1037 __ Branch(&use_cache); 1033 __ Branch(&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(a0); // Duplicate the enumerable object on the stack. 1037 __ push(a0); // 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 __ ld(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); 1045 __ ld(a2, FieldMemOperand(v0, HeapObject::kMapOffset));
1050 __ LoadRoot(at, Heap::kMetaMapRootIndex); 1046 __ LoadRoot(at, Heap::kMetaMapRootIndex);
1051 __ Branch(&fixed_array, ne, a2, Operand(at)); 1047 __ Branch(&fixed_array, ne, a2, Operand(at));
1052 1048
1053 // We got a map in register v0. Get the enumeration cache from it. 1049 // We got a map in register v0. Get the enumeration cache from it.
(...skipping 17 matching lines...) Expand all
1071 __ Drop(1); 1067 __ Drop(1);
1072 __ jmp(&exit); 1068 __ jmp(&exit);
1073 1069
1074 // We got a fixed array in register v0. Iterate through that. 1070 // We got a fixed array in register v0. Iterate through that.
1075 __ bind(&fixed_array); 1071 __ bind(&fixed_array);
1076 1072
1077 __ li(a1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check 1073 __ li(a1, Operand(Smi::FromInt(1))); // Smi(1) indicates slow check
1078 __ Push(a1, v0); // Smi and array 1074 __ Push(a1, v0); // Smi and array
1079 __ ld(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); 1075 __ ld(a1, FieldMemOperand(v0, FixedArray::kLengthOffset));
1080 __ Push(a1); // Fixed array length (as smi). 1076 __ Push(a1); // Fixed array length (as smi).
1081 PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); 1077 PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS);
1082 __ li(a0, Operand(Smi::FromInt(0))); 1078 __ li(a0, Operand(Smi::FromInt(0)));
1083 __ Push(a0); // Initial index. 1079 __ Push(a0); // Initial index.
1084 1080
1085 // Generate code for doing the condition check. 1081 // Generate code for doing the condition check.
1086 __ bind(&loop); 1082 __ bind(&loop);
1087 SetExpressionAsStatementPosition(stmt->each()); 1083 SetExpressionAsStatementPosition(stmt->each());
1088 1084
1089 // Load the current count to a0, load the length to a1. 1085 // Load the current count to a0, load the length to a1.
1090 __ ld(a0, MemOperand(sp, 0 * kPointerSize)); 1086 __ ld(a0, MemOperand(sp, 0 * kPointerSize));
1091 __ ld(a1, MemOperand(sp, 1 * kPointerSize)); 1087 __ ld(a1, MemOperand(sp, 1 * kPointerSize));
(...skipping 21 matching lines...) Expand all
1113 int const vector_index = SmiFromSlot(slot)->value(); 1109 int const vector_index = SmiFromSlot(slot)->value();
1114 __ EmitLoadTypeFeedbackVector(a0); 1110 __ EmitLoadTypeFeedbackVector(a0);
1115 __ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1111 __ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1116 __ sd(a2, FieldMemOperand(a0, FixedArray::OffsetOfElementAt(vector_index))); 1112 __ sd(a2, FieldMemOperand(a0, FixedArray::OffsetOfElementAt(vector_index)));
1117 1113
1118 // Convert the entry to a string or (smi) 0 if it isn't a property 1114 // Convert the entry to a string or (smi) 0 if it isn't a property
1119 // any more. If the property has been removed while iterating, we 1115 // any more. If the property has been removed while iterating, we
1120 // just skip it. 1116 // just skip it.
1121 __ Push(a1, a3); // Enumerable and current entry. 1117 __ Push(a1, a3); // Enumerable and current entry.
1122 __ CallRuntime(Runtime::kForInFilter); 1118 __ CallRuntime(Runtime::kForInFilter);
1123 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); 1119 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1124 __ mov(a3, result_register()); 1120 __ mov(a3, result_register());
1125 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 1121 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
1126 __ Branch(loop_statement.continue_label(), eq, a3, Operand(at)); 1122 __ Branch(loop_statement.continue_label(), eq, a3, Operand(at));
1127 1123
1128 // Update the 'each' property or variable from the possibly filtered 1124 // Update the 'each' property or variable from the possibly filtered
1129 // entry in register a3. 1125 // entry in register a3.
1130 __ bind(&update_each); 1126 __ bind(&update_each);
1131 __ mov(result_register(), a3); 1127 __ mov(result_register(), a3);
1132 // Perform the assignment as if via '='. 1128 // Perform the assignment as if via '='.
1133 { EffectContext context(this); 1129 { EffectContext context(this);
1134 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); 1130 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1135 PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); 1131 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS);
1136 } 1132 }
1137 1133
1138 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). 1134 // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1139 PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); 1135 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
1140 // Generate code for the body of the loop. 1136 // Generate code for the body of the loop.
1141 Visit(stmt->body()); 1137 Visit(stmt->body());
1142 1138
1143 // Generate code for the going to the next element by incrementing 1139 // Generate code for the going to the next element by incrementing
1144 // the index (smi) stored on top of the stack. 1140 // the index (smi) stored on top of the stack.
1145 __ bind(loop_statement.continue_label()); 1141 __ bind(loop_statement.continue_label());
1146 __ pop(a0); 1142 __ pop(a0);
1147 __ Daddu(a0, a0, Operand(Smi::FromInt(1))); 1143 __ Daddu(a0, a0, Operand(Smi::FromInt(1)));
1148 __ push(a0); 1144 __ push(a0);
1149 1145
1150 EmitBackEdgeBookkeeping(stmt, &loop); 1146 EmitBackEdgeBookkeeping(stmt, &loop);
1151 __ Branch(&loop); 1147 __ Branch(&loop);
1152 1148
1153 // Remove the pointers stored on the stack. 1149 // Remove the pointers stored on the stack.
1154 __ bind(loop_statement.break_label()); 1150 __ bind(loop_statement.break_label());
1155 DropOperands(5); 1151 DropOperands(5);
1156 1152
1157 // Exit and decrement the loop depth. 1153 // Exit and decrement the loop depth.
1158 PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); 1154 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1159 __ bind(&exit); 1155 __ bind(&exit);
1160 decrement_loop_depth(); 1156 decrement_loop_depth();
1161 } 1157 }
1162 1158
1163 1159
1164 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, 1160 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1165 FeedbackVectorSlot slot) { 1161 FeedbackVectorSlot slot) {
1166 DCHECK(NeedsHomeObject(initializer)); 1162 DCHECK(NeedsHomeObject(initializer));
1167 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1163 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1168 __ li(StoreDescriptor::NameRegister(), 1164 __ li(StoreDescriptor::NameRegister(),
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 __ li(LoadDescriptor::SlotRegister(), 1303 __ li(LoadDescriptor::SlotRegister(),
1308 Operand(SmiFromSlot(proxy->VariableFeedbackSlot()))); 1304 Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
1309 CallLoadIC(typeof_mode); 1305 CallLoadIC(typeof_mode);
1310 } 1306 }
1311 1307
1312 1308
1313 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1309 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1314 TypeofMode typeof_mode) { 1310 TypeofMode typeof_mode) {
1315 // Record position before possible IC call. 1311 // Record position before possible IC call.
1316 SetExpressionPosition(proxy); 1312 SetExpressionPosition(proxy);
1317 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1313 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
1318 Variable* var = proxy->var(); 1314 Variable* var = proxy->var();
1319 1315
1320 // Three cases: global variables, lookup variables, and all other types of 1316 // Three cases: global variables, lookup variables, and all other types of
1321 // variables. 1317 // variables.
1322 switch (var->location()) { 1318 switch (var->location()) {
1323 case VariableLocation::GLOBAL: 1319 case VariableLocation::GLOBAL:
1324 case VariableLocation::UNALLOCATED: { 1320 case VariableLocation::UNALLOCATED: {
1325 Comment cmnt(masm_, "[ Global variable"); 1321 Comment cmnt(masm_, "[ Global variable");
1326 EmitGlobalVariableLoad(proxy, typeof_mode); 1322 EmitGlobalVariableLoad(proxy, typeof_mode);
1327 context()->Plug(v0); 1323 context()->Plug(v0);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 __ li(a1, Operand(constant_properties)); 1410 __ li(a1, Operand(constant_properties));
1415 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); 1411 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags())));
1416 if (MustCreateObjectLiteralWithRuntime(expr)) { 1412 if (MustCreateObjectLiteralWithRuntime(expr)) {
1417 __ Push(a3, a2, a1, a0); 1413 __ Push(a3, a2, a1, a0);
1418 __ CallRuntime(Runtime::kCreateObjectLiteral); 1414 __ CallRuntime(Runtime::kCreateObjectLiteral);
1419 } else { 1415 } else {
1420 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); 1416 FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
1421 __ CallStub(&stub); 1417 __ CallStub(&stub);
1422 RestoreContext(); 1418 RestoreContext();
1423 } 1419 }
1424 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); 1420 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1425 1421
1426 // If result_saved is true the result is on top of the stack. If 1422 // If result_saved is true the result is on top of the stack. If
1427 // result_saved is false the result is in v0. 1423 // result_saved is false the result is in v0.
1428 bool result_saved = false; 1424 bool result_saved = false;
1429 1425
1430 AccessorTable accessor_table(zone()); 1426 AccessorTable accessor_table(zone());
1431 int property_index = 0; 1427 int property_index = 0;
1432 for (; property_index < expr->properties()->length(); property_index++) { 1428 for (; property_index < expr->properties()->length(); property_index++) {
1433 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1429 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1434 if (property->is_computed_name()) break; 1430 if (property->is_computed_name()) break;
(...skipping 16 matching lines...) Expand all
1451 // contains computed properties with an uninitialized value. 1447 // contains computed properties with an uninitialized value.
1452 if (key->value()->IsInternalizedString()) { 1448 if (key->value()->IsInternalizedString()) {
1453 if (property->emit_store()) { 1449 if (property->emit_store()) {
1454 VisitForAccumulatorValue(value); 1450 VisitForAccumulatorValue(value);
1455 __ mov(StoreDescriptor::ValueRegister(), result_register()); 1451 __ mov(StoreDescriptor::ValueRegister(), result_register());
1456 DCHECK(StoreDescriptor::ValueRegister().is(a0)); 1452 DCHECK(StoreDescriptor::ValueRegister().is(a0));
1457 __ li(StoreDescriptor::NameRegister(), Operand(key->value())); 1453 __ li(StoreDescriptor::NameRegister(), Operand(key->value()));
1458 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1454 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1459 EmitLoadStoreICSlot(property->GetSlot(0)); 1455 EmitLoadStoreICSlot(property->GetSlot(0));
1460 CallStoreIC(); 1456 CallStoreIC();
1461 PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); 1457 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1462 1458
1463 if (NeedsHomeObject(value)) { 1459 if (NeedsHomeObject(value)) {
1464 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); 1460 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1465 } 1461 }
1466 } else { 1462 } else {
1467 VisitForEffect(value); 1463 VisitForEffect(value);
1468 } 1464 }
1469 break; 1465 break;
1470 } 1466 }
1471 // Duplicate receiver on stack. 1467 // Duplicate receiver on stack.
(...skipping 13 matching lines...) Expand all
1485 } 1481 }
1486 break; 1482 break;
1487 case ObjectLiteral::Property::PROTOTYPE: 1483 case ObjectLiteral::Property::PROTOTYPE:
1488 // Duplicate receiver on stack. 1484 // Duplicate receiver on stack.
1489 __ ld(a0, MemOperand(sp)); 1485 __ ld(a0, MemOperand(sp));
1490 PushOperand(a0); 1486 PushOperand(a0);
1491 VisitForStackValue(value); 1487 VisitForStackValue(value);
1492 DCHECK(property->emit_store()); 1488 DCHECK(property->emit_store());
1493 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1489 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1494 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1490 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1495 BailoutState::NO_REGISTERS); 1491 NO_REGISTERS);
1496 break; 1492 break;
1497 case ObjectLiteral::Property::GETTER: 1493 case ObjectLiteral::Property::GETTER:
1498 if (property->emit_store()) { 1494 if (property->emit_store()) {
1499 accessor_table.lookup(key)->second->getter = property; 1495 accessor_table.lookup(key)->second->getter = property;
1500 } 1496 }
1501 break; 1497 break;
1502 case ObjectLiteral::Property::SETTER: 1498 case ObjectLiteral::Property::SETTER:
1503 if (property->emit_store()) { 1499 if (property->emit_store()) {
1504 accessor_table.lookup(key)->second->setter = property; 1500 accessor_table.lookup(key)->second->setter = property;
1505 } 1501 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 1538
1543 __ ld(a0, MemOperand(sp)); // Duplicate receiver. 1539 __ ld(a0, MemOperand(sp)); // Duplicate receiver.
1544 PushOperand(a0); 1540 PushOperand(a0);
1545 1541
1546 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1542 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1547 DCHECK(!property->is_computed_name()); 1543 DCHECK(!property->is_computed_name());
1548 VisitForStackValue(value); 1544 VisitForStackValue(value);
1549 DCHECK(property->emit_store()); 1545 DCHECK(property->emit_store());
1550 CallRuntimeWithOperands(Runtime::kInternalSetPrototype); 1546 CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1551 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), 1547 PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1552 BailoutState::NO_REGISTERS); 1548 NO_REGISTERS);
1553 } else { 1549 } else {
1554 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); 1550 EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1555 VisitForStackValue(value); 1551 VisitForStackValue(value);
1556 if (NeedsHomeObject(value)) { 1552 if (NeedsHomeObject(value)) {
1557 EmitSetHomeObject(value, 2, property->GetSlot()); 1553 EmitSetHomeObject(value, 2, property->GetSlot());
1558 } 1554 }
1559 1555
1560 switch (property->kind()) { 1556 switch (property->kind()) {
1561 case ObjectLiteral::Property::CONSTANT: 1557 case ObjectLiteral::Property::CONSTANT:
1562 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1558 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); 1610 __ li(a2, Operand(Smi::FromInt(expr->literal_index())));
1615 __ li(a1, Operand(constant_elements)); 1611 __ li(a1, Operand(constant_elements));
1616 if (MustCreateArrayLiteralWithRuntime(expr)) { 1612 if (MustCreateArrayLiteralWithRuntime(expr)) {
1617 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); 1613 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags())));
1618 __ Push(a3, a2, a1, a0); 1614 __ Push(a3, a2, a1, a0);
1619 __ CallRuntime(Runtime::kCreateArrayLiteral); 1615 __ CallRuntime(Runtime::kCreateArrayLiteral);
1620 } else { 1616 } else {
1621 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1617 FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1622 __ CallStub(&stub); 1618 __ CallStub(&stub);
1623 } 1619 }
1624 PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); 1620 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1625 1621
1626 bool result_saved = false; // Is the result saved to the stack? 1622 bool result_saved = false; // Is the result saved to the stack?
1627 ZoneList<Expression*>* subexprs = expr->values(); 1623 ZoneList<Expression*>* subexprs = expr->values();
1628 int length = subexprs->length(); 1624 int length = subexprs->length();
1629 1625
1630 // Emit code to evaluate all the non-constant subexpressions and to store 1626 // Emit code to evaluate all the non-constant subexpressions and to store
1631 // them into the newly cloned array. 1627 // them into the newly cloned array.
1632 int array_index = 0; 1628 int array_index = 0;
1633 for (; array_index < length; array_index++) { 1629 for (; array_index < length; array_index++) {
1634 Expression* subexpr = subexprs->at(array_index); 1630 Expression* subexpr = subexprs->at(array_index);
(...skipping 11 matching lines...) Expand all
1646 VisitForAccumulatorValue(subexpr); 1642 VisitForAccumulatorValue(subexpr);
1647 1643
1648 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index))); 1644 __ li(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index)));
1649 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 1645 __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1650 __ mov(StoreDescriptor::ValueRegister(), result_register()); 1646 __ mov(StoreDescriptor::ValueRegister(), result_register());
1651 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot()); 1647 EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1652 Handle<Code> ic = 1648 Handle<Code> ic =
1653 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 1649 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1654 CallIC(ic); 1650 CallIC(ic);
1655 1651
1656 PrepareForBailoutForId(expr->GetIdForElement(array_index), 1652 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1657 BailoutState::NO_REGISTERS);
1658 } 1653 }
1659 1654
1660 // In case the array literal contains spread expressions it has two parts. The 1655 // In case the array literal contains spread expressions it has two parts. The
1661 // first part is the "static" array which has a literal index is handled 1656 // first part is the "static" array which has a literal index is handled
1662 // above. The second part is the part after the first spread expression 1657 // above. The second part is the part after the first spread expression
1663 // (inclusive) and these elements gets appended to the array. Note that the 1658 // (inclusive) and these elements gets appended to the array. Note that the
1664 // number elements an iterable produces is unknown ahead of time. 1659 // number elements an iterable produces is unknown ahead of time.
1665 if (array_index < length && result_saved) { 1660 if (array_index < length && result_saved) {
1666 PopOperand(v0); 1661 PopOperand(v0);
1667 result_saved = false; 1662 result_saved = false;
1668 } 1663 }
1669 for (; array_index < length; array_index++) { 1664 for (; array_index < length; array_index++) {
1670 Expression* subexpr = subexprs->at(array_index); 1665 Expression* subexpr = subexprs->at(array_index);
1671 1666
1672 PushOperand(v0); 1667 PushOperand(v0);
1673 DCHECK(!subexpr->IsSpread()); 1668 DCHECK(!subexpr->IsSpread());
1674 VisitForStackValue(subexpr); 1669 VisitForStackValue(subexpr);
1675 CallRuntimeWithOperands(Runtime::kAppendElement); 1670 CallRuntimeWithOperands(Runtime::kAppendElement);
1676 1671
1677 PrepareForBailoutForId(expr->GetIdForElement(array_index), 1672 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS);
1678 BailoutState::NO_REGISTERS);
1679 } 1673 }
1680 1674
1681 if (result_saved) { 1675 if (result_saved) {
1682 context()->PlugTOS(); 1676 context()->PlugTOS();
1683 } else { 1677 } else {
1684 context()->Plug(v0); 1678 context()->Plug(v0);
1685 } 1679 }
1686 } 1680 }
1687 1681
1688 1682
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 break; 1745 break;
1752 } 1746 }
1753 1747
1754 // For compound assignments we need another deoptimization point after the 1748 // For compound assignments we need another deoptimization point after the
1755 // variable/property load. 1749 // variable/property load.
1756 if (expr->is_compound()) { 1750 if (expr->is_compound()) {
1757 { AccumulatorValueContext context(this); 1751 { AccumulatorValueContext context(this);
1758 switch (assign_type) { 1752 switch (assign_type) {
1759 case VARIABLE: 1753 case VARIABLE:
1760 EmitVariableLoad(expr->target()->AsVariableProxy()); 1754 EmitVariableLoad(expr->target()->AsVariableProxy());
1761 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); 1755 PrepareForBailout(expr->target(), TOS_REG);
1762 break; 1756 break;
1763 case NAMED_PROPERTY: 1757 case NAMED_PROPERTY:
1764 EmitNamedPropertyLoad(property); 1758 EmitNamedPropertyLoad(property);
1765 PrepareForBailoutForId(property->LoadId(), 1759 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1766 BailoutState::TOS_REGISTER);
1767 break; 1760 break;
1768 case NAMED_SUPER_PROPERTY: 1761 case NAMED_SUPER_PROPERTY:
1769 EmitNamedSuperPropertyLoad(property); 1762 EmitNamedSuperPropertyLoad(property);
1770 PrepareForBailoutForId(property->LoadId(), 1763 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1771 BailoutState::TOS_REGISTER);
1772 break; 1764 break;
1773 case KEYED_SUPER_PROPERTY: 1765 case KEYED_SUPER_PROPERTY:
1774 EmitKeyedSuperPropertyLoad(property); 1766 EmitKeyedSuperPropertyLoad(property);
1775 PrepareForBailoutForId(property->LoadId(), 1767 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1776 BailoutState::TOS_REGISTER);
1777 break; 1768 break;
1778 case KEYED_PROPERTY: 1769 case KEYED_PROPERTY:
1779 EmitKeyedPropertyLoad(property); 1770 EmitKeyedPropertyLoad(property);
1780 PrepareForBailoutForId(property->LoadId(), 1771 PrepareForBailoutForId(property->LoadId(), TOS_REG);
1781 BailoutState::TOS_REGISTER);
1782 break; 1772 break;
1783 } 1773 }
1784 } 1774 }
1785 1775
1786 Token::Value op = expr->binary_op(); 1776 Token::Value op = expr->binary_op();
1787 PushOperand(v0); // Left operand goes on the stack. 1777 PushOperand(v0); // Left operand goes on the stack.
1788 VisitForAccumulatorValue(expr->value()); 1778 VisitForAccumulatorValue(expr->value());
1789 1779
1790 AccumulatorValueContext context(this); 1780 AccumulatorValueContext context(this);
1791 if (ShouldInlineSmiCase(op)) { 1781 if (ShouldInlineSmiCase(op)) {
1792 EmitInlineSmiBinaryOp(expr->binary_operation(), 1782 EmitInlineSmiBinaryOp(expr->binary_operation(),
1793 op, 1783 op,
1794 expr->target(), 1784 expr->target(),
1795 expr->value()); 1785 expr->value());
1796 } else { 1786 } else {
1797 EmitBinaryOp(expr->binary_operation(), op); 1787 EmitBinaryOp(expr->binary_operation(), op);
1798 } 1788 }
1799 1789
1800 // Deoptimization point in case the binary operation may have side effects. 1790 // Deoptimization point in case the binary operation may have side effects.
1801 PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); 1791 PrepareForBailout(expr->binary_operation(), TOS_REG);
1802 } else { 1792 } else {
1803 VisitForAccumulatorValue(expr->value()); 1793 VisitForAccumulatorValue(expr->value());
1804 } 1794 }
1805 1795
1806 SetExpressionPosition(expr); 1796 SetExpressionPosition(expr);
1807 1797
1808 // Store the value. 1798 // Store the value.
1809 switch (assign_type) { 1799 switch (assign_type) {
1810 case VARIABLE: 1800 case VARIABLE:
1811 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1801 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1812 expr->op(), expr->AssignmentSlot()); 1802 expr->op(), expr->AssignmentSlot());
1813 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 1803 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
1814 context()->Plug(v0); 1804 context()->Plug(v0);
1815 break; 1805 break;
1816 case NAMED_PROPERTY: 1806 case NAMED_PROPERTY:
1817 EmitNamedPropertyAssignment(expr); 1807 EmitNamedPropertyAssignment(expr);
1818 break; 1808 break;
1819 case NAMED_SUPER_PROPERTY: 1809 case NAMED_SUPER_PROPERTY:
1820 EmitNamedSuperPropertyStore(property); 1810 EmitNamedSuperPropertyStore(property);
1821 context()->Plug(v0); 1811 context()->Plug(v0);
1822 break; 1812 break;
1823 case KEYED_SUPER_PROPERTY: 1813 case KEYED_SUPER_PROPERTY:
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 DCHECK(prop != NULL); 2268 DCHECK(prop != NULL);
2279 DCHECK(prop->key()->IsLiteral()); 2269 DCHECK(prop->key()->IsLiteral());
2280 2270
2281 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2271 __ mov(StoreDescriptor::ValueRegister(), result_register());
2282 __ li(StoreDescriptor::NameRegister(), 2272 __ li(StoreDescriptor::NameRegister(),
2283 Operand(prop->key()->AsLiteral()->value())); 2273 Operand(prop->key()->AsLiteral()->value()));
2284 PopOperand(StoreDescriptor::ReceiverRegister()); 2274 PopOperand(StoreDescriptor::ReceiverRegister());
2285 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2275 EmitLoadStoreICSlot(expr->AssignmentSlot());
2286 CallStoreIC(); 2276 CallStoreIC();
2287 2277
2288 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2278 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2289 context()->Plug(v0); 2279 context()->Plug(v0);
2290 } 2280 }
2291 2281
2292 2282
2293 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2283 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2294 // Assignment to named property of super. 2284 // Assignment to named property of super.
2295 // v0 : value 2285 // v0 : value
2296 // stack : receiver ('this'), home_object 2286 // stack : receiver ('this'), home_object
2297 DCHECK(prop != NULL); 2287 DCHECK(prop != NULL);
2298 Literal* key = prop->key()->AsLiteral(); 2288 Literal* key = prop->key()->AsLiteral();
(...skipping 30 matching lines...) Expand all
2329 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2319 __ mov(StoreDescriptor::ValueRegister(), result_register());
2330 PopOperands(StoreDescriptor::ReceiverRegister(), 2320 PopOperands(StoreDescriptor::ReceiverRegister(),
2331 StoreDescriptor::NameRegister()); 2321 StoreDescriptor::NameRegister());
2332 DCHECK(StoreDescriptor::ValueRegister().is(a0)); 2322 DCHECK(StoreDescriptor::ValueRegister().is(a0));
2333 2323
2334 Handle<Code> ic = 2324 Handle<Code> ic =
2335 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2325 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2336 EmitLoadStoreICSlot(expr->AssignmentSlot()); 2326 EmitLoadStoreICSlot(expr->AssignmentSlot());
2337 CallIC(ic); 2327 CallIC(ic);
2338 2328
2339 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2329 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2340 context()->Plug(v0); 2330 context()->Plug(v0);
2341 } 2331 }
2342 2332
2343 2333
2344 void FullCodeGenerator::CallIC(Handle<Code> code, 2334 void FullCodeGenerator::CallIC(Handle<Code> code,
2345 TypeFeedbackId id) { 2335 TypeFeedbackId id) {
2346 ic_total_count_++; 2336 ic_total_count_++;
2347 __ Call(code, RelocInfo::CODE_TARGET, id); 2337 __ Call(code, RelocInfo::CODE_TARGET, id);
2348 } 2338 }
2349 2339
2350 2340
2351 // Code common for calls using the IC. 2341 // Code common for calls using the IC.
2352 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2342 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2353 Expression* callee = expr->expression(); 2343 Expression* callee = expr->expression();
2354 2344
2355 // Get the target function. 2345 // Get the target function.
2356 ConvertReceiverMode convert_mode; 2346 ConvertReceiverMode convert_mode;
2357 if (callee->IsVariableProxy()) { 2347 if (callee->IsVariableProxy()) {
2358 { StackValueContext context(this); 2348 { StackValueContext context(this);
2359 EmitVariableLoad(callee->AsVariableProxy()); 2349 EmitVariableLoad(callee->AsVariableProxy());
2360 PrepareForBailout(callee, BailoutState::NO_REGISTERS); 2350 PrepareForBailout(callee, NO_REGISTERS);
2361 } 2351 }
2362 // Push undefined as receiver. This is patched in the method prologue if it 2352 // Push undefined as receiver. This is patched in the method prologue if it
2363 // is a sloppy mode method. 2353 // is a sloppy mode method.
2364 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 2354 __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
2365 PushOperand(at); 2355 PushOperand(at);
2366 convert_mode = ConvertReceiverMode::kNullOrUndefined; 2356 convert_mode = ConvertReceiverMode::kNullOrUndefined;
2367 } else { 2357 } else {
2368 // Load the function from the receiver. 2358 // Load the function from the receiver.
2369 DCHECK(callee->IsProperty()); 2359 DCHECK(callee->IsProperty());
2370 DCHECK(!callee->AsProperty()->IsSuperAccess()); 2360 DCHECK(!callee->AsProperty()->IsSuperAccess());
2371 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2361 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2372 EmitNamedPropertyLoad(callee->AsProperty()); 2362 EmitNamedPropertyLoad(callee->AsProperty());
2373 PrepareForBailoutForId(callee->AsProperty()->LoadId(), 2363 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2374 BailoutState::TOS_REGISTER);
2375 // Push the target function under the receiver. 2364 // Push the target function under the receiver.
2376 __ ld(at, MemOperand(sp, 0)); 2365 __ ld(at, MemOperand(sp, 0));
2377 PushOperand(at); 2366 PushOperand(at);
2378 __ sd(v0, MemOperand(sp, kPointerSize)); 2367 __ sd(v0, MemOperand(sp, kPointerSize));
2379 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; 2368 convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
2380 } 2369 }
2381 2370
2382 EmitCall(expr, convert_mode); 2371 EmitCall(expr, convert_mode);
2383 } 2372 }
2384 2373
(...skipping 16 matching lines...) Expand all
2401 PushOperands(scratch, v0, v0, scratch); 2390 PushOperands(scratch, v0, v0, scratch);
2402 PushOperand(key->value()); 2391 PushOperand(key->value());
2403 2392
2404 // Stack here: 2393 // Stack here:
2405 // - home_object 2394 // - home_object
2406 // - this (receiver) 2395 // - this (receiver)
2407 // - this (receiver) <-- LoadFromSuper will pop here and below. 2396 // - this (receiver) <-- LoadFromSuper will pop here and below.
2408 // - home_object 2397 // - home_object
2409 // - key 2398 // - key
2410 CallRuntimeWithOperands(Runtime::kLoadFromSuper); 2399 CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2411 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); 2400 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
2412 2401
2413 // Replace home_object with target function. 2402 // Replace home_object with target function.
2414 __ sd(v0, MemOperand(sp, kPointerSize)); 2403 __ sd(v0, MemOperand(sp, kPointerSize));
2415 2404
2416 // Stack here: 2405 // Stack here:
2417 // - target function 2406 // - target function
2418 // - this (receiver) 2407 // - this (receiver)
2419 EmitCall(expr); 2408 EmitCall(expr);
2420 } 2409 }
2421 2410
2422 2411
2423 // Code common for calls using the IC. 2412 // Code common for calls using the IC.
2424 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2413 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2425 Expression* key) { 2414 Expression* key) {
2426 // Load the key. 2415 // Load the key.
2427 VisitForAccumulatorValue(key); 2416 VisitForAccumulatorValue(key);
2428 2417
2429 Expression* callee = expr->expression(); 2418 Expression* callee = expr->expression();
2430 2419
2431 // Load the function from the receiver. 2420 // Load the function from the receiver.
2432 DCHECK(callee->IsProperty()); 2421 DCHECK(callee->IsProperty());
2433 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); 2422 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2434 __ Move(LoadDescriptor::NameRegister(), v0); 2423 __ Move(LoadDescriptor::NameRegister(), v0);
2435 EmitKeyedPropertyLoad(callee->AsProperty()); 2424 EmitKeyedPropertyLoad(callee->AsProperty());
2436 PrepareForBailoutForId(callee->AsProperty()->LoadId(), 2425 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2437 BailoutState::TOS_REGISTER);
2438 2426
2439 // Push the target function under the receiver. 2427 // Push the target function under the receiver.
2440 __ ld(at, MemOperand(sp, 0)); 2428 __ ld(at, MemOperand(sp, 0));
2441 PushOperand(at); 2429 PushOperand(at);
2442 __ sd(v0, MemOperand(sp, kPointerSize)); 2430 __ sd(v0, MemOperand(sp, kPointerSize));
2443 2431
2444 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); 2432 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
2445 } 2433 }
2446 2434
2447 2435
(...skipping 13 matching lines...) Expand all
2461 PushOperands(scratch, v0, v0, scratch); 2449 PushOperands(scratch, v0, v0, scratch);
2462 VisitForStackValue(prop->key()); 2450 VisitForStackValue(prop->key());
2463 2451
2464 // Stack here: 2452 // Stack here:
2465 // - home_object 2453 // - home_object
2466 // - this (receiver) 2454 // - this (receiver)
2467 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. 2455 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2468 // - home_object 2456 // - home_object
2469 // - key 2457 // - key
2470 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); 2458 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2471 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); 2459 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
2472 2460
2473 // Replace home_object with target function. 2461 // Replace home_object with target function.
2474 __ sd(v0, MemOperand(sp, kPointerSize)); 2462 __ sd(v0, MemOperand(sp, kPointerSize));
2475 2463
2476 // Stack here: 2464 // Stack here:
2477 // - target function 2465 // - target function
2478 // - this (receiver) 2466 // - this (receiver)
2479 EmitCall(expr); 2467 EmitCall(expr);
2480 } 2468 }
2481 2469
2482 2470
2483 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { 2471 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2484 // Load the arguments. 2472 // Load the arguments.
2485 ZoneList<Expression*>* args = expr->arguments(); 2473 ZoneList<Expression*>* args = expr->arguments();
2486 int arg_count = args->length(); 2474 int arg_count = args->length();
2487 for (int i = 0; i < arg_count; i++) { 2475 for (int i = 0; i < arg_count; i++) {
2488 VisitForStackValue(args->at(i)); 2476 VisitForStackValue(args->at(i));
2489 } 2477 }
2490 2478
2491 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); 2479 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
2492 // Record source position of the IC call. 2480 // Record source position of the IC call.
2493 SetCallPosition(expr, expr->tail_call_mode()); 2481 SetCallPosition(expr, expr->tail_call_mode());
2494 if (expr->tail_call_mode() == TailCallMode::kAllow) { 2482 if (expr->tail_call_mode() == TailCallMode::kAllow) {
2495 if (FLAG_trace) { 2483 if (FLAG_trace) {
2496 __ CallRuntime(Runtime::kTraceTailCall); 2484 __ CallRuntime(Runtime::kTraceTailCall);
2497 } 2485 }
2498 // Update profiling counters before the tail call since we will 2486 // Update profiling counters before the tail call since we will
2499 // not return to this function. 2487 // not return to this function.
2500 EmitProfilingCounterHandlingForReturnSequence(true); 2488 EmitProfilingCounterHandlingForReturnSequence(true);
2501 } 2489 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2551 // Generate code for loading from variables potentially shadowed by 2539 // Generate code for loading from variables potentially shadowed by
2552 // eval-introduced variables. 2540 // eval-introduced variables.
2553 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); 2541 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
2554 2542
2555 __ bind(&slow); 2543 __ bind(&slow);
2556 // Call the runtime to find the function to call (returned in v0) 2544 // Call the runtime to find the function to call (returned in v0)
2557 // and the object holding it (returned in v1). 2545 // and the object holding it (returned in v1).
2558 __ Push(callee->name()); 2546 __ Push(callee->name());
2559 __ CallRuntime(Runtime::kLoadLookupSlotForCall); 2547 __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2560 PushOperands(v0, v1); // Function, receiver. 2548 PushOperands(v0, v1); // Function, receiver.
2561 PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); 2549 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS);
2562 2550
2563 // If fast case code has been generated, emit code to push the 2551 // If fast case code has been generated, emit code to push the
2564 // function and receiver and have the slow path jump around this 2552 // function and receiver and have the slow path jump around this
2565 // code. 2553 // code.
2566 if (done.is_linked()) { 2554 if (done.is_linked()) {
2567 Label call; 2555 Label call;
2568 __ Branch(&call); 2556 __ Branch(&call);
2569 __ bind(&done); 2557 __ bind(&done);
2570 // Push function. 2558 // Push function.
2571 __ push(v0); 2559 __ push(v0);
(...skipping 27 matching lines...) Expand all
2599 2587
2600 // Push a copy of the function (found below the arguments) and 2588 // Push a copy of the function (found below the arguments) and
2601 // resolve eval. 2589 // resolve eval.
2602 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2590 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2603 __ push(a1); 2591 __ push(a1);
2604 EmitResolvePossiblyDirectEval(expr); 2592 EmitResolvePossiblyDirectEval(expr);
2605 2593
2606 // Touch up the stack with the resolved function. 2594 // Touch up the stack with the resolved function.
2607 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2595 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2608 2596
2609 PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); 2597 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
2610 // Record source position for debugger. 2598 // Record source position for debugger.
2611 SetCallPosition(expr); 2599 SetCallPosition(expr);
2612 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2600 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2613 __ li(a0, Operand(arg_count)); 2601 __ li(a0, Operand(arg_count));
2614 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny, 2602 __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2615 expr->tail_call_mode()), 2603 expr->tail_call_mode()),
2616 RelocInfo::CODE_TARGET); 2604 RelocInfo::CODE_TARGET);
2617 OperandStackDepthDecrement(arg_count + 1); 2605 OperandStackDepthDecrement(arg_count + 1);
2618 RecordJSReturnSite(expr); 2606 RecordJSReturnSite(expr);
2619 RestoreContext(); 2607 RestoreContext();
(...skipping 28 matching lines...) Expand all
2648 __ li(a0, Operand(arg_count)); 2636 __ li(a0, Operand(arg_count));
2649 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); 2637 __ ld(a1, MemOperand(sp, arg_count * kPointerSize));
2650 2638
2651 // Record call targets in unoptimized code. 2639 // Record call targets in unoptimized code.
2652 __ EmitLoadTypeFeedbackVector(a2); 2640 __ EmitLoadTypeFeedbackVector(a2);
2653 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot()))); 2641 __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2654 2642
2655 CallConstructStub stub(isolate()); 2643 CallConstructStub stub(isolate());
2656 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); 2644 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2657 OperandStackDepthDecrement(arg_count + 1); 2645 OperandStackDepthDecrement(arg_count + 1);
2658 PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); 2646 PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
2659 RestoreContext(); 2647 RestoreContext();
2660 context()->Plug(v0); 2648 context()->Plug(v0);
2661 } 2649 }
2662 2650
2663 2651
2664 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) { 2652 void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2665 SuperCallReference* super_call_ref = 2653 SuperCallReference* super_call_ref =
2666 expr->expression()->AsSuperCallReference(); 2654 expr->expression()->AsSuperCallReference();
2667 DCHECK_NOT_NULL(super_call_ref); 2655 DCHECK_NOT_NULL(super_call_ref);
2668 2656
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
3096 } 3084 }
3097 3085
3098 3086
3099 void FullCodeGenerator::EmitCall(CallRuntime* expr) { 3087 void FullCodeGenerator::EmitCall(CallRuntime* expr) {
3100 ZoneList<Expression*>* args = expr->arguments(); 3088 ZoneList<Expression*>* args = expr->arguments();
3101 DCHECK_LE(2, args->length()); 3089 DCHECK_LE(2, args->length());
3102 // Push target, receiver and arguments onto the stack. 3090 // Push target, receiver and arguments onto the stack.
3103 for (Expression* const arg : *args) { 3091 for (Expression* const arg : *args) {
3104 VisitForStackValue(arg); 3092 VisitForStackValue(arg);
3105 } 3093 }
3106 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); 3094 PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
3107 // Move target to a1. 3095 // Move target to a1.
3108 int const argc = args->length() - 2; 3096 int const argc = args->length() - 2;
3109 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize)); 3097 __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize));
3110 // Call the target. 3098 // Call the target.
3111 __ li(a0, Operand(argc)); 3099 __ li(a0, Operand(argc));
3112 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 3100 __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
3113 OperandStackDepthDecrement(argc + 1); 3101 OperandStackDepthDecrement(argc + 1);
3114 RestoreContext(); 3102 RestoreContext();
3115 // Discard the function left on TOS. 3103 // Discard the function left on TOS.
3116 context()->DropAndPlug(1, v0); 3104 context()->DropAndPlug(1, v0);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3307 // because we need to prepare a pair of extra administrative AST ids 3295 // because we need to prepare a pair of extra administrative AST ids
3308 // for the optimizing compiler. 3296 // for the optimizing compiler.
3309 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 3297 DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
3310 Label materialize_true, materialize_false, done; 3298 Label materialize_true, materialize_false, done;
3311 VisitForControl(expr->expression(), 3299 VisitForControl(expr->expression(),
3312 &materialize_false, 3300 &materialize_false,
3313 &materialize_true, 3301 &materialize_true,
3314 &materialize_true); 3302 &materialize_true);
3315 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); 3303 if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
3316 __ bind(&materialize_true); 3304 __ bind(&materialize_true);
3317 PrepareForBailoutForId(expr->MaterializeTrueId(), 3305 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
3318 BailoutState::NO_REGISTERS);
3319 __ LoadRoot(v0, Heap::kTrueValueRootIndex); 3306 __ LoadRoot(v0, Heap::kTrueValueRootIndex);
3320 if (context()->IsStackValue()) __ push(v0); 3307 if (context()->IsStackValue()) __ push(v0);
3321 __ jmp(&done); 3308 __ jmp(&done);
3322 __ bind(&materialize_false); 3309 __ bind(&materialize_false);
3323 PrepareForBailoutForId(expr->MaterializeFalseId(), 3310 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
3324 BailoutState::NO_REGISTERS);
3325 __ LoadRoot(v0, Heap::kFalseValueRootIndex); 3311 __ LoadRoot(v0, Heap::kFalseValueRootIndex);
3326 if (context()->IsStackValue()) __ push(v0); 3312 if (context()->IsStackValue()) __ push(v0);
3327 __ bind(&done); 3313 __ bind(&done);
3328 } 3314 }
3329 break; 3315 break;
3330 } 3316 }
3331 3317
3332 case Token::TYPEOF: { 3318 case Token::TYPEOF: {
3333 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 3319 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3334 { 3320 {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3414 } 3400 }
3415 3401
3416 case VARIABLE: 3402 case VARIABLE:
3417 UNREACHABLE(); 3403 UNREACHABLE();
3418 } 3404 }
3419 } 3405 }
3420 3406
3421 // We need a second deoptimization point after loading the value 3407 // We need a second deoptimization point after loading the value
3422 // in case evaluating the property load my have a side effect. 3408 // in case evaluating the property load my have a side effect.
3423 if (assign_type == VARIABLE) { 3409 if (assign_type == VARIABLE) {
3424 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); 3410 PrepareForBailout(expr->expression(), TOS_REG);
3425 } else { 3411 } else {
3426 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); 3412 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
3427 } 3413 }
3428 3414
3429 // Inline smi case if we are in a loop. 3415 // Inline smi case if we are in a loop.
3430 Label stub_call, done; 3416 Label stub_call, done;
3431 JumpPatchSite patch_site(masm_); 3417 JumpPatchSite patch_site(masm_);
3432 3418
3433 int count_value = expr->op() == Token::INC ? 1 : -1; 3419 int count_value = expr->op() == Token::INC ? 1 : -1;
3434 __ mov(a0, v0); 3420 __ mov(a0, v0);
3435 if (ShouldInlineSmiCase(expr->op())) { 3421 if (ShouldInlineSmiCase(expr->op())) {
3436 Label slow; 3422 Label slow;
(...skipping 30 matching lines...) Expand all
3467 __ DaddBranchNoOvf(v0, v0, Operand(scratch1), &done); 3453 __ DaddBranchNoOvf(v0, v0, Operand(scratch1), &done);
3468 // Call stub. Undo operation first. 3454 // Call stub. Undo operation first.
3469 __ Move(v0, a0); 3455 __ Move(v0, a0);
3470 __ jmp(&stub_call); 3456 __ jmp(&stub_call);
3471 __ bind(&slow); 3457 __ bind(&slow);
3472 } 3458 }
3473 3459
3474 // Convert old value into a number. 3460 // Convert old value into a number.
3475 ToNumberStub convert_stub(isolate()); 3461 ToNumberStub convert_stub(isolate());
3476 __ CallStub(&convert_stub); 3462 __ CallStub(&convert_stub);
3477 PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); 3463 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG);
3478 3464
3479 // Save result for postfix expressions. 3465 // Save result for postfix expressions.
3480 if (expr->is_postfix()) { 3466 if (expr->is_postfix()) {
3481 if (!context()->IsEffect()) { 3467 if (!context()->IsEffect()) {
3482 // Save the result on the stack. If we have a named or keyed property 3468 // Save the result on the stack. If we have a named or keyed property
3483 // we store the result under the receiver that is currently on top 3469 // we store the result under the receiver that is currently on top
3484 // of the stack. 3470 // of the stack.
3485 switch (assign_type) { 3471 switch (assign_type) {
3486 case VARIABLE: 3472 case VARIABLE:
3487 PushOperand(v0); 3473 PushOperand(v0);
(...skipping 25 matching lines...) Expand all
3513 patch_site.EmitPatchInfo(); 3499 patch_site.EmitPatchInfo();
3514 __ bind(&done); 3500 __ bind(&done);
3515 3501
3516 // Store the value returned in v0. 3502 // Store the value returned in v0.
3517 switch (assign_type) { 3503 switch (assign_type) {
3518 case VARIABLE: 3504 case VARIABLE:
3519 if (expr->is_postfix()) { 3505 if (expr->is_postfix()) {
3520 { EffectContext context(this); 3506 { EffectContext context(this);
3521 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3507 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3522 Token::ASSIGN, expr->CountSlot()); 3508 Token::ASSIGN, expr->CountSlot());
3523 PrepareForBailoutForId(expr->AssignmentId(), 3509 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3524 BailoutState::TOS_REGISTER);
3525 context.Plug(v0); 3510 context.Plug(v0);
3526 } 3511 }
3527 // For all contexts except EffectConstant we have the result on 3512 // For all contexts except EffectConstant we have the result on
3528 // top of the stack. 3513 // top of the stack.
3529 if (!context()->IsEffect()) { 3514 if (!context()->IsEffect()) {
3530 context()->PlugTOS(); 3515 context()->PlugTOS();
3531 } 3516 }
3532 } else { 3517 } else {
3533 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3518 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3534 Token::ASSIGN, expr->CountSlot()); 3519 Token::ASSIGN, expr->CountSlot());
3535 PrepareForBailoutForId(expr->AssignmentId(), 3520 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3536 BailoutState::TOS_REGISTER);
3537 context()->Plug(v0); 3521 context()->Plug(v0);
3538 } 3522 }
3539 break; 3523 break;
3540 case NAMED_PROPERTY: { 3524 case NAMED_PROPERTY: {
3541 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3525 __ mov(StoreDescriptor::ValueRegister(), result_register());
3542 __ li(StoreDescriptor::NameRegister(), 3526 __ li(StoreDescriptor::NameRegister(),
3543 Operand(prop->key()->AsLiteral()->value())); 3527 Operand(prop->key()->AsLiteral()->value()));
3544 PopOperand(StoreDescriptor::ReceiverRegister()); 3528 PopOperand(StoreDescriptor::ReceiverRegister());
3545 EmitLoadStoreICSlot(expr->CountSlot()); 3529 EmitLoadStoreICSlot(expr->CountSlot());
3546 CallStoreIC(); 3530 CallStoreIC();
3547 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 3531 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3548 if (expr->is_postfix()) { 3532 if (expr->is_postfix()) {
3549 if (!context()->IsEffect()) { 3533 if (!context()->IsEffect()) {
3550 context()->PlugTOS(); 3534 context()->PlugTOS();
3551 } 3535 }
3552 } else { 3536 } else {
3553 context()->Plug(v0); 3537 context()->Plug(v0);
3554 } 3538 }
3555 break; 3539 break;
3556 } 3540 }
3557 case NAMED_SUPER_PROPERTY: { 3541 case NAMED_SUPER_PROPERTY: {
(...skipping 19 matching lines...) Expand all
3577 break; 3561 break;
3578 } 3562 }
3579 case KEYED_PROPERTY: { 3563 case KEYED_PROPERTY: {
3580 __ mov(StoreDescriptor::ValueRegister(), result_register()); 3564 __ mov(StoreDescriptor::ValueRegister(), result_register());
3581 PopOperands(StoreDescriptor::ReceiverRegister(), 3565 PopOperands(StoreDescriptor::ReceiverRegister(),
3582 StoreDescriptor::NameRegister()); 3566 StoreDescriptor::NameRegister());
3583 Handle<Code> ic = 3567 Handle<Code> ic =
3584 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 3568 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3585 EmitLoadStoreICSlot(expr->CountSlot()); 3569 EmitLoadStoreICSlot(expr->CountSlot());
3586 CallIC(ic); 3570 CallIC(ic);
3587 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 3571 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3588 if (expr->is_postfix()) { 3572 if (expr->is_postfix()) {
3589 if (!context()->IsEffect()) { 3573 if (!context()->IsEffect()) {
3590 context()->PlugTOS(); 3574 context()->PlugTOS();
3591 } 3575 }
3592 } else { 3576 } else {
3593 context()->Plug(v0); 3577 context()->Plug(v0);
3594 } 3578 }
3595 break; 3579 break;
3596 } 3580 }
3597 } 3581 }
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
3968 reinterpret_cast<uint64_t>( 3952 reinterpret_cast<uint64_t>(
3969 isolate->builtins()->OnStackReplacement()->entry())); 3953 isolate->builtins()->OnStackReplacement()->entry()));
3970 return ON_STACK_REPLACEMENT; 3954 return ON_STACK_REPLACEMENT;
3971 } 3955 }
3972 3956
3973 3957
3974 } // namespace internal 3958 } // namespace internal
3975 } // namespace v8 3959 } // namespace v8
3976 3960
3977 #endif // V8_TARGET_ARCH_MIPS64 3961 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/full-codegen/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698