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

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

Powered by Google App Engine
This is Rietveld 408576698